diff --git a/Documentation/ABI/stable/sysfs-fs-orangefs b/Documentation/ABI/stable/sysfs-fs-orangefs
new file mode 100644
index 000000000000..affdb114bd33
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-fs-orangefs
@@ -0,0 +1,87 @@
+What:			/sys/fs/orangefs/perf_counters/*
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Counters and settings for various caches.
+			Read only.
+
+
+What:			/sys/fs/orangefs/perf_counter_reset
+Date:			June 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			echo a 0 or a 1 into perf_counter_reset to
+			reset all the counters in
+			/sys/fs/orangefs/perf_counters
+			except ones with PINT_PERF_PRESERVE set.
+
+
+What:			/sys/fs/orangefs/perf_time_interval_secs
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Length of perf counter intervals in
+			seconds.
+
+
+What:			/sys/fs/orangefs/perf_history_size
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			The perf_counters cache statistics have N, or
+			perf_history_size, samples. The default is
+			one.
+
+			Every perf_time_interval_secs the (first)
+			samples are reset.
+
+			If N is greater than one, the "current" set
+			of samples is reset, and the samples from the
+			other N-1 intervals remain available.
+
+
+What:			/sys/fs/orangefs/op_timeout_secs
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Service operation timeout in seconds.
+
+
+What:			/sys/fs/orangefs/slot_timeout_secs
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			"Slot" timeout in seconds. A "slot"
+			is an indexed buffer in the shared
+			memory segment used for communication
+			between the kernel module and userspace.
+			Slots are requested and waited for,
+			the wait times out after slot_timeout_secs.
+
+
+What:			/sys/fs/orangefs/acache/*
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Attribute cache configurable settings.
+
+
+What:			/sys/fs/orangefs/ncache/*
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Name cache configurable settings.
+
+
+What:			/sys/fs/orangefs/capcache/*
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Capability cache configurable settings.
+
+
+What:			/sys/fs/orangefs/ccache/*
+Date:			Jun 2015
+Contact:		Mike Marshall <hubcap@omnibond.com>
+Description:
+			Credential cache configurable settings.
diff --git a/Documentation/DocBook/.gitignore b/Documentation/DocBook/.gitignore
index 7ebd5465d927..e05da3f7aa21 100644
--- a/Documentation/DocBook/.gitignore
+++ b/Documentation/DocBook/.gitignore
@@ -11,5 +11,7 @@
 *.png
 *.gif
 *.svg
+*.proc
+*.db
 media-indices.tmpl
 media-entities.tmpl
diff --git a/Documentation/Makefile b/Documentation/Makefile
index bc0548201755..e2127a76b5d6 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,4 +1,4 @@
 subdir-y := accounting auxdisplay blackfin connector \
-	filesystems filesystems ia64 laptops mic misc-devices \
+	filesystems filesystems ia64 kdbus laptops mic misc-devices \
 	networking pcmcia prctl ptp spi timers vDSO video4linux \
 	watchdog
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index b19fc34efdb1..c9d1cacb4395 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -542,6 +542,10 @@ The routines xchg() and cmpxchg() must provide the same exact
 memory-barrier semantics as the atomic and bit operations returning
 values.
 
+Note: If someone wants to use xchg(), cmpxchg() and their variants,
+linux/atomic.h should be included rather than asm/cmpxchg.h, unless
+the code is in arch/* and can take care of itself.
+
 Spinlocks and rwlocks have memory barrier expectations as well.
 The rule to follow is simple:
 
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index 2d6356d8daf4..bf5fc59a6938 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -10,6 +10,7 @@ Properties:
 		   - "samsung,exynos5260-pmu" - for Exynos5260 SoC.
 		   - "samsung,exynos5410-pmu" - for Exynos5410 SoC,
 		   - "samsung,exynos5420-pmu" - for Exynos5420 SoC.
+		   - "samsung,exynos5433-pmu" - for Exynos5433 SoC.
 		   - "samsung,exynos7-pmu" - for Exynos7 SoC.
 		second value must be always "syscon".
 
diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
new file mode 100644
index 000000000000..b614e3b1008b
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
@@ -0,0 +1,21 @@
+Binding for Freescale QorIQ AHCI SATA Controller
+
+Required properties:
+  - reg: Physical base address and size of the controller's register area.
+  - compatible: Compatibility string. Must be 'fsl,<chip>-ahci', where
+    chip could be ls1021a, ls2085a, ls1043a etc.
+  - clocks: Input clock specifier. Refer to common clock bindings.
+  - interrupts: Interrupt specifier. Refer to interrupt binding.
+
+Optional properties:
+  - dma-coherent: Enable ACHI coherency DMA operation.
+  - reg-names: register area names when there are more then 1 regster area.
+
+Examples:
+	sata@3200000 {
+		compatible = "fsl,ls1021a-ahci";
+		reg = <0x0 0x3200000 0x0 0x10000>;
+		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&platform_clk 1>;
+		dma-coherent;
+	};
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index a2321819e7f5..c2340eeeb97f 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -16,8 +16,6 @@ Required properties:
   - "snps,dwc-ahci"
   - "snps,exynos5440-ahci"
   - "snps,spear-ahci"
-  - "fsl,qoriq-ahci" : for qoriq series socs which include ls1021, ls2085, etc.
-  - "fsl,<chip>-ahci" : chip could be ls1021, ls2085 etc.
   - "generic-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
 - reg               : <registers mapping>
diff --git a/Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt b/Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt
index 36c2b528245c..399e0da22348 100644
--- a/Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt
@@ -2,7 +2,7 @@
 
 Required Properties:
 
-  - compatible: Must be "renesas,sh73a0-h8300-div-clock"
+  - compatible: Must be "renesas,h8300-div-clock"
 
   - clocks: Reference to the parent clocks ("extal1" and "extal2")
 
diff --git a/Documentation/devicetree/bindings/hwmon/pwm-fan.txt b/Documentation/devicetree/bindings/hwmon/pwm-fan.txt
index 610757ce4492..c6d533202d3e 100644
--- a/Documentation/devicetree/bindings/hwmon/pwm-fan.txt
+++ b/Documentation/devicetree/bindings/hwmon/pwm-fan.txt
@@ -3,10 +3,35 @@ Bindings for a fan connected to the PWM lines
 Required properties:
 - compatible	: "pwm-fan"
 - pwms		: the PWM that is used to control the PWM fan
+- cooling-levels      : PWM duty cycle values in a range from 0 to 255
+			which correspond to thermal cooling states
 
 Example:
-	pwm-fan {
+	fan0: pwm-fan {
 		compatible = "pwm-fan";
-		status = "okay";
+		cooling-min-state = <0>;
+		cooling-max-state = <3>;
+		#cooling-cells = <2>;
 		pwms = <&pwm 0 10000 0>;
+		cooling-levels = <0 102 170 230>;
 	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			     thermal-sensors = <&tmu 0>;
+			     polling-delay-passive = <0>;
+			     polling-delay = <0>;
+			     trips {
+					cpu_alert1: cpu-alert1 {
+						    temperature = <100000>; /* millicelsius */
+						    hysteresis = <2000>; /* millicelsius */
+						    type = "passive";
+					};
+			     };
+			     cooling-maps {
+					map0 {
+						    trip = <&cpu_alert1>;
+						    cooling-device = <&fan0 0 1>;
+					};
+			     };
+		};
diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
index 57a045016fca..90eaef393325 100644
--- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
+++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
@@ -15,6 +15,10 @@ Optional properties:
 - interrupt-parent: Specifies the phandle of the interrupt controller to which
   the interrupts from s2mps11 are delivered to.
 - interrupts: Interrupt specifiers for interrupt sources.
+- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
+  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
+  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
+  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
 
 Optional nodes:
 - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
diff --git a/Documentation/devicetree/bindings/regulator/pbias-regulator.txt b/Documentation/devicetree/bindings/regulator/pbias-regulator.txt
index 32aa26f1e434..acbcb452a69a 100644
--- a/Documentation/devicetree/bindings/regulator/pbias-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/pbias-regulator.txt
@@ -2,7 +2,12 @@ PBIAS internal regulator for SD card dual voltage i/o pads on OMAP SoCs.
 
 Required properties:
 - compatible:
-  - "ti,pbias-omap" for OMAP2, OMAP3, OMAP4, OMAP5, DRA7.
+  - should be "ti,pbias-dra7" for DRA7
+  - should be "ti,pbias-omap2" for OMAP2
+  - should be "ti,pbias-omap3" for OMAP3
+  - should be "ti,pbias-omap4" for OMAP4
+  - should be "ti,pbias-omap5" for OMAP5
+  - "ti,pbias-omap" is deprecated
 - reg: pbias register offset from syscon base and size of pbias register.
 - syscon : phandle of the system control module
 - regulator-name : should be
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
index dcefc438272f..6160ffbcb3d3 100644
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
@@ -15,17 +15,18 @@ Required properties:
 - interrupts: Should contain spi interrupt
 
 - clocks: phandles to input clocks.
-  The first should be <&topckgen CLK_TOP_SPI_SEL>.
-  The second should be one of the following.
+  The first should be one of the following. It's PLL.
    -  <&clk26m>: specify parent clock 26MHZ.
    -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
 				      It's the default one.
    -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
    -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
    -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
+  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
+  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
 
-- clock-names: shall be "spi-clk" for the controller clock, and
-  "parent-clk" for the parent clock.
+- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
+  muxes clock, and "spi-clk" for the clock gate.
 
 Optional properties:
 - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
@@ -44,8 +45,11 @@ spi: spi@1100a000 {
 	#size-cells = <0>;
 	reg = <0 0x1100a000 0 0x1000>;
 	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
-	clock-names = "spi-clk", "parent-clk";
+	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+		 <&topckgen CLK_TOP_SPI_SEL>,
+		 <&pericfg CLK_PERI_SPI0>;
+	clock-names = "parent-clk", "sel-clk", "spi-clk";
+
 	mediatek,pad-select = <0>;
 	status = "disabled";
 };
diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt
new file mode 100644
index 000000000000..ec9c8416427e
--- /dev/null
+++ b/Documentation/filesystems/orangefs.txt
@@ -0,0 +1,137 @@
+ORANGEFS
+========
+
+OrangeFS is an LGPL userspace scale-out parallel storage system. It is ideal
+for large storage problems faced by HPC, BigData, Streaming Video,
+Genomics, Bioinformatics.
+
+Orangefs, originally called PVFS, was first developed in 1993 by
+Walt Ligon and Eric Blumer as a parallel file system for Parallel
+Virtual Machine (PVM) as part of a NASA grant to study the I/O patterns
+of parallel programs.
+
+Orangefs features include:
+
+  * Distributes file data among multiple file servers
+  * Supports simultaneous access by multiple clients
+  * Stores file data and metadata on servers using local file system
+    and access methods
+  * Userspace implementation is easy to install and maintain
+  * Direct MPI support
+  * Stateless
+
+
+MAILING LIST
+============
+
+http://beowulf-underground.org/mailman/listinfo/pvfs2-users
+
+
+DOCUMENTATION
+=============
+
+http://www.orangefs.org/documentation/
+
+
+USERSPACE FILESYSTEM SOURCE
+===========================
+
+http://www.orangefs.org/download
+
+Orangefs versions prior to 2.9.3 would not be compatible with the
+upstream version of the kernel client.
+
+
+BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER
+====================================================
+
+When Orangefs is upstream, "--with-kernel" shouldn't be needed, but
+until then the path to where the kernel with the Orangefs kernel client
+patch was built is needed to ensure that pvfs2-client-core (the bridge
+between kernel space and user space) will build properly. You can omit
+--prefix if you don't care that things are sprinkled around in
+/usr/local.
+
+./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel
+
+make
+
+make install
+
+Create an orangefs config file:
+/opt/ofs/bin/pvfs2-genconfig /etc/pvfs2.conf
+
+  for "Enter hostnames", use the hostname, don't let it default to
+  localhost.
+
+create a pvfs2tab file in /etc:
+cat /etc/pvfs2tab
+tcp://myhostname:3334/orangefs /mymountpoint pvfs2 defaults,noauto 0 0
+
+create the mount point you specified in the tab file if needed:
+mkdir /mymountpoint
+
+bootstrap the server:
+/opt/ofs/sbin/pvfs2-server /etc/pvfs2.conf -f
+
+start the server:
+/opt/osf/sbin/pvfs2-server /etc/pvfs2.conf
+
+Now the server is running. At this point you might like to
+prove things are working with:
+
+/opt/osf/bin/pvfs2-ls /mymountpoint
+
+You might not want to enforce selinux, it doesn't seem to matter by
+linux 3.11...
+
+If stuff seems to be working, turn on the client core:
+/opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core
+
+Mount your filesystem.
+mount -t pvfs2 tcp://myhostname:3334/orangefs /mymountpoint
+
+
+OPTIONS
+=======
+
+The following mount options are accepted:
+
+  acl
+    Allow the use of Access Control Lists on files and directories.
+
+  intr
+    Some operations between the kernel client and the user space
+    filesystem can be interruptible, such as changes in debug levels
+    and the setting of tunable parameters.
+
+  local_lock
+    Enable posix locking from the perspective of "this" kernel. The
+    default file_operations lock action is to return ENOSYS. Posix
+    locking kicks in if the filesystem is mounted with -o local_lock.
+    Distributed locking is being worked on for the future.
+
+
+DEBUGGING
+=========
+
+If you want the debug (GOSSIP) statments in a particular
+source file (inode.c for example) go to syslog:
+
+  echo inode > /sys/kernel/debug/orangefs/kernel-debug
+
+No debugging (the default):
+
+  echo none > /sys/kernel/debug/orangefs/kernel-debug
+
+Debugging from several source files:
+
+  echo inode,dir > /sys/kernel/debug/orangefs/kernel-debug
+
+All debugging:
+
+  echo all > /sys/kernel/debug/orangefs/kernel-debug
+
+Get a list of all debugging keywords:
+
+  cat /sys/kernel/debug/orangefs/debug-help
diff --git a/Documentation/filesystems/sysfs-tagging.txt b/Documentation/filesystems/sysfs-tagging.txt
index eb843e49c5a3..c7c8e6438958 100644
--- a/Documentation/filesystems/sysfs-tagging.txt
+++ b/Documentation/filesystems/sysfs-tagging.txt
@@ -17,13 +17,13 @@ the sysfs directory entries we ensure that we don't have conflicts
 in the directories and applications only see a limited set of
 the network devices.
 
-Each sysfs directory entry may be tagged with zero or one
-namespaces.  A sysfs_dirent is augmented with a void *s_ns.  If a
-directory entry is tagged, then sysfs_dirent->s_flags will have a
-flag between KOBJ_NS_TYPE_NONE and KOBJ_NS_TYPES, and s_ns will
-point to the namespace to which it belongs.
+Each sysfs directory entry may be tagged with a namespace via the
+void *ns member of its kernfs_node.  If a directory entry is tagged,
+then kernfs_node->flags will have a flag between KOBJ_NS_TYPE_NONE
+and KOBJ_NS_TYPES, and ns will point to the namespace to which it
+belongs.
 
-Each sysfs superblock's sysfs_super_info contains an array void
+Each sysfs superblock's kernfs_super_info contains an array void
 *ns[KOBJ_NS_TYPES].  When a task in a tagging namespace
 kobj_nstype first mounts sysfs, a new superblock is created.  It
 will be differentiated from other sysfs mounts by having its
@@ -31,7 +31,7 @@ s_fs_info->ns[kobj_nstype] set to the new namespace.  Note that
 through bind mounting and mounts propagation, a task can easily view
 the contents of other namespaces' sysfs mounts.  Therefore, when a
 namespace exits, it will call kobj_ns_exit() to invalidate any
-sysfs_dirent->s_ns pointers pointing to it.
+kernfs_node->ns pointers pointing to it.
 
 Users of this interface:
 - define a type in the kobj_ns_type enumeration.
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 9494afb9476a..24da7b32c489 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -40,7 +40,7 @@ ancestors of object hierarchies; i.e. the subsystems the objects
 belong to. 
 
 Sysfs internally stores a pointer to the kobject that implements a
-directory in the sysfs_dirent object associated with the directory. In
+directory in the kernfs_node object associated with the directory. In
 the past this kobject pointer has been used by sysfs to do reference
 counting directly on the kobject whenever the file is opened or closed.
 With the current sysfs implementation the kobject reference count is
@@ -191,9 +191,10 @@ implementations:
   be called again, rearmed, to fill the buffer.
 
 - On write(2), sysfs expects the entire buffer to be passed during the
-  first write. Sysfs then passes the entire buffer to the store()
-  method. 
-  
+  first write. Sysfs then passes the entire buffer to the store() method.
+  A terminating null is added after the data on stores. This makes
+  functions like sysfs_streq() safe to use.
+
   When writing sysfs files, userspace processes should first read the
   entire file, modify the values it wishes to change, then write the
   entire buffer back. 
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt
index b80606de545a..f59c43b6411b 100644
--- a/Documentation/gpio/board.txt
+++ b/Documentation/gpio/board.txt
@@ -21,8 +21,8 @@ exact way to do it depends on the GPIO controller providing the GPIOs, see the
 device tree bindings for your controller.
 
 GPIOs mappings are defined in the consumer device's node, in a property named
-<function>-gpios, where <function> is the function the driver will request
-through gpiod_get(). For example:
+either <function>-gpios or <function>-gpio, where <function> is the function
+the driver will request through gpiod_get(). For example:
 
 	foo_device {
 		compatible = "acme,foo";
@@ -31,7 +31,7 @@ through gpiod_get(). For example:
 			    <&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
 			    <&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
 
-		power-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+		power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
 	};
 
 This property will make GPIOs 15, 16 and 17 available to the driver under the
@@ -39,15 +39,24 @@ This property will make GPIOs 15, 16 and 17 available to the driver under the
 
 	struct gpio_desc *red, *green, *blue, *power;
 
-	red = gpiod_get_index(dev, "led", 0);
-	green = gpiod_get_index(dev, "led", 1);
-	blue = gpiod_get_index(dev, "led", 2);
+	red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
+	green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
+	blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);
 
-	power = gpiod_get(dev, "power");
+	power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);
 
 The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
 gpiod_is_active_low(power) will be true).
 
+The second parameter of the gpiod_get() functions, the con_id string, has to be
+the <function>-prefix of the GPIO suffixes ("gpios" or "gpio", automatically
+looked up by the gpiod functions internally) used in the device tree. With above
+"led-gpios" example, use the prefix without the "-" as con_id parameter: "led".
+
+Internally, the GPIO subsystem prefixes the GPIO suffix ("gpios" or "gpio")
+with the string passed in con_id to get the resulting string
+(snprintf(... "%s-%s", con_id, gpio_suffixes[]).
+
 ACPI
 ----
 ACPI also supports function names for GPIOs in a similar fashion to DT.
@@ -142,13 +151,14 @@ The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
 
 	struct gpio_desc *red, *green, *blue, *power;
 
-	red = gpiod_get_index(dev, "led", 0);
-	green = gpiod_get_index(dev, "led", 1);
-	blue = gpiod_get_index(dev, "led", 2);
+	red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
+	green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
+	blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);
 
-	power = gpiod_get(dev, "power");
-	gpiod_direction_output(power, 1);
+	power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);
 
-Since the "power" GPIO is mapped as active-low, its actual signal will be 0
-after this code. Contrary to the legacy integer GPIO interface, the active-low
-property is handled during mapping and is thus transparent to GPIO consumers.
+Since the "led" GPIOs are mapped as active-high, this example will switch their
+signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped
+as active-low, its actual signal will be 0 after this code. Contrary to the legacy
+integer GPIO interface, the active-low property is handled during mapping and is
+thus transparent to GPIO consumers.
diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt
index a206639454ab..e000502fde20 100644
--- a/Documentation/gpio/consumer.txt
+++ b/Documentation/gpio/consumer.txt
@@ -39,6 +39,9 @@ device that displays digits), an additional index argument can be specified:
 					  const char *con_id, unsigned int idx,
 					  enum gpiod_flags flags)
 
+For a more detailed description of the con_id parameter in the DeviceTree case
+see Documentation/gpio/board.txt
+
 The flags parameter is used to optionally specify a direction and initial value
 for the GPIO. Values can be:
 
diff --git a/Documentation/hwmon/max31790 b/Documentation/hwmon/max31790
new file mode 100644
index 000000000000..855e62430da9
--- /dev/null
+++ b/Documentation/hwmon/max31790
@@ -0,0 +1,37 @@
+Kernel driver max31790
+======================
+
+Supported chips:
+  * Maxim MAX31790
+    Prefix: 'max31790'
+    Addresses scanned: -
+    Datasheet: http://pdfserv.maximintegrated.com/en/ds/MAX31790.pdf
+
+Author: Il Han <corone.il.han@gmail.com>
+
+
+Description
+-----------
+
+This driver implements support for the Maxim MAX31790 chip.
+
+The MAX31790 controls the speeds of up to six fans using six independent
+PWM outputs. The desired fan speeds (or PWM duty cycles) are written
+through the I2C interface. The outputs drive "4-wire" fans directly,
+or can be used to modulate the fan's power terminals using an external
+pass transistor.
+
+Tachometer inputs monitor fan tachometer logic outputs for precise (+/-1%)
+monitoring and control of fan RPM as well as detection of fan failure.
+Six pins are dedicated tachometer inputs. Any of the six PWM outputs can
+also be configured to serve as tachometer inputs.
+
+
+Sysfs entries
+-------------
+
+fan[1-12]_input    RO  fan tachometer speed in RPM
+fan[1-12]_fault    RO  fan experienced fault
+fan[1-6]_target    RW  desired fan speed in RPM
+pwm[1-6]_enable    RW  regulator mode, 0=disabled, 1=manual mode, 2=rpm mode
+pwm[1-6]           RW  fan target duty cycle (0-255)
diff --git a/Documentation/hwmon/nct6775 b/Documentation/hwmon/nct6775
index f0dd3d2fec96..76add4c9cd68 100644
--- a/Documentation/hwmon/nct6775
+++ b/Documentation/hwmon/nct6775
@@ -32,6 +32,10 @@ Supported chips:
     Prefix: 'nct6792'
     Addresses scanned: ISA address retrieved from Super I/O registers
     Datasheet: Available from Nuvoton upon request
+  * Nuvoton NCT6793D
+    Prefix: 'nct6793'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: Available from Nuvoton upon request
 
 Authors:
         Guenter Roeck <linux@roeck-us.net>
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index df1b25eb8382..50b737402038 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -294,6 +294,7 @@ Code  Seq#(hex)	Include File		Comments
 0x92	00-0F	drivers/usb/mon/mon_bin.c
 0x93	60-7F	linux/auto_fs.h
 0x94	all	fs/btrfs/ioctl.h
+0x95	all	uapi/linux/kdbus.h	kdbus IPC driver
 0x97	00-7F	fs/ceph/ioctl.h		Ceph file system
 0x99	00-0F				537-Addinboard driver
 					<mailto:buk@buks.ipn.de>
diff --git a/Documentation/kdbus/.gitignore b/Documentation/kdbus/.gitignore
new file mode 100644
index 000000000000..b4a77ccba9b4
--- /dev/null
+++ b/Documentation/kdbus/.gitignore
@@ -0,0 +1,2 @@
+*.7
+*.html
diff --git a/Documentation/kdbus/Makefile b/Documentation/kdbus/Makefile
new file mode 100644
index 000000000000..8caffe565750
--- /dev/null
+++ b/Documentation/kdbus/Makefile
@@ -0,0 +1,44 @@
+DOCS :=	\
+	kdbus.xml		\
+	kdbus.bus.xml		\
+	kdbus.connection.xml	\
+	kdbus.endpoint.xml	\
+	kdbus.fs.xml		\
+	kdbus.item.xml		\
+	kdbus.match.xml		\
+	kdbus.message.xml	\
+	kdbus.name.xml		\
+	kdbus.policy.xml	\
+	kdbus.pool.xml
+
+XMLFILES := $(addprefix $(obj)/,$(DOCS))
+MANFILES := $(patsubst %.xml, %.7, $(XMLFILES))
+HTMLFILES := $(patsubst %.xml, %.html, $(XMLFILES))
+
+XMLTO_ARGS := -m $(srctree)/$(src)/stylesheet.xsl --skip-validation
+
+quiet_cmd_db2man = MAN     $@
+      cmd_db2man = xmlto man $(XMLTO_ARGS) -o $(obj) $<
+%.7: %.xml
+	@(which xmlto > /dev/null 2>&1) || \
+	 (echo "*** You need to install xmlto ***"; \
+	  exit 1)
+	$(call cmd,db2man)
+
+quiet_cmd_db2html = HTML    $@
+      cmd_db2html = xmlto html-nochunks $(XMLTO_ARGS) -o $(obj) $<
+%.html: %.xml
+	@(which xmlto > /dev/null 2>&1) || \
+	 (echo "*** You need to install xmlto ***"; \
+	  exit 1)
+	$(call cmd,db2html)
+
+mandocs: $(MANFILES)
+
+htmldocs: $(HTMLFILES)
+
+clean-files := $(MANFILES) $(HTMLFILES)
+
+# we don't support other %docs targets right now
+%docs:
+	@true
diff --git a/Documentation/kdbus/kdbus.bus.xml b/Documentation/kdbus/kdbus.bus.xml
new file mode 100644
index 000000000000..83f1198bc6a1
--- /dev/null
+++ b/Documentation/kdbus/kdbus.bus.xml
@@ -0,0 +1,344 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.bus">
+
+  <refentryinfo>
+    <title>kdbus.bus</title>
+    <productname>kdbus.bus</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.bus</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.bus</refname>
+    <refpurpose>kdbus bus</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      A bus is a resource that is shared between connections in order to
+      transmit messages (see
+      <citerefentry>
+        <refentrytitle>kdbus.message</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>).
+      Each bus is independent, and operations on the bus will not have any
+      effect on other buses. A bus is a management entity that controls the
+      addresses of its connections, their policies and message transactions
+      performed via this bus.
+    </para>
+    <para>
+      Each bus is bound to the mount instance it was created on. It has a
+      custom name that is unique across all buses of a domain. In
+      <citerefentry>
+        <refentrytitle>kdbus.fs</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      a bus is presented as a directory. No operations can be performed on
+      the bus itself; instead you need to perform the operations on an endpoint
+      associated with the bus. Endpoints are accessible as files underneath the
+      bus directory. A default endpoint called <constant>bus</constant> is
+      provided on each bus.
+    </para>
+    <para>
+      Bus names may be chosen freely except for one restriction: the name must
+      be prefixed with the numeric effective UID of the creator and a dash. This
+      is required to avoid namespace clashes between different users. When
+      creating a bus, the name that is passed in must be properly formatted, or
+      the kernel will refuse creation of the bus. Example:
+      <literal>1047-foobar</literal> is an acceptable name for a bus
+      registered by a user with UID 1047. However,
+      <literal>1024-foobar</literal> is not, and neither is
+      <literal>foobar</literal>. The UID must be provided in the
+      user-namespace of the bus owner.
+    </para>
+    <para>
+      To create a new bus, you need to open the control file of a domain and
+      employ the <constant>KDBUS_CMD_BUS_MAKE</constant> ioctl. The control
+      file descriptor that was used to issue
+      <constant>KDBUS_CMD_BUS_MAKE</constant> must not previously have been
+      used for any other control-ioctl and must be kept open for the entire
+      life-time of the created bus. Closing it will immediately cleanup the
+      entire bus and all its associated resources and endpoints. Every control
+      file descriptor can only be used to create a single new bus; from that
+      point on, it is not used for any further communication until the final
+      <citerefentry>
+        <refentrytitle>close</refentrytitle>
+        <manvolnum>2</manvolnum>
+      </citerefentry>
+      .
+    </para>
+    <para>
+      Each bus will generate a random, 128-bit UUID upon creation. This UUID
+      will be returned to creators of connections through
+      <varname>kdbus_cmd_hello.id128</varname> and can be used to uniquely
+      identify buses, even across different machines or containers. The UUID
+      will have its variant bits set to <literal>DCE</literal>, and denote
+      version 4 (random). For more details on UUIDs, see <ulink
+      url="https://en.wikipedia.org/wiki/Universally_unique_identifier">
+      the Wikipedia article on UUIDs</ulink>.
+    </para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Creating buses</title>
+    <para>
+      To create a new bus, the <constant>KDBUS_CMD_BUS_MAKE</constant>
+      command is used. It takes a <type>struct kdbus_cmd</type> argument.
+    </para>
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>The flags for creation.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_MAKE_ACCESS_GROUP</constant></term>
+              <listitem>
+                <para>Make the bus file group-accessible.</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_MAKE_ACCESS_WORLD</constant></term>
+              <listitem>
+                <para>Make the bus file world-accessible.</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following items (see
+            <citerefentry>
+              <refentrytitle>kdbus.item</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>)
+            are expected for <constant>KDBUS_CMD_BUS_MAKE</constant>.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_MAKE_NAME</constant></term>
+              <listitem>
+                <para>
+                  Contains a null-terminated string that identifies the
+                  bus. The name must be unique across the kdbus domain and
+                  must start with the effective UID of the caller, followed by
+                  a '<literal>-</literal>' (dash). This item is mandatory.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_BLOOM_PARAMETER</constant></term>
+              <listitem>
+                <para>
+                  Bus-wide bloom parameters passed in a
+                  <type>struct kdbus_bloom_parameter</type>. These settings are
+                  copied back to new connections verbatim. This item is
+                  mandatory. See
+                  <citerefentry>
+                    <refentrytitle>kdbus.item</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>
+                  for a more detailed description of this item.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_ATTACH_FLAGS_SEND</constant></term>
+              <listitem>
+                <para>
+                  An optional item that contains a set of attach flags that are
+                  returned to connections when they query the bus creator
+                  metadata. If not set, no metadata is returned.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Unrecognized items are rejected, and the ioctl will fail with
+      <varname>errno</varname> set to <constant>EINVAL</constant>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_BUS_MAKE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EBADMSG</constant></term>
+          <listitem><para>
+            A mandatory item is missing.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The flags supplied in the <constant>struct kdbus_cmd</constant>
+            are invalid or the supplied name does not start with the current
+            UID and a '<literal>-</literal>' (dash).
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EEXIST</constant></term>
+          <listitem><para>
+            A bus of that name already exists.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ESHUTDOWN</constant></term>
+          <listitem><para>
+            The kdbus mount instance for the bus was already shut down.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMFILE</constant></term>
+          <listitem><para>
+            The maximum number of buses for the current user is exhausted.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.connection.xml b/Documentation/kdbus/kdbus.connection.xml
new file mode 100644
index 000000000000..4bb5f30f379a
--- /dev/null
+++ b/Documentation/kdbus/kdbus.connection.xml
@@ -0,0 +1,1244 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.connection">
+
+  <refentryinfo>
+    <title>kdbus.connection</title>
+    <productname>kdbus.connection</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.connection</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.connection</refname>
+    <refpurpose>kdbus connection</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      Connections are identified by their <emphasis>connection ID</emphasis>,
+      internally implemented as a <type>uint64_t</type> counter.
+      The IDs of every newly created bus start at <constant>1</constant>, and
+      every new connection will increment the counter by <constant>1</constant>.
+      The IDs are not reused.
+    </para>
+    <para>
+      In higher level tools, the user visible representation of a connection is
+      defined by the D-Bus protocol specification as
+      <constant>":1.&lt;ID&gt;"</constant>.
+    </para>
+    <para>
+      Messages with a specific <type>uint64_t</type> destination ID are
+      directly delivered to the connection with the corresponding ID. Signal
+      messages (see
+      <citerefentry>
+        <refentrytitle>kdbus.message</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>)
+      may be addressed to the special destination ID
+      <constant>KDBUS_DST_ID_BROADCAST</constant> (~0ULL) and will then
+      potentially be delivered to all currently active connections on the bus.
+      However, in order to receive any signal messages, clients must subscribe
+      to them by installing a match (see
+      <citerefentry>
+        <refentrytitle>kdbus.match</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>).
+    </para>
+    <para>
+      Messages synthesized and sent directly by the kernel will carry the
+      special source ID <constant>KDBUS_SRC_ID_KERNEL</constant> (0).
+    </para>
+    <para>
+      In addition to the unique <type>uint64_t</type> connection ID,
+      established connections can request the ownership of
+      <emphasis>well-known names</emphasis>, under which they can be found and
+      addressed by other bus clients. A well-known name is associated with one
+      and only one connection at a time. See
+      <citerefentry>
+        <refentrytitle>kdbus.name</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      on name acquisition, the name registry, and the validity of names.
+    </para>
+    <para>
+      Messages can specify the special destination ID
+      <constant>KDBUS_DST_ID_NAME</constant> (0) and carry a well-known name
+      in the message data. Such a message is delivered to the destination
+      connection which owns that well-known name.
+    </para>
+
+    <programlisting><![CDATA[
+  +-------------------------------------------------------------------------+
+  | +---------------+     +---------------------------+                     |
+  | | Connection    |     | Message                   | -----------------+  |
+  | | :1.22         | --> | src: 22                   |                  |  |
+  | |               |     | dst: 25                   |                  |  |
+  | |               |     |                           |                  |  |
+  | |               |     |                           |                  |  |
+  | |               |     +---------------------------+                  |  |
+  | |               |                                                    |  |
+  | |               | <--------------------------------------+           |  |
+  | +---------------+                                        |           |  |
+  |                                                          |           |  |
+  | +---------------+     +---------------------------+      |           |  |
+  | | Connection    |     | Message                   | -----+           |  |
+  | | :1.25         | --> | src: 25                   |                  |  |
+  | |               |     | dst: 0xffffffffffffffff   | -------------+   |  |
+  | |               |     |  (KDBUS_DST_ID_BROADCAST) |              |   |  |
+  | |               |     |                           | ---------+   |   |  |
+  | |               |     +---------------------------+          |   |   |  |
+  | |               |                                            |   |   |  |
+  | |               | <--------------------------------------------------+  |
+  | +---------------+                                            |   |      |
+  |                                                              |   |      |
+  | +---------------+     +---------------------------+          |   |      |
+  | | Connection    |     | Message                   | --+      |   |      |
+  | | :1.55         | --> | src: 55                   |   |      |   |      |
+  | |               |     | dst: 0 / org.foo.bar      |   |      |   |      |
+  | |               |     |                           |   |      |   |      |
+  | |               |     |                           |   |      |   |      |
+  | |               |     +---------------------------+   |      |   |      |
+  | |               |                                     |      |   |      |
+  | |               | <------------------------------------------+   |      |
+  | +---------------+                                     |          |      |
+  |                                                       |          |      |
+  | +---------------+                                     |          |      |
+  | | Connection    |                                     |          |      |
+  | | :1.81         |                                     |          |      |
+  | | org.foo.bar   |                                     |          |      |
+  | |               |                                     |          |      |
+  | |               |                                     |          |      |
+  | |               | <-----------------------------------+          |      |
+  | |               |                                                |      |
+  | |               | <----------------------------------------------+      |
+  | +---------------+                                                       |
+  +-------------------------------------------------------------------------+
+    ]]></programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Privileged connections</title>
+    <para>
+      A connection is considered <emphasis>privileged</emphasis> if the user
+      it was created by is the same that created the bus, or if the creating
+      task had <constant>CAP_IPC_OWNER</constant> set when it called
+      <constant>KDBUS_CMD_HELLO</constant> (see below).
+    </para>
+    <para>
+      Privileged connections have permission to employ certain restricted
+      functions and commands, which are explained below and in other kdbus
+      man-pages.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Activator and policy holder connection</title>
+    <para>
+      An <emphasis>activator</emphasis> connection is a placeholder for a
+      <emphasis>well-known name</emphasis>. Messages sent to such a connection
+      can be used to start an implementer connection, which will then get all
+      the messages from the activator copied over. An activator connection
+      cannot be used to send any message.
+    </para>
+    <para>
+      A <emphasis>policy holder</emphasis> connection only installs a policy
+      for one or more names. These policy entries are kept active as long as
+      the connection is alive, and are removed once it terminates. Such a
+      policy connection type can be used to deploy restrictions for names that
+      are not yet active on the bus. A policy holder connection cannot be used
+      to send any message.
+    </para>
+    <para>
+      The creation of activator or policy holder connections is restricted to
+      privileged users on the bus (see above).
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Monitor connections</title>
+    <para>
+      Monitors are eavesdropping connections that receive all the traffic on the
+      bus, but is invisible to other connections. Such connections have all
+      properties of any other, regular connection, except for the following
+      details:
+    </para>
+
+    <itemizedlist>
+      <listitem><para>
+        They will get every message sent over the bus, both unicasts and
+        broadcasts.
+      </para></listitem>
+
+      <listitem><para>
+        Installing matches for signal messages is neither necessary
+        nor allowed.
+      </para></listitem>
+
+      <listitem><para>
+        They cannot send messages or be directly addressed as receiver.
+      </para></listitem>
+
+      <listitem><para>
+        They cannot own well-known names. Therefore, they also can't operate as
+        activators.
+      </para></listitem>
+
+      <listitem><para>
+        Their creation and destruction will not cause
+        <constant>KDBUS_ITEM_ID_{ADD,REMOVE}</constant> (see
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>).
+      </para></listitem>
+
+      <listitem><para>
+        They are not listed with their unique name in name registry dumps
+        (see <constant>KDBUS_CMD_NAME_LIST</constant> in
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>), so other connections cannot detect the presence of
+	a monitor.
+      </para></listitem>
+    </itemizedlist>
+    <para>
+      The creation of monitor connections is restricted to privileged users on
+      the bus (see above).
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Creating connections</title>
+    <para>
+      A connection to a bus is created by opening an endpoint file (see
+      <citerefentry>
+        <refentrytitle>kdbus.endpoint</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>)
+      of a bus and becoming an active client with the
+      <constant>KDBUS_CMD_HELLO</constant> ioctl. Every connection has a unique
+      identifier on the bus and can address messages to every other connection
+      on the same bus by using the peer's connection ID as the destination.
+    </para>
+    <para>
+      The <constant>KDBUS_CMD_HELLO</constant> ioctl takes a <type>struct
+      kdbus_cmd_hello</type> as argument.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_hello {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __u64 attach_flags_send;
+  __u64 attach_flags_recv;
+  __u64 bus_flags;
+  __u64 id;
+  __u64 pool_size;
+  __u64 offset;
+  __u8 id128[16];
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem>
+          <para>Flags to apply to this connection</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_HELLO_ACCEPT_FD</constant></term>
+              <listitem>
+                <para>
+                  When this flag is set, the connection can be sent file
+                  descriptors as message payload of unicast messages. If it's
+                  not set, an attempt to send file descriptors will result in
+                  <constant>-ECOMM</constant> on the sender's side.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_HELLO_ACTIVATOR</constant></term>
+              <listitem>
+                <para>
+                  Make this connection an activator (see above). With this bit
+                  set, an item of type <constant>KDBUS_ITEM_NAME</constant> has
+                  to be attached. This item describes the well-known name this
+                  connection should be an activator for.
+                  A connection can not be an activator and a policy holder at
+                  the same time time, so this bit is not allowed together with
+                  <constant>KDBUS_HELLO_POLICY_HOLDER</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_HELLO_POLICY_HOLDER</constant></term>
+              <listitem>
+                <para>
+                  Make this connection a policy holder (see above). With this
+                  bit set, an item of type <constant>KDBUS_ITEM_NAME</constant>
+                  has to be attached. This item describes the well-known name
+                  this connection should hold a policy for.
+                  A connection can not be an activator and a policy holder at
+                  the same time time, so this bit is not allowed together with
+                  <constant>KDBUS_HELLO_ACTIVATOR</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_HELLO_MONITOR</constant></term>
+              <listitem>
+                <para>
+                  Make this connection a monitor connection (see above).
+                </para>
+                <para>
+                  This flag can only be set by privileged bus connections. See
+                  below for more information.
+                  A connection can not be monitor and an activator or a policy
+                  holder at the same time time, so this bit is not allowed
+                  together with <constant>KDBUS_HELLO_ACTIVATOR</constant> or
+                  <constant>KDBUS_HELLO_POLICY_HOLDER</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>attach_flags_send</varname></term>
+        <listitem><para>
+          Set the bits for metadata this connection permits to be sent to the
+          receiving peer. Only metadata items that are both allowed to be sent
+          by the sender and that are requested by the receiver will be attached
+          to the message.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>attach_flags_recv</varname></term>
+        <listitem><para>
+          Request the attachment of metadata for each message received by this
+          connection. See
+          <citerefentry>
+            <refentrytitle>kdbus</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for information about metadata, and
+          <citerefentry>
+            <refentrytitle>kdbus.item</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          regarding items in general.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>bus_flags</varname></term>
+        <listitem><para>
+          Upon successful completion of the ioctl, this member will contain the
+          flags of the bus it connected to.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+          Upon successful completion of the command, this member will contain
+          the numerical ID of the new connection.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>pool_size</varname></term>
+        <listitem><para>
+          The size of the communication pool, in bytes. The pool can be
+          accessed by calling
+          <citerefentry>
+            <refentrytitle>mmap</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>
+          on the file descriptor that was used to issue the
+          <constant>KDBUS_CMD_HELLO</constant> ioctl.
+          The pool size of a connection must be greater than
+          <constant>0</constant> and a multiple of
+          <constant>PAGE_SIZE</constant>. See
+          <citerefentry>
+            <refentrytitle>kdbus.pool</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for more information.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>offset</varname></term>
+        <listitem><para>
+          The kernel will return the offset in the pool where returned details
+          will be stored. See below.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id128</varname></term>
+        <listitem><para>
+          Upon successful completion of the ioctl, this member will contain the
+          <emphasis>128-bit UUID</emphasis> of the connected bus.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Variable list of items containing optional additional information.
+            The following items are currently expected/valid:
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_CONN_DESCRIPTION</constant></term>
+              <listitem>
+                <para>
+                  Contains a string that describes this connection, so it can
+                  be identified later.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME</constant></term>
+              <term><constant>KDBUS_ITEM_POLICY_ACCESS</constant></term>
+              <listitem>
+                <para>
+                  For activators and policy holders only, combinations of
+                  these two items describe policy access entries. See
+                  <citerefentry>
+                    <refentrytitle>kdbus.policy</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>
+                  for further details.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_CREDS</constant></term>
+              <term><constant>KDBUS_ITEM_PIDS</constant></term>
+              <term><constant>KDBUS_ITEM_SECLABEL</constant></term>
+              <listitem>
+                <para>
+                  Privileged bus users may submit these types in order to
+                  create connections with faked credentials. This information
+                  will be returned when peer information is queried by
+                  <constant>KDBUS_CMD_CONN_INFO</constant>. See below for more
+                  information on retrieving information on connections.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      At the offset returned in the <varname>offset</varname> field of
+      <type>struct kdbus_cmd_hello</type>, the kernel will store items
+      of the following types:
+    </para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>KDBUS_ITEM_BLOOM_PARAMETER</constant></term>
+        <listitem>
+          <para>
+            Bloom filter parameter as defined by the bus creator.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The offset in the pool has to be freed with the
+      <constant>KDBUS_CMD_FREE</constant> ioctl. See
+      <citerefentry>
+        <refentrytitle>kdbus.pool</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for further information.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Retrieving information on a connection</title>
+    <para>
+      The <constant>KDBUS_CMD_CONN_INFO</constant> ioctl can be used to
+      retrieve credentials and properties of the initial creator of a
+      connection. This ioctl uses the following struct.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_info {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __u64 id;
+  __u64 attach_flags;
+  __u64 offset;
+  __u64 info_size;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Currently, no flags are supported.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will return <errorcode>0</errorcode>,
+          and the <varname>flags</varname> field is set to
+          <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+          The numerical ID of the connection for which information is to be
+          retrieved. If set to a non-zero value, the
+          <constant>KDBUS_ITEM_OWNED_NAME</constant> item is ignored.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>attach_flags</varname></term>
+        <listitem><para>
+          Specifies which metadata items should be attached to the answer. See
+          <citerefentry>
+            <refentrytitle>kdbus.message</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>offset</varname></term>
+        <listitem><para>
+          When the ioctl returns, this field will contain the offset of the
+          connection information inside the caller's pool. See
+          <citerefentry>
+            <refentrytitle>kdbus.pool</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for further information.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>info_size</varname></term>
+        <listitem><para>
+          The kernel will return the size of the returned information, so
+          applications can optionally
+          <citerefentry>
+            <refentrytitle>mmap</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>
+          specific parts of the pool. See
+          <citerefentry>
+            <refentrytitle>kdbus.pool</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for further information.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following items are expected for
+            <constant>KDBUS_CMD_CONN_INFO</constant>.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_OWNED_NAME</constant></term>
+              <listitem>
+                <para>
+                  Contains the well-known name of the connection to look up as.
+                  This item is mandatory if the <varname>id</varname> field is
+                  set to 0.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      When the ioctl returns, the following struct will be stored in the
+      caller's pool at <varname>offset</varname>. The fields in this struct
+      are described below.
+    </para>
+
+    <programlisting>
+struct kdbus_info {
+  __u64 size;
+  __u64 id;
+  __u64 flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+          The connection's unique ID.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          The connection's flags as specified when it was created.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Depending on the <varname>flags</varname> field in
+            <type>struct kdbus_cmd_info</type>, items of types
+            <constant>KDBUS_ITEM_OWNED_NAME</constant> and
+            <constant>KDBUS_ITEM_CONN_DESCRIPTION</constant> may follow here.
+            <constant>KDBUS_ITEM_NEGOTIATE</constant> is also allowed.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Once the caller is finished with parsing the return buffer, it needs to
+      employ the <constant>KDBUS_CMD_FREE</constant> command for the offset, in
+      order to free the buffer part. See
+      <citerefentry>
+        <refentrytitle>kdbus.pool</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for further information.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Getting information about a connection's bus creator</title>
+    <para>
+      The <constant>KDBUS_CMD_BUS_CREATOR_INFO</constant> ioctl takes the same
+      struct as <constant>KDBUS_CMD_CONN_INFO</constant>, but is used to
+      retrieve information about the creator of the bus the connection is
+      attached to. The metadata returned by this call is collected during the
+      creation of the bus and is never altered afterwards, so it provides
+      pristine information on the task that created the bus, at the moment when
+      it did so.
+    </para>
+    <para>
+      In response to this call, a slice in the connection's pool is allocated
+      and filled with an object of type <type>struct kdbus_info</type>,
+      pointed to by the ioctl's <varname>offset</varname> field.
+    </para>
+
+    <programlisting>
+struct kdbus_info {
+  __u64 size;
+  __u64 id;
+  __u64 flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+          The bus ID.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          The bus flags as specified when it was created.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Metadata information is stored in items here. The item list
+            contains a <constant>KDBUS_ITEM_MAKE_NAME</constant> item that
+            indicates the bus name of the calling connection.
+            <constant>KDBUS_ITEM_NEGOTIATE</constant> is allowed to probe
+            for known item types.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Once the caller is finished with parsing the return buffer, it needs to
+      employ the <constant>KDBUS_CMD_FREE</constant> command for the offset, in
+      order to free the buffer part. See
+      <citerefentry>
+        <refentrytitle>kdbus.pool</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for further information.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Updating connection details</title>
+    <para>
+      Some of a connection's details can be updated with the
+      <constant>KDBUS_CMD_CONN_UPDATE</constant> ioctl, using the file
+      descriptor that was used to create the connection. The update command
+      uses the following struct.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Currently, no flags are supported.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will return <errorcode>0</errorcode>,
+          and the <varname>flags</varname> field is set to
+          <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Items to describe the connection details to be updated. The
+            following item types are supported.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_ATTACH_FLAGS_SEND</constant></term>
+              <listitem>
+                <para>
+                  Supply a new set of metadata items that this connection
+                  permits to be sent along with messages.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_ATTACH_FLAGS_RECV</constant></term>
+              <listitem>
+                <para>
+                  Supply a new set of metadata items that this connection
+                  requests to be attached to each message.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME</constant></term>
+              <term><constant>KDBUS_ITEM_POLICY_ACCESS</constant></term>
+              <listitem>
+                <para>
+                  Policy holder connections may supply a new set of policy
+                  information with these items. For other connection types,
+                  <constant>EOPNOTSUPP</constant> is returned in
+                  <varname>errno</varname>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Termination of connections</title>
+    <para>
+      A connection can be terminated by simply calling
+      <citerefentry>
+        <refentrytitle>close</refentrytitle>
+        <manvolnum>2</manvolnum>
+      </citerefentry>
+      on its file descriptor. All pending incoming messages will be discarded,
+      and the memory allocated by the pool will be freed.
+    </para>
+
+    <para>
+      An alternative way of closing down a connection is via the
+      <constant>KDBUS_CMD_BYEBYE</constant> ioctl. This ioctl will succeed only
+      if the message queue of the connection is empty at the time of closing;
+      otherwise, the ioctl will fail with <varname>errno</varname> set to
+      <constant>EBUSY</constant>. When this ioctl returns
+      successfully, the connection has been terminated and won't accept any new
+      messages from remote peers. This way, a connection can be terminated
+      race-free, without losing any messages. The ioctl takes an argument of
+      type <type>struct kdbus_cmd</type>.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Currently, no flags are supported.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will fail with
+          <varname>errno</varname> set to <constant>EPROTO</constant>, and
+          the <varname>flags</varname> field is set to <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following item types are supported.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_HELLO</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EFAULT</constant></term>
+          <listitem><para>
+            The supplied pool size was 0 or not a multiple of the page size.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The flags supplied in <type>struct kdbus_cmd_hello</type>
+            are invalid.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            An illegal combination of
+            <constant>KDBUS_HELLO_MONITOR</constant>,
+            <constant>KDBUS_HELLO_ACTIVATOR</constant> and
+            <constant>KDBUS_HELLO_POLICY_HOLDER</constant> was passed in
+            <varname>flags</varname>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            An invalid set of items was supplied.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ECONNREFUSED</constant></term>
+          <listitem><para>
+            The attach_flags_send field did not satisfy the requirements of
+            the bus.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EPERM</constant></term>
+          <listitem><para>
+            A <constant>KDBUS_ITEM_CREDS</constant> items was supplied, but the
+            current user is not privileged.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ESHUTDOWN</constant></term>
+          <listitem><para>
+            The bus you were trying to connect to has already been shut down.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMFILE</constant></term>
+          <listitem><para>
+            The maximum number of connections on the bus has been reached.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EOPNOTSUPP</constant></term>
+          <listitem><para>
+            The endpoint does not support the connection flags supplied in
+            <type>struct kdbus_cmd_hello</type>.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_BYEBYE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EALREADY</constant></term>
+          <listitem><para>
+            The connection has already been shut down.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EBUSY</constant></term>
+          <listitem><para>
+            There are still messages queued up in the connection's pool.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_CONN_INFO</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Invalid flags, or neither an ID nor a name was provided, or the
+            name is invalid.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ESRCH</constant></term>
+          <listitem><para>
+            Connection lookup by name failed.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ENXIO</constant></term>
+          <listitem><para>
+            No connection with the provided connection ID found.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_CONN_UPDATE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal flags or items.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Wildcards submitted in policy entries, or illegal sequence
+            of policy items.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EOPNOTSUPP</constant></term>
+          <listitem><para>
+            Operation not supported by connection.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>E2BIG</constant></term>
+          <listitem><para>
+            Too many policy items attached.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.policy</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.endpoint.xml b/Documentation/kdbus/kdbus.endpoint.xml
new file mode 100644
index 000000000000..6632485f3e84
--- /dev/null
+++ b/Documentation/kdbus/kdbus.endpoint.xml
@@ -0,0 +1,429 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.endpoint">
+
+  <refentryinfo>
+    <title>kdbus.endpoint</title>
+    <productname>kdbus.endpoint</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.endpoint</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.endpoint</refname>
+    <refpurpose>kdbus endpoint</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      Endpoints are entry points to a bus (see
+      <citerefentry>
+        <refentrytitle>kdbus.bus</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>).
+      By default, each bus has a default
+      endpoint called 'bus'. The bus owner has the ability to create custom
+      endpoints with specific names, permissions, and policy databases
+      (see below). An endpoint is presented as file underneath the directory
+      of the parent bus.
+    </para>
+    <para>
+      To create a custom endpoint, open the default endpoint
+      (<literal>bus</literal>) and use the
+      <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> ioctl with
+      <type>struct kdbus_cmd</type>. Custom endpoints always have a policy
+      database that, by default, forbids any operation. You have to explicitly
+      install policy entries to allow any operation on this endpoint.
+    </para>
+    <para>
+      Once <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> succeeded, the new
+      endpoint will appear in the filesystem
+      (<citerefentry>
+        <refentrytitle>kdbus.bus</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>), and the used file descriptor will manage the
+      newly created endpoint resource. It cannot be used to manage further
+      resources and must be kept open as long as the endpoint is needed. The
+      endpoint will be terminated as soon as the file descriptor is closed.
+    </para>
+    <para>
+      Endpoint names may be chosen freely except for one restriction: the name
+      must be prefixed with the numeric effective UID of the creator and a dash.
+      This is required to avoid namespace clashes between different users. When
+      creating an endpoint, the name that is passed in must be properly
+      formatted or the kernel will refuse creation of the endpoint. Example:
+      <literal>1047-my-endpoint</literal> is an acceptable name for an
+      endpoint registered by a user with UID 1047. However,
+      <literal>1024-my-endpoint</literal> is not, and neither is
+      <literal>my-endpoint</literal>. The UID must be provided in the
+      user-namespace of the bus.
+    </para>
+    <para>
+      To create connections to a bus, use <constant>KDBUS_CMD_HELLO</constant>
+      on a file descriptor returned by <function>open()</function> on an
+      endpoint node. See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for further details.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Creating custom endpoints</title>
+    <para>
+      To create a new endpoint, the
+      <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> command is used. Along with
+      the endpoint's name, which will be used to expose the endpoint in the
+      <citerefentry>
+        <refentrytitle>kdbus.fs</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>,
+      the command also optionally takes items to set up the endpoint's
+      <citerefentry>
+        <refentrytitle>kdbus.policy</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>.
+      <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> takes a
+      <type>struct kdbus_cmd</type> argument.
+    </para>
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>The flags for creation.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_MAKE_ACCESS_GROUP</constant></term>
+              <listitem>
+                <para>Make the endpoint file group-accessible.</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_MAKE_ACCESS_WORLD</constant></term>
+              <listitem>
+                <para>Make the endpoint file world-accessible.</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following items are expected for
+            <constant>KDBUS_CMD_ENDPOINT_MAKE</constant>.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_MAKE_NAME</constant></term>
+              <listitem>
+                <para>Contains a string to identify the endpoint name.</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME</constant></term>
+              <term><constant>KDBUS_ITEM_POLICY_ACCESS</constant></term>
+              <listitem>
+                <para>
+                  These items are used to set the policy attached to the
+                  endpoint. For more details on bus and endpoint policies, see
+                  <citerefentry>
+                    <refentrytitle>kdbus.policy</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <varname>EINVAL</varname>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Updating endpoints</title>
+    <para>
+      To update an existing endpoint, the
+      <constant>KDBUS_CMD_ENDPOINT_UPDATE</constant> command is used on the file
+      descriptor that was used to create the endpoint, using
+      <constant>KDBUS_CMD_ENDPOINT_MAKE</constant>. The only relevant detail of
+      the endpoint that can be updated is the policy. When the command is
+      employed, the policy of the endpoint is <emphasis>replaced</emphasis>
+      atomically with the new set of rules.
+      The command takes a <type>struct kdbus_cmd</type> argument.
+    </para>
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Unused for this command.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will return <errorcode>0</errorcode>,
+          and the <varname>flags</varname> field is set to
+          <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following items are expected for
+            <constant>KDBUS_CMD_ENDPOINT_UPDATE</constant>.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME</constant></term>
+              <term><constant>KDBUS_ITEM_POLICY_ACCESS</constant></term>
+              <listitem>
+                <para>
+                  These items are used to set the policy attached to the
+                  endpoint. For more details on bus and endpoint policies, see
+                  <citerefentry>
+                    <refentrytitle>kdbus.policy</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>.
+                  Existing policy is atomically replaced with the new rules
+                  provided.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> may fail with the
+        following errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The flags supplied in the <type>struct kdbus_cmd</type>
+            are invalid.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal combination of <constant>KDBUS_ITEM_NAME</constant> and
+            <constant>KDBUS_ITEM_POLICY_ACCESS</constant> was provided.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EEXIST</constant></term>
+          <listitem><para>
+            An endpoint of that name already exists.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EPERM</constant></term>
+          <listitem><para>
+            The calling user is not privileged. See
+            <citerefentry>
+              <refentrytitle>kdbus</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for information about privileged users.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_ENDPOINT_UPDATE</constant> may fail with the
+        following errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The flags supplied in <type>struct kdbus_cmd</type>
+            are invalid.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal combination of <constant>KDBUS_ITEM_NAME</constant> and
+            <constant>KDBUS_ITEM_POLICY_ACCESS</constant> was provided.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+           <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.fs.xml b/Documentation/kdbus/kdbus.fs.xml
new file mode 100644
index 000000000000..8c2a90e10b66
--- /dev/null
+++ b/Documentation/kdbus/kdbus.fs.xml
@@ -0,0 +1,124 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus_fs">
+
+  <refentryinfo>
+    <title>kdbus.fs</title>
+    <productname>kdbus.fs</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.fs</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.fs</refname>
+    <refpurpose>kdbus file system</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>File-system Layout</title>
+
+    <para>
+      The <emphasis>kdbusfs</emphasis> pseudo filesystem provides access to
+      kdbus entities, such as <emphasis>buses</emphasis> and
+      <emphasis>endpoints</emphasis>. Each time the filesystem is mounted,
+      a new, isolated kdbus instance is created, which is independent from the
+      other instances.
+    </para>
+    <para>
+      The system-wide standard mount point for <emphasis>kdbusfs</emphasis> is
+      <constant>/sys/fs/kdbus</constant>.
+    </para>
+
+    <para>
+      Buses are represented as directories in the file system layout, whereas
+      endpoints are exposed as files inside these directories. At the top-level,
+      a <emphasis>control</emphasis> node is present, which can be opened to
+      create new buses via the <constant>KDBUS_CMD_BUS_MAKE</constant> ioctl.
+      Each <emphasis>bus</emphasis> shows a default endpoint called
+      <varname>bus</varname>, which can be opened to either create a connection
+      with the <constant>KDBUS_CMD_HELLO</constant> ioctl, or to create new
+      custom endpoints for the bus with
+      <constant>KDBUS_CMD_ENDPOINT_MAKE</constant>. See
+      <citerefentry>
+        <refentrytitle>kdbus.bus</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry> and
+      <citerefentry>
+        <refentrytitle>kdbus.endpoint</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more details.
+    </para>
+
+    <para>Following, you can see an example layout of the
+    <emphasis>kdbusfs</emphasis> filesystem:</para>
+
+<programlisting>
+        /sys/fs/kdbus/                          ; mount-point
+        |-- 0-system                            ; bus directory
+        |   |-- bus                             ; default endpoint
+        |   `-- 1017-custom                     ; custom endpoint
+        |-- 1000-user                           ; bus directory
+        |   |-- bus                             ; default endpoint
+        |   |-- 1000-service-A                  ; custom endpoint
+        |   `-- 1000-service-B                  ; custom endpoint
+        `-- control                             ; control file
+</programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Mounting instances</title>
+    <para>
+      In order to get a new and separate kdbus environment, a new instance
+      of <emphasis>kdbusfs</emphasis> can be mounted like this:
+    </para>
+<programlisting>
+  # mount -t kdbusfs kdbusfs /tmp/new_kdbus/
+</programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>mount</refentrytitle>
+          <manvolnum>8</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.item.xml b/Documentation/kdbus/kdbus.item.xml
new file mode 100644
index 000000000000..ee09dfa443b8
--- /dev/null
+++ b/Documentation/kdbus/kdbus.item.xml
@@ -0,0 +1,839 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus">
+
+  <refentryinfo>
+    <title>kdbus.item</title>
+    <productname>kdbus item</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.item</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.item</refname>
+    <refpurpose>kdbus item structure, layout and usage</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      To flexibly augment transport structures, data blobs of type
+      <type>struct kdbus_item</type> can be attached to the structs passed
+      into the ioctls. Some ioctls make items of certain types mandatory,
+      others are optional. Items that are unsupported by ioctls they are
+      attached to will cause the ioctl to fail with <varname>errno</varname>
+      set to <constant>EINVAL</constant>.
+      Items are also used for information stored in a connection's
+      <emphasis>pool</emphasis>, such as received messages, name lists or
+      requested connection or bus owner information. Depending on the type of
+      an item, its total size is either fixed or variable.
+    </para>
+
+    <refsect2>
+      <title>Chaining items</title>
+      <para>
+        Whenever items are used as part of the kdbus kernel API, they are
+        embedded in structs that are embedded inside structs that themselves
+        include a size field containing the overall size of the structure.
+        This allows multiple items to be chained up, and an item iterator
+        (see below) is capable of detecting the end of an item chain.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Alignment</title>
+      <para>
+        The kernel expects all items to be aligned to 8-byte boundaries.
+        Unaligned items will cause the ioctl they are used with to fail
+        with <varname>errno</varname> set to <constant>EINVAL</constant>.
+        An item that has an unaligned size itself hence needs to be padded
+        if it is followed by another item.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Iterating items</title>
+      <para>
+        A simple iterator would iterate over the items until the items have
+        reached the embedding structure's overall size. An example
+        implementation is shown below.
+      </para>
+
+      <programlisting><![CDATA[
+#define KDBUS_ALIGN8(val) (((val) + 7) & ~7)
+
+#define KDBUS_ITEM_NEXT(item) \
+    (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
+
+#define KDBUS_ITEM_FOREACH(item, head, first)                      \
+    for ((item) = (head)->first;                                   \
+         ((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
+          ((uint8_t *)(item) >= (uint8_t *)(head));                \
+         (item) = KDBUS_ITEM_NEXT(item))
+      ]]></programlisting>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>Item layout</title>
+    <para>
+      A <type>struct kdbus_item</type> consists of a
+      <varname>size</varname> field, describing its overall size, and a
+      <varname>type</varname> field, both 64 bit wide. They are followed by
+      a union to store information that is specific to the item's type.
+      The struct layout is shown below.
+    </para>
+
+    <programlisting>
+struct kdbus_item {
+  __u64 size;
+  __u64 type;
+  /* item payload - see below */
+  union {
+    __u8 data[0];
+    __u32 data32[0];
+    __u64 data64[0];
+    char str[0];
+
+    __u64 id;
+    struct kdbus_vec vec;
+    struct kdbus_creds creds;
+    struct kdbus_pids pids;
+    struct kdbus_audit audit;
+    struct kdbus_caps caps;
+    struct kdbus_timestamp timestamp;
+    struct kdbus_name name;
+    struct kdbus_bloom_parameter bloom_parameter;
+    struct kdbus_bloom_filter bloom_filter;
+    struct kdbus_memfd memfd;
+    int fds[0];
+    struct kdbus_notify_name_change name_change;
+    struct kdbus_notify_id_change id_change;
+    struct kdbus_policy_access policy_access;
+  };
+};
+    </programlisting>
+
+    <para>
+      <type>struct kdbus_item</type> should never be used to allocate
+      an item instance, as its size may grow in future releases of the API.
+      Instead, it should be manually assembled by storing the
+      <varname>size</varname>, <varname>type</varname> and payload to a
+      struct of its own.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Item types</title>
+
+    <refsect2>
+      <title>Negotiation item</title>
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+          <listitem><para>
+            With this item is attached to any ioctl, programs can
+            <emphasis>probe</emphasis> the kernel for known item types.
+            The item carries an array of <type>uint64_t</type> values in
+            <varname>item.data64</varname>, each set to an item type to
+            probe. The kernel will reset each member of this array that is
+            not recognized as valid item type to <constant>0</constant>.
+            This way, users can negotiate kernel features at start-up to
+            keep newer userspace compatible with older kernels. This item
+            is never attached by the kernel in response to any command.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Command specific items</title>
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_PAYLOAD_VEC</constant></term>
+          <term><constant>KDBUS_ITEM_PAYLOAD_OFF</constant></term>
+          <listitem><para>
+            Messages are directly copied by the sending process into the
+            receiver's
+            <citerefentry>
+              <refentrytitle>kdbus.pool</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+            This way, two peers can exchange data by effectively doing a
+            single-copy from one process to another; the kernel will not buffer
+            the data anywhere else. <constant>KDBUS_ITEM_PAYLOAD_VEC</constant>
+            is used when <emphasis>sending</emphasis> message. The item
+            references a memory address when the payload data can be found.
+            <constant>KDBUS_ITEM_PAYLOAD_OFF</constant> is used when messages
+            are <emphasis>received</emphasis>, and the
+            <constant>offset</constant> value describes the offset inside the
+            receiving connection's
+            <citerefentry>
+              <refentrytitle>kdbus.pool</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            where the message payload can be found. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on passing of payload data along with a
+            message.
+            <programlisting>
+struct kdbus_vec {
+  __u64 size;
+  union {
+    __u64 address;
+    __u64 offset;
+  };
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant></term>
+          <listitem><para>
+            Transports a file descriptor of a <emphasis>memfd</emphasis> in
+            <type>struct kdbus_memfd</type> in <varname>item.memfd</varname>.
+            The <varname>size</varname> field has to match the actual size of
+            the memfd that was specified when it was created. The
+            <varname>start</varname> parameter denotes the offset inside the
+            memfd at which the referenced payload starts. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on passing of payload data along with a
+            message.
+            <programlisting>
+struct kdbus_memfd {
+  __u64 start;
+  __u64 size;
+  int fd;
+  __u32 __pad;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_FDS</constant></term>
+          <listitem><para>
+            Contains an array of <emphasis>file descriptors</emphasis>.
+            When used with <constant>KDBUS_CMD_SEND</constant>, the values of
+            this array must be filled with valid file descriptor numbers.
+            When received as item attached to a message, the array will
+            contain the numbers of the installed file descriptors, or
+            <constant>-1</constant> in case an error occurred.
+            In either case, the number of entries in the array is derived from
+            the item's total size. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Items specific to some commands</title>
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CANCEL_FD</constant></term>
+          <listitem><para>
+            Transports a file descriptor that can be used to cancel a
+            synchronous <constant>KDBUS_CMD_SEND</constant> operation by
+            writing to it. The file descriptor is stored in
+            <varname>item.fd[0]</varname>. The item may only contain one
+            file descriptor. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on this item and how to use it.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_BLOOM_PARAMETER</constant></term>
+          <listitem><para>
+            Contains a set of <emphasis>bloom parameters</emphasis> as
+            <type>struct kdbus_bloom_parameter</type> in
+            <varname>item.bloom_parameter</varname>.
+            The item is passed from userspace to kernel during the
+            <constant>KDBUS_CMD_BUS_MAKE</constant> ioctl, and returned
+            verbatim when <constant>KDBUS_CMD_HELLO</constant> is called.
+            The kernel does not use the bloom parameters, but they need to
+            be known by each connection on the bus in order to define the
+            bloom filter hash details. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on matching and bloom filters.
+            <programlisting>
+struct kdbus_bloom_parameter {
+  __u64 size;
+  __u64 n_hash;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_BLOOM_FILTER</constant></term>
+          <listitem><para>
+            Carries a <emphasis>bloom filter</emphasis> as
+            <type>struct kdbus_bloom_filter</type> in
+            <varname>item.bloom_filter</varname>. It is mandatory to send this
+            item attached to a <type>struct kdbus_msg</type>, in case the
+            message is a signal. This item is never transported from kernel to
+            userspace. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on matching and bloom filters.
+            <programlisting>
+struct kdbus_bloom_filter {
+  __u64 generation;
+  __u64 data[0];
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_BLOOM_MASK</constant></term>
+          <listitem><para>
+            Transports a <emphasis>bloom mask</emphasis> as binary data blob
+            stored in <varname>item.data</varname>. This item is used to
+            describe a match into a connection's match database. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on matching and bloom filters.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_DST_NAME</constant></term>
+          <listitem><para>
+            Contains a <emphasis>well-known name</emphasis> to send a
+            message to, as null-terminated string in
+            <varname>item.str</varname>. This item is used with
+            <constant>KDBUS_CMD_SEND</constant>. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on how to send a message.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_MAKE_NAME</constant></term>
+          <listitem><para>
+            Contains a <emphasis>bus name</emphasis> or
+            <emphasis>endpoint name</emphasis>, stored as null-terminated
+            string in <varname>item.str</varname>. This item is sent from
+            userspace to kernel when buses or endpoints are created, and
+            returned back to userspace when the bus creator information is
+            queried. See
+            <citerefentry>
+              <refentrytitle>kdbus.bus</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            and
+            <citerefentry>
+              <refentrytitle>kdbus.endpoint</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_ATTACH_FLAGS_SEND</constant></term>
+          <term><constant>KDBUS_ITEM_ATTACH_FLAGS_RECV</constant></term>
+          <listitem><para>
+            Contains a set of <emphasis>attach flags</emphasis> at
+            <emphasis>send</emphasis> or <emphasis>receive</emphasis> time. See
+            <citerefentry>
+              <refentrytitle>kdbus</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>,
+            <citerefentry>
+              <refentrytitle>kdbus.bus</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry> and
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on attach flags.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_ID</constant></term>
+          <listitem><para>
+            Transports a connection's <emphasis>numerical ID</emphasis> of
+            a connection as <type>uint64_t</type> value in
+            <varname>item.id</varname>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_NAME</constant></term>
+          <listitem><para>
+            Transports a name associated with the
+            <emphasis>name registry</emphasis> as null-terminated string as
+            <type>struct kdbus_name</type> in
+            <varname>item.name</varname>. The <varname>flags</varname>
+            contains the flags of the name. See
+            <citerefentry>
+              <refentrytitle>kdbus.name</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on how to access the name registry of a bus.
+            <programlisting>
+struct kdbus_name {
+  __u64 flags;
+  char name[0];
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Items attached by the kernel as metadata</title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_TIMESTAMP</constant></term>
+          <listitem><para>
+            Contains both the <emphasis>monotonic</emphasis> and the
+            <emphasis>realtime</emphasis> timestamp, taken when the message
+            was processed on the kernel side.
+            Stored as <type>struct kdbus_timestamp</type> in
+            <varname>item.timestamp</varname>.
+            <programlisting>
+struct kdbus_timestamp {
+  __u64 seqnum;
+  __u64 monotonic_ns;
+  __u64 realtime_ns;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CREDS</constant></term>
+          <listitem><para>
+            Contains a set of <emphasis>user</emphasis> and
+            <emphasis>group</emphasis> information as 32-bit values, in the
+            usual four flavors: real, effective, saved and filesystem related.
+            Stored as <type>struct kdbus_creds</type> in
+            <varname>item.creds</varname>.
+            <programlisting>
+struct kdbus_creds {
+  __u32 uid;
+  __u32 euid;
+  __u32 suid;
+  __u32 fsuid;
+  __u32 gid;
+  __u32 egid;
+  __u32 sgid;
+  __u32 fsgid;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_PIDS</constant></term>
+          <listitem><para>
+            Contains the <emphasis>PID</emphasis>, <emphasis>TID</emphasis>
+            and <emphasis>parent PID (PPID)</emphasis> of a remote peer.
+            Stored as <type>struct kdbus_pids</type> in
+            <varname>item.pids</varname>.
+            <programlisting>
+struct kdbus_pids {
+  __u64 pid;
+  __u64 tid;
+  __u64 ppid;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_AUXGROUPS</constant></term>
+          <listitem><para>
+            Contains the <emphasis>auxiliary (supplementary) groups</emphasis>
+            a remote peer is a member of, stored as array of
+            <type>uint32_t</type> values in <varname>item.data32</varname>.
+            The array length can be determined by looking at the item's total
+            size, subtracting the size of the header and dividing the
+            remainder by <constant>sizeof(uint32_t)</constant>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_OWNED_NAME</constant></term>
+          <listitem><para>
+            Contains a <emphasis>well-known name</emphasis> currently owned
+            by a connection. The name is stored as null-terminated string in
+            <varname>item.str</varname>. Its length can also be derived from
+            the item's total size.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_TID_COMM</constant> [*]</term>
+          <listitem><para>
+            Contains the <emphasis>comm</emphasis> string of a task's
+            <emphasis>TID</emphasis> (thread ID), stored as null-terminated
+            string in <varname>item.str</varname>. Its length can also be
+            derived from the item's total size. Receivers of this item should
+            not use its contents for any kind of security measures. See below.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_PID_COMM</constant> [*]</term>
+          <listitem><para>
+            Contains the <emphasis>comm</emphasis> string of a task's
+            <emphasis>PID</emphasis> (process ID), stored as null-terminated
+            string in <varname>item.str</varname>. Its length can also be
+            derived from the item's total size. Receivers of this item should
+            not use its contents for any kind of security measures. See below.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_EXE</constant> [*]</term>
+          <listitem><para>
+            Contains the <emphasis>path to the executable</emphasis> of a task,
+            stored as null-terminated string in <varname>item.str</varname>. Its
+            length can also be derived from the item's total size. Receivers of
+            this item should not use its contents for any kind of security
+            measures. See below.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CMDLINE</constant> [*]</term>
+          <listitem><para>
+            Contains the <emphasis>command line arguments</emphasis> of a
+            task, stored as an <emphasis>array</emphasis> of null-terminated
+            strings in <varname>item.str</varname>. The total length of all
+            strings in the array can be derived from the item's total size.
+            Receivers of this item should not use its contents for any kind
+            of security measures. See below.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CGROUP</constant></term>
+          <listitem><para>
+            Contains the <emphasis>cgroup path</emphasis> of a task, stored
+            as null-terminated string in <varname>item.str</varname>. Its
+            length can also be derived from the item's total size.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CAPS</constant></term>
+          <listitem><para>
+            Contains sets of <emphasis>capabilities</emphasis>, stored as
+            <type>struct kdbus_caps</type> in <varname>item.caps</varname>.
+            As the item size may increase in the future, programs should be
+            written in a way that it takes
+            <varname>item.caps.last_cap</varname> into account, and derive
+            the number of sets and rows from the item size and the reported
+            number of valid capability bits.
+            <programlisting>
+struct kdbus_caps {
+  __u32 last_cap;
+  __u32 caps[0];
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_SECLABEL</constant></term>
+          <listitem><para>
+            Contains the <emphasis>LSM label</emphasis> of a task, stored as
+            null-terminated string in <varname>item.str</varname>. Its length
+            can also be derived from the item's total size.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_AUDIT</constant></term>
+          <listitem><para>
+            Contains the audit <emphasis>sessionid</emphasis> and
+            <emphasis>loginuid</emphasis> of a task, stored as
+            <type>struct kdbus_audit</type> in
+            <varname>item.audit</varname>.
+            <programlisting>
+struct kdbus_audit {
+  __u32 sessionid;
+  __u32 loginuid;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_CONN_DESCRIPTION</constant></term>
+          <listitem><para>
+            Contains the <emphasis>connection description</emphasis>, as set
+            by <constant>KDBUS_CMD_HELLO</constant> or
+            <constant>KDBUS_CMD_CONN_UPDATE</constant>, stored as
+            null-terminated string in <varname>item.str</varname>. Its length
+            can also be derived from the item's total size.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>
+        All metadata is automatically translated into the
+        <emphasis>namespaces</emphasis> of the task that receives them. See
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more information.
+      </para>
+
+      <para>
+        [*] Note that the content stored in metadata items of type
+        <constant>KDBUS_ITEM_TID_COMM</constant>,
+        <constant>KDBUS_ITEM_PID_COMM</constant>,
+        <constant>KDBUS_ITEM_EXE</constant> and
+        <constant>KDBUS_ITEM_CMDLINE</constant>
+        can easily be tampered by the sending tasks. Therefore, they should
+        <emphasis>not</emphasis> be used for any sort of security relevant
+        assumptions. The only reason they are transmitted is to let
+        receivers know about details that were set when metadata was
+        collected, even though the task they were collected from is not
+        active any longer when the items are received.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Items used for policy entries, matches and notifications</title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_POLICY_ACCESS</constant></term>
+          <listitem><para>
+            This item describes a <emphasis>policy access</emphasis> entry to
+            access the policy database of a
+            <citerefentry>
+              <refentrytitle>kdbus.bus</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry> or
+            <citerefentry>
+              <refentrytitle>kdbus.endpoint</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+            Please refer to
+            <citerefentry>
+              <refentrytitle>kdbus.policy</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on the policy database and how to access it.
+            <programlisting>
+struct kdbus_policy_access {
+  __u64 type;
+  __u64 access;
+  __u64 id;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_ID_ADD</constant></term>
+          <term><constant>KDBUS_ITEM_ID_REMOVE</constant></term>
+          <listitem><para>
+            This item is sent as attachment to a
+            <emphasis>kernel notification</emphasis> and indicates that a
+            new connection was created on the bus, or that a connection was
+            disconnected, respectively. It stores a
+            <type>struct kdbus_notify_id_change</type> in
+            <varname>item.id_change</varname>.
+            The <varname>id</varname> field contains the numeric ID of the
+            connection that was added or removed, and <varname>flags</varname>
+            is set to the connection flags, as passed by
+            <constant>KDBUS_CMD_HELLO</constant>. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            and
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on matches and notification messages.
+            <programlisting>
+struct kdbus_notify_id_change {
+  __u64 id;
+  __u64 flags;
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_NAME_ADD</constant></term>
+          <term><constant>KDBUS_ITEM_NAME_REMOVE</constant></term>
+          <term><constant>KDBUS_ITEM_NAME_CHANGE</constant></term>
+          <listitem><para>
+            This item is sent as attachment to a
+            <emphasis>kernel notification</emphasis> and indicates that a
+            <emphasis>well-known name</emphasis> appeared, disappeared or
+            transferred to another owner on the bus. It stores a
+            <type>struct kdbus_notify_name_change</type> in
+            <varname>item.name_change</varname>.
+            <varname>old_id</varname> describes the former owner of the name
+            and is set to <constant>0</constant> values in case of
+            <constant>KDBUS_ITEM_NAME_ADD</constant>.
+            <varname>new_id</varname> describes the new owner of the name and
+            is set to <constant>0</constant> values in case of
+            <constant>KDBUS_ITEM_NAME_REMOVE</constant>.
+            The <varname>name</varname> field contains the well-known name the
+            notification is about, as null-terminated string. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            and
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information on matches and notification messages.
+            <programlisting>
+struct kdbus_notify_name_change {
+  struct kdbus_notify_id_change old_id;
+  struct kdbus_notify_id_change new_id;
+  char name[0];
+};
+            </programlisting>
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_REPLY_TIMEOUT</constant></term>
+          <listitem><para>
+            This item is sent as attachment to a
+            <emphasis>kernel notification</emphasis>. It informs the receiver
+            that an expected reply to a message was not received in time.
+            The remote peer ID and the message cookie are stored in the message
+            header. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information about messages, timeouts and notifications.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ITEM_REPLY_DEAD</constant></term>
+          <listitem><para>
+            This item is sent as attachment to a
+            <emphasis>kernel notification</emphasis>. It informs the receiver
+            that a remote connection a reply is expected from was disconnected
+            before that reply was sent. The remote peer ID and the message
+            cookie are stored in the message header. See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for more information about messages, timeouts and notifications.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>memfd_create</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+
+</refentry>
diff --git a/Documentation/kdbus/kdbus.match.xml b/Documentation/kdbus/kdbus.match.xml
new file mode 100644
index 000000000000..ae38e04ab4d6
--- /dev/null
+++ b/Documentation/kdbus/kdbus.match.xml
@@ -0,0 +1,555 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.match">
+
+  <refentryinfo>
+    <title>kdbus.match</title>
+    <productname>kdbus.match</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.match</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.match</refname>
+    <refpurpose>kdbus match</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      kdbus connections can install matches in order to subscribe to signal
+      messages sent on the bus. Such signal messages can be either directed
+      to a single connection (by setting a specific connection ID in
+      <varname>struct kdbus_msg.dst_id</varname> or by sending it to a
+      well-known name), or to potentially <emphasis>all</emphasis> currently
+      active connections on the bus (by setting
+      <varname>struct kdbus_msg.dst_id</varname> to
+      <constant>KDBUS_DST_ID_BROADCAST</constant>).
+      A signal message always has the <constant>KDBUS_MSG_SIGNAL</constant>
+      bit set in the <varname>flags</varname> bitfield.
+      Also, signal messages can originate from either the kernel (called
+      <emphasis>notifications</emphasis>), or from other bus connections.
+      In either case, a bus connection needs to have a suitable
+      <emphasis>match</emphasis> installed in order to receive any signal
+      message. Without any rules installed in the connection, no signal message
+      will be received.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Matches for signal messages from other connections</title>
+    <para>
+      Matches for messages from other connections (not kernel notifications)
+      are implemented as bloom filters (see below). The sender adds certain
+      properties of the message as elements to a bloom filter bit field, and
+      sends that along with the signal message.
+
+      The receiving connection adds the message properties it is interested in
+      as elements to a bloom mask bit field, and uploads the mask as match rule,
+      possibly along with some other rules to further limit the match.
+
+      The kernel will match the signal message's bloom filter against the
+      connection's bloom mask (simply by &amp;-ing it), and will decide whether
+      the message should be delivered to a connection.
+    </para>
+    <para>
+      The kernel has no notion of any specific properties of the signal message,
+      all it sees are the bit fields of the bloom filter and the mask to match
+      against. The use of bloom filters allows simple and efficient matching,
+      without exposing any message properties or internals to the kernel side.
+      Clients need to deal with the fact that they might receive signal messages
+      which they did not subscribe to, as the bloom filter might allow
+      false-positives to pass the filter.
+
+      To allow the future extension of the set of elements in the bloom filter,
+      the filter specifies a <emphasis>generation</emphasis> number. A later
+      generation must always contain all elements of the set of the previous
+      generation, but can add new elements to the set. The match rules mask can
+      carry an array with all previous generations of masks individually stored.
+      When the filter and mask are matched by the kernel, the mask with the
+      closest matching generation is selected as the index into the mask array.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Bloom filters</title>
+    <para>
+      Bloom filters allow checking whether a given word is present in a
+      dictionary.  This allows connections to set up a mask for information it
+      is interested in, and will be delivered signal messages that have a
+      matching filter.
+
+      For general information, see
+      <ulink url="https://en.wikipedia.org/wiki/Bloom_filter">the Wikipedia
+      article on bloom filters</ulink>.
+    </para>
+    <para>
+      The size of the bloom filter is defined per bus when it is created, in
+      <varname>kdbus_bloom_parameter.size</varname>. All bloom filters attached
+      to signal messages on the bus must match this size, and all bloom filter
+      matches uploaded by connections must also match the size, or a multiple
+      thereof (see below).
+
+      The calculation of the mask has to be done in userspace applications. The
+      kernel just checks the bitmasks to decide whether or not to let the
+      message pass. All bits in the mask must match the filter in and bit-wise
+      <emphasis>AND</emphasis> logic, but the mask may have more bits set than
+      the filter. Consequently, false positive matches are expected to happen,
+      and programs must deal with that fact by checking the contents of the
+      payload again at receive time.
+    </para>
+    <para>
+      Masks are entities that are always passed to the kernel as part of a
+      match (with an item of type <constant>KDBUS_ITEM_BLOOM_MASK</constant>),
+      and filters can be attached to signals, with an item of type
+      <constant>KDBUS_ITEM_BLOOM_FILTER</constant>. For a filter to match, all
+      its bits have to be set in the match mask as well.
+    </para>
+    <para>
+      For example, consider a bus that has a bloom size of 8 bytes, and the
+      following mask/filter combinations:
+    </para>
+    <programlisting><![CDATA[
+          filter  0x0101010101010101
+          mask    0x0101010101010101
+                  -> matches
+
+          filter  0x0303030303030303
+          mask    0x0101010101010101
+                  -> doesn't match
+
+          filter  0x0101010101010101
+          mask    0x0303030303030303
+                  -> matches
+    ]]></programlisting>
+
+    <para>
+      Hence, in order to catch all messages, a mask filled with
+      <constant>0xff</constant> bytes can be installed as a wildcard match rule.
+    </para>
+
+    <refsect2>
+      <title>Generations</title>
+
+      <para>
+        Uploaded matches may contain multiple masks, which have to be as large
+        as the bloom filter size defined by the bus. Each block of a mask is
+        called a <emphasis>generation</emphasis>, starting at index 0.
+
+        At match time, when a signal is about to be delivered, a bloom mask
+        generation is passed, which denotes which of the bloom masks the filter
+        should be matched against. This allows programs to provide backward
+        compatible masks at upload time, while older clients can still match
+        against older versions of filters.
+      </para>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>Matches for kernel notifications</title>
+    <para>
+      To receive kernel generated notifications (see
+      <citerefentry>
+        <refentrytitle>kdbus.message</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>),
+      a connection must install match rules that are different from
+      the bloom filter matches described in the section above. They can be
+      filtered by the connection ID that caused the notification to be sent, by
+      one of the names it currently owns, or by the type of the notification
+      (ID/name add/remove/change).
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Adding a match</title>
+    <para>
+      To add a match, the <constant>KDBUS_CMD_MATCH_ADD</constant> ioctl is
+      used, which takes a <type>struct kdbus_cmd_match</type> as an argument
+      described below.
+
+      Note that each of the items attached to this command will internally
+      create one match <emphasis>rule</emphasis>, and the collection of them,
+      which is submitted as one block via the ioctl, is called a
+      <emphasis>match</emphasis>. To allow a message to pass, all rules of a
+      match have to be satisfied. Hence, adding more items to the command will
+      only narrow the possibility of a match to effectively let the message
+      pass, and will decrease the chance that the connection's process will be
+      woken up needlessly.
+
+      Multiple matches can be installed per connection. As long as one of it has
+      a set of rules which allows the message to pass, this one will be
+      decisive.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_match {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __u64 cookie;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>Flags to control the behavior of the ioctl.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_MATCH_REPLACE</constant></term>
+              <listitem>
+                <para>Make the endpoint file group-accessible</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>cookie</varname></term>
+        <listitem><para>
+          A cookie which identifies the match, so it can be referred to when
+          removing it.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+        <para>
+          Items to define the actual rules of the matches. The following item
+          types are expected. Each item will create one new match rule.
+        </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_BLOOM_MASK</constant></term>
+              <listitem>
+                <para>
+                  An item that carries the bloom filter mask to match against
+                  in its data field. The payload size must match the bloom
+                  filter size that was specified when the bus was created.
+                  See the "Bloom filters" section above for more information on
+                  bloom filters.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME</constant></term>
+              <listitem>
+                <para>
+                  When used as part of kernel notifications, this item specifies
+                  a name that is acquired, lost or that changed its owner (see
+                  below). When used as part of a match for user-generated signal
+                  messages, it specifies a name that the sending connection must
+                  own at the time of sending the signal.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_ID</constant></term>
+              <listitem>
+                <para>
+                  Specify a sender connection's ID that will match this rule.
+                  For kernel notifications, this specifies the ID of a
+                  connection that was added to or removed from the bus.
+                  For used-generated signals, it specifies the ID of the
+                  connection that sent the signal message.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NAME_ADD</constant></term>
+              <term><constant>KDBUS_ITEM_NAME_REMOVE</constant></term>
+              <term><constant>KDBUS_ITEM_NAME_CHANGE</constant></term>
+              <listitem>
+                <para>
+                  These items request delivery of kernel notifications that
+                  describe a name acquisition, loss, or change. The details
+                  are stored in the item's
+                  <varname>kdbus_notify_name_change</varname> member.
+                  All information specified must be matched in order to make
+                  the message pass. Use
+                  <constant>KDBUS_MATCH_ID_ANY</constant> to
+                  match against any unique connection ID.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_ID_ADD</constant></term>
+              <term><constant>KDBUS_ITEM_ID_REMOVE</constant></term>
+              <listitem>
+                <para>
+                  These items request delivery of kernel notifications that are
+                  generated when a connection is created or terminated.
+                  <type>struct kdbus_notify_id_change</type> is used to
+                  store the actual match information. This item can be used to
+                  monitor one particular connection ID, or, when the ID field
+                  is set to <constant>KDBUS_MATCH_ID_ANY</constant>,
+                  all of them.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term>
+              <listitem><para>
+                With this item, programs can <emphasis>probe</emphasis> the
+                kernel for known item types. See
+                <citerefentry>
+                  <refentrytitle>kdbus.item</refentrytitle>
+                  <manvolnum>7</manvolnum>
+                </citerefentry>
+                for more details.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Refer to
+      <citerefentry>
+        <refentrytitle>kdbus.message</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information on message types.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Removing a match</title>
+    <para>
+      Matches can be removed with the
+      <constant>KDBUS_CMD_MATCH_REMOVE</constant> ioctl, which takes
+      <type>struct kdbus_cmd_match</type> as argument, but its fields
+      usage slightly differs compared to that of
+      <constant>KDBUS_CMD_MATCH_ADD</constant>.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_match {
+  __u64 size;
+  __u64 cookie;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>cookie</varname></term>
+        <listitem><para>
+          The cookie of the match, as it was passed when the match was added.
+          All matches that have this cookie will be removed.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          No flags are supported for this use case.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will fail with
+          <errorcode>-1</errorcode>, <varname>errno</varname> is set to
+          <constant>EPROTO</constant>, and the <varname>flags</varname> field
+          is set to <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            No items are supported for this use case, but
+            <constant>KDBUS_ITEM_NEGOTIATE</constant> is allowed nevertheless.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_MATCH_ADD</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal flags or items.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EDOM</constant></term>
+          <listitem><para>
+            Illegal bloom filter size.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMFILE</constant></term>
+          <listitem><para>
+            Too many matches for this connection.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_MATCH_REMOVE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal flags.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EBADSLT</constant></term>
+          <listitem><para>
+            A match entry with the given cookie could not be found.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.match</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.message.xml b/Documentation/kdbus/kdbus.message.xml
new file mode 100644
index 000000000000..0115d9d50db3
--- /dev/null
+++ b/Documentation/kdbus/kdbus.message.xml
@@ -0,0 +1,1276 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.message">
+
+  <refentryinfo>
+    <title>kdbus.message</title>
+    <productname>kdbus.message</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.message</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.message</refname>
+    <refpurpose>kdbus message</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      A kdbus message is used to exchange information between two connections
+      on a bus, or to transport notifications from the kernel to one or many
+      connections. This document describes the layout of messages, how payload
+      is added to them and how they are sent and received.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Message layout</title>
+
+    <para>The layout of a message is shown below.</para>
+
+    <programlisting>
+  +-------------------------------------------------------------------------+
+  | Message                                                                 |
+  | +---------------------------------------------------------------------+ |
+  | | Header                                                              | |
+  | | size:          overall message size, including the data records     | |
+  | | destination:   connection ID of the receiver                        | |
+  | | source:        connection ID of the sender (set by kernel)          | |
+  | | payload_type:  "DBusDBus" textual identifier stored as uint64_t     | |
+  | +---------------------------------------------------------------------+ |
+  | +---------------------------------------------------------------------+ |
+  | | Data Record                                                         | |
+  | | size:  overall record size (without padding)                        | |
+  | | type:  type of data                                                 | |
+  | | data:  reference to data (address or file descriptor)               | |
+  | +---------------------------------------------------------------------+ |
+  | +---------------------------------------------------------------------+ |
+  | | padding bytes to the next 8 byte alignment                          | |
+  | +---------------------------------------------------------------------+ |
+  | +---------------------------------------------------------------------+ |
+  | | Data Record                                                         | |
+  | | size:  overall record size (without padding)                        | |
+  | | ...                                                                 | |
+  | +---------------------------------------------------------------------+ |
+  | +---------------------------------------------------------------------+ |
+  | | padding bytes to the next 8 byte alignment                          | |
+  | +---------------------------------------------------------------------+ |
+  | +---------------------------------------------------------------------+ |
+  | | Data Record                                                         | |
+  | | size:  overall record size                                          | |
+  | | ...                                                                 | |
+  | +---------------------------------------------------------------------+ |
+  |   ... further data records ...                                          |
+  +-------------------------------------------------------------------------+
+    </programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Message payload</title>
+
+    <para>
+      When connecting to the bus, receivers request a memory pool of a given
+      size, large enough to carry all backlog of data enqueued for the
+      connection. The pool is internally backed by a shared memory file which
+      can be <function>mmap()</function>ed by the receiver. See
+      <citerefentry>
+        <refentrytitle>kdbus.pool</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information.
+    </para>
+
+    <para>
+      Message payload must be described in items attached to a message when
+      it is sent. A receiver can access the payload by looking at the items
+      that are attached to a message in its pool. The following items are used.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>KDBUS_ITEM_PAYLOAD_VEC</constant></term>
+        <listitem>
+          <para>
+            This item references a piece of memory on the sender side which is
+            directly copied into the receiver's pool. This way, two peers can
+            exchange data by effectively doing a single-copy from one process
+            to another; the kernel will not buffer the data anywhere else.
+            This item is never found in a message received by a connection.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>KDBUS_ITEM_PAYLOAD_OFF</constant></term>
+        <listitem>
+          <para>
+            This item is attached to messages on the receiving side and points
+            to a memory area inside the receiver's pool. The
+            <varname>offset</varname> variable in the item denotes the memory
+            location relative to the message itself.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant></term>
+        <listitem>
+          <para>
+            Messages can reference <emphasis>memfd</emphasis> files which
+            contain the data. memfd files are tmpfs-backed files that allow
+            sealing of the content of the file, which prevents all writable
+            access to the file content.
+          </para>
+          <para>
+            Only memfds that have
+            <constant>(F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_SEAL)
+            </constant>
+            set are accepted as payload data, which enforces reliable passing of
+            data. The receiver can assume that neither the sender nor anyone
+            else can alter the content after the message is sent. If those
+            seals are not set on the memfd, the ioctl will fail with
+            <errorcode>-1</errorcode>, and <varname>errno</varname> will be
+            set to <constant>ETXTBUSY</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>KDBUS_ITEM_FDS</constant></term>
+        <listitem>
+          <para>
+            Messages can transport regular file descriptors via
+            <constant>KDBUS_ITEM_FDS</constant>. This item carries an array
+            of <type>int</type> values in <varname>item.fd</varname>. The
+            maximum number of file descriptors in the item is
+            <constant>253</constant>, and only one item of this type is
+            accepted per message. All passed values must be valid file
+            descriptors; the open count of each file descriptors is increased
+            by installing it to the receiver's task. This item can only be
+            used for directed messages, not for broadcasts, and only to
+            remote peers that have opted-in for receiving file descriptors
+            at connection time (<constant>KDBUS_HELLO_ACCEPT_FD</constant>).
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The sender must not make any assumptions on the type in which data is
+      received by the remote peer. The kernel is free to re-pack multiple
+      <constant>KDBUS_ITEM_PAYLOAD_VEC</constant> and
+      <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant> payloads. For instance, the
+      kernel may decide to merge multiple <constant>VECs</constant> into a
+      single <constant>VEC</constant>, inline <constant>MEMFD</constant>
+      payloads into memory, or merge all passed <constant>VECs</constant> into a
+      single <constant>MEMFD</constant>. However, the kernel preserves the order
+      of passed data. This means that the order of all <constant>VEC</constant>
+      and <constant>MEMFD</constant> items is not changed in respect to each
+      other. In other words: All passed <constant>VEC</constant> and
+      <constant>MEMFD</constant> data payloads are treated as a single stream
+      of data that may be received by the remote peer in a different set of
+      chunks than it was sent as.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Sending messages</title>
+
+    <para>
+      Messages are passed to the kernel with the
+      <constant>KDBUS_CMD_SEND</constant> ioctl. Depending on the destination
+      address of the message, the kernel delivers the message to the specific
+      destination connection, or to some subset of all connections on the same
+      bus. Sending messages across buses is not possible. Messages are always
+      queued in the memory pool of the destination connection (see above).
+    </para>
+
+    <para>
+      The <constant>KDBUS_CMD_SEND</constant> ioctl uses a
+      <type>struct kdbus_cmd_send</type> to describe the message
+      transfer.
+    </para>
+    <programlisting>
+struct kdbus_cmd_send {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __u64 msg_address;
+  struct kdbus_msg_info reply;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>Flags for message delivery</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_SEND_SYNC_REPLY</constant></term>
+              <listitem>
+                <para>
+                  By default, all calls to kdbus are considered asynchronous,
+                  non-blocking. However, as there are many use cases that need
+                  to wait for a remote peer to answer a method call, there's a
+                  way to send a message and wait for a reply in a synchronous
+                  fashion. This is what the
+                  <constant>KDBUS_SEND_SYNC_REPLY</constant> controls. The
+                  <constant>KDBUS_CMD_SEND</constant> ioctl will block until the
+                  reply has arrived, the timeout limit is reached, in case the
+                  remote connection was shut down, or if interrupted by a signal
+                  before any reply; see
+                  <citerefentry>
+                    <refentrytitle>signal</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>.
+
+                  The offset of the reply message in the sender's pool is stored
+                  in <varname>reply</varname> when the ioctl has returned without
+                  error. Hence, there is no need for another
+                  <constant>KDBUS_CMD_RECV</constant> ioctl or anything else to
+                  receive the reply.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Request a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will fail with
+                  <errorcode>-1</errorcode>, <varname>errno</varname>
+                  is set to <constant>EPROTO</constant>.
+                  Once the ioctl returned, the <varname>flags</varname>
+                  field will have all bits set that the kernel recognizes as
+                  valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>msg_address</varname></term>
+        <listitem><para>
+          In this field, users have to provide a pointer to a message
+          (<type>struct kdbus_msg</type>) to send. See below for a
+          detailed description.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>reply</varname></term>
+        <listitem><para>
+          Only used for synchronous replies. See description of
+          <type>struct kdbus_cmd_recv</type> for more details.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            The following items are currently recognized.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_CANCEL_FD</constant></term>
+              <listitem>
+                <para>
+                  When this optional item is passed in, and the call is
+                  executed as SYNC call, the passed in file descriptor can be
+                  used as alternative cancellation point. The kernel will call
+                  <citerefentry>
+                    <refentrytitle>poll</refentrytitle>
+                    <manvolnum>2</manvolnum>
+                  </citerefentry>
+                  on this file descriptor, and once it reports any incoming
+                  bytes, the blocking send operation will be canceled; the
+                  blocking, synchronous ioctl call will return
+                  <errorcode>-1</errorcode>, and <varname>errno</varname> will
+                  be set to <errorname>ECANCELED</errorname>.
+                  Any type of file descriptor on which
+                  <citerefentry>
+                    <refentrytitle>poll</refentrytitle>
+                    <manvolnum>2</manvolnum>
+                  </citerefentry>
+                  can be called on can be used as payload to this item; for
+                  example, an eventfd can be used for this purpose, see
+                  <citerefentry>
+                    <refentrytitle>eventfd</refentrytitle>
+                    <manvolnum>2</manvolnum>
+                  </citerefentry>.
+                  For asynchronous message sending, this item is allowed but
+                  ignored.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The message referenced by the <varname>msg_address</varname> above has
+      the following layout.
+    </para>
+
+    <programlisting>
+struct kdbus_msg {
+  __u64 size;
+  __u64 flags;
+  __s64 priority;
+  __u64 dst_id;
+  __u64 src_id;
+  __u64 payload_type;
+  __u64 cookie;
+  __u64 timeout_ns;
+  __u64 cookie_reply;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>Flags to describe message details.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_MSG_EXPECT_REPLY</constant></term>
+              <listitem>
+                <para>
+                  Expect a reply to this message from the remote peer. With
+                  this bit set, the timeout_ns field must be set to a non-zero
+                  number of nanoseconds in which the receiving peer is expected
+                  to reply. If such a reply is not received in time, the sender
+                  will be notified with a timeout message (see below). The
+                  value must be an absolute value, in nanoseconds and based on
+                  <constant>CLOCK_MONOTONIC</constant>.
+                </para><para>
+                  For a message to be accepted as reply, it must be a direct
+                  message to the original sender (not a broadcast and not a
+                  signal message), and its
+                  <varname>kdbus_msg.cookie_reply</varname> must match the
+                  previous message's <varname>kdbus_msg.cookie</varname>.
+                </para><para>
+                  Expected replies also temporarily open the policy of the
+                  sending connection, so the other peer is allowed to respond
+                  within the given time window.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_MSG_NO_AUTO_START</constant></term>
+              <listitem>
+                <para>
+                  By default, when a message is sent to an activator
+                  connection, the activator is notified and will start an
+                  implementer. This flag inhibits that behavior. With this bit
+                  set, and the remote being an activator, the ioctl will fail
+                  with <varname>errno</varname> set to
+                  <constant>EADDRNOTAVAIL</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>priority</varname></term>
+        <listitem><para>
+          The priority of this message. Receiving messages (see below) may
+          optionally be constrained to messages of a minimal priority. This
+          allows for use cases where timing critical data is interleaved with
+          control data on the same connection. If unused, the priority field
+          should be set to <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>dst_id</varname></term>
+        <listitem><para>
+          The numeric ID of the destination connection, or
+          <constant>KDBUS_DST_ID_BROADCAST</constant>
+          (~0ULL) to address every peer on the bus, or
+          <constant>KDBUS_DST_ID_NAME</constant> (0) to look
+          it up dynamically from the bus' name registry.
+          In the latter case, an item of type
+          <constant>KDBUS_ITEM_DST_NAME</constant> is mandatory.
+          Also see
+          <citerefentry>
+            <refentrytitle>kdbus.name</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          .
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>src_id</varname></term>
+        <listitem><para>
+          Upon return of the ioctl, this member will contain the sending
+          connection's numerical ID. Should be 0 at send time.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>payload_type</varname></term>
+        <listitem><para>
+          Type of the payload in the actual data records. Currently, only
+          <constant>KDBUS_PAYLOAD_DBUS</constant> is accepted as input value
+          of this field. When receiving messages that are generated by the
+          kernel (notifications), this field will contain
+          <constant>KDBUS_PAYLOAD_KERNEL</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>cookie</varname></term>
+        <listitem><para>
+          Cookie of this message, for later recognition. Also, when replying
+          to a message (see above), the <varname>cookie_reply</varname>
+          field must match this value.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>timeout_ns</varname></term>
+        <listitem><para>
+          If the message sent requires a reply from the remote peer (see above),
+          this field contains the timeout in absolute nanoseconds based on
+          <constant>CLOCK_MONOTONIC</constant>. Also see
+          <citerefentry>
+            <refentrytitle>clock_gettime</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>cookie_reply</varname></term>
+        <listitem><para>
+          If the message sent is a reply to another message, this field must
+          match the cookie of the formerly received message.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            A dynamically sized list of items to contain additional information.
+            The following items are expected/valid:
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_PAYLOAD_VEC</constant></term>
+              <term><constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant></term>
+              <term><constant>KDBUS_ITEM_FDS</constant></term>
+              <listitem>
+                <para>
+                  Actual data records containing the payload. See section
+                  "Message payload".
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_BLOOM_FILTER</constant></term>
+              <listitem>
+                <para>
+                  Bloom filter for matches (see below).
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_ITEM_DST_NAME</constant></term>
+              <listitem>
+                <para>
+                  Well-known name to send this message to. Required if
+                  <varname>dst_id</varname> is set to
+                  <constant>KDBUS_DST_ID_NAME</constant>.
+                  If a connection holding the given name can't be found,
+                  the ioctl will fail with <varname>errno</varname> set to
+                  <constant>ESRCH</constant> is returned.
+                </para>
+                <para>
+                  For messages to a unique name (ID), this item is optional. If
+                  present, the kernel will make sure the name owner matches the
+                  given unique name. This allows programs to tie the message
+                  sending to the condition that a name is currently owned by a
+                  certain unique name.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The message will be augmented by the requested metadata items when
+      queued into the receiver's pool. See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      and
+      <citerefentry>
+        <refentrytitle>kdbus.item</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information on metadata.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Receiving messages</title>
+
+    <para>
+      Messages are received by the client with the
+      <constant>KDBUS_CMD_RECV</constant> ioctl. The endpoint file of the bus
+      supports <function>poll()/epoll()/select()</function>; when new messages
+      are available on the connection's file descriptor,
+      <constant>POLLIN</constant> is reported. For compatibility reasons,
+      <constant>POLLOUT</constant> is always reported as well. Note, however,
+      that the latter does not guarantee that a message can in fact be sent, as
+      this depends on how many pending messages the receiver has in its pool.
+    </para>
+
+    <para>
+      With the <constant>KDBUS_CMD_RECV</constant> ioctl, a
+      <type>struct kdbus_cmd_recv</type> is used.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_recv {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __s64 priority;
+  __u64 dropped_msgs;
+  struct kdbus_msg_info msg;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>Flags to control the receive command.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_RECV_PEEK</constant></term>
+              <listitem>
+                <para>
+                  Just return the location of the next message. Do not install
+                  file descriptors or anything else. This is usually used to
+                  determine the sender of the next queued message.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_RECV_DROP</constant></term>
+              <listitem>
+                <para>
+                  Drop the next message without doing anything else with it,
+                  and free the pool slice. This a short-cut for
+                  <constant>KDBUS_RECV_PEEK</constant> and
+                  <constant>KDBUS_CMD_FREE</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_RECV_USE_PRIORITY</constant></term>
+              <listitem>
+                <para>
+                  Dequeue the messages ordered by their priority, and filtering
+                  them with the priority field (see below).
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Request a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will fail with
+                  <errorcode>-1</errorcode>, <varname>errno</varname>
+                  is set to <constant>EPROTO</constant>.
+                  Once the ioctl returned, the <varname>flags</varname>
+                  field will have all bits set that the kernel recognizes as
+                  valid for this command.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. If the <varname>dropped_msgs</varname>
+          field is non-zero, <constant>KDBUS_RECV_RETURN_DROPPED_MSGS</constant>
+          is set. If a file descriptor could not be installed, the
+          <constant>KDBUS_RECV_RETURN_INCOMPLETE_FDS</constant> flag is set.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>priority</varname></term>
+        <listitem><para>
+          With <constant>KDBUS_RECV_USE_PRIORITY</constant> set in
+          <varname>flags</varname>, messages will be dequeued ordered by their
+          priority, starting with the highest value. Also, messages will be
+          filtered by the value given in this field, so the returned message
+          will at least have the requested priority. If no such message is
+          waiting in the queue, the ioctl will fail, and
+          <varname>errno</varname> will be set to <constant>EAGAIN</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>dropped_msgs</varname></term>
+        <listitem><para>
+          Whenever a message with <constant>KDBUS_MSG_SIGNAL</constant> is sent
+          but cannot be queued on a peer (e.g., as it contains FDs but the peer
+          does not support FDs, or there is no space left in the peer's pool)
+          the 'dropped_msgs' counter of the peer is incremented. On the next
+          RECV ioctl, the 'dropped_msgs' field is copied into the ioctl struct
+          and cleared on the peer. If it was non-zero, the
+          <constant>KDBUS_RECV_RETURN_DROPPED_MSGS</constant> flag will be set
+          in <varname>return_flags</varname>. Note that this will only happen
+          if the ioctl succeeded or failed with <constant>EAGAIN</constant>. In
+          other error cases, the 'dropped_msgs' field of the peer is left
+          untouched.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>msg</varname></term>
+        <listitem><para>
+          Embedded struct containing information on the received message when
+          this command succeeded (see below).
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem><para>
+          Items to specify further details for the receive command.
+          Currently unused, and all items will be rejected with
+          <varname>errno</varname> set to <constant>EINVAL</constant>.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Both <type>struct kdbus_cmd_recv</type> and
+      <type>struct kdbus_cmd_send</type> embed
+      <type>struct kdbus_msg_info</type>.
+      For the <constant>KDBUS_CMD_SEND</constant> ioctl, it is used to catch
+      synchronous replies, if one was requested, and is unused otherwise.
+    </para>
+
+    <programlisting>
+struct kdbus_msg_info {
+  __u64 offset;
+  __u64 msg_size;
+  __u64 return_flags;
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>offset</varname></term>
+        <listitem><para>
+          Upon return of the ioctl, this field contains the offset in the
+          receiver's memory pool. The memory must be freed with
+          <constant>KDBUS_CMD_FREE</constant>. See
+          <citerefentry>
+            <refentrytitle>kdbus.pool</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for further details.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>msg_size</varname></term>
+        <listitem><para>
+          Upon successful return of the ioctl, this field contains the size of
+          the allocated slice at offset <varname>offset</varname>.
+          It is the combination of the size of the stored
+          <type>struct kdbus_msg</type> object plus all appended VECs.
+          You can use it in combination with <varname>offset</varname> to map
+          a single message, instead of mapping the entire pool. See
+          <citerefentry>
+            <refentrytitle>kdbus.pool</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for further details.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem>
+          <para>
+            Kernel-provided return flags. Currently, the following flags are
+            defined.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_RECV_RETURN_INCOMPLETE_FDS</constant></term>
+              <listitem>
+                <para>
+                  The message contained memfds or file descriptors, and the
+                  kernel failed to install one or more of them at receive time.
+                  Most probably that happened because the maximum number of
+                  file descriptors for the receiver's task were exceeded.
+                  In such cases, the message is still delivered, so this is not
+                  a fatal condition. File descriptors numbers inside the
+                  <constant>KDBUS_ITEM_FDS</constant> item or memfd files
+                  referenced by <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant>
+                  items which could not be installed will be set to
+                  <constant>-1</constant>.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      Unless <constant>KDBUS_RECV_DROP</constant> was passed, the
+      <varname>offset</varname> field contains the location of the new message
+      inside the receiver's pool after the <constant>KDBUS_CMD_RECV</constant>
+      ioctl was employed. The message is stored as <type>struct kdbus_msg</type>
+      at this offset, and can be interpreted with the semantics described above.
+    </para>
+    <para>
+      Also, if the connection allowed for file descriptor to be passed
+      (<constant>KDBUS_HELLO_ACCEPT_FD</constant>), and if the message contained
+      any, they will be installed into the receiving process when the
+      <constant>KDBUS_CMD_RECV</constant> ioctl is called.
+      <emphasis>memfds</emphasis> may always be part of the message payload.
+      The receiving task is obliged to close all file descriptors appropriately
+      once no longer needed. If <constant>KDBUS_RECV_PEEK</constant> is set, no
+      file descriptors are installed. This allows for peeking at a message,
+      looking at its metadata only and dropping it via
+      <constant>KDBUS_RECV_DROP</constant>, without installing any of the file
+      descriptors into the receiving process.
+    </para>
+    <para>
+      The caller is obliged to call the <constant>KDBUS_CMD_FREE</constant>
+      ioctl with the returned offset when the memory is no longer needed.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Notifications</title>
+    <para>
+      A kernel notification is a regular kdbus message with the following
+      details.
+    </para>
+
+    <itemizedlist>
+      <listitem><para>
+          kdbus_msg.src_id == <constant>KDBUS_SRC_ID_KERNEL</constant>
+      </para></listitem>
+      <listitem><para>
+        kdbus_msg.dst_id == <constant>KDBUS_DST_ID_BROADCAST</constant>
+      </para></listitem>
+      <listitem><para>
+        kdbus_msg.payload_type == <constant>KDBUS_PAYLOAD_KERNEL</constant>
+      </para></listitem>
+      <listitem><para>
+        Has exactly one of the items attached that are described below.
+      </para></listitem>
+      <listitem><para>
+        Always has a timestamp item (<constant>KDBUS_ITEM_TIMESTAMP</constant>)
+        attached.
+      </para></listitem>
+    </itemizedlist>
+
+    <para>
+      The kernel will notify its users of the following events.
+    </para>
+
+    <itemizedlist>
+      <listitem><para>
+        When connection <emphasis>A</emphasis> is terminated while connection
+        <emphasis>B</emphasis> is waiting for a reply from it, connection
+        <emphasis>B</emphasis> is notified with a message with an item of
+        type <constant>KDBUS_ITEM_REPLY_DEAD</constant>.
+      </para></listitem>
+
+      <listitem><para>
+        When connection <emphasis>A</emphasis> does not receive a reply from
+        connection <emphasis>B</emphasis> within the specified timeout window,
+        connection <emphasis>A</emphasis> will receive a message with an
+        item of type <constant>KDBUS_ITEM_REPLY_TIMEOUT</constant>.
+      </para></listitem>
+
+      <listitem><para>
+        When an ordinary connection (not a monitor) is created on or removed
+        from a bus, messages with an item of type
+        <constant>KDBUS_ITEM_ID_ADD</constant> or
+        <constant>KDBUS_ITEM_ID_REMOVE</constant>, respectively, are delivered
+        to all bus members that match these messages through their match
+        database. Eavesdroppers (monitor connections) do not cause such
+        notifications to be sent. They are invisible on the bus.
+      </para></listitem>
+
+      <listitem><para>
+        When a connection gains or loses ownership of a name, messages with an
+        item of type <constant>KDBUS_ITEM_NAME_ADD</constant>,
+        <constant>KDBUS_ITEM_NAME_REMOVE</constant> or
+        <constant>KDBUS_ITEM_NAME_CHANGE</constant> are delivered to all bus
+        members that match these messages through their match database.
+      </para></listitem>
+    </itemizedlist>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_SEND</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EOPNOTSUPP</constant></term>
+          <listitem><para>
+            The connection is not an ordinary connection, or the passed
+            file descriptors in <constant>KDBUS_ITEM_FDS</constant> item are
+            either kdbus handles or unix domain sockets. Both are currently
+            unsupported.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The submitted payload type is
+            <constant>KDBUS_PAYLOAD_KERNEL</constant>,
+            <constant>KDBUS_MSG_EXPECT_REPLY</constant> was set without timeout
+            or cookie values, <constant>KDBUS_SEND_SYNC_REPLY</constant> was
+            set without <constant>KDBUS_MSG_EXPECT_REPLY</constant>, an invalid
+            item was supplied, <constant>src_id</constant> was non-zero and was
+            different from the current connection's ID, a supplied memfd had a
+            size of 0, or a string was not properly null-terminated.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ENOTUNIQ</constant></term>
+          <listitem><para>
+            The supplied destination is
+            <constant>KDBUS_DST_ID_BROADCAST</constant> and either
+            file descriptors were passed, or
+            <constant>KDBUS_MSG_EXPECT_REPLY</constant> was set,
+            or a timeout was given.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>E2BIG</constant></term>
+          <listitem><para>
+            Too many items.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMSGSIZE</constant></term>
+          <listitem><para>
+            The size of the message header and items or the payload vector
+            is excessive.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EEXIST</constant></term>
+          <listitem><para>
+            Multiple <constant>KDBUS_ITEM_FDS</constant>,
+            <constant>KDBUS_ITEM_BLOOM_FILTER</constant> or
+            <constant>KDBUS_ITEM_DST_NAME</constant> items were supplied.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EBADF</constant></term>
+          <listitem><para>
+            The supplied <constant>KDBUS_ITEM_FDS</constant> or
+            <constant>KDBUS_ITEM_PAYLOAD_MEMFD</constant> items
+            contained an illegal file descriptor.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMEDIUMTYPE</constant></term>
+          <listitem><para>
+            The supplied memfd is not a sealed kdbus memfd.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EMFILE</constant></term>
+          <listitem><para>
+            Too many file descriptors inside a
+            <constant>KDBUS_ITEM_FDS</constant>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EBADMSG</constant></term>
+          <listitem><para>
+            An item had illegal size, both a <constant>dst_id</constant> and a
+            <constant>KDBUS_ITEM_DST_NAME</constant> was given, or both a name
+            and a bloom filter was given.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ETXTBSY</constant></term>
+          <listitem><para>
+            The supplied kdbus memfd file cannot be sealed or the seal
+            was removed, because it is shared with other processes or
+            still mapped with
+            <citerefentry>
+              <refentrytitle>mmap</refentrytitle>
+              <manvolnum>2</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ECOMM</constant></term>
+          <listitem><para>
+            A peer does not accept the file descriptors addressed to it.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EFAULT</constant></term>
+          <listitem><para>
+            The supplied bloom filter size was not 64-bit aligned, or supplied
+            memory could not be accessed by the kernel.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EDOM</constant></term>
+          <listitem><para>
+            The supplied bloom filter size did not match the bloom filter
+            size of the bus.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EDESTADDRREQ</constant></term>
+          <listitem><para>
+            <constant>dst_id</constant> was set to
+            <constant>KDBUS_DST_ID_NAME</constant>, but no
+            <constant>KDBUS_ITEM_DST_NAME</constant> was attached.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ESRCH</constant></term>
+          <listitem><para>
+            The name to look up was not found in the name registry.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EADDRNOTAVAIL</constant></term>
+          <listitem><para>
+            <constant>KDBUS_MSG_NO_AUTO_START</constant> was given but the
+            destination connection is an activator.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ENXIO</constant></term>
+          <listitem><para>
+            The passed numeric destination connection ID couldn't be found,
+            or is not connected.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ECONNRESET</constant></term>
+          <listitem><para>
+            The destination connection is no longer active.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ETIMEDOUT</constant></term>
+          <listitem><para>
+            Timeout while synchronously waiting for a reply.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINTR</constant></term>
+          <listitem><para>
+            Interrupted system call while synchronously waiting for a reply.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EPIPE</constant></term>
+          <listitem><para>
+            When sending a message, a synchronous reply from the receiving
+            connection was expected but the connection died before answering.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ENOBUFS</constant></term>
+          <listitem><para>
+            Too many pending messages on the receiver side.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EREMCHG</constant></term>
+          <listitem><para>
+            Both a well-known name and a unique name (ID) was given, but
+            the name is not currently owned by that connection.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EXFULL</constant></term>
+          <listitem><para>
+            The memory pool of the receiver is full.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EREMOTEIO</constant></term>
+          <listitem><para>
+            While synchronously waiting for a reply, the remote peer
+            failed with an I/O error.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_RECV</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EOPNOTSUPP</constant></term>
+          <listitem><para>
+            The connection is not an ordinary connection, or the passed
+            file descriptors are either kdbus handles or unix domain
+            sockets. Both are currently unsupported.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Invalid flags or offset.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EAGAIN</constant></term>
+          <listitem><para>
+            No message found in the queue.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>clock_gettime</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>ioctl</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>poll</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>select</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>epoll</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>eventfd</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>memfd_create</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.name.xml b/Documentation/kdbus/kdbus.name.xml
new file mode 100644
index 000000000000..3f5f6a6c5ed6
--- /dev/null
+++ b/Documentation/kdbus/kdbus.name.xml
@@ -0,0 +1,711 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.name">
+
+  <refentryinfo>
+    <title>kdbus.name</title>
+    <productname>kdbus.name</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.name</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.name</refname>
+    <refpurpose>kdbus.name</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+    <para>
+      Each
+      <citerefentry>
+        <refentrytitle>kdbus.bus</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      instantiates a name registry to resolve well-known names into unique
+      connection IDs for message delivery. The registry will be queried when a
+      message is sent with <varname>kdbus_msg.dst_id</varname> set to
+      <constant>KDBUS_DST_ID_NAME</constant>, or when a registry dump is
+      requested with <constant>KDBUS_CMD_NAME_LIST</constant>.
+    </para>
+
+    <para>
+      All of the below is subject to policy rules for <emphasis>SEE</emphasis>
+      and <emphasis>OWN</emphasis> permissions. See
+      <citerefentry>
+        <refentrytitle>kdbus.policy</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Name validity</title>
+    <para>
+      A name has to comply with the following rules in order to be considered
+      valid.
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <para>
+          The name has two or more elements separated by a
+          '<literal>.</literal>' (period) character.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          All elements must contain at least one character.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Each element must only contain the ASCII characters
+          <literal>[A-Z][a-z][0-9]_</literal> and must not begin with a
+          digit.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The name must contain at least one '<literal>.</literal>' (period)
+          character (and thus at least two elements).
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The name must not begin with a '<literal>.</literal>' (period)
+          character.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          The name must not exceed <constant>255</constant> characters in
+          length.
+        </para>
+      </listitem>
+    </itemizedlist>
+  </refsect1>
+
+  <refsect1>
+    <title>Acquiring a name</title>
+    <para>
+      To acquire a name, a client uses the
+      <constant>KDBUS_CMD_NAME_ACQUIRE</constant> ioctl with
+      <type>struct kdbus_cmd</type> as argument.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>Flags to control details in the name acquisition.</para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_NAME_REPLACE_EXISTING</constant></term>
+              <listitem>
+                <para>
+                  Acquiring a name that is already present usually fails,
+                  unless this flag is set in the call, and
+                  <constant>KDBUS_NAME_ALLOW_REPLACEMENT</constant> (see below)
+                  was set when the current owner of the name acquired it, or
+                  if the current owner is an activator connection (see
+                  <citerefentry>
+                    <refentrytitle>kdbus.connection</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>).
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_NAME_ALLOW_REPLACEMENT</constant></term>
+              <listitem>
+                <para>
+                  Allow other connections to take over this name. When this
+                  happens, the former owner of the connection will be notified
+                  of the name loss.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_NAME_QUEUE</constant></term>
+              <listitem>
+                <para>
+                  A name that is already acquired by a connection can not be
+                  acquired again (unless the
+                  <constant>KDBUS_NAME_ALLOW_REPLACEMENT</constant> flag was
+                  set during acquisition; see above).
+                  However, a connection can put itself in a queue of
+                  connections waiting for the name to be released. Once that
+                  happens, the first connection in that queue becomes the new
+                  owner and is notified accordingly.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Request a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will fail with
+                  <errorcode>-1</errorcode>, and <varname>errno</varname>
+                  is set to <constant>EPROTO</constant>.
+                  Once the ioctl returned, the <varname>flags</varname>
+                  field will have all bits set that the kernel recognizes as
+                  valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem>
+          <para>
+            Flags returned by the kernel. Currently, the following may be
+            returned by the kernel.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_NAME_IN_QUEUE</constant></term>
+              <listitem>
+                <para>
+                  The name was not acquired yet, but the connection was
+                  placed in the queue of peers waiting for the name.
+                  This can only happen if <constant>KDBUS_NAME_QUEUE</constant>
+                  was set in the <varname>flags</varname> member (see above).
+                  The connection will receive a name owner change notification
+                  once the current owner has given up the name and its
+                  ownership was transferred.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Items to submit the name. Currently, one item of type
+            <constant>KDBUS_ITEM_NAME</constant> is expected and allowed, and
+            the contained string must be a valid bus name.
+            <constant>KDBUS_ITEM_NEGOTIATE</constant> may be used to probe for
+            valid item types. See
+            <citerefentry>
+              <refentrytitle>kdbus.item</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for a detailed description of how this item is used.
+          </para>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <errorname>>EINVAL</errorname>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Releasing a name</title>
+    <para>
+      A connection may release a name explicitly with the
+      <constant>KDBUS_CMD_NAME_RELEASE</constant> ioctl. If the connection was
+      an implementer of an activatable name, its pending messages are moved
+      back to the activator. If there are any connections queued up as waiters
+      for the name, the first one in the queue (the oldest entry) will become
+      the new owner. The same happens implicitly for all names once a
+      connection terminates. See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information on connections.
+    </para>
+    <para>
+      The <constant>KDBUS_CMD_NAME_RELEASE</constant> ioctl uses the same data
+      structure as the acquisition call
+      (<constant>KDBUS_CMD_NAME_ACQUIRE</constant>),
+      but with slightly different field usage.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Flags to the command. Currently unused.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will return <errorcode>0</errorcode>,
+          and the <varname>flags</varname> field is set to
+          <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Items to submit the name. Currently, one item of type
+            <constant>KDBUS_ITEM_NAME</constant> is expected and allowed, and
+            the contained string must be a valid bus name.
+            <constant>KDBUS_ITEM_NEGOTIATE</constant> may be used to probe for
+            valid item types. See
+            <citerefentry>
+              <refentrytitle>kdbus.item</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+            for a detailed description of how this item is used.
+          </para>
+          <para>
+            Unrecognized items are rejected, and the ioctl will fail with
+            <varname>errno</varname> set to <constant>EINVAL</constant>.
+          </para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Dumping the name registry</title>
+    <para>
+      A connection may request a complete or filtered dump of currently active
+      bus names with the <constant>KDBUS_CMD_LIST</constant> ioctl, which
+      takes a <type>struct kdbus_cmd_list</type> as argument.
+    </para>
+
+    <programlisting>
+struct kdbus_cmd_list {
+  __u64 flags;
+  __u64 return_flags;
+  __u64 offset;
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem>
+          <para>
+            Any combination of flags to specify which names should be dumped.
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_LIST_UNIQUE</constant></term>
+              <listitem>
+                <para>
+                  List the unique (numeric) IDs of the connection, whether it
+                  owns a name or not.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_LIST_NAMES</constant></term>
+              <listitem>
+                <para>
+                  List well-known names stored in the database which are
+                  actively owned by a real connection (not an activator).
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_LIST_ACTIVATORS</constant></term>
+              <listitem>
+                <para>
+                  List names that are owned by an activator.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_LIST_QUEUED</constant></term>
+              <listitem>
+                <para>
+                  List connections that are not yet owning a name but are
+                  waiting for it to become available.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Request a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will fail with
+                  <errorcode>-1</errorcode>, and <varname>errno</varname>
+                  is set to <constant>EPROTO</constant>.
+                  Once the ioctl returned, the <varname>flags</varname>
+                  field will have all bits set that the kernel recognizes as
+                  valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>offset</varname></term>
+        <listitem><para>
+          When the ioctl returns successfully, the offset to the name registry
+          dump inside the connection's pool will be stored in this field.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The returned list of names is stored in a <type>struct kdbus_list</type>
+      that in turn contains an array of type <type>struct kdbus_info</type>,
+      The array-size in bytes is given as <varname>list_size</varname>.
+      The fields inside <type>struct kdbus_info</type> is described next.
+    </para>
+
+    <programlisting>
+struct kdbus_info {
+  __u64 size;
+  __u64 id;
+  __u64 flags;
+  struct kdbus_item items[0];
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+          The owning connection's unique ID.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          The flags of the owning connection.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem>
+          <para>
+            Items containing the actual name. Currently, one item of type
+            <constant>KDBUS_ITEM_OWNED_NAME</constant> will be attached,
+            including the name's flags. In that item, the flags field of the
+            name may carry the following bits:
+          </para>
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_NAME_ALLOW_REPLACEMENT</constant></term>
+              <listitem>
+                <para>
+                  Other connections are allowed to take over this name from the
+                  connection that owns it.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_NAME_IN_QUEUE</constant></term>
+              <listitem>
+                <para>
+                  When retrieving a list of currently acquired names in the
+                  registry, this flag indicates whether the connection
+                  actually owns the name or is currently waiting for it to
+                  become available.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_NAME_ACTIVATOR</constant></term>
+              <listitem>
+                <para>
+                  An activator connection owns a name as a placeholder for an
+                  implementer, which is started on demand by programs as soon
+                  as the first message arrives. There's some more information
+                  on this topic in
+                  <citerefentry>
+                    <refentrytitle>kdbus.connection</refentrytitle>
+                    <manvolnum>7</manvolnum>
+                  </citerefentry>
+                  .
+                </para>
+                <para>
+                  In contrast to
+                  <constant>KDBUS_NAME_REPLACE_EXISTING</constant>,
+                  when a name is taken over from an activator connection, all
+                  the messages that have been queued in the activator
+                  connection will be moved over to the new owner. The activator
+                  connection will still be tracked for the name and will take
+                  control again if the implementer connection terminates.
+                </para>
+                <para>
+                  This flag can not be used when acquiring a name, but is
+                  implicitly set through <constant>KDBUS_CMD_HELLO</constant>
+                  with <constant>KDBUS_HELLO_ACTIVATOR</constant> set in
+                  <varname>kdbus_cmd_hello.conn_flags</varname>.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term>
+              <listitem>
+                <para>
+                  Requests a set of valid flags for this ioctl. When this bit is
+                  set, no action is taken; the ioctl will return
+                  <errorcode>0</errorcode>, and the <varname>flags</varname>
+                  field will have all bits set that are valid for this command.
+                  The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be
+                  cleared by the operation.
+                </para>
+              </listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      The returned buffer must be freed with the
+      <constant>KDBUS_CMD_FREE</constant> ioctl when the user is finished with
+      it. See
+      <citerefentry>
+        <refentrytitle>kdbus.pool</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_NAME_ACQUIRE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Illegal command flags, illegal name provided, or an activator
+            tried to acquire a second name.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EPERM</constant></term>
+          <listitem><para>
+            Policy prohibited name ownership.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EALREADY</constant></term>
+          <listitem><para>
+            Connection already owns that name.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EEXIST</constant></term>
+          <listitem><para>
+            The name already exists and can not be taken over.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>E2BIG</constant></term>
+          <listitem><para>
+            The maximum number of well-known names per connection is exhausted.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_NAME_RELEASE</constant>
+        may fail with the following errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Invalid command flags, or invalid name provided.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ESRCH</constant></term>
+          <listitem><para>
+            Name is not found in the registry.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EADDRINUSE</constant></term>
+          <listitem><para>
+            Name is owned by a different connection and can't be released.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_LIST</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Invalid command flags
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>ENOBUFS</constant></term>
+          <listitem><para>
+            No available memory in the connection's pool.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.policy</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.policy.xml b/Documentation/kdbus/kdbus.policy.xml
new file mode 100644
index 000000000000..67324163880a
--- /dev/null
+++ b/Documentation/kdbus/kdbus.policy.xml
@@ -0,0 +1,406 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.policy">
+
+  <refentryinfo>
+    <title>kdbus.policy</title>
+    <productname>kdbus.policy</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.policy</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.policy</refname>
+    <refpurpose>kdbus policy</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      A kdbus policy restricts the possibilities of connections to own, see and
+      talk to well-known names. A policy can be associated with a bus (through a
+      policy holder connection) or a custom endpoint. kdbus stores its policy
+      information in a database that can be accessed through the following
+      ioctl commands:
+    </para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>KDBUS_CMD_HELLO</constant></term>
+        <listitem><para>
+          When creating, or updating, a policy holder connection. See
+          <citerefentry>
+            <refentrytitle>kdbus.connection</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>KDBUS_CMD_ENDPOINT_MAKE</constant></term>
+        <term><constant>KDBUS_CMD_ENDPOINT_UPDATE</constant></term>
+        <listitem><para>
+          When creating, or updating, a bus custom endpoint. See
+          <citerefentry>
+            <refentrytitle>kdbus.endpoint</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      In all cases, the name and policy access information is stored in items
+      of type <constant>KDBUS_ITEM_NAME</constant> and
+      <constant>KDBUS_ITEM_POLICY_ACCESS</constant>. For this transport, the
+      following rules apply.
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <para>
+          An item of type <constant>KDBUS_ITEM_NAME</constant> must be followed
+          by at least one <constant>KDBUS_ITEM_POLICY_ACCESS</constant> item.
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+          An item of type <constant>KDBUS_ITEM_NAME</constant> can be followed
+          by an arbitrary number of
+          <constant>KDBUS_ITEM_POLICY_ACCESS</constant> items.
+        </para>
+      </listitem>
+
+      <listitem>
+        <para>
+          An arbitrary number of groups of names and access levels can be given.
+        </para>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      Names passed in items of type <constant>KDBUS_ITEM_NAME</constant> must
+      comply to the rules of valid kdbus.name. See
+      <citerefentry>
+        <refentrytitle>kdbus.name</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information.
+
+      The payload of an item of type
+      <constant>KDBUS_ITEM_POLICY_ACCESS</constant> is defined by the following
+      struct. For more information on the layout of items, please refer to
+      <citerefentry>
+        <refentrytitle>kdbus.item</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>.
+    </para>
+
+    <programlisting>
+struct kdbus_policy_access {
+  __u64 type;
+  __u64 access;
+  __u64 id;
+};
+    </programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>type</varname></term>
+        <listitem>
+          <para>
+            One of the following.
+          </para>
+
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_ACCESS_USER</constant></term>
+              <listitem><para>
+                Grant access to a user with the UID stored in the
+                <varname>id</varname> field.
+              </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_ACCESS_GROUP</constant></term>
+              <listitem><para>
+                Grant access to a user with the GID stored in the
+                <varname>id</varname> field.
+              </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_ACCESS_WORLD</constant></term>
+              <listitem><para>
+                Grant access to everyone. The <varname>id</varname> field
+                is ignored.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>access</varname></term>
+        <listitem>
+          <para>
+            The access to grant. One of the following.
+          </para>
+
+          <variablelist>
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_SEE</constant></term>
+              <listitem><para>
+                Allow the name to be seen.
+              </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_TALK</constant></term>
+              <listitem><para>
+                Allow the name to be talked to.
+              </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term><constant>KDBUS_POLICY_OWN</constant></term>
+              <listitem><para>
+                Allow the name to be owned.
+              </para></listitem>
+            </varlistentry>
+          </variablelist>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>id</varname></term>
+        <listitem><para>
+           For <constant>KDBUS_POLICY_ACCESS_USER</constant>, stores the UID.
+           For <constant>KDBUS_POLICY_ACCESS_GROUP</constant>, stores the GID.
+        </para></listitem>
+      </varlistentry>
+
+    </variablelist>
+
+    <para>
+      All endpoints of buses have an empty policy database by default.
+      Therefore, unless policy rules are added, all operations will also be
+      denied by default. Also see
+      <citerefentry>
+        <refentrytitle>kdbus.endpoint</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Wildcard names</title>
+    <para>
+      Policy holder connections may upload names that contain the wildcard
+      suffix (<literal>".*"</literal>). Such a policy entry is effective for
+      every well-known name that extends the provided name by exactly one more
+      level.
+
+      For example, the name <literal>foo.bar.*</literal> matches both
+      <literal>"foo.bar.baz"</literal> and
+      <literal>"foo.bar.bazbaz"</literal> are, but not
+      <literal>"foo.bar.baz.baz"</literal>.
+
+      This allows connections to take control over multiple names that the
+      policy holder doesn't need to know about when uploading the policy.
+
+      Such wildcard entries are not allowed for custom endpoints.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Privileged connections</title>
+    <para>
+      The policy database is overruled when action is taken by a privileged
+      connection. Please refer to
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information on what makes a connection privileged.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <para>
+      For instance, a set of policy rules may look like this:
+    </para>
+
+    <programlisting>
+KDBUS_ITEM_NAME: str='org.foo.bar'
+KDBUS_ITEM_POLICY_ACCESS: type=USER, access=OWN, ID=1000
+KDBUS_ITEM_POLICY_ACCESS: type=USER, access=TALK, ID=1001
+KDBUS_ITEM_POLICY_ACCESS: type=WORLD, access=SEE
+
+KDBUS_ITEM_NAME: str='org.blah.baz'
+KDBUS_ITEM_POLICY_ACCESS: type=USER, access=OWN, ID=0
+KDBUS_ITEM_POLICY_ACCESS: type=WORLD, access=TALK
+    </programlisting>
+
+    <para>
+      That means that 'org.foo.bar' may only be owned by UID 1000, but every
+      user on the bus is allowed to see the name. However, only UID 1001 may
+      actually send a message to the connection and receive a reply from it.
+
+      The second rule allows 'org.blah.baz' to be owned by UID 0 only, but
+      every user may talk to it.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>TALK access and multiple well-known names per connection</title>
+    <para>
+      Note that TALK access is checked against all names of a connection. For
+      example, if a connection owns both <constant>'org.foo.bar'</constant> and
+      <constant>'org.blah.baz'</constant>, and the policy database allows
+      <constant>'org.blah.baz'</constant> to be talked to by WORLD, then this
+      permission is also granted to <constant>'org.foo.bar'</constant>. That
+      might sound illogical, but after all, we allow messages to be directed to
+      either the ID or a well-known name, and policy is applied to the
+      connection, not the name. In other words, the effective TALK policy for a
+      connection is the most permissive of all names the connection owns.
+
+      For broadcast messages, the receiver needs TALK permissions to the sender
+      to receive the broadcast.
+    </para>
+    <para>
+      Both the endpoint and the bus policy databases are consulted to allow
+      name registry listing, owning a well-known name and message delivery.
+      If either one fails, the operation is failed with
+      <varname>errno</varname> set to <constant>EPERM</constant>.
+
+      For best practices, connections that own names with a restricted TALK
+      access should not install matches. This avoids cases where the sent
+      message may pass the bloom filter due to false-positives and may also
+      satisfy the policy rules.
+
+      Also see
+      <citerefentry>
+        <refentrytitle>kdbus.match</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Implicit policies</title>
+    <para>
+      Depending on the type of the endpoint, a set of implicit rules that
+      override installed policies might be enforced.
+
+      On default endpoints, the following set is enforced and checked before
+      any user-supplied policy is checked.
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <para>
+          Privileged connections always override any installed policy. Those
+          connections could easily install their own policies, so there is no
+          reason to enforce installed policies.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Connections can always talk to connections of the same user. This
+          includes broadcast messages.
+        </para>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      Custom endpoints have stricter policies. The following rules apply:
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <para>
+          Policy rules are always enforced, even if the connection is a
+          privileged connection.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Policy rules are always enforced for <constant>TALK</constant> access,
+          even if both ends are running under the same user. This includes
+          broadcast messages.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          To restrict the set of names that can be seen, endpoint policies can
+          install <constant>SEE</constant> policies.
+        </para>
+      </listitem>
+    </itemizedlist>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.pool.xml b/Documentation/kdbus/kdbus.pool.xml
new file mode 100644
index 000000000000..a9e16f196d39
--- /dev/null
+++ b/Documentation/kdbus/kdbus.pool.xml
@@ -0,0 +1,326 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus.pool">
+
+  <refentryinfo>
+    <title>kdbus.pool</title>
+    <productname>kdbus.pool</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus.pool</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus.pool</refname>
+    <refpurpose>kdbus pool</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+    <para>
+      A pool for data received from the kernel is installed for every
+      <emphasis>connection</emphasis> of the <emphasis>bus</emphasis>, and
+      is sized according to the information stored in the
+      <varname>pool_size</varname> member of <type>struct kdbus_cmd_hello</type>
+      when <constant>KDBUS_CMD_HELLO</constant> is employed. Internally, the
+      pool is segmented into <emphasis>slices</emphasis>, each referenced by its
+      <emphasis>offset</emphasis> in the pool, expressed in <type>bytes</type>.
+      See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more information about <constant>KDBUS_CMD_HELLO</constant>.
+    </para>
+
+    <para>
+      The pool is written to by the kernel when one of the following
+      <emphasis>ioctls</emphasis> is issued:
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_CMD_HELLO</constant></term>
+          <listitem><para>
+            ... to receive details about the bus the connection was made to
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><constant>KDBUS_CMD_RECV</constant></term>
+          <listitem><para>
+            ... to receive a message
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><constant>KDBUS_CMD_LIST</constant></term>
+          <listitem><para>
+            ... to dump the name registry
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><constant>KDBUS_CMD_CONN_INFO</constant></term>
+          <listitem><para>
+            ... to retrieve information on a connection
+          </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><constant>KDBUS_CMD_BUS_CREATOR_INFO</constant></term>
+          <listitem><para>
+            ... to retrieve information about a connection's bus creator
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+
+    </para>
+    <para>
+      The <varname>offset</varname> fields returned by either one of the
+      aforementioned ioctls describe offsets inside the pool. In order to make
+      the slice available for subsequent calls,
+      <constant>KDBUS_CMD_FREE</constant> has to be called on that offset
+      (see below). Otherwise, the pool will fill up, and the connection won't
+      be able to receive any more information through its pool.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Pool slice allocation</title>
+    <para>
+      Pool slices are allocated by the kernel in order to report information
+      back to a task, such as messages, returned name list etc.
+      Allocation of pool slices cannot be initiated by userspace. See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      and
+      <citerefentry>
+        <refentrytitle>kdbus.name</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for examples of commands that use the <emphasis>pool</emphasis> to
+      return data.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Accessing the pool memory</title>
+    <para>
+      Memory in the pool is read-only for userspace and may only be written
+      to by the kernel. To read from the pool memory, the caller is expected to
+      <citerefentry>
+        <refentrytitle>mmap</refentrytitle>
+        <manvolnum>2</manvolnum>
+      </citerefentry>
+      the buffer into its task, like this:
+    </para>
+    <programlisting>
+uint8_t *buf = mmap(NULL, size, PROT_READ, MAP_SHARED, conn_fd, 0);
+    </programlisting>
+
+    <para>
+      In order to map the entire pool, the <varname>size</varname> parameter in
+      the example above should be set to the value of the
+      <varname>pool_size</varname> member of
+      <type>struct kdbus_cmd_hello</type> when
+      <constant>KDBUS_CMD_HELLO</constant> was employed to create the
+      connection (see above).
+    </para>
+
+    <para>
+      The <emphasis>file descriptor</emphasis> used to map the memory must be
+      the one that was used to create the <emphasis>connection</emphasis>.
+      In other words, the one that was used to call
+      <constant>KDBUS_CMD_HELLO</constant>. See
+      <citerefentry>
+        <refentrytitle>kdbus.connection</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>
+      for more details.
+    </para>
+
+    <para>
+      Alternatively, instead of mapping the entire pool buffer, only parts
+      of it can be mapped. Every kdbus command that returns an
+      <emphasis>offset</emphasis> (see above) also reports a
+      <emphasis>size</emphasis> along with it, so programs can be written
+      in a way that it only maps portions of the pool to access a specific
+      <emphasis>slice</emphasis>.
+    </para>
+
+    <para>
+      When access to the pool memory is no longer needed, programs should
+      call <function>munmap()</function> on the pointer returned by
+      <function>mmap()</function>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Freeing pool slices</title>
+    <para>
+      The <constant>KDBUS_CMD_FREE</constant> ioctl is used to free a slice
+      inside the pool, describing an offset that was returned in an
+      <varname>offset</varname> field of another ioctl struct.
+      The <constant>KDBUS_CMD_FREE</constant> command takes a
+      <type>struct kdbus_cmd_free</type> as argument.
+    </para>
+
+<programlisting>
+struct kdbus_cmd_free {
+  __u64 size;
+  __u64 flags;
+  __u64 return_flags;
+  __u64 offset;
+  struct kdbus_item items[0];
+};
+</programlisting>
+
+    <para>The fields in this struct are described below.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>size</varname></term>
+        <listitem><para>
+          The overall size of the struct, including its items.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>flags</varname></term>
+        <listitem><para>
+          Currently unused.
+          <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for
+          valid flags. If set, the ioctl will return <errorcode>0</errorcode>,
+          and the <varname>flags</varname> field is set to
+          <constant>0</constant>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>return_flags</varname></term>
+        <listitem><para>
+          Flags returned by the kernel. Currently unused and always set to
+          <constant>0</constant> by the kernel.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>offset</varname></term>
+        <listitem><para>
+          The offset to free, as returned by other ioctls that allocated
+          memory for returned information.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>items</varname></term>
+        <listitem><para>
+          Items to specify further details for the receive command.
+          Currently unused.
+          Unrecognized items are rejected, and the ioctl will fail with
+          <varname>errno</varname> set to <constant>EINVAL</constant>.
+          All items except for
+          <constant>KDBUS_ITEM_NEGOTIATE</constant> (see
+            <citerefentry>
+              <refentrytitle>kdbus.item</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>
+          ) will be rejected.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Return value</title>
+    <para>
+      On success, all mentioned ioctl commands return <errorcode>0</errorcode>;
+      on error, <errorcode>-1</errorcode> is returned, and
+      <varname>errno</varname> is set to indicate the error.
+      If the issued ioctl is illegal for the file descriptor used,
+      <varname>errno</varname> will be set to <constant>ENOTTY</constant>.
+    </para>
+
+    <refsect2>
+      <title>
+        <constant>KDBUS_CMD_FREE</constant> may fail with the following
+        errors
+      </title>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>ENXIO</constant></term>
+          <listitem><para>
+            No pool slice found at given offset.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            Invalid flags provided.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>EINVAL</constant></term>
+          <listitem><para>
+            The offset is valid, but the user is not allowed to free the slice.
+            This happens, for example, if the offset was retrieved with
+            <constant>KDBUS_RECV_PEEK</constant>.
+          </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>mmap</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>
+        </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>munmap</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+    </simplelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/kdbus/kdbus.xml b/Documentation/kdbus/kdbus.xml
new file mode 100644
index 000000000000..d8e7400df2af
--- /dev/null
+++ b/Documentation/kdbus/kdbus.xml
@@ -0,0 +1,1012 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="kdbus">
+
+  <refentryinfo>
+    <title>kdbus</title>
+    <productname>kdbus</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>kdbus</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>kdbus</refname>
+    <refpurpose>Kernel Message Bus</refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Synopsis</title>
+    <para>
+      kdbus is an inter-process communication bus system controlled by the
+      kernel. It provides user-space with an API to create buses and send
+      unicast and multicast messages to one, or many, peers connected to the
+      same bus. It does not enforce any layout on the transmitted data, but
+      only provides the transport layer used for message interchange between
+      peers.
+    </para>
+    <para>
+      This set of man-pages gives a comprehensive overview of the kernel-level
+      API, with all ioctl commands, associated structs and bit masks. However,
+      most people will not use this API level directly, but rather let one of
+      the high-level abstraction libraries help them integrate D-Bus
+      functionality into their applications.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>
+      kdbus provides a pseudo filesystem called <emphasis>kdbusfs</emphasis>,
+      which is usually mounted on <filename>/sys/fs/kdbus</filename>. Bus
+      primitives can be accessed as files and sub-directories underneath this
+      mount-point. Any advanced operations are done via
+      <function>ioctl()</function> on files created by
+      <emphasis>kdbusfs</emphasis>. Multiple mount-points of
+      <emphasis>kdbusfs</emphasis> are independent of each other. This allows
+      namespacing of kdbus by mounting a new instance of
+      <emphasis>kdbusfs</emphasis> in a new mount-namespace. kdbus calls these
+      mount instances domains and each bus belongs to exactly one domain.
+    </para>
+
+    <para>
+      kdbus was designed as a transport layer for D-Bus, but is in no way
+      limited, nor controlled by the D-Bus protocol specification. The D-Bus
+      protocol is one possible application layer on top of kdbus.
+    </para>
+
+    <para>
+      For the general D-Bus protocol specification, its payload format, its
+      marshaling, and its communication semantics, please refer to the
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html">
+      D-Bus specification</ulink>.
+    </para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Terminology</title>
+
+    <refsect2>
+      <title>Domain</title>
+      <para>
+        A domain is a <emphasis>kdbusfs</emphasis> mount-point containing all
+        the bus primitives. Each domain is independent, and separate domains
+        do not affect each other.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Bus</title>
+      <para>
+        A bus is a named object inside a domain. Clients exchange messages
+        over a bus. Multiple buses themselves have no connection to each other;
+        messages can only be exchanged on the same bus. The default endpoint of
+        a bus, to which clients establish connections, is the "bus" file
+        /sys/fs/kdbus/&lt;bus name&gt;/bus.
+        Common operating system setups create one "system bus" per system,
+        and one "user bus" for every logged-in user. Applications or services
+        may create their own private buses. The kernel driver does not
+        distinguish between different bus types, they are all handled the same
+        way. See
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Endpoint</title>
+      <para>
+        An endpoint provides a file to talk to a bus. Opening an endpoint
+        creates a new connection to the bus to which the endpoint belongs. All
+        endpoints have unique names and are accessible as files underneath the
+        directory of a bus, e.g., /sys/fs/kdbus/&lt;bus&gt;/&lt;endpoint&gt;
+        Every bus has a default endpoint called "bus".
+        A bus can optionally offer additional endpoints with custom names
+        to provide restricted access to the bus. Custom endpoints carry
+        additional policy which can be used to create sandboxes with
+        locked-down, limited, filtered access to a bus. See
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Connection</title>
+      <para>
+        A connection to a bus is created by opening an endpoint file of a
+        bus. Every ordinary client connection has a unique identifier on the
+        bus and can address messages to every other connection on the same
+        bus by using the peer's connection ID as the destination. See
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Pool</title>
+      <para>
+        Each connection allocates a piece of shmem-backed memory that is
+        used to receive messages and answers to ioctl commands from the kernel.
+        It is never used to send anything to the kernel. In order to access that
+        memory, an application must mmap() it into its address space. See
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Well-known Name</title>
+      <para>
+        A connection can, in addition to its implicit unique connection ID,
+        request the ownership of a textual well-known name. Well-known names are
+        noted in reverse-domain notation, such as com.example.service1. A
+        connection that offers a service on a bus is usually reached by its
+        well-known name. An analogy of connection ID and well-known name is an
+        IP address and a DNS name associated with that address. See
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Message</title>
+      <para>
+        Connections can exchange messages with other connections by addressing
+        the peers with their connection ID or well-known name. A message
+        consists of a message header with information on how to route the
+        message, and the message payload, which is a logical byte stream of
+        arbitrary size. Messages can carry additional file descriptors to be
+        passed from one connection to another, just like passing file
+        descriptors over UNIX domain sockets. Every connection can specify which
+        set of metadata the kernel should attach to the message when it is
+        delivered to the receiving connection. Metadata contains information
+        like: system time stamps, UID, GID, TID, proc-starttime, well-known
+        names, process comm, process exe, process argv, cgroup, capabilities,
+        seclabel, audit session, loginuid and the connection's human-readable
+        name. See
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Item</title>
+      <para>
+        The API of kdbus implements the notion of items, submitted through and
+        returned by most ioctls, and stored inside data structures in the
+        connection's pool. See
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Broadcast, signal, filter, match</title>
+      <para>
+        Signals are messages that a receiver opts in for by installing a blob of
+        bytes, called a 'match'. Signal messages must always carry a
+        counter-part blob, called a 'filter', and signals are only delivered to
+        peers which have a match that white-lists the message's filter. Senders
+        of signal messages can use either a single connection ID as receiver,
+        or the special connection ID
+        <constant>KDBUS_DST_ID_BROADCAST</constant> to potentially send it to
+        all connections of a bus, following the logic described above. See
+        <citerefentry>
+          <refentrytitle>kdbus.match</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        and
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Policy</title>
+      <para>
+        A policy is a set of rules that define which connections can see, talk
+        to, or register a well-known name on the bus. A policy is attached to
+        buses and custom endpoints, and modified by policy holder connections or
+        owners of custom endpoints. See
+        <citerefentry>
+          <refentrytitle>kdbus.policy</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Privileged bus users</title>
+      <para>
+        A user connecting to the bus is considered privileged if it is either
+        the creator of the bus, or if it has the CAP_IPC_OWNER capability flag
+        set. See
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for more details.
+      </para>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>Bus Layout</title>
+
+    <para>
+      A <emphasis>bus</emphasis> provides and defines an environment that peers
+      can connect to for message interchange. A bus is created via the kdbus
+      control interface and can be modified by the bus creator. It applies the
+      policy that control all bus operations. The bus creator itself does not
+      participate as a peer. To establish a peer
+      <emphasis>connection</emphasis>, you have to open one of the
+      <emphasis>endpoints</emphasis> of a bus. Each bus provides a default
+      endpoint, but further endpoints can be created on-demand. Endpoints are
+      used to apply additional policies for all connections on this endpoint.
+      Thus, they provide additional filters to further restrict access of
+      specific connections to the bus.
+    </para>
+
+    <para>
+      Following, you can see an example bus layout:
+    </para>
+
+    <programlisting><![CDATA[
+                                  Bus Creator
+                                       |
+                                       |
+                                    +-----+
+                                    | Bus |
+                                    +-----+
+                                       |
+                    __________________/ \__________________
+                   /                                       \
+                   |                                       |
+             +----------+                             +----------+
+             | Endpoint |                             | Endpoint |
+             +----------+                             +----------+
+         _________/|\_________                   _________/|\_________
+        /          |          \                 /          |          \
+        |          |          |                 |          |          |
+        |          |          |                 |          |          |
+   Connection  Connection  Connection      Connection  Connection  Connection
+    ]]></programlisting>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Data structures and interconnections</title>
+    <programlisting><![CDATA[
+  +--------------------------------------------------------------------------+
+  | Domain (Mount Point)                                                     |
+  | /sys/fs/kdbus/control                                                    |
+  | +----------------------------------------------------------------------+ |
+  | | Bus (System Bus)                                                     | |
+  | | /sys/fs/kdbus/0-system/                                              | |
+  | | +-------------------------------+ +--------------------------------+ | |
+  | | | Endpoint                      | | Endpoint                       | | |
+  | | | /sys/fs/kdbus/0-system/bus    | | /sys/fs/kdbus/0-system/ep.app  | | |
+  | | +-------------------------------+ +--------------------------------+ | |
+  | | +--------------+ +--------------+ +--------------+ +---------------+ | |
+  | | | Connection   | | Connection   | | Connection   | | Connection    | | |
+  | | | :1.22        | | :1.25        | | :1.55        | | :1.81         | | |
+  | | +--------------+ +--------------+ +--------------+ +---------------+ | |
+  | +----------------------------------------------------------------------+ |
+  |                                                                          |
+  | +----------------------------------------------------------------------+ |
+  | | Bus (User Bus for UID 2702)                                          | |
+  | | /sys/fs/kdbus/2702-user/                                             | |
+  | | +-------------------------------+ +--------------------------------+ | |
+  | | | Endpoint                      | | Endpoint                       | | |
+  | | | /sys/fs/kdbus/2702-user/bus   | | /sys/fs/kdbus/2702-user/ep.app | | |
+  | | +-------------------------------+ +--------------------------------+ | |
+  | | +--------------+ +--------------+ +--------------+ +---------------+ | |
+  | | | Connection   | | Connection   | | Connection   | | Connection    | | |
+  | | | :1.22        | | :1.25        | | :1.55        | | :1.81         | | |
+  | | +--------------+ +--------------+ +--------------------------------+ | |
+  | +----------------------------------------------------------------------+ |
+  +--------------------------------------------------------------------------+
+    ]]></programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Metadata</title>
+
+    <refsect2>
+      <title>When metadata is collected</title>
+      <para>
+        kdbus records data about the system in certain situations. Such metadata
+        can refer to the currently active process (creds, PIDs, current user
+        groups, process names and its executable path, cgroup membership,
+        capabilities, security label and audit information), connection
+        information (description string, currently owned names) and time stamps.
+      </para>
+      <para>
+        Metadata is collected at the following times.
+      </para>
+
+      <itemizedlist>
+        <listitem><para>
+          When a bus is created (<constant>KDBUS_CMD_MAKE</constant>),
+          information about the calling task is collected. This data is returned
+          by the kernel via the <constant>KDBUS_CMD_BUS_CREATOR_INFO</constant>
+          call.
+        </para></listitem>
+
+        <listitem>
+          <para>
+            When a connection is created (<constant>KDBUS_CMD_HELLO</constant>),
+            information about the calling task is collected. Alternatively, a
+            privileged connection may provide 'faked' information about
+            credentials, PIDs and security labels which will be stored instead.
+            This data is returned by the kernel as information on a connection
+            (<constant>KDBUS_CMD_CONN_INFO</constant>). Only metadata that a
+            connection allowed to be sent (by setting its bit in
+            <varname>attach_flags_send</varname>) will be exported in this way.
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            When a message is sent (<constant>KDBUS_CMD_SEND</constant>),
+            information about the sending task and the sending connection is
+            collected. This metadata will be attached to the message when it
+            arrives in the receiver's pool. If the connection sending the
+            message installed faked credentials (see
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>),
+            the message will not be augmented by any information about the
+            currently sending task. Note that only metadata that was requested
+            by the receiving connection will be collected and attached to
+            messages.
+          </para>
+        </listitem>
+      </itemizedlist>
+
+      <para>
+        Which metadata items are actually delivered depends on the following
+        sets and masks:
+      </para>
+
+      <itemizedlist>
+        <listitem><para>
+          (a) the system-wide kmod creds mask
+          (module parameter <varname>attach_flags_mask</varname>)
+        </para></listitem>
+
+        <listitem><para>
+          (b) the per-connection send creds mask, set by the connecting client
+        </para></listitem>
+
+        <listitem><para>
+          (c) the per-connection receive creds mask, set by the connecting
+          client
+        </para></listitem>
+
+        <listitem><para>
+          (d) the per-bus minimal creds mask, set by the bus creator
+        </para></listitem>
+
+        <listitem><para>
+          (e) the per-bus owner creds mask, set by the bus creator
+        </para></listitem>
+
+        <listitem><para>
+          (f) the mask specified when querying creds of a bus peer
+        </para></listitem>
+
+        <listitem><para>
+          (g) the mask specified when querying creds of a bus owner
+        </para></listitem>
+      </itemizedlist>
+
+      <para>
+        With the following rules:
+      </para>
+
+      <itemizedlist>
+        <listitem>
+          <para>
+            [1] The creds attached to messages are determined as
+            <constant>a &amp; b &amp; c</constant>.
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            [2] When connecting to a bus (<constant>KDBUS_CMD_HELLO</constant>),
+            and <constant>~b &amp; d != 0</constant>, the call will fail with,
+            <errorcode>-1</errorcode>, and <varname>errno</varname> is set to
+            <constant>ECONNREFUSED</constant>.
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            [3] When querying creds of a bus peer, the creds returned are
+            <constant>a &amp; b &amp; f</constant>.
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            [4] When querying creds of a bus owner, the creds returned are
+            <constant>a &amp; e &amp; g</constant>.
+          </para>
+        </listitem>
+      </itemizedlist>
+
+      <para>
+        Hence, programs might not always get all requested metadata items that
+        it requested. Code must be written so that it can cope with this fact.
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Benefits and heads-up</title>
+      <para>
+        Attaching metadata to messages has two major benefits.
+
+        <itemizedlist>
+          <listitem>
+            <para>
+              Metadata attached to messages is gathered at the moment when the
+              other side calls <constant>KDBUS_CMD_SEND</constant>, or,
+              respectively, then the kernel notification is generated. There is
+              no need for the receiving peer to retrieve information about the
+              task in a second step. This closes a race gap that would otherwise
+              be inherent.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              As metadata is delivered along with messages in the same data
+              blob, no extra calls to kernel functions etc. are needed to gather
+              them.
+            </para>
+          </listitem>
+        </itemizedlist>
+
+        Note, however, that collecting metadata does come at a price for
+        performance, so developers should carefully assess which metadata to
+        really opt-in for. For best practice, data that is not needed as part
+        of a message should not be requested by the connection in the first
+        place (see <varname>attach_flags_recv</varname> in
+        <constant>KDBUS_CMD_HELLO</constant>).
+      </para>
+    </refsect2>
+
+    <refsect2>
+      <title>Attach flags for metadata items</title>
+      <para>
+        To let the kernel know which metadata information to attach as items
+        to the aforementioned commands, it uses a bitmask. In those, the
+        following <emphasis>attach flags</emphasis> are currently supported.
+        Both the <varname>attach_flags_recv</varname> and
+        <varname>attach_flags_send</varname> fields of
+        <type>struct kdbus_cmd_hello</type>, as well as the payload of the
+        <constant>KDBUS_ITEM_ATTACH_FLAGS_SEND</constant> and
+        <constant>KDBUS_ITEM_ATTACH_FLAGS_RECV</constant> items follow this
+        scheme.
+      </para>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_TIMESTAMP</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_TIMESTAMP</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_CREDS</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_CREDS</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_PIDS</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_PIDS</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_AUXGROUPS</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_AUXGROUPS</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_NAMES</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_OWNED_NAME</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_TID_COMM</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_TID_COMM</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_PID_COMM</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_PID_COMM</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_EXE</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_EXE</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_CMDLINE</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_CMDLINE</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_CGROUP</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_CGROUP</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_CAPS</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_CAPS</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_SECLABEL</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_SECLABEL</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_AUDIT</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_AUDIT</constant>.
+            </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>KDBUS_ATTACH_CONN_DESCRIPTION</constant></term>
+            <listitem><para>
+              Requests the attachment of an item of type
+              <constant>KDBUS_ITEM_CONN_DESCRIPTION</constant>.
+            </para></listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>
+        Please refer to
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+        for detailed information about the layout and payload of items and
+        what metadata should be used to.
+      </para>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>The ioctl interface</title>
+
+    <para>
+      As stated in the 'synopsis' section above, application developers are
+      strongly encouraged to use kdbus through one of the high-level D-Bus
+      abstraction libraries, rather than using the low-level API directly.
+    </para>
+
+    <para>
+      kdbus on the kernel level exposes its functions exclusively through
+      <citerefentry>
+        <refentrytitle>ioctl</refentrytitle>
+        <manvolnum>2</manvolnum>
+      </citerefentry>,
+      employed on file descriptors returned by
+      <citerefentry>
+        <refentrytitle>open</refentrytitle>
+        <manvolnum>2</manvolnum>
+      </citerefentry>
+      on pseudo files exposed by
+      <citerefentry>
+        <refentrytitle>kdbus.fs</refentrytitle>
+        <manvolnum>7</manvolnum>
+      </citerefentry>.
+    </para>
+    <para>
+      Following is a list of all the ioctls, along with the command structs
+      they must be used with.
+    </para>
+
+    <informaltable frame="none">
+      <tgroup cols="3" colsep="1">
+        <thead>
+          <row>
+            <entry>ioctl signature</entry>
+            <entry>command</entry>
+            <entry>transported struct</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry><constant>0x40189500</constant></entry>
+            <entry><constant>KDBUS_CMD_BUS_MAKE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x40189510</constant></entry>
+            <entry><constant>KDBUS_CMD_ENDPOINT_MAKE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0xc0609580</constant></entry>
+            <entry><constant>KDBUS_CMD_HELLO</constant></entry>
+            <entry><type>struct kdbus_cmd_hello *</type></entry>
+          </row><row>
+            <entry><constant>0x40189582</constant></entry>
+            <entry><constant>KDBUS_CMD_BYEBYE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x40389590</constant></entry>
+            <entry><constant>KDBUS_CMD_SEND</constant></entry>
+            <entry><type>struct kdbus_cmd_send *</type></entry>
+          </row><row>
+            <entry><constant>0x80409591</constant></entry>
+            <entry><constant>KDBUS_CMD_RECV</constant></entry>
+            <entry><type>struct kdbus_cmd_recv *</type></entry>
+          </row><row>
+            <entry><constant>0x40209583</constant></entry>
+            <entry><constant>KDBUS_CMD_FREE</constant></entry>
+            <entry><type>struct kdbus_cmd_free *</type></entry>
+          </row><row>
+            <entry><constant>0x401895a0</constant></entry>
+            <entry><constant>KDBUS_CMD_NAME_ACQUIRE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x401895a1</constant></entry>
+            <entry><constant>KDBUS_CMD_NAME_RELEASE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x80289586</constant></entry>
+            <entry><constant>KDBUS_CMD_LIST</constant></entry>
+            <entry><type>struct kdbus_cmd_list *</type></entry>
+          </row><row>
+            <entry><constant>0x80309584</constant></entry>
+            <entry><constant>KDBUS_CMD_CONN_INFO</constant></entry>
+            <entry><type>struct kdbus_cmd_info *</type></entry>
+          </row><row>
+            <entry><constant>0x40209551</constant></entry>
+            <entry><constant>KDBUS_CMD_UPDATE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x80309585</constant></entry>
+            <entry><constant>KDBUS_CMD_BUS_CREATOR_INFO</constant></entry>
+            <entry><type>struct kdbus_cmd_info *</type></entry>
+          </row><row>
+            <entry><constant>0x40189511</constant></entry>
+            <entry><constant>KDBUS_CMD_ENDPOINT_UPDATE</constant></entry>
+            <entry><type>struct kdbus_cmd *</type></entry>
+          </row><row>
+            <entry><constant>0x402095b0</constant></entry>
+            <entry><constant>KDBUS_CMD_MATCH_ADD</constant></entry>
+            <entry><type>struct kdbus_cmd_match *</type></entry>
+          </row><row>
+            <entry><constant>0x402095b1</constant></entry>
+            <entry><constant>KDBUS_CMD_MATCH_REMOVE</constant></entry>
+            <entry><type>struct kdbus_cmd_match *</type></entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </informaltable>
+
+    <para>
+      Depending on the type of <emphasis>kdbusfs</emphasis> node that was
+      opened and what ioctls have been executed on a file descriptor before,
+      a different sub-set of ioctl commands is allowed.
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <para>
+          On a file descriptor resulting from opening a
+          <emphasis>control node</emphasis>, only the
+          <constant>KDBUS_CMD_BUS_MAKE</constant> ioctl may be executed.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          On a file descriptor resulting from opening a
+          <emphasis>bus endpoint node</emphasis>, only the
+          <constant>KDBUS_CMD_ENDPOINT_MAKE</constant> and
+          <constant>KDBUS_CMD_HELLO</constant> ioctls may be executed.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          A file descriptor that was used to create a bus
+          (via <constant>KDBUS_CMD_BUS_MAKE</constant>) is called a
+          <emphasis>bus owner</emphasis> file descriptor. The bus will be
+          active as long as the file descriptor is kept open.
+          A bus owner file descriptor can not be used to
+          employ any further ioctls. As soon as
+          <citerefentry>
+            <refentrytitle>close</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>
+          is called on it, the bus will be shut down, along will all associated
+          endpoints and connections. See
+          <citerefentry>
+            <refentrytitle>kdbus.bus</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for more details.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          A file descriptor that was used to create an endpoint
+          (via <constant>KDBUS_CMD_ENDPOINT_MAKE</constant>) is called an
+          <emphasis>endpoint owner</emphasis> file descriptor. The endpoint
+          will be active as long as the file descriptor is kept open.
+          An endpoint owner file descriptor can only be used
+          to update details of an endpoint through the
+          <constant>KDBUS_CMD_ENDPOINT_UPDATE</constant> ioctl. As soon as
+          <citerefentry>
+            <refentrytitle>close</refentrytitle>
+            <manvolnum>2</manvolnum>
+          </citerefentry>
+          is called on it, the endpoint will be removed from the bus, and all
+          connections that are connected to the bus through it are shut down.
+          See
+          <citerefentry>
+            <refentrytitle>kdbus.endpoint</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          for more details.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          A file descriptor that was used to create a connection
+          (via <constant>KDBUS_CMD_HELLO</constant>) is called a
+          <emphasis>connection owner</emphasis> file descriptor. The connection
+          will be active as long as the file descriptor is kept open.
+          A connection owner file descriptor may be used to
+          issue any of the following ioctls.
+        </para>
+
+        <itemizedlist>
+          <listitem><para>
+            <constant>KDBUS_CMD_UPDATE</constant> to tweak details of the
+            connection. See
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_BYEBYE</constant> to shut down a connection
+            without losing messages. See
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_FREE</constant> to free a slice of memory in
+            the pool. See
+            <citerefentry>
+              <refentrytitle>kdbus.pool</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_CONN_INFO</constant> to retrieve information
+            on other connections on the bus. See
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_BUS_CREATOR_INFO</constant> to retrieve
+            information on the bus creator. See
+            <citerefentry>
+              <refentrytitle>kdbus.connection</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_LIST</constant> to retrieve a list of
+            currently active well-known names and unique IDs on the bus. See
+            <citerefentry>
+              <refentrytitle>kdbus.name</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_SEND</constant> and
+            <constant>KDBUS_CMD_RECV</constant> to send or receive a message.
+            See
+            <citerefentry>
+              <refentrytitle>kdbus.message</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_NAME_ACQUIRE</constant> and
+            <constant>KDBUS_CMD_NAME_RELEASE</constant> to acquire or release
+            a well-known name on the bus. See
+            <citerefentry>
+              <refentrytitle>kdbus.name</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+
+          <listitem><para>
+            <constant>KDBUS_CMD_MATCH_ADD</constant> and
+            <constant>KDBUS_CMD_MATCH_REMOVE</constant> to add or remove
+            a match for signal messages. See
+            <citerefentry>
+              <refentrytitle>kdbus.match</refentrytitle>
+              <manvolnum>7</manvolnum>
+            </citerefentry>.
+          </para></listitem>
+        </itemizedlist>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      These ioctls, along with the structs they transport, are explained in
+      detail in the other documents linked to in the "See Also" section below.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <simplelist type="inline">
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.bus</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.connection</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.endpoint</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.fs</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.item</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.message</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.name</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>kdbus.pool</refentrytitle>
+          <manvolnum>7</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>ioctl</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>mmap</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>open</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <citerefentry>
+          <refentrytitle>close</refentrytitle>
+          <manvolnum>2</manvolnum>
+        </citerefentry>
+      </member>
+      <member>
+        <ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>
+      </member>
+    </simplelist>
+  </refsect1>
+
+</refentry>
diff --git a/Documentation/kdbus/stylesheet.xsl b/Documentation/kdbus/stylesheet.xsl
new file mode 100644
index 000000000000..52565eac7d0d
--- /dev/null
+++ b/Documentation/kdbus/stylesheet.xsl
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
+	<param name="chunk.quietly">1</param>
+	<param name="funcsynopsis.style">ansi</param>
+	<param name="funcsynopsis.tabular.threshold">80</param>
+	<param name="callout.graphics">0</param>
+	<param name="paper.type">A4</param>
+	<param name="generate.section.toc.level">2</param>
+	<param name="use.id.as.filename">1</param>
+	<param name="citerefentry.link">1</param>
+	<strip-space elements="*"/>
+	<template name="generate.citerefentry.link">
+		<value-of select="refentrytitle"/>
+		<text>.html</text>
+	</template>
+</stylesheet>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 22a4b687ea5b..c6dd5f350684 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -929,11 +929,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
-	drm_kms_helper.edid_firmware=[<connector>:]<file>
-			Broken monitors, graphic adapters and KVMs may
-			send no or incorrect EDID data sets. This parameter
-			allows to specify an EDID data set in the
-			/lib/firmware directory that is used instead.
+	drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
+			Broken monitors, graphic adapters, KVMs and EDIDless
+			panels may send no or incorrect EDID data sets.
+			This parameter allows to specify an EDID data sets
+			in the /lib/firmware directory that are used instead.
 			Generic built-in EDID data sets are used, if one of
 			edid/1024x768.bin, edid/1280x1024.bin,
 			edid/1680x1050.bin, or edid/1920x1080.bin is given
@@ -942,7 +942,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			available in Documentation/EDID/HOWTO.txt. An EDID
 			data set will only be used for a particular connector,
 			if its name and a colon are prepended to the EDID
-			name.
+			name. Each connector may use a unique EDID data
+			set by separating the files with a comma.  An EDID
+			data set with no connector name will be used for
+			any connectors not explicitly specified.
 
 	dscc4.setup=	[NET]
 
diff --git a/Documentation/locking/lockstat.txt b/Documentation/locking/lockstat.txt
index 568bbbacee91..5786ad2cd5e6 100644
--- a/Documentation/locking/lockstat.txt
+++ b/Documentation/locking/lockstat.txt
@@ -12,7 +12,7 @@ Because things like lock contention can severely impact performance.
 - HOW
 
 Lockdep already has hooks in the lock functions and maps lock instances to
-lock classes. We build on that (see Documentation/lokcing/lockdep-design.txt).
+lock classes. We build on that (see Documentation/locking/lockdep-design.txt).
 The graph below shows the relation between the lock functions and the various
 hooks therein.
 
diff --git a/Documentation/lto-build b/Documentation/lto-build
new file mode 100644
index 000000000000..5dcce1e9cc25
--- /dev/null
+++ b/Documentation/lto-build
@@ -0,0 +1,173 @@
+Link time optimization (LTO) for the Linux kernel
+
+This is an experimental feature.
+
+Link Time Optimization allows the compiler to optimize the complete program
+instead of just each file.  LTO requires at least gcc 4.8 (but
+works more efficiently with 4.9+) LTO requires Linux binutils (the normal FSF
+releases used in many distributions do not work at the moment)
+
+The compiler can inline functions between files and do various other global
+optimizations, like specializing functions for common parameters,
+determing when global variables are clobbered, making functions pure/const,
+propagating constants globally, removing unneeded data and others.
+
+It will also drop unused functions which can make the kernel
+image smaller in some circumstances, in particular for small kernel
+configurations.
+
+For small monolithic kernels it can throw away unused code very effectively
+(especially when modules are disabled) and usually shrinks
+the code size.
+
+Build time and memory consumption at build time will increase, depending
+on the size of the largest binary. Modular kernels are less affected.
+With LTO incremental builds are less incremental, as always the whole
+binary needs to be re-optimized (but not re-parsed)
+
+Oops can be somewhat more difficult to read, due to the more aggressive
+inlining.
+
+Normal "reasonable" builds work with less than 4GB of RAM, but very large
+configurations like allyesconfig may need more memory. The actual
+memory needed depends on the available memory (gcc sizes its garbage
+collector pools based on that or on the ulimit -m limits) and
+the compiler version.
+
+gcc 4.9+ has much better build performance and less memory consumption
+
+- A few kernel features are currently incompatible with LTO, in particular
+function tracing, because they require special compiler flags for
+specific files, which is not supported in LTO right now.
+- Jobserver control for -j does not work correctly for the final
+LTO phase due to some problems with the kernel's pipe code.
+The makefiles hard codes -j<number of online cpus> for the final
+LTO phase to work around for this
+
+Configuration:
+- Enable CONFIG_LTO_MENU and then disable CONFIG_LTO_DISABLE.
+This is mainly to not have allyesconfig default to LTO.
+- FUNCTION_TRACER, STACK_TRACER, FUNCTION_GRAPH_TRACER, KALLSYMS_ALL, GCOV
+have to disabled because they are currently incompatible with LTO.
+- MODVERSIONS have to be disabled (may work with 4.9+)
+
+Requirements:
+- Enough memory: 4GB for a standard build, more for allyesconfig
+The peak memory usage happens single threaded (when lto-wpa merges types),
+so dialing back -j options will not help much.
+
+A 32bit compiler is unlikely to work due to the memory requirements.
+You can however build a kernel targeted at 32bit on a 64bit host.
+
+Example build procedure:
+
+Simplified procedure for distributions that have gcc 4.8, but not
+the Linux binutils (for example openSUSE 13.1 or FC20):
+
+The LTO builds requires gcc-nm/gcc-ar. Some distributions ship
+those in separate packages, which may need to be explicitely installed.
+
+- Get the latest Linux binutils from
+http://www.kernel.org/pub/linux/devel/binutils/
+and unpack it.
+
+We install it in a separate directory to not overwrite the system binutils.
+
+# replace VERSION with respective version numbers
+
+cd binutils*
+# don't forget the --enable-plugins!
+./configure --prefix=/opt/binutils-VERSION --enable-plugins
+make -j $(getconf _NPROCESSORS_ONLN) && sudo make install
+
+Fix up the kernel configuration to allow LTO:
+
+<start with a suitable kernel configuration>
+./source/scripts/config --disable function_tracer \
+			--disable function_graph_tracer \
+			--disable stack_tracer --enable lto_menu \
+                        --disable lto_disable \
+			--disable gcov \
+			--disable kallsyms_all \
+			--disable modversions
+make oldconfig
+
+Then you can build with
+
+# The COMPILER_PATH is needed to let gcc use the new binutils
+# as the LTO plugin linker
+# if you installed gcc in a separate directory like below also
+# add it to the PATH line below before the regular $PATH
+# The COMPILER_PATH setting is only needed if the gcc was not built
+# with --with-plugin-ld pointing to the Linux binutils ld
+# The AR/NM setting works around a Makefile bug
+COMPILER_PATH=/opt/binutils-VERSION/bin PATH=$COMPILER_PATH:$PATH \
+make -j$(getconf _NPROCESSORS_ONLN) AR=gcc-ar NM=gcc-nm
+
+If you don't have gcc 4.8+ as system compiler you would also need
+to install that compiler. In this case I recommend getting
+a gcc 4.9+ snapshot from http://gcc.gnu.org (or release when available),
+as it builds much faster for LTO than 4.8.
+
+Here's an example build procedure:
+
+Assuming gcc is unpacked in gcc-VERSION
+
+cd gcc-VERSION
+./contrib/download_preqrequisites
+cd ..
+
+mkdir obj-gcc
+# please don't skip this cd. the build will not work correctly in the
+# source dir, you have to use the separate object dir
+cd obj-gcc
+../gcc-VERSION/configure --prefix=/opt/gcc-VERSION --enable-lto \
+--with-plugin-ld=/opt/binutils-VERSION/bin/ld
+--disable-nls --enable-languages=c,c++ \
+--disable-libstdcxx-pch
+make -j$(getconf _NPROCESSORS_ONLN)
+sudo make install-no-fixedincludes
+
+FAQs:
+
+Q: I get a section type attribute conflict
+A: Usually because of someone doing
+const __initdata (should be const __initconst) or const __read_mostly
+(should be just const). Check both symbols reported by gcc.
+
+Q: I see lots of undefined symbols for memcmp etc.
+A: Usually because NM=gcc-nm AR=gcc-ar are missing.
+The Makefile tries to set those automatically, but it doesn't always
+work. Better to set it manually on the make command line.
+
+Q: It's quite slow / uses too much memory.
+A: Consider a gcc 4.9 snapshot/release (not released yet)
+The main problem in 4.8 is the type merging in the single threaded WPA pass,
+which has been improved considerably in 4.9 by running it distributed.
+
+Q: It's still slow
+A: It'll always be somewhat slower than non LTO sorry.
+
+Q: What's up with .XXXXX numeric post fixes
+A: This is due LTO turning (near) all symbols to static
+Use gcc 4.9, it avoids them in most cases. They are also filtered out
+in kallsyms.
+
+References:
+
+Presentation on Kernel LTO
+(note, performance numbers/details outdated.  In particular gcc 4.9 fixed
+most of the build time problems):
+http://halobates.de/kernel-lto.pdf
+
+Generic gcc LTO:
+http://www.ucw.cz/~hubicka/slides/labs2013.pdf
+http://www.hipeac.net/system/files/barcelona.pdf
+
+Somewhat outdated too:
+http://gcc.gnu.org/projects/lto/lto.pdf
+http://gcc.gnu.org/projects/lto/whopr.pdf
+
+Happy Link-Time-Optimizing!
+
+Andi Kleen
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt
index 1700756af057..aa69ccc481db 100644
--- a/Documentation/networking/ieee802154.txt
+++ b/Documentation/networking/ieee802154.txt
@@ -7,11 +7,11 @@ Introduction
 The IEEE 802.15.4 working group focuses on standardization of bottom
 two layers: Medium Access Control (MAC) and Physical (PHY). And there
 are mainly two options available for upper layers:
- - ZigBee - proprietary protocol from ZigBee Alliance
- - 6LowPAN - IPv6 networking over low rate personal area networks
+ - ZigBee - proprietary protocol from the ZigBee Alliance
+ - 6LoWPAN - IPv6 networking over low rate personal area networks
 
-The Linux-ZigBee project goal is to provide complete implementation
-of IEEE 802.15.4 and 6LoWPAN protocols. IEEE 802.15.4 is a stack
+The linux-wpan project goal is to provide a complete implementation
+of the IEEE 802.15.4 and 6LoWPAN protocols. IEEE 802.15.4 is a stack
 of protocols for organizing Low-Rate Wireless Personal Area Networks.
 
 The stack is composed of three main parts:
diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt
index 39873ef41bf9..b9d9cc57be18 100644
--- a/Documentation/rbtree.txt
+++ b/Documentation/rbtree.txt
@@ -203,7 +203,7 @@ functions with the user provided augmentation callback when inserting
 and erasing nodes.
 
 C files implementing augmented rbtree manipulation must include
-<linux/rbtree_augmented.h> instead of <linus/rbtree.h>. Note that
+<linux/rbtree_augmented.h> instead of <linux/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
diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt
index f4cb0b2d5cd7..ec911583f6c5 100644
--- a/Documentation/static-keys.txt
+++ b/Documentation/static-keys.txt
@@ -16,7 +16,7 @@ The updated API replacements are:
 DEFINE_STATIC_KEY_TRUE(key);
 DEFINE_STATIC_KEY_FALSE(key);
 static_key_likely()
-statick_key_unlikely()
+static_key_unlikely()
 
 0) Abstract
 
diff --git a/Documentation/zh_CN/filesystems/sysfs.txt b/Documentation/zh_CN/filesystems/sysfs.txt
index e230eaa33122..7d3b05edb8ce 100644
--- a/Documentation/zh_CN/filesystems/sysfs.txt
+++ b/Documentation/zh_CN/filesystems/sysfs.txt
@@ -61,7 +61,7 @@ Documentation/kobject.txt 文档以获得更多关于 kobject 接口的
 内核的对象层次到用户空间。sysfs 中的顶层目录代表着内核对象层次的
 共同祖先；例如：某些对象属于某个子系统。
 
-Sysfs 在与其目录关联的 sysfs_dirent 对象中内部保存一个指向实现
+Sysfs 在与其目录关联的 kernfs_node 对象中内部保存一个指向实现
 目录的 kobject 的指针。以前，这个 kobject 指针被 sysfs 直接用于
 kobject 文件打开和关闭的引用计数。而现在的 sysfs 实现中，kobject
 引用计数只能通过 sysfs_schedule_callback() 函数直接修改。
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ba7ab749c85..241f0e49adb6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3496,6 +3496,8 @@ M:	Jonathan Corbet <corbet@lwn.net>
 L:	linux-doc@vger.kernel.org
 S:	Maintained
 F:	Documentation/
+F:	scripts/docproc.c
+F:	scripts/kernel-doc*
 X:	Documentation/ABI/
 X:	Documentation/devicetree/
 X:	Documentation/acpi
@@ -5870,6 +5872,19 @@ S:	Maintained
 F:	Documentation/kbuild/kconfig-language.txt
 F:	scripts/kconfig/
 
+KDBUS
+M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+M:	Daniel Mack <daniel@zonque.org>
+M:	David Herrmann <dh.herrmann@googlemail.com>
+M:	Djalal Harouni <tixxdz@opendz.org>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	ipc/kdbus/*
+F:	samples/kdbus/*
+F:	Documentation/kdbus/*
+F:	include/uapi/linux/kdbus.h
+F:	tools/testing/selftests/kdbus/
+
 KDUMP
 M:	Vivek Goyal <vgoyal@redhat.com>
 M:	Haren Myneni <hbabu@us.ibm.com>
@@ -9904,8 +9919,8 @@ F:	drivers/staging/media/lirc/
 STAGING - LUSTRE PARALLEL FILESYSTEM
 M:	Oleg Drokin <oleg.drokin@intel.com>
 M:	Andreas Dilger <andreas.dilger@intel.com>
-L:	HPDD-discuss@lists.01.org (moderated for non-subscribers)
-W:	http://lustre.opensfs.org/
+L:	lustre-devel@lists.lustre.org (moderated for non-subscribers)
+W:	http://wiki.lustre.org/
 S:	Maintained
 F:	drivers/staging/lustre
 
@@ -9975,8 +9990,10 @@ F:	drivers/staging/vt665?/
 STAGING - WILC1000 WIFI DRIVER
 M:	Johnny Kim <johnny.kim@atmel.com>
 M:	Rachel Kim <rachel.kim@atmel.com>
-M:	Dean Lee <dean.lee@atmel.com>
 M:	Chris Park <chris.park@atmel.com>
+M:	Tony Cho <tony.cho@atmel.com>
+M:	Glen Lee <glen.lee@atmel.com>
+M:	Leo Kim <leo.kim@atmel.com>
 L:	linux-wireless@vger.kernel.org
 S:	Supported
 F:	drivers/staging/wilc1000/
diff --git a/Makefile b/Makefile
index 1a132ea43ca5..541e150ca731 100644
--- a/Makefile
+++ b/Makefile
@@ -342,9 +342,14 @@ include scripts/Kbuild.include
 # Make variables (CC, etc...)
 AS		= $(CROSS_COMPILE)as
 LD		= $(CROSS_COMPILE)ld
+LDFINAL	= $(LD)
 CC		= $(CROSS_COMPILE)gcc
 CPP		= $(CC) -E
+ifdef CONFIG_LTO
+AR		= $(CROSS_COMPILE)gcc-ar
+else
 AR		= $(CROSS_COMPILE)ar
+endif
 NM		= $(CROSS_COMPILE)nm
 STRIP		= $(CROSS_COMPILE)strip
 OBJCOPY		= $(CROSS_COMPILE)objcopy
@@ -406,7 +411,7 @@ KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(S
 
 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
 export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
-export CPP AR NM STRIP OBJCOPY OBJDUMP
+export CPP AR NM STRIP OBJCOPY OBJDUMP LDFINAL
 export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
@@ -417,6 +422,17 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 export KBUILD_ARFLAGS
 
+ifdef CONFIG_LTO
+# LTO gcc creates a lot of files in TMPDIR, and with /tmp as tmpfs
+# it's easy to drive the machine OOM. Use the object directory
+# instead.
+ifndef TMPDIR
+TMPDIR ?= $(objtree)
+export TMPDIR
+$(info setting TMPDIR=$(objtree) for LTO build)
+endif
+endif
+
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
 # even be read-only.
@@ -777,6 +793,7 @@ endif
 
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
+include scripts/Makefile.lto
 
 # Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the
 # last assignments
@@ -1338,6 +1355,7 @@ $(help-board-dirs): help-%:
 %docs: scripts_basic FORCE
 	$(Q)$(MAKE) $(build)=scripts build_docproc
 	$(Q)$(MAKE) $(build)=Documentation/DocBook $@
+	$(Q)$(MAKE) $(build)=Documentation/kdbus $@
 
 else # KBUILD_EXTMOD
 
diff --git a/Next/SHA1s b/Next/SHA1s
new file mode 100644
index 000000000000..d0720d7c5623
--- /dev/null
+++ b/Next/SHA1s
@@ -0,0 +1,228 @@
+Name		SHA1
+----		----
+origin		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+fixes		c7e9ad7da219cf3f8a7cc45eb1c02fdd91199e8d
+kbuild-current	3d1450d54a4fc277fc4598acf2335f74b66b08fc
+arc-current	e4140819dadc3624accac8294881bca8a3cba4ed
+arm-current	c2172ce2303051764829d4958bd50a11ada0590f
+m68k-current	1ecb40643a9af05683b7a898d7141884bcb28a82
+metag-fixes	0164a711c97b0beeb7994b7d32ccddf586b6d81a
+mips-fixes	1795cd9b3a91d4b5473c97f491d63892442212ab
+powerpc-fixes	e297c939b745e420ef0b9dc989cb87bda617b399
+powerpc-merge-mpe	bc0195aad0daa2ad5b0d76cce22b167bc3435590
+sparc		73958c651fbf70d8d8bf2a60b871af5f7a2e3199
+net		e8684c88774c0ddfeefdbed0aa469b25b9962f3e
+ipsec		93efac3f2e03321129de67a3c0ba53048bb53e31
+sound-current	5ee20bc792467d7d612157e0a9962765aa943b08
+pci-current	45ea2a5fed6dacb9bb0558d8b21eacc1c45d5bb4
+wireless-drivers	741e3b9902d11585e18bfc7f8d47e913616bb070
+driver-core.current	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+tty.current	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+usb.current	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+usb-gadget-fixes	c93e64e91248becd0edb8f01723dff9da890e2ab
+usb-serial-fixes	d071a3cdd2e1bff7a10ab4c421cbb2b2cda0d0c5
+staging.current	8b5081c876bde9b1df5e96ee6990d5acd20c128b
+char-misc.current	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+input-current	53431d0a3534263168c8ee576bad1c2c3a4cd9e0
+crypto-current	84cba178a3b88efe2668a9039f70abda072faa21
+ide		d681f1166919d6829083c069a83edcd59bfd5e34
+devicetree-current	f76502aa9140ec338a59487218bf70a9c9e92b8f
+rr-fixes	275d7d44d802ef271a42dc87ac091a495ba72fc5
+vfio-fixes	4bc94d5dc95d3a2159d821b39277477e69507f67
+kselftest-fixes	fee50f3c8427aacabfb603229bf0a9056c3f2638
+backlight-fixes	68feaca0b13e453aa14ee064c1736202b48b342f
+ftrace-fixes	6224beb12e190ff11f3c7d4bf50cb2922878f600
+mfd-fixes	fb9caeedafe61599371d057696bff3baef01f455
+drm-intel-fixes	c13dcf9f2d6f5f06ef1bf79ec456df614c5e058b
+asm-generic	643165c8bbc8617d8222cb50c89e34fe64d226cf
+arc		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+arm		4cd545806d3cd676f6f8e9f369b271f76138acd0
+arm-perf	fa8ad7889d83bcf0a6cdbf6d3622f3ec019cde14
+arm-soc		f47c3594f8547919ecd4bab8524430ac9ff7c279
+at91		253ebd4df402d807a8e2448c2f2a4ef8bd2a41ee
+bcm2835		b2776bf7149bddd1f4161f14f79520f17fc1d71d
+berlin		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+cortex-m	f719a0d6a8541b383c506aaa4b4fa6b4109669f4
+imx-mxs		c746ef1b64e96d5305d0ed079737dc167d9da455
+keystone	a6ba4234e474f1caebec211c949846ac2956a332
+mvebu		adfc8c76d84a3bba27326ded7508dec1f4652c90
+omap		b2a882022a1eb97901f018732e8808648f4b9940
+omap-pending	30aa18d3bea5f9470af5aa48ab8df88bde97c795
+qcom		37a7a47c0031ea4ca5757f45f0c77ac4b53f7e88
+renesas		53d5bd1b09d2dc12bc844bbc47d48ff44226bc12
+rockchip	ed0450118b2ffbcf20b31f760272f74fd93e51f9
+rpi		bc0195aad0daa2ad5b0d76cce22b167bc3435590
+samsung		112129267f1ac43d68051d2bd3b1321cbcd1083a
+samsung-krzk	6fab115d07625d28239945ec381051803bc31979
+sunxi		9d73c13a139c119151e41ce78e36188aac73b272
+tegra		bea5a17a8beb0bbc3a64fa8528477947bf45854c
+arm64		674c242c9323d3c293fc4f9a3a3a619fe3063290
+blackfin	d91e14b3b9e1d8e1d552f4d6aff45551bbb410b1
+c6x		960a2741d5fd48e4b2a2151c3dc5ac268a5ea87a
+cris		254a0f4135482dc02701562a38e10675a48c8ddf
+h8300		99bcfda85f66499b9318fa349dea0f73be8c0a68
+hexagon		02cc2ccfe771677db3cd40a71837e1467ebc839a
+ia64		ae40b7e2875228d961c2202d69b55d416644e830
+m68k		bab84fa9cc09dfa9702029f83ea6bf8bf5ae96af
+m68knommu	50e48bd0673180311874d0c1bd88505eefd75c4e
+metag		3fe6942f04866ec38b515da6eb38eeceafcbfce3
+microblaze	b14132797d8041a42e03f4ffa1e722da1425adfb
+mips		807249d3ada1ff28a47c4054ca4edd479421b671
+nios2		08441d462ebdc64df79b392f877e26522616bad5
+parisc-hd	64291f7db5bd8150a74ad2036f1037e6a0428df2
+powerpc		ff474e8ca8547d09cb82ebab56d4c96f9eea01ce
+powerpc-mpe	bc0195aad0daa2ad5b0d76cce22b167bc3435590
+fsl		4524cd093fa8f03b198e095ebbb679c30839559c
+mpc5xxx		9e813308a5c18c58f9ccae1ec72ed4e14eaf9025
+s390		e94f6761a7da74aa1d410b33cfaa58b63c96c2b3
+sparc-next	9f935675d41aa51ebf929fc977cf530ff7d1a7fc
+tile		fa5d8f13afb8618dc83aa4039360bc19b06ac50f
+uml		bdbac7d0e2b3930ae7f6d40eb37c5ea575ef763b
+unicore32	d670878e2c9adb86b37e42b0937b2d4825bd2b39
+xtensa		895fb3159280fe7695b35ec7c87ec19e13ca5b6e
+btrfs		3a9508b0221dfd290b95fb0ab199958fe078bbdf
+ceph		8dbd263de1cba18100a9fb30fed606e6d7939b9d
+cifs		eda2116f4ab6d79cfcffc202b5d2bbb0797ba013
+ecryptfs	0dad87fcb732691bfd3183acccda6709e1e759ca
+ext3		9181f8bf5abf4b9d59b12e878895375b84fe32ba
+ext4		bdfe0cbd746aa9b2509c2f6d6be17193cf7facd7
+f2fs		51e771c0d25b43d0f12b2c7c01939942becbbe28
+fscache		b00c2ae2ed3c0c40e0740549fe0e42e234a97dc2
+fuse		0a30f612d6cfd936235b41b090dbe0119c9039d1
+gfs2		8f7e0a806db0a3ba33234af3c39d68ed8c144071
+jfs		26456955719b79cc4a011b18221aa68f599f6b6c
+nfs		5445b1fbd123420bffed5e629a420aa2a16bf849
+nfsd		a909e9f9d73ae54d91b207a8112e8bdfd53b5662
+orangefs	600896a3b8b088ac4a1ca9ab250e6ddef527ae73
+overlayfs	cdb672795876d7bc1870aed9a2d7cb59f43d1d96
+squashfs	62421645bb702c077ee5a462815525106cb53bcf
+v9fs		46cfbe8e037a5041e17a672016550d358b232319
+ubifs		071a1f837f72b4953ef145ea705fe5314e2e3006
+xfs		5d54b8cdeaf4679c51a510dea3f8921992d0b064
+file-locks	ee296d7c5709440f8abd36b5b65c6b3e388538d9
+vfs		397d425dc26da728396e66d392d5dcb8dac30c37
+pci		9ca678d1dff610f7df6ac9b31fd9152c4426f815
+hid		c5a0db1eed32bad065bd73dd06294b3f076ec0ba
+i2c		f5956abbe4301c11216527422b7904a492b5f9a8
+jdelvare-hwmon	902fd32b771142a69a37cec7b09eda334181ef8e
+dmi		1dc51b8288007753ad7cd7d08bb8fa930fc8bb10
+hwmon-staging	1b1165fa06dbc843a232af2d08d0ffecb664902e
+v4l-dvb		41a8f406dacde0d1faf4adb9015426a7d285801a
+kbuild		a8503631df45237a70bff4e8f9baf1dad14cda46
+kconfig		c0ddc8c745b7f89c50385fd7aa03c78dc543fa7a
+libata		88622d80af827b23201d62bbc1697541308f85e9
+pm		d9ef4fce71bced6dabe515cd990fc1a574407e0e
+idle		aba5686671dc81dd6cf21ecd0d38781c3e255308
+apm		53675abbd1e54a30e621a9744bf9cce0712ddd6c
+thermal		5a924a07f882e866f2337bf65048be357956691a
+thermal-soc	a794b4f3292160bb3fd0f1f90ec8df454e3b17b3
+ieee1394	d71e6a11737f4b3d857425a1d6f893231cbd1296
+dlm		b3a5bbfd780d9e9291f5f257be06e9ad6db11657
+swiotlb		023600f192be3f5776336e2c61d577b551a1ca9c
+slave-dma	f53d906c6323d3e35b71b30516533d04133ba8b9
+net-next	64d1def7d33856824d2c5c6fd6d4579d4d54bb87
+ipsec-next	e69948a0a5309f3ef5715cb4ca7a9bd77d64e2cf
+wireless-drivers-next	0ba3ac03c1f38be17102d1c76c42a7c66a3e9ff2
+bluetooth	c258b966b5d6857e6e7c15c3467363f918bfa0ac
+rdma		64291f7db5bd8150a74ad2036f1037e6a0428df2
+mtd		2ff46e6fea6254ac8fa97aeb9c14e51436ab95f6
+l2-mtd		2ff46e6fea6254ac8fa97aeb9c14e51436ab95f6
+crypto		bf433416e67597ba105ece55b3136557874945db
+drm		73bf1b7be7aab60d7c651402441dd0b0b4991098
+drm-panel	a33ee95f8f456c241897a4b6153610b8488d009d
+drm-intel	824257857fd81f5e749831ff9cd63566b5a86abe
+drm-tegra	459cc2c6800b545a482e428a631d99bca8da7790
+drm-misc	216c59d65f99aa1ef1a92e1ae64f1f1c2590dddc
+drm-exynos	7d9071a095023cd1db8fa18fa0d648dc1a5210e0
+drm-msm		d248b61f611463cca906d5663a9a0de63ade97a9
+sound		0052b7dcf9d9ec6be4fc3fe815a2ceda623bb9d1
+sound-asoc	d1abb17624f95e46daac32bf6b1456b565852c45
+modules		5cfb203a304deaaa8c7c5368722b214d24583137
+input		ade9c1a47c811a7ae1c874882ad9178af1ed1098
+block		3cb73014ad0656464c433ab9f8a931a1b4cfa2eb
+device-mapper	9efb520a57f13b92b5a0f0e526caa32489657465
+pcmcia		e8e68fd86d22fa5bd9c7bed16043e27ac86998f8
+mmc		11bc9381b277a65ea4b3fe994e658f4a78512139
+mmc-uh		b8889c4fc6ba03e289cec6a4d692f6f080a55e53
+kgdb		2d289f14f00a0da6bae7c8415fc8dd9d030458b8
+md		e89c6fdf9e0eb1b5a03574d4ca73e83eae8deb91
+mfd		5a688c455066c21c133bc8ffa7b11f8c66b7fe0b
+backlight	13d20b3b618adc43168b034792eec57063b5ec6f
+battery		e11fc21e756e662e465cac3da6547d438d0b1446
+omap_dss2	7b554088d56e9df3ee5dff8989b44903965bad95
+regulator	f39628069744842a08eb61c17b21cf8bf19dda99
+security	07f081fb5057b2ea98baeca3a47bf0eb33e94aa1
+integrity	24fd03c87695a76f0517df42a37e51b1597d2c8a
+selinux		fda4d578ed0a7e1d116f56a15efea0e4ba78acad
+lblnet		b2776bf7149bddd1f4161f14f79520f17fc1d71d
+watchdog	330de3d856717bdd3a3c5f8b86fdbb6ffa54da2c
+iommu		4ad79562577a3936b08365260f86eeb83156479f
+dwmw2-iommu	5dbaf90a6780b2989515212cb2584b7771cecad1
+vfio		a714ea5fa41623c8d8c42bed0dfb38a4d653451d
+jc_docs		4d73270192ec8238135d9fb65b49f6f42f50818d
+trivial		e5f6450c3f40668de0b9c4cbc53bb345242df78f
+audit		15ce414b82b07acb99afda6e4d9bd14f317b6011
+devicetree	48a9b733e644ab4cc8e2a98950a36ddb12b8c54e
+dt-rh		c8fb70a3e8dd60e31c4422bae85783cf1733f038
+mailbox		86e488adaab77a733b01e759bf7bfda054479660
+spi		4509c045226138cdd8f020bb315778cd3687d2b5
+tip		b84834af3560740a7ce643a94c95a444710c1372
+clockevents	e4485500949c6843417569b08005a3a3d2989d18
+edac		12f0721c5a70408e86257c5c99605cf743cd44c6
+edac-amd	99e1dfb7d2094d9afc1dca57d525f7b36aa18079
+irqchip		a8bcdc32fafbeb236910e6ddc0161003a458ffc1
+tiny		f114040e3ea6e07372334ade75d1ee0775c355e1
+ftrace		b7dc42fd79390c074e2bff3b172b585d5c2d80c2
+rcu		dc3a04d551b5d21f1badbb39bfe8e5bc1289b184
+kvm		ba60c41ae392b473a1897faa0b8739fcb8759d69
+kvm-arm		0c0672922dcc70ffba11d96385e98e42fb3ae08d
+kvm-ppc		c63517c2e3810071359af926f621c1f784388c3f
+kvm-ppc-paulus	4e33d1f0a145d48e8cf287954bbf791af8387cfb
+kvms390		152b28392a8d9dd08e789b48b602eb75eef436fa
+xen-tip		3e64472c1c7413a573a116ee69febab98c227de4
+percpu		292c24a073ee34c629966eec8b48d54b0a206667
+workqueues	355c06633e233a57155b827ebe99b91c35bc1f5c
+drivers-x86	85b4e4eb2f9ac29ee8ec47f1f055f251cb251a3c
+chrome-platform	1d95e6f10fd88b936815b669f51bba2685a61b5d
+regmap		072502a67c9164625288cca17704808e6c06273f
+hsi		d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754
+leds		b0ba362c611f6cba047a298655eeffea560a3b81
+ipmi		bf2d087749d91e1fa2826edde1e2fd650d3053ca
+driver-core	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+tty		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+usb		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+usb-gadget	2f3cc24f07b8bfe8302a46ceb1ed58cde62cbd09
+usb-serial	26c78daade0fbeef7f20bae3c5508a7c571078cd
+staging		e714b7eab150a609b9c2bb1ae7605d882b2cceec
+char-misc	6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+extcon		722b9c505ea547c60703789a4a81b4de09045d8f
+kdbus		a36324913ff21d7a0989c52b7208e8d738e17d64
+cgroup		eacb1e7d4bfa1b24fde5cece5c9d5209f5efac37
+scsi		294ab783ad98066b87296db1311c7ba2a60206a5
+target-updates	ac64a2ce509104a746321a4f9646b6750cf281eb
+target-merge	8edb1554f7c2eb73cf70c9856aec01e786b9bcf9
+pinctrl		3249524451f17e131b99c6b19073daa7c6f3f197
+vhost		997e120843e82609c8d99a9d5714e6cf91e14cbe
+remoteproc	8de3dbd0895bebe52d069a82feae8e3fb51c1bdf
+rpmsg		b1b9891441fa33fd0d49b5cb3aa7f04bca1cc1db
+gpio		1fd19dd13a806d7e91d92f45ba614e3300f7067b
+dma-mapping	d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754
+pwm		7a5938201834a9c25155176d0f5942d48336b244
+dma-buf		86ea07ca846a7c352f39dd0b7d81f15f403c7db8
+userns		4b75de8615050c1b0dd8d7794838c42f74ed36ba
+ktest		b953c0d234bc72e8489d3bf51a276c5c4ec85345
+clk		3bba75a2ec32bd5fa7024a4de3b8cf9ee113a76a
+random		7185ad2672a7d50bc384de0e38d90b75d99f3d82
+aio		6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
+llvmlinux	25d4aee23af28a6ef04d70a1028c012665384df1
+kselftest	7eba7d90d48217a97afc171a311b386bde965f39
+y2038		ed8c2241c1ae1b64e4a783ae7a2c685c93142a8d
+luto-misc	a6c5170d1edea97c538c81e377e56c7b5c5b7e63
+access_once	c231afa3ccf176490dcafc3666559e7567690e76
+livepatching	07d42d41dfc438dc21e24e60e3f1092ff4ab2d0e
+coresight	8503d45d4f27f7a4a1c0b55bde10e9ae9b8689cc
+rtc		5f1b2f77646fc0ef2f36fc554f5722a1381d0892
+hwspinlock	bd5717a4632cdecafe82d03de7dcb3b1876e2828
+nvdimm		004f1afbe199e6ab20805b95aefd83ccd24bc5c7
+akpm-current	fadfe9f500679384a1b0f78909d76a05ed7fad38
+akpm		09b0ea9865a4f3b6e347bab45ea59c1391f0d649
diff --git a/Next/Trees b/Next/Trees
new file mode 100644
index 000000000000..52d77e0707ee
--- /dev/null
+++ b/Next/Trees
@@ -0,0 +1,230 @@
+Trees included into this release:
+
+Name		Type	URL
+----		----	---
+origin		git	git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git#master
+fixes		git	git://git.kernel.org/pub/scm/linux/kernel/git/sfr/next-fixes.git#master
+kbuild-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git#rc-fixes
+arc-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git#for-curr
+arm-current	git	git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git#fixes
+m68k-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-linus
+metag-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git#fixes
+mips-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips.git#mips-fixes
+powerpc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#fixes
+powerpc-merge-mpe	git	git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux.git#fixes
+sparc		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git#master
+net		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git#master
+ipsec		git	git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git#master
+sound-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-linus
+pci-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git#for-linus
+wireless-drivers	git	git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git#master
+driver-core.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-linus
+tty.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-linus
+usb.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-linus
+usb-gadget-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git#fixes
+usb-serial-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-linus
+staging.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-linus
+char-misc.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-linus
+input-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#for-linus
+crypto-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git#master
+ide		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git#master
+devicetree-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux.git#devicetree/merge
+rr-fixes		git	git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux.git#fixes
+vfio-fixes	git	git://github.com/awilliam/linux-vfio.git#for-linus
+kselftest-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#fixes
+backlight-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-fixes
+ftrace-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git#for-next-urgent
+mfd-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-fixes
+drm-intel-fixes	git	git://anongit.freedesktop.org/drm-intel#for-linux-next-fixes
+asm-generic	git	git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git#master
+arc		git	git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git#for-next
+arm		git	git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-arm.git#for-next
+arm-perf		git	git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git#for-next/perf
+arm-soc		git	git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git#for-next
+at91		git	git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git#at91-next
+bcm2835		git	git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git#for-next
+berlin		git	git://git.infradead.org/users/hesselba/linux-berlin.git#berlin/for-next
+cortex-m		git	git://git.pengutronix.de/git/ukl/linux.git#for-next
+imx-mxs		git	git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git#for-next
+keystone		git	git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git#next
+mvebu		git	git://git.infradead.org/linux-mvebu.git#for-next
+omap		git	git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git#for-next
+omap-pending	git	git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending.git#for-next
+qcom		git	git://codeaurora.org/quic/kernel/agross-msm.git#qcom/for-next
+renesas		git	git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git#next
+rockchip		git	git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git#for-next
+rpi		git	git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git#for-rpi-next
+samsung		git	git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#for-next
+samsung-krzk	git	git://github.com/krzk/linux.git#for-next
+sunxi		git	git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git#sunxi/for-next
+tegra		git	git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git#for-next
+arm64		git	git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux#for-next/core
+blackfin		git	http://git.kernel.org/pub/scm/linux/kernel/git/realmz6/blackfin-linux.git#for-linus
+c6x		git	git://linux-c6x.org/git/projects/linux-c6x-upstreaming.git#for-linux-next
+cris		git	git://git.kernel.org/pub/scm/linux/kernel/git/jesper/cris.git#for-next
+h8300		git	git://git.sourceforge.jp/gitroot/uclinux-h8/linux.git#h8300-next
+hexagon		git	git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.git#linux-next
+ia64		git	git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git#next
+m68k		git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-next
+m68knommu	git	git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git#for-next
+metag		git	git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git#for-next
+microblaze	git	git://git.monstr.eu/linux-2.6-microblaze.git#next
+mips		git	git://git.linux-mips.org/pub/scm/ralf/upstream-sfr.git#mips-for-linux-next
+nios2		git	git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2.git#for-next
+parisc-hd	git	git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git#for-next
+powerpc		git	git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#next
+powerpc-mpe	git	git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux.git#next
+fsl		git	git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git#next
+mpc5xxx		git	git://git.denx.de/linux-denx-agust.git#next
+s390		git	git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#features
+sparc-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git#master
+tile		git	git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile.git#master
+uml		git	git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git#linux-next
+unicore32	git	git://github.com/gxt/linux.git#unicore32
+xtensa		git	git://github.com/czankel/xtensa-linux.git#for_next
+btrfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git#next
+ceph		git	git://github.com/ceph/ceph-client.git#master
+cifs		git	git://git.samba.org/sfrench/cifs-2.6.git#for-next
+ecryptfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git#next
+ext3		git	git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git#for_next
+ext4		git	git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git#dev
+f2fs		git	git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git#dev
+fscache		git	git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git#fscache
+fuse		git	git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
+gfs2		git	git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git#for-next
+jfs		git	git://github.com/kleikamp/linux-shaggy.git#jfs-next
+nfs		git	git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git#linux-next
+nfsd		git	git://git.linux-nfs.org/~bfields/linux.git#nfsd-next
+orangefs		git	git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux#for-next
+overlayfs	git	git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git#overlayfs-next
+squashfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next.git#master
+v9fs		git	git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git#for-next
+ubifs		git	git://git.infradead.org/ubifs-2.6.git#linux-next
+xfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git#for-next
+file-locks	git	git://git.samba.org/jlayton/linux.git#linux-next
+vfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6.git#for-next
+pci		git	git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git#next
+hid		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git#for-next
+i2c		git	git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git#i2c/for-next
+jdelvare-hwmon	quilt	http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/
+dmi		quilt	http://jdelvare.nerim.net/devel/linux/jdelvare-dmi/
+hwmon-staging	git	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon-next
+v4l-dvb		git	git://linuxtv.org/mchehab/media-next.git#master
+kbuild		git	git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git#for-next
+kconfig		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-kconfig.git#for-next
+libata		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git#for-next
+pm		git	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git#linux-next
+idle		git	git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git#next
+apm		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm.git#for-next
+thermal		git	git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git#next
+thermal-soc	git	git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git#next
+ieee1394		git	git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git#for-next
+dlm		git	git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git#next
+swiotlb		git	git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git#linux-next
+slave-dma	git	git://git.infradead.org/users/vkoul/slave-dma.git#next
+net-next		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git#master
+ipsec-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git#master
+wireless-drivers-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git#master
+bluetooth	git	git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git#master
+rdma		git	git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma.git#for-next
+mtd		git	git://git.infradead.org/mtd-2.6.git#master
+l2-mtd		git	git://git.infradead.org/l2-mtd.git#master
+crypto		git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git#master
+drm		git	git://people.freedesktop.org/~airlied/linux.git#drm-next
+drm-panel	git	git://anongit.freedesktop.org/tegra/linux.git#drm/panel/for-next
+drm-intel	git	git://anongit.freedesktop.org/drm-intel#for-linux-next
+drm-tegra	git	git://anongit.freedesktop.org/tegra/linux.git#drm/tegra/for-next
+drm-misc		git	git://anongit.freedesktop.org/drm-intel#topic/drm-misc
+drm-exynos	git	git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git#exynos-drm/for-next
+drm-msm		git	git://people.freedesktop.org/~robclark/linux#msm-next
+sound		git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-next
+sound-asoc	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-next
+modules		git	git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux.git#modules-next
+input		git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#next
+block		git	git://git.kernel.dk/linux-block.git#for-next
+device-mapper	git	git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git#for-next
+pcmcia		git	git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia.git#master
+mmc		git	git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git#mmc-next
+mmc-uh		git	git://git.linaro.org/people/ulf.hansson/mmc.git#next
+kgdb		git	git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git#kgdb-next
+md		git	git://neil.brown.name/md#for-next
+mfd		git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-next
+backlight	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-next
+battery		git	git://git.infradead.org/battery-2.6.git#master
+omap_dss2	git	git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git#for-next
+regulator	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-next
+security		git	git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git#next
+integrity	git	git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity#next
+selinux		git	git://git.infradead.org/users/pcmoore/selinux#next
+lblnet		git	git://git.infradead.org/users/pcmoore/lblnet#next
+watchdog		git	git://www.linux-watchdog.org/linux-watchdog-next.git#master
+iommu		git	git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git#next
+dwmw2-iommu	git	git://git.infradead.org/iommu-2.6.git#master
+vfio		git	git://github.com/awilliam/linux-vfio.git#next
+jc_docs		git	git://git.lwn.net/linux-2.6.git#docs-next
+trivial		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git#for-next
+audit		git	git://git.infradead.org/users/pcmoore/audit#next
+devicetree	git	git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux.git#devicetree/next
+dt-rh		git	git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git#for-next
+mailbox		git	git://git.linaro.org/landing-teams/working/fujitsu/integration.git#mailbox-for-next
+spi		git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git#for-next
+tip		git	git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#auto-latest
+clockevents	git	git://git.linaro.org/people/daniel.lezcano/linux.git#clockevents/next
+edac		git	git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git#linux_next
+edac-amd		git	git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git#for-next
+irqchip		git	git://git.infradead.org/users/jcooper/linux.git#irqchip/for-next
+tiny		git	git://git.kernel.org/pub/scm/linux/kernel/git/josh/linux.git#tiny/next
+ftrace		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git#for-next
+rcu		git	git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git#rcu/next
+kvm		git	git://git.kernel.org/pub/scm/virt/kvm/kvm.git#linux-next
+kvm-arm		git	git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git#next
+kvm-ppc		git	git://github.com/agraf/linux-2.6.git#kvm-ppc-next
+kvm-ppc-paulus	git	git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git#kvm-ppc-next
+kvms390		git	git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git#next
+xen-tip		git	git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git#linux-next
+percpu		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git#for-next
+workqueues	git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git#for-next
+drivers-x86	git	git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git#for-next
+chrome-platform	git	git://git.kernel.org/pub/scm/linux/kernel/git/olof/chrome-platform.git#for-next
+regmap		git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-next
+hsi		git	git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git#for-next
+leds		git	git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git#for-next
+ipmi		git	git://git.code.sf.net/p/openipmi/linux-ipmi#for-next
+driver-core	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-next
+tty		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-next
+usb		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-next
+usb-gadget	git	git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git#next
+usb-serial	git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-next
+staging		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-next
+char-misc	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-next
+extcon		git	git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git#extcon-next
+kdbus		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#kdbus
+cgroup		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git#for-next
+scsi		git	git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git#for-next
+target-updates	git	git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git#for-next
+target-merge	git	git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git#for-next-merge
+pinctrl		git	git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git#for-next
+vhost		git	git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git#linux-next
+remoteproc	git	git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc.git#for-next
+rpmsg		git	git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg.git#for-next
+gpio		git	git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git#for-next
+dma-mapping	git	git://git.linaro.org/people/mszyprowski/linux-dma-mapping.git#dma-mapping-next
+pwm		git	git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git#for-next
+dma-buf		git	git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git#for-next
+userns		git	git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git#for-next
+ktest		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest.git#for-next
+clk		git	git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git#clk-next
+random		git	git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random.git#dev
+aio		git	git://git.kvack.org/~bcrl/aio-next.git#master
+llvmlinux	git	git://git.linuxfoundation.org/llvmlinux/kernel.git#for-next
+kselftest	git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#next
+y2038		git	git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git#y2038
+luto-misc	git	git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git#next
+access_once	git	git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux.git#linux-next
+livepatching	git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching#for-next
+coresight	git	git://git.linaro.org/kernel/coresight.git#next
+rtc		git	git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git#rtc-next
+hwspinlock	git	git://git.kernel.org/pub/scm/linux/kernel/git/ohad/hwspinlock.git#for-next
+nvdimm		git	git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git#libnvdimm-for-next
+akpm-current	mmotm	http://www.ozlabs.org/~akpm/mmotm/
+akpm		mmotm	http://www.ozlabs.org/~akpm/mmotm/
diff --git a/Next/merge.log b/Next/merge.log
new file mode 100644
index 000000000000..e06942ae5576
--- /dev/null
+++ b/Next/merge.log
@@ -0,0 +1,2179 @@
+$ date -R
+Mon, 14 Sep 2015 09:06:00 +1000
+$ git checkout master
+Already on 'master'
+$ git reset --hard stable
+HEAD is now at 06a660ada206 Merge tag 'media/v4.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
+Merging origin/master (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge origin/master
+Updating 06a660ada206..6ff33f3902c3
+Fast-forward
+ .../bindings/input/touchscreen/colibri-vf50-ts.txt |  36 ++
+ .../bindings/input/touchscreen/imx6ul_tsc.txt      |  36 ++
+ MAINTAINERS                                        |  10 +
+ Makefile                                           |   4 +-
+ arch/arc/plat-axs10x/axs10x.c                      |   2 +
+ arch/cris/Kconfig                                  |  12 +
+ arch/cris/arch-v10/kernel/entry.S                  |   8 +
+ arch/cris/arch-v10/lib/dmacopy.c                   |  42 --
+ arch/cris/arch-v10/lib/old_checksum.c              |  86 ---
+ arch/cris/arch-v32/drivers/Kconfig                 |  16 +-
+ arch/cris/arch-v32/drivers/axisflashmap.c          |   9 +-
+ arch/cris/arch-v32/drivers/mach-a3/gpio.c          |   4 +-
+ arch/cris/arch-v32/drivers/mach-fs/gpio.c          |   3 +-
+ arch/cris/arch-v32/kernel/entry.S                  |  19 +
+ arch/cris/arch-v32/kernel/process.c                |   4 +-
+ arch/cris/arch-v32/kernel/signal.c                 |   1 -
+ arch/cris/arch-v32/mach-fs/pinmux.c                |   8 +-
+ arch/cris/configs/artpec_3_defconfig               |   5 +-
+ arch/cris/configs/etraxfs_defconfig                |   1 +
+ arch/cris/include/arch-v32/arch/bug.h              |  11 +-
+ arch/cris/include/arch-v32/arch/irqflags.h         |   2 +-
+ arch/cris/include/asm/Kbuild                       |  17 +
+ arch/cris/include/asm/mmu_context.h                |   9 +-
+ arch/cris/include/asm/stacktrace.h                 |   8 +
+ arch/cris/include/asm/types.h                      |  12 -
+ arch/cris/include/asm/unistd.h                     |   2 +-
+ arch/cris/include/uapi/asm/Kbuild                  |   5 +
+ arch/cris/include/uapi/asm/auxvec.h                |   4 -
+ arch/cris/include/uapi/asm/bitsperlong.h           |   1 -
+ arch/cris/include/{ => uapi}/asm/elf.h             |   9 +-
+ .../{arch-v10/arch/elf.h => uapi/asm/elf_v10.h}    |   5 +-
+ .../{arch-v32/arch/elf.h => uapi/asm/elf_v32.h}    |   5 +-
+ arch/cris/include/uapi/asm/errno.h                 |   6 -
+ arch/cris/include/uapi/asm/fcntl.h                 |   1 -
+ arch/cris/include/uapi/asm/ioctl.h                 |   1 -
+ arch/cris/include/uapi/asm/ipcbuf.h                |   1 -
+ arch/cris/include/uapi/asm/kvm_para.h              |   1 -
+ arch/cris/include/uapi/asm/mman.h                  |   1 -
+ arch/cris/include/uapi/asm/msgbuf.h                |  33 --
+ arch/cris/include/uapi/asm/poll.h                  |   1 -
+ arch/cris/include/uapi/asm/ptrace.h                |   6 +-
+ .../arch/ptrace.h => uapi/asm/ptrace_v10.h}        |   0
+ .../arch/ptrace.h => uapi/asm/ptrace_v32.h}        |   0
+ arch/cris/include/uapi/asm/resource.h              |   6 -
+ arch/cris/include/uapi/asm/sembuf.h                |  25 -
+ arch/cris/include/uapi/asm/shmbuf.h                |  42 --
+ arch/cris/include/uapi/asm/siginfo.h               |   6 -
+ arch/cris/include/uapi/asm/socket.h                |  92 ---
+ arch/cris/include/uapi/asm/sockios.h               |  13 -
+ arch/cris/include/uapi/asm/statfs.h                |   6 -
+ arch/cris/include/uapi/asm/types.h                 |   1 -
+ arch/cris/include/uapi/asm/unistd.h                |   8 +
+ arch/cris/kernel/Makefile                          |   1 +
+ arch/cris/kernel/irq.c                             |   6 +-
+ arch/cris/kernel/stacktrace.c                      |  76 +++
+ arch/x86/entry/syscalls/syscall_32.tbl             |   1 +
+ arch/x86/entry/syscalls/syscall_64.tbl             |   1 +
+ drivers/base/power/domain.c                        |  38 +-
+ drivers/base/power/opp.c                           |  28 +
+ drivers/cpufreq/Kconfig.arm                        |   1 +
+ drivers/cpufreq/cpufreq-dt.c                       |  39 +-
+ drivers/cpufreq/cpufreq.c                          |   9 +-
+ drivers/cpufreq/intel_pstate.c                     |  38 +-
+ drivers/cpuidle/coupled.c                          |  22 +
+ drivers/cpuidle/cpuidle.h                          |   6 +
+ drivers/cpuidle/driver.c                           |   4 +
+ drivers/infiniband/ulp/isert/ib_isert.c            |  29 +-
+ drivers/input/evdev.c                              |  13 +-
+ drivers/input/keyboard/imx_keypad.c                |   2 -
+ drivers/input/misc/ab8500-ponkey.c                 |   1 +
+ drivers/input/misc/pwm-beeper.c                    |   1 +
+ drivers/input/misc/regulator-haptic.c              |   1 +
+ drivers/input/misc/sparcspkr.c                     |   2 +
+ drivers/input/mouse/elan_i2c_core.c                |   1 +
+ drivers/input/serio/i8042.c                        |   2 +-
+ drivers/input/touchscreen/Kconfig                  |  24 +
+ drivers/input/touchscreen/Makefile                 |   2 +
+ drivers/input/touchscreen/colibri-vf50-ts.c        | 386 +++++++++++++
+ drivers/input/touchscreen/cyttsp4_i2c.c            |   1 -
+ drivers/input/touchscreen/cyttsp_i2c.c             |   1 -
+ drivers/input/touchscreen/elants_i2c.c             |   2 +-
+ drivers/input/touchscreen/imx6ul_tsc.c             | 523 +++++++++++++++++
+ drivers/iommu/omap-iommu-debug.c                   |   3 +-
+ drivers/md/Kconfig                                 |   2 +-
+ drivers/md/dm-mpath.c                              |  27 +-
+ drivers/net/ntb_netdev.c                           |  77 +++
+ drivers/ntb/hw/intel/ntb_hw_intel.c                |  39 +-
+ drivers/ntb/hw/intel/ntb_hw_intel.h                |   3 +
+ drivers/ntb/ntb_transport.c                        | 126 +++--
+ drivers/scsi/Makefile                              |   1 +
+ drivers/scsi/aic94xx/aic94xx_sds.c                 |   5 +-
+ drivers/scsi/bfa/bfa_ioc.c                         |  24 +-
+ drivers/scsi/device_handler/Kconfig                |   2 +-
+ drivers/scsi/device_handler/Makefile               |   1 -
+ drivers/scsi/device_handler/scsi_dh.c              | 621 ---------------------
+ drivers/scsi/device_handler/scsi_dh_alua.c         |  31 +-
+ drivers/scsi/device_handler/scsi_dh_emc.c          |  58 +-
+ drivers/scsi/device_handler/scsi_dh_hp_sw.c        |  55 +-
+ drivers/scsi/device_handler/scsi_dh_rdac.c         |  80 +--
+ drivers/scsi/fcoe/fcoe.c                           |   2 +-
+ drivers/scsi/ipr.c                                 |   8 +-
+ drivers/scsi/libiscsi.c                            |   9 +-
+ drivers/scsi/lpfc/lpfc_mbox.c                      |   7 +-
+ drivers/scsi/mpt2sas/mpt2sas_base.c                |   6 +
+ drivers/scsi/mpt2sas/mpt2sas_base.h                |  41 +-
+ drivers/scsi/mpt2sas/mpt2sas_ctl.c                 |  38 +-
+ drivers/scsi/mpt2sas/mpt2sas_scsih.c               | 605 ++++++++++++++------
+ drivers/scsi/mpt2sas/mpt2sas_transport.c           |  12 +-
+ drivers/scsi/mpt3sas/mpi/mpi2.h                    |   8 +-
+ drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h               |  52 +-
+ drivers/scsi/mpt3sas/mpi/mpi2_ioc.h                |   4 +-
+ drivers/scsi/mpt3sas/mpi/mpi2_tool.h               |   4 +-
+ drivers/scsi/mpt3sas/mpt3sas_base.c                | 310 ++++++++--
+ drivers/scsi/mpt3sas/mpt3sas_base.h                |  57 +-
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c               | 343 ++++++++++--
+ drivers/scsi/mpt3sas/mpt3sas_transport.c           |  22 +-
+ drivers/scsi/pm8001/pm8001_hwi.c                   |   1 +
+ drivers/scsi/pm8001/pm80xx_hwi.c                   |   1 +
+ drivers/scsi/qla2xxx/Kconfig                       |   4 +-
+ drivers/scsi/qla2xxx/tcm_qla2xxx.c                 |  13 +-
+ drivers/scsi/scsi_common.c                         | 109 ++++
+ drivers/scsi/scsi_debug.c                          | 158 +++---
+ drivers/scsi/scsi_dh.c                             | 437 +++++++++++++++
+ drivers/scsi/scsi_error.c                          |  85 +--
+ drivers/scsi/scsi_lib.c                            |   6 +-
+ drivers/scsi/scsi_priv.h                           |   9 +
+ drivers/scsi/scsi_sysfs.c                          |  10 +
+ drivers/scsi/scsi_transport_sas.c                  |  10 -
+ drivers/staging/board/armadillo800eva.c            |   2 +-
+ drivers/staging/board/board.c                      |  36 +-
+ drivers/target/iscsi/iscsi_target.c                |  86 ++-
+ drivers/target/iscsi/iscsi_target.h                |   6 +-
+ drivers/target/iscsi/iscsi_target_configfs.c       |  34 +-
+ drivers/target/iscsi/iscsi_target_device.c         |  10 +-
+ drivers/target/iscsi/iscsi_target_login.c          |  78 ++-
+ drivers/target/iscsi/iscsi_target_login.h          |   4 +-
+ drivers/target/iscsi/iscsi_target_nego.c           |   7 +-
+ drivers/target/iscsi/iscsi_target_stat.c           |   2 +-
+ drivers/target/iscsi/iscsi_target_tmr.c            |   2 +-
+ drivers/target/iscsi/iscsi_target_tpg.c            |  38 +-
+ drivers/target/iscsi/iscsi_target_tpg.h            |   3 +-
+ drivers/target/iscsi/iscsi_target_util.c           |  39 +-
+ drivers/target/loopback/tcm_loop.c                 |  22 +-
+ drivers/target/target_core_device.c                |  11 +-
+ drivers/target/target_core_fabric_configfs.c       |   2 +-
+ drivers/target/target_core_hba.c                   |   5 +
+ drivers/target/target_core_sbc.c                   |  49 +-
+ drivers/target/target_core_spc.c                   |  55 +-
+ drivers/target/target_core_tpg.c                   |  17 +
+ drivers/target/target_core_transport.c             | 507 ++++++++---------
+ drivers/target/target_core_user.c                  |  14 +-
+ drivers/target/target_core_xcopy.c                 |   6 +-
+ drivers/target/tcm_fc/tfc_cmd.c                    |   2 +-
+ drivers/thermal/intel_pch_thermal.c                |  11 +-
+ fs/fs-writeback.c                                  |  13 +-
+ fs/nsfs.c                                          |   3 +-
+ fs/ocfs2/dlm/dlmrecovery.c                         |   6 +-
+ fs/seq_file.c                                      |  70 +--
+ include/linux/blkdev.h                             |   2 +-
+ include/linux/ntb.h                                |   9 +-
+ include/linux/ntb_transport.h                      |   1 +
+ include/linux/pm_opp.h                             |   6 +
+ include/linux/seq_file.h                           |  19 +-
+ include/linux/syscalls.h                           |   2 +
+ include/scsi/scsi_common.h                         |   5 +
+ include/scsi/scsi_device.h                         |  27 +-
+ include/scsi/scsi_dh.h                             |  29 +-
+ include/scsi/scsi_eh.h                             |   6 +-
+ include/target/iscsi/iscsi_target_core.h           |  15 +-
+ include/target/iscsi/iscsi_target_stat.h           |   2 +-
+ include/target/iscsi/iscsi_transport.h             |   2 +-
+ include/target/target_core_backend.h               |   2 +
+ include/target/target_core_base.h                  |  27 +-
+ include/target/target_core_fabric.h                |  14 +
+ include/uapi/asm-generic/unistd.h                  |   4 +-
+ include/uapi/linux/Kbuild                          |   1 +
+ include/uapi/linux/membarrier.h                    |  53 ++
+ include/uapi/linux/target_core_user.h              |   4 -
+ init/Kconfig                                       |  12 +
+ kernel/Makefile                                    |   1 +
+ kernel/cpu_pm.c                                    |   2 +-
+ kernel/membarrier.c                                |  66 +++
+ kernel/sys_ni.c                                    |   3 +
+ mm/early_ioremap.c                                 |   1 +
+ scripts/extract-cert.c                             |   2 +-
+ tools/testing/selftests/Makefile                   |   1 +
+ tools/testing/selftests/membarrier/.gitignore      |   1 +
+ tools/testing/selftests/membarrier/Makefile        |  11 +
+ .../testing/selftests/membarrier/membarrier_test.c | 121 ++++
+ 189 files changed, 4526 insertions(+), 2498 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
+ create mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+ delete mode 100644 arch/cris/arch-v10/lib/dmacopy.c
+ delete mode 100644 arch/cris/arch-v10/lib/old_checksum.c
+ create mode 100644 arch/cris/include/asm/stacktrace.h
+ delete mode 100644 arch/cris/include/asm/types.h
+ delete mode 100644 arch/cris/include/uapi/asm/auxvec.h
+ delete mode 100644 arch/cris/include/uapi/asm/bitsperlong.h
+ rename arch/cris/include/{ => uapi}/asm/elf.h (95%)
+ rename arch/cris/include/{arch-v10/arch/elf.h => uapi/asm/elf_v10.h} (98%)
+ rename arch/cris/include/{arch-v32/arch/elf.h => uapi/asm/elf_v32.h} (98%)
+ delete mode 100644 arch/cris/include/uapi/asm/errno.h
+ delete mode 100644 arch/cris/include/uapi/asm/fcntl.h
+ delete mode 100644 arch/cris/include/uapi/asm/ioctl.h
+ delete mode 100644 arch/cris/include/uapi/asm/ipcbuf.h
+ delete mode 100644 arch/cris/include/uapi/asm/kvm_para.h
+ delete mode 100644 arch/cris/include/uapi/asm/mman.h
+ delete mode 100644 arch/cris/include/uapi/asm/msgbuf.h
+ delete mode 100644 arch/cris/include/uapi/asm/poll.h
+ rename arch/cris/include/{arch-v10/arch/ptrace.h => uapi/asm/ptrace_v10.h} (100%)
+ rename arch/cris/include/{arch-v32/arch/ptrace.h => uapi/asm/ptrace_v32.h} (100%)
+ delete mode 100644 arch/cris/include/uapi/asm/resource.h
+ delete mode 100644 arch/cris/include/uapi/asm/sembuf.h
+ delete mode 100644 arch/cris/include/uapi/asm/shmbuf.h
+ delete mode 100644 arch/cris/include/uapi/asm/siginfo.h
+ delete mode 100644 arch/cris/include/uapi/asm/socket.h
+ delete mode 100644 arch/cris/include/uapi/asm/sockios.h
+ delete mode 100644 arch/cris/include/uapi/asm/statfs.h
+ delete mode 100644 arch/cris/include/uapi/asm/types.h
+ create mode 100644 arch/cris/kernel/stacktrace.c
+ create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
+ create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
+ delete mode 100644 drivers/scsi/device_handler/scsi_dh.c
+ create mode 100644 drivers/scsi/scsi_dh.c
+ create mode 100644 include/uapi/linux/membarrier.h
+ create mode 100644 kernel/membarrier.c
+ create mode 100644 tools/testing/selftests/membarrier/.gitignore
+ create mode 100644 tools/testing/selftests/membarrier/Makefile
+ create mode 100644 tools/testing/selftests/membarrier/membarrier_test.c
+Merging fixes/master (c7e9ad7da219 Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip)
+$ git merge fixes/master
+Already up-to-date.
+Merging kbuild-current/rc-fixes (3d1450d54a4f Makefile: Force gzip and xz on module install)
+$ git merge kbuild-current/rc-fixes
+Already up-to-date.
+Merging arc-current/for-curr (e4140819dadc ARC: signal handling robustify)
+$ git merge arc-current/for-curr
+Already up-to-date.
+Merging arm-current/fixes (c2172ce23030 Merge branch 'uaccess' into fixes)
+$ git merge arm-current/fixes
+Auto-merging arch/arm/kernel/process.c
+Auto-merging arch/arm/include/asm/thread_info.h
+Auto-merging arch/arm/include/asm/assembler.h
+Merge made by the 'recursive' strategy.
+ arch/arm/Makefile                  |  8 ++++++++
+ arch/arm/include/asm/assembler.h   |  5 -----
+ arch/arm/include/asm/bug.h         |  1 +
+ arch/arm/include/asm/domain.h      |  6 ++++--
+ arch/arm/include/asm/thread_info.h |  1 -
+ arch/arm/kernel/process.c          |  2 ++
+ arch/arm/nwfpe/entry.S             |  3 ++-
+ arch/arm/xen/hypercall.S           | 15 +++++++++++++++
+ 8 files changed, 32 insertions(+), 9 deletions(-)
+Merging m68k-current/for-linus (1ecb40643a9a m68k/bootinfo: Use kmemdup rather than duplicating its implementation)
+$ git merge m68k-current/for-linus
+Already up-to-date.
+Merging metag-fixes/fixes (0164a711c97b metag: Fix ioremap_wc/ioremap_cached build errors)
+$ git merge metag-fixes/fixes
+Already up-to-date.
+Merging mips-fixes/mips-fixes (1795cd9b3a91 Linux 3.16-rc5)
+$ git merge mips-fixes/mips-fixes
+Already up-to-date.
+Merging powerpc-fixes/fixes (e297c939b745 powerpc/MSI: Fix race condition in tearing down MSI interrupts)
+$ git merge powerpc-fixes/fixes
+Merge made by the 'recursive' strategy.
+ arch/powerpc/include/asm/systbl.h         |  1 +
+ arch/powerpc/include/asm/unistd.h         |  2 +-
+ arch/powerpc/include/uapi/asm/unistd.h    |  1 +
+ arch/powerpc/platforms/pasemi/msi.c       |  5 +++--
+ arch/powerpc/platforms/powernv/pci-ioda.c | 16 +++++++++++++++-
+ arch/powerpc/platforms/powernv/pci.c      |  5 +++--
+ arch/powerpc/platforms/pseries/dlpar.c    |  4 +++-
+ arch/powerpc/sysdev/fsl_msi.c             |  5 +++--
+ arch/powerpc/sysdev/mpic_u3msi.c          |  5 +++--
+ arch/powerpc/sysdev/ppc4xx_msi.c          |  5 +++--
+ drivers/misc/cxl/vphb.c                   |  6 ++++++
+ 11 files changed, 42 insertions(+), 13 deletions(-)
+Merging powerpc-merge-mpe/fixes (bc0195aad0da Linux 4.2-rc2)
+$ git merge powerpc-merge-mpe/fixes
+Already up-to-date.
+Merging sparc/master (73958c651fbf sparc64: use ENTRY/ENDPROC in VISsave)
+$ git merge sparc/master
+Merge made by the 'recursive' strategy.
+ arch/sparc/include/uapi/asm/asi.h |  2 +-
+ arch/sparc/lib/VISsave.S          | 10 +++++-----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+Merging net/master (e8684c88774c irda: ali-ircc: Fix deadlock in ali_ircc_sir_change_speed())
+$ git merge net/master
+Merge made by the 'recursive' strategy.
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |  6 +--
+ drivers/net/irda/ali-ircc.c                      |  6 ---
+ net/bridge/br_multicast.c                        |  4 +-
+ net/core/filter.c                                |  2 +-
+ net/netlink/af_netlink.c                         | 30 ++++++++---
+ net/netlink/af_netlink.h                         |  9 ++++
+ net/openvswitch/Kconfig                          |  3 +-
+ net/sctp/protocol.c                              | 64 +++++++++++++++---------
+ 8 files changed, 80 insertions(+), 44 deletions(-)
+Merging ipsec/master (93efac3f2e03 ipv6: Fix IPsec pre-encap fragmentation check)
+$ git merge ipsec/master
+Merge made by the 'recursive' strategy.
+ net/ipv6/xfrm6_output.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+Merging sound-current/for-linus (5ee20bc79246 ALSA: usb-audio: Change internal PCM order)
+$ git merge sound-current/for-linus
+Already up-to-date.
+Merging pci-current/for-linus (45ea2a5fed6d PCI: Don't use 64-bit bus addresses on PA-RISC)
+$ git merge pci-current/for-linus
+Already up-to-date.
+Merging wireless-drivers/master (741e3b9902d1 rtlwifi: rtl8723be: Add module parameter for MSI interrupts)
+$ git merge wireless-drivers/master
+Already up-to-date.
+Merging driver-core.current/driver-core-linus (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge driver-core.current/driver-core-linus
+Already up-to-date.
+Merging tty.current/tty-linus (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge tty.current/tty-linus
+Already up-to-date.
+Merging usb.current/usb-linus (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge usb.current/usb-linus
+Already up-to-date.
+Merging usb-gadget-fixes/fixes (c93e64e91248 usb: udc: core: add device_del() call to error pathway)
+$ git merge usb-gadget-fixes/fixes
+Already up-to-date.
+Merging usb-serial-fixes/usb-linus (d071a3cdd2e1 USB: qcserial: add HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module)
+$ git merge usb-serial-fixes/usb-linus
+Merge made by the 'recursive' strategy.
+Merging staging.current/staging-linus (8b5081c876bd staging: unisys: visornic: handle error return from device registration)
+$ git merge staging.current/staging-linus
+Merge made by the 'recursive' strategy.
+ MAINTAINERS                                     |  4 ++--
+ drivers/staging/android/TODO                    | 20 ++++++++++++++++++++
+ drivers/staging/fbtft/fb_uc1611.c               |  2 +-
+ drivers/staging/fbtft/fb_watterott.c            |  4 ++--
+ drivers/staging/fbtft/fbtft-core.c              | 10 +++-------
+ drivers/staging/fbtft/flexfb.c                  | 11 ++++-------
+ drivers/staging/lustre/README.txt               | 16 ++++++----------
+ drivers/staging/most/Kconfig                    |  1 +
+ drivers/staging/most/hdm-usb/Kconfig            |  2 +-
+ drivers/staging/most/mostcore/Kconfig           |  1 +
+ drivers/staging/unisys/visorbus/visorbus_main.c | 13 +++++++++----
+ drivers/staging/unisys/visornic/visornic_main.c | 18 +++++++++++-------
+ 12 files changed, 61 insertions(+), 41 deletions(-)
+Merging char-misc.current/char-misc-linus (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge char-misc.current/char-misc-linus
+Already up-to-date.
+Merging input-current/for-linus (53431d0a3534 Merge branch 'next' into for-linus)
+$ git merge input-current/for-linus
+Already up-to-date.
+Merging crypto-current/master (84cba178a3b8 crypto: testmgr - don't copy from source IV too much)
+$ git merge crypto-current/master
+Merge made by the 'recursive' strategy.
+ crypto/testmgr.c                          | 5 +++--
+ drivers/crypto/Kconfig                    | 2 +-
+ drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 2 +-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+Merging ide/master (d681f1166919 ide: remove deprecated use of pci api)
+$ git merge ide/master
+Already up-to-date.
+Merging devicetree-current/devicetree/merge (f76502aa9140 of/dynamic: Fix test for PPC_PSERIES)
+$ git merge devicetree-current/devicetree/merge
+Already up-to-date.
+Merging rr-fixes/fixes (275d7d44d802 module: Fix locking in symbol_put_addr())
+$ git merge rr-fixes/fixes
+Merge made by the 'recursive' strategy.
+ kernel/module.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+Merging vfio-fixes/for-linus (4bc94d5dc95d vfio: Fix lockdep issue)
+$ git merge vfio-fixes/for-linus
+Already up-to-date.
+Merging kselftest-fixes/fixes (fee50f3c8427 selftests/futex: Fix futex_cmp_requeue_pi() error handling)
+$ git merge kselftest-fixes/fixes
+Already up-to-date.
+Merging backlight-fixes/for-backlight-fixes (68feaca0b13e backlight: pwm: Handle EPROBE_DEFER while requesting the PWM)
+$ git merge backlight-fixes/for-backlight-fixes
+Already up-to-date.
+Merging ftrace-fixes/for-next-urgent (6224beb12e19 tracing: Have branch tracer use recursive field of task struct)
+$ git merge ftrace-fixes/for-next-urgent
+Already up-to-date.
+Merging mfd-fixes/for-mfd-fixes (fb9caeedafe6 mfd: Remove MFD_CROS_EC_SPI depends on OF)
+$ git merge mfd-fixes/for-mfd-fixes
+Already up-to-date.
+Merging drm-intel-fixes/for-linux-next-fixes (c13dcf9f2d6f Linux 4.2-rc8)
+$ git merge drm-intel-fixes/for-linux-next-fixes
+Already up-to-date.
+Merging asm-generic/master (643165c8bbc8 Merge tag 'uaccess_for_upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost into asm-generic)
+$ git merge asm-generic/master
+Already up-to-date.
+Merging arc/for-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge arc/for-next
+Already up-to-date.
+Merging arm/for-next (4cd545806d3c Merge branch 'drm-dwhdmi-devel' into for-next)
+$ git merge arm/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging arm-perf/for-next/perf (fa8ad7889d83 arm: perf: factor arm_pmu core out to drivers)
+$ git merge arm-perf/for-next/perf
+Already up-to-date.
+Merging arm-soc/for-next (f47c3594f854 Merge branch 'next/late' into for-next)
+$ git merge arm-soc/for-next
+Resolved 'Documentation/devicetree/bindings/serial/mtk-uart.txt' using previous resolution.
+Auto-merging Documentation/devicetree/bindings/serial/mtk-uart.txt
+CONFLICT (content): Merge conflict in Documentation/devicetree/bindings/serial/mtk-uart.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 931925cbec50] Merge remote-tracking branch 'arm-soc/for-next'
+$ git diff -M --stat --summary HEAD^..
+ arch/arm/arm-soc-for-next-contents.txt | 303 +++++++++++++++++++++++++++++++++
+ 1 file changed, 303 insertions(+)
+ create mode 100644 arch/arm/arm-soc-for-next-contents.txt
+Merging at91/at91-next (253ebd4df402 Merge branch 'at91-4.3-defconfig' into at91-next)
+$ git merge at91/at91-next
+Resolved 'arch/arm/configs/at91_dt_defconfig' using previous resolution.
+Resolved 'arch/arm/mach-at91/sama5.c' using previous resolution.
+Auto-merging arch/arm/mach-at91/sama5.c
+CONFLICT (content): Merge conflict in arch/arm/mach-at91/sama5.c
+Auto-merging arch/arm/configs/at91_dt_defconfig
+CONFLICT (content): Merge conflict in arch/arm/configs/at91_dt_defconfig
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 0838d0213c7c] Merge remote-tracking branch 'at91/at91-next'
+$ git diff -M --stat --summary HEAD^..
+Merging bcm2835/for-next (b2776bf7149b Linux 3.18)
+$ git merge bcm2835/for-next
+Already up-to-date.
+Merging berlin/berlin/for-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge berlin/berlin/for-next
+Already up-to-date.
+Merging cortex-m/for-next (f719a0d6a854 ARM: efm32: switch to vendor,device compatible strings)
+$ git merge cortex-m/for-next
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/dts/efm32gg-dk3750.dts |  8 ++++----
+ arch/arm/boot/dts/efm32gg.dtsi       | 32 ++++++++++++++++----------------
+ 2 files changed, 20 insertions(+), 20 deletions(-)
+Merging imx-mxs/for-next (c746ef1b64e9 Merge branch 'imx/defconfig' into for-next)
+$ git merge imx-mxs/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging keystone/next (a6ba4234e474 ARM: dts: k2l: fix the netcp range size)
+$ git merge keystone/next
+Resolved 'arch/arm/boot/dts/k2e.dtsi' using previous resolution.
+Resolved 'arch/arm/boot/dts/k2hk.dtsi' using previous resolution.
+Resolved 'arch/arm/boot/dts/k2l.dtsi' using previous resolution.
+Auto-merging arch/arm/boot/dts/k2l.dtsi
+CONFLICT (content): Merge conflict in arch/arm/boot/dts/k2l.dtsi
+Auto-merging arch/arm/boot/dts/k2hk.dtsi
+CONFLICT (content): Merge conflict in arch/arm/boot/dts/k2hk.dtsi
+Auto-merging arch/arm/boot/dts/k2e.dtsi
+CONFLICT (content): Merge conflict in arch/arm/boot/dts/k2e.dtsi
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master f7f5ebfa2cf6] Merge remote-tracking branch 'keystone/next'
+$ git diff -M --stat --summary HEAD^..
+Merging mvebu/for-next (adfc8c76d84a Merge branch 'mvebu/config' into mvebu/for-next)
+$ git merge mvebu/for-next
+Merge made by the 'recursive' strategy.
+Merging omap/for-next (b2a882022a1e Merge branch 'omap-for-v4.3/dt-v2' into for-next)
+$ git merge omap/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging omap-pending/for-next (30aa18d3bea5 MAINTAINERS: add maintainer for OMAP hwmod data)
+$ git merge omap-pending/for-next
+Resolved 'arch/arm/mach-omap2/omap_hwmod_43xx_data.c' using previous resolution.
+Resolved 'arch/arm/mach-omap2/omap_hwmod_7xx_data.c' using previous resolution.
+Auto-merging arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+CONFLICT (content): Merge conflict in arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+Auto-merging arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+CONFLICT (content): Merge conflict in arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master e578e9dad6c9] Merge remote-tracking branch 'omap-pending/for-next'
+$ git diff -M --stat --summary HEAD^..
+Merging qcom/qcom/for-next (37a7a47c0031 Merge tag 'qcom-fixes-for-4.3-rc1' into next-base)
+$ git merge qcom/qcom/for-next
+Auto-merging drivers/firmware/Makefile
+Auto-merging drivers/firmware/Kconfig
+Merge made by the 'recursive' strategy.
+ drivers/firmware/Kconfig       |  8 ++++++
+ drivers/firmware/Makefile      |  3 +-
+ drivers/firmware/qcom_scm-64.c | 63 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 73 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/firmware/qcom_scm-64.c
+Merging renesas/next (53d5bd1b09d2 Merge branch 'heads/sh-drivers-for-v4.3' into next)
+$ git merge renesas/next
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/dts/r8a7790.dtsi |  1 +
+ arch/arm/boot/dts/r8a7791.dtsi |  1 +
+ drivers/sh/intc/internals.h    | 10 +---------
+ drivers/sh/pm_runtime.c        | 19 +++++--------------
+ 4 files changed, 8 insertions(+), 23 deletions(-)
+Merging rockchip/for-next (ed0450118b2f Merge branch 'v4.3-armsoc/soc' into for-next)
+$ git merge rockchip/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging rpi/for-rpi-next (bc0195aad0da Linux 4.2-rc2)
+$ git merge rpi/for-rpi-next
+Already up-to-date.
+Merging samsung/for-next (112129267f1a Merge branch 'v4.3-next/dt64-samsung' into for-next)
+$ git merge samsung/for-next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/arm/samsung/pmu.txt        |   1 +
+ .../devicetree/bindings/hwmon/pwm-fan.txt          |  29 +-
+ Documentation/devicetree/bindings/mfd/s2mps11.txt  |   4 +
+ arch/arm/boot/dts/exynos4412-odroidu3.dts          |  43 +
+ arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   1 +
+ arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 698 +++++++++++++++
+ .../dts/exynos/exynos5433-tmu-sensor-conf.dtsi     |  22 +
+ arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi     | 231 +++++
+ arch/arm64/boot/dts/exynos/exynos5433.dtsi         | 931 +++++++++++++++++++++
+ 9 files changed, 1958 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
+ create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
+ create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi
+ create mode 100644 arch/arm64/boot/dts/exynos/exynos5433.dtsi
+Merging samsung-krzk/for-next (6fab115d0762 Merge branch 'defconfig-for-next' into for-next)
+$ git merge samsung-krzk/for-next
+Auto-merging arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/dts/exynos4.dtsi                     |   8 ++
+ arch/arm/boot/dts/exynos5250-smdk5250.dts          |   1 +
+ arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   1 -
+ arch/arm/configs/exynos_defconfig                  |   9 +-
+ arch/arm/configs/multi_v7_defconfig                |   2 +
+ arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi    | 111 +++++++++++++++++++++
+ arch/arm64/boot/dts/exynos/exynos7.dtsi            |   7 ++
+ 7 files changed, 137 insertions(+), 2 deletions(-)
+Merging sunxi/sunxi/for-next (9d73c13a139c Merge branches 'sunxi/dt-for-4.3' and 'sunxi/defconfig-for-4.3' into sunxi/for-next)
+$ git merge sunxi/sunxi/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging tegra/for-next (bea5a17a8beb Merge branch for-4.3/defconfig into for-next)
+$ git merge tegra/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging arm64/for-next/core (674c242c9323 arm64: flush FP/SIMD state correctly after execve())
+$ git merge arm64/for-next/core
+Already up-to-date.
+Merging blackfin/for-linus (d91e14b3b9e1 eth: bf609 eth clock: add pclk clock for stmmac driver probe)
+$ git merge blackfin/for-linus
+Already up-to-date.
+Merging c6x/for-linux-next (960a2741d5fd c67: irq: Use __handle_domain_irq())
+$ git merge c6x/for-linux-next
+Merge made by the 'recursive' strategy.
+ arch/c6x/Kconfig      |  1 +
+ arch/c6x/kernel/irq.c | 13 ++-----------
+ 2 files changed, 3 insertions(+), 11 deletions(-)
+Merging cris/for-next (254a0f413548 CRISv10: delete unused lib/dmacopy.c)
+$ git merge cris/for-next
+Already up-to-date.
+Merging h8300/h8300-next (99bcfda85f66 Revert "asm-generic: {get,put}_user ptr argument evaluate only 1 time")
+$ git merge h8300/h8300-next
+Auto-merging drivers/clk/h8300/clk-h8s2678.c
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt | 2 +-
+ drivers/clk/h8300/clk-h8s2678.c                                     | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+Merging hexagon/linux-next (02cc2ccfe771 Revert "Hexagon: fix signal.c compile error")
+$ git merge hexagon/linux-next
+Already up-to-date.
+Merging ia64/next (ae40b7e28752 Merge branch 'misc-4.2' into next)
+$ git merge ia64/next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging m68k/for-next (bab84fa9cc09 m68k/sun3: Use %pM format specifier to print ethernet address)
+$ git merge m68k/for-next
+Merge made by the 'recursive' strategy.
+ arch/m68k/sun3/idprom.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+Merging m68knommu/for-next (50e48bd06731 m68k/coldfire: use PFN_DOWN macro)
+$ git merge m68knommu/for-next
+Already up-to-date.
+Merging metag/for-next (3fe6942f0486 Documentation/features/vm: Meta2 is capable of THP)
+$ git merge metag/for-next
+Merge made by the 'recursive' strategy.
+Merging microblaze/next (b14132797d80 elf-em.h: move EM_MICROBLAZE to the common header)
+$ git merge microblaze/next
+Already up-to-date.
+Merging mips/mips-for-linux-next (807249d3ada1 Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus)
+$ git merge mips/mips-for-linux-next
+Already up-to-date.
+Merging nios2/for-next (08441d462ebd nios2: add Max10 defconfig)
+$ git merge nios2/for-next
+Already up-to-date.
+Merging parisc-hd/for-next (64291f7db5bd Linux 4.2)
+$ git merge parisc-hd/for-next
+Already up-to-date.
+Merging powerpc/next (ff474e8ca854 Merge tag 'powerpc-4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux)
+$ git merge powerpc/next
+Already up-to-date.
+Merging powerpc-mpe/next (bc0195aad0da Linux 4.2-rc2)
+$ git merge powerpc-mpe/next
+Already up-to-date.
+Merging fsl/next (4524cd093fa8 powerpc/t1023rdb/dts: set ifc nand chip select from 2 to 1)
+$ git merge fsl/next
+Already up-to-date.
+Merging mpc5xxx/next (9e813308a5c1 powerpc/thp: Add tracepoints to track hugepage invalidate)
+$ git merge mpc5xxx/next
+Already up-to-date.
+Merging s390/features (e94f6761a7da s390/dasd: mark DASD devices as non rotational)
+$ git merge s390/features
+Auto-merging drivers/s390/crypto/zcrypt_api.c
+Merge made by the 'recursive' strategy.
+ arch/s390/kernel/compat_signal.c       | 27 ++++++++++++++++++++----
+ arch/s390/kernel/entry.S               |  2 ++
+ arch/s390/kernel/swsusp.S              | 38 +++-------------------------------
+ arch/s390/numa/mode_emu.c              | 10 +++++++--
+ drivers/s390/block/dasd.c              |  1 +
+ drivers/s390/crypto/zcrypt_api.c       |  3 +--
+ drivers/s390/crypto/zcrypt_cca_key.h   |  2 +-
+ drivers/s390/crypto/zcrypt_msgtype50.c |  2 +-
+ drivers/s390/crypto/zcrypt_pcica.c     |  2 +-
+ 9 files changed, 41 insertions(+), 46 deletions(-)
+Merging sparc-next/master (9f935675d41a Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input)
+$ git merge sparc-next/master
+Already up-to-date.
+Merging tile/master (fa5d8f13afb8 tile: fix build failure)
+$ git merge tile/master
+Merge made by the 'recursive' strategy.
+ arch/tile/kernel/usb.c | 1 +
+ 1 file changed, 1 insertion(+)
+Merging uml/linux-next (bdbac7d0e2b3 um: Fix kernel mode fault condition)
+$ git merge uml/linux-next
+Auto-merging arch/um/kernel/trap.c
+Merge made by the 'recursive' strategy.
+ arch/um/Makefile          | 4 ++--
+ arch/um/kernel/trap.c     | 2 +-
+ arch/um/os-Linux/helper.c | 6 +++---
+ arch/x86/um/ldt.c         | 5 ++++-
+ 4 files changed, 10 insertions(+), 7 deletions(-)
+Merging unicore32/unicore32 (d670878e2c9a unicore32: Remove ARCH_HAS_CPUFREQ config option)
+$ git merge unicore32/unicore32
+Already up-to-date.
+Merging xtensa/for_next (895fb3159280 xtensa: improve vmlinux.lds.S sed post-processing)
+$ git merge xtensa/for_next
+Already up-to-date.
+Merging btrfs/next (3a9508b0221d btrfs: fix compile when block cgroups are not enabled)
+$ git merge btrfs/next
+Already up-to-date.
+Merging ceph/master (8dbd263de1cb ceph: improve readahead for file holes)
+$ git merge ceph/master
+Merge made by the 'recursive' strategy.
+Merging cifs/for-next (eda2116f4ab6 [CIFS] mount option sec=none not displayed properly in /proc/mounts)
+$ git merge cifs/for-next
+Merge made by the 'recursive' strategy.
+ fs/cifs/cifsfs.c | 5 ++++-
+ fs/cifs/ioctl.c  | 6 ++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+Merging ecryptfs/next (0dad87fcb732 eCryptfs: Delete a check before the function call "key_put")
+$ git merge ecryptfs/next
+Already up-to-date.
+Merging ext3/for_next (9181f8bf5abf udf: Don't modify filesystem for read-only mounts)
+$ git merge ext3/for_next
+Already up-to-date.
+Merging ext4/dev (bdfe0cbd746a Revert "ext4: remove block_device_ejected")
+$ git merge ext4/dev
+Already up-to-date.
+Merging f2fs/dev (51e771c0d25b Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input)
+$ git merge f2fs/dev
+Already up-to-date.
+Merging fscache/fscache (b00c2ae2ed3c FS-Cache: Don't override netfs's primary_index if registering failed)
+$ git merge fscache/fscache
+Merge made by the 'recursive' strategy.
+ fs/fscache/netfs.c | 38 ++++++++++++++++++--------------------
+ 1 file changed, 18 insertions(+), 20 deletions(-)
+Merging fuse/for-next (0a30f612d6cf fuse: update MAINTAINERS entry)
+$ git merge fuse/for-next
+Already up-to-date.
+Merging gfs2/for-next (8f7e0a806db0 gfs2: A minor "sbstats" cleanup)
+$ git merge gfs2/for-next
+Already up-to-date.
+Merging jfs/jfs-next (26456955719b jfs: clean up jfs_rename and fix out of order unlock)
+$ git merge jfs/jfs-next
+Already up-to-date.
+Merging nfs/linux-next (5445b1fbd123 NFSv4: Respect the server imposed limit on how many changes we may cache)
+$ git merge nfs/linux-next
+Already up-to-date.
+Merging nfsd/nfsd-next (a909e9f9d73a nfsd: don't hold i_mutex over userspace upcalls)
+$ git merge nfsd/nfsd-next
+Auto-merging fs/namei.c
+Merge made by the 'recursive' strategy.
+ fs/namei.c            | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/nfsd/nfs3xdr.c     |  2 +-
+ fs/nfsd/nfs4xdr.c     |  8 +++---
+ fs/nfsd/vfs.c         | 23 +++++++---------
+ include/linux/namei.h |  1 +
+ 5 files changed, 89 insertions(+), 19 deletions(-)
+Merging orangefs/for-next (600896a3b8b0 Orangefs: Swap order of include files)
+$ git merge orangefs/for-next
+Auto-merging fs/Makefile
+Auto-merging fs/Kconfig
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/stable/sysfs-fs-orangefs |   87 ++
+ Documentation/filesystems/orangefs.txt     |  137 +++
+ fs/Kconfig                                 |    1 +
+ fs/Makefile                                |    1 +
+ fs/orangefs/Kconfig                        |    6 +
+ fs/orangefs/Makefile                       |   10 +
+ fs/orangefs/acl.c                          |  175 +++
+ fs/orangefs/dcache.c                       |  142 +++
+ fs/orangefs/devpvfs2-req.c                 | 1004 ++++++++++++++++
+ fs/orangefs/dir.c                          |  378 ++++++
+ fs/orangefs/downcall.h                     |  138 +++
+ fs/orangefs/file.c                         | 1016 ++++++++++++++++
+ fs/orangefs/inode.c                        |  469 ++++++++
+ fs/orangefs/namei.c                        |  473 ++++++++
+ fs/orangefs/protocol.h                     |  672 +++++++++++
+ fs/orangefs/pvfs2-bufmap.c                 |  974 +++++++++++++++
+ fs/orangefs/pvfs2-bufmap.h                 |   76 ++
+ fs/orangefs/pvfs2-cache.c                  |  260 ++++
+ fs/orangefs/pvfs2-debug.h                  |  290 +++++
+ fs/orangefs/pvfs2-debugfs.c                |  458 +++++++
+ fs/orangefs/pvfs2-debugfs.h                |    3 +
+ fs/orangefs/pvfs2-dev-proto.h              |  102 ++
+ fs/orangefs/pvfs2-kernel.h                 |  864 ++++++++++++++
+ fs/orangefs/pvfs2-mod.c                    |  315 +++++
+ fs/orangefs/pvfs2-sysfs.c                  | 1787 ++++++++++++++++++++++++++++
+ fs/orangefs/pvfs2-sysfs.h                  |    2 +
+ fs/orangefs/pvfs2-utils.c                  | 1129 ++++++++++++++++++
+ fs/orangefs/super.c                        |  558 +++++++++
+ fs/orangefs/symlink.c                      |   31 +
+ fs/orangefs/upcall.h                       |  255 ++++
+ fs/orangefs/waitqueue.c                    |  529 ++++++++
+ fs/orangefs/xattr.c                        |  530 +++++++++
+ 32 files changed, 12872 insertions(+)
+ create mode 100644 Documentation/ABI/stable/sysfs-fs-orangefs
+ create mode 100644 Documentation/filesystems/orangefs.txt
+ create mode 100644 fs/orangefs/Kconfig
+ create mode 100644 fs/orangefs/Makefile
+ create mode 100644 fs/orangefs/acl.c
+ create mode 100644 fs/orangefs/dcache.c
+ create mode 100644 fs/orangefs/devpvfs2-req.c
+ create mode 100644 fs/orangefs/dir.c
+ create mode 100644 fs/orangefs/downcall.h
+ create mode 100644 fs/orangefs/file.c
+ create mode 100644 fs/orangefs/inode.c
+ create mode 100644 fs/orangefs/namei.c
+ create mode 100644 fs/orangefs/protocol.h
+ create mode 100644 fs/orangefs/pvfs2-bufmap.c
+ create mode 100644 fs/orangefs/pvfs2-bufmap.h
+ create mode 100644 fs/orangefs/pvfs2-cache.c
+ create mode 100644 fs/orangefs/pvfs2-debug.h
+ create mode 100644 fs/orangefs/pvfs2-debugfs.c
+ create mode 100644 fs/orangefs/pvfs2-debugfs.h
+ create mode 100644 fs/orangefs/pvfs2-dev-proto.h
+ create mode 100644 fs/orangefs/pvfs2-kernel.h
+ create mode 100644 fs/orangefs/pvfs2-mod.c
+ create mode 100644 fs/orangefs/pvfs2-sysfs.c
+ create mode 100644 fs/orangefs/pvfs2-sysfs.h
+ create mode 100644 fs/orangefs/pvfs2-utils.c
+ create mode 100644 fs/orangefs/super.c
+ create mode 100644 fs/orangefs/symlink.c
+ create mode 100644 fs/orangefs/upcall.h
+ create mode 100644 fs/orangefs/waitqueue.c
+ create mode 100644 fs/orangefs/xattr.c
+Merging overlayfs/overlayfs-next (cdb672795876 ovl: lookup whiteouts outside iterate_dir())
+$ git merge overlayfs/overlayfs-next
+Already up-to-date.
+Merging squashfs/master (62421645bb70 Squashfs: Add LZ4 compression configuration option)
+$ git merge squashfs/master
+Already up-to-date.
+Merging v9fs/for-next (46cfbe8e037a 9p: trans_fd, bail out if recv fcall if missing)
+$ git merge v9fs/for-next
+Merge made by the 'recursive' strategy.
+ net/9p/trans_fd.c     | 88 +++++++++++++++++++++++++++------------------------
+ net/9p/trans_virtio.c |  2 +-
+ 2 files changed, 47 insertions(+), 43 deletions(-)
+Merging ubifs/linux-next (071a1f837f72 UGIFS: fix a typo in comment of ubifs_budget_req)
+$ git merge ubifs/linux-next
+Merge made by the 'recursive' strategy.
+ fs/ubifs/lpt.c   | 6 ++----
+ fs/ubifs/tnc.c   | 3 +--
+ fs/ubifs/ubifs.h | 4 ++--
+ 3 files changed, 5 insertions(+), 8 deletions(-)
+Merging xfs/for-next (5d54b8cdeaf4 Merge branch 'xfs-misc-fixes-for-4.3-4' into for-next)
+$ git merge xfs/for-next
+Already up-to-date.
+Merging file-locks/linux-next (ee296d7c5709 locks: inline posix_lock_file_wait and flock_lock_file_wait)
+$ git merge file-locks/linux-next
+Already up-to-date.
+Merging vfs/for-next (397d425dc26d vfs: Test for and handle paths that are unreachable from their mnt_root)
+$ git merge vfs/for-next
+Already up-to-date.
+Merging pci/next (9ca678d1dff6 Merge branches 'pci/enumeration' and 'pci/misc' into next)
+$ git merge pci/next
+Already up-to-date.
+Merging hid/for-next (c5a0db1eed32 Merge branch 'for-4.3/wacom' into for-next)
+$ git merge hid/for-next
+Merge made by the 'recursive' strategy.
+Merging i2c/i2c/for-next (f5956abbe430 Merge branch 'i2c/for-4.3' into i2c/for-next)
+$ git merge i2c/i2c/for-next
+Merge made by the 'recursive' strategy.
+ drivers/i2c/busses/i2c-imx.c | 76 +++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 65 insertions(+), 11 deletions(-)
+Merging jdelvare-hwmon/master (902fd32b7711 hwmon: (k10temp) Remove duplicate pci-id define)
+$ git merge jdelvare-hwmon/master
+Merge made by the 'recursive' strategy.
+ drivers/hwmon/k10temp.c | 1 -
+ 1 file changed, 1 deletion(-)
+Merging dmi/master (1dc51b828800 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs)
+$ git merge dmi/master
+Already up-to-date.
+Merging hwmon-staging/hwmon-next (1b1165fa06db hwmon: Driver for Maxim MAX31790)
+$ git merge hwmon-staging/hwmon-next
+Merge made by the 'recursive' strategy.
+ Documentation/hwmon/max31790 |  37 +++
+ Documentation/hwmon/nct6775  |   4 +
+ drivers/hwmon/Kconfig        |  14 +-
+ drivers/hwmon/Makefile       |   1 +
+ drivers/hwmon/max31790.c     | 603 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/hwmon/nct6775.c      |  64 +++--
+ 6 files changed, 699 insertions(+), 24 deletions(-)
+ create mode 100644 Documentation/hwmon/max31790
+ create mode 100644 drivers/hwmon/max31790.c
+Merging v4l-dvb/master (41a8f406dacd Merge branch 'missed' into to_next)
+$ git merge v4l-dvb/master
+Resolved 'mm/Makefile' using previous resolution.
+Auto-merging mm/Makefile
+CONFLICT (content): Merge conflict in mm/Makefile
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 9ebc4b585b79] Merge remote-tracking branch 'v4l-dvb/master'
+$ git diff -M --stat --summary HEAD^..
+Merging kbuild/for-next (a8503631df45 Merge branch 'kbuild/kbuild' into kbuild/for-next)
+$ git merge kbuild/for-next
+Auto-merging lib/Kconfig.debug
+Auto-merging init/Kconfig
+Auto-merging arch/x86/Kconfig
+Auto-merging Makefile
+Merge made by the 'recursive' strategy.
+ Documentation/lto-build  | 173 +++++++++++++++++++++++++++++++++++++++++++++++
+ Makefile                 |  19 +++++-
+ arch/x86/Kconfig         |   2 +-
+ init/Kconfig             |  73 ++++++++++++++++++++
+ kernel/gcov/Kconfig      |   2 +-
+ lib/Kconfig.debug        |   2 +-
+ scripts/Makefile.lto     |  84 +++++++++++++++++++++++
+ scripts/Makefile.modpost |   7 +-
+ scripts/link-vmlinux.sh  |   2 +-
+ 9 files changed, 356 insertions(+), 8 deletions(-)
+ create mode 100644 Documentation/lto-build
+ create mode 100644 scripts/Makefile.lto
+Merging kconfig/for-next (c0ddc8c745b7 localmodconfig: Use Kbuild files too)
+$ git merge kconfig/for-next
+Already up-to-date.
+Merging libata/for-next (88622d80af82 ata: pata_pxa: dmaengine conversion)
+$ git merge libata/for-next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/ata/ahci-fsl-qoriq.txt     |  21 ++
+ .../devicetree/bindings/ata/ahci-platform.txt      |   2 -
+ drivers/ata/Kconfig                                |   9 +
+ drivers/ata/Makefile                               |   1 +
+ drivers/ata/ahci_platform.c                        |   1 -
+ drivers/ata/ahci_qoriq.c                           | 272 +++++++++++++++++++++
+ drivers/ata/pata_pxa.c                             | 171 +++++--------
+ 7 files changed, 362 insertions(+), 115 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
+ create mode 100644 drivers/ata/ahci_qoriq.c
+Merging pm/linux-next (d9ef4fce71bc Merge branch 'pm-cpufreq' into linux-next)
+$ git merge pm/linux-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging idle/next (aba5686671dc Merge branch 'cpuidle' into release)
+$ git merge idle/next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging apm/for-next (53675abbd1e5 x86, apm: Remove unused variable)
+$ git merge apm/for-next
+Already up-to-date.
+Merging thermal/next (5a924a07f882 Merge branches 'thermal-core' and 'thermal-intel' of .git into next)
+$ git merge thermal/next
+Already up-to-date.
+Merging thermal-soc/next (a794b4f32921 Merge tag 'for-linus-4.3' of git://git.code.sf.net/p/openipmi/linux-ipmi)
+$ git merge thermal-soc/next
+Already up-to-date.
+Merging ieee1394/for-next (d71e6a11737f firewire: core: use correct vendor/model IDs)
+$ git merge ieee1394/for-next
+Already up-to-date.
+Merging dlm/next (b3a5bbfd780d dlm: print error from kernel_sendpage)
+$ git merge dlm/next
+Already up-to-date.
+Merging swiotlb/linux-next (023600f192be swiotlb: do not export map_single function)
+$ git merge swiotlb/linux-next
+Already up-to-date.
+Merging slave-dma/next (f53d906c6323 Merge branch 'for-linus' into next)
+$ git merge slave-dma/next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging net-next/master (64d1def7d338 Merge tag 'sound-fix-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound)
+$ git merge net-next/master
+Already up-to-date.
+Merging ipsec-next/master (e69948a0a530 net: Document xfrm4_gc_thresh and xfrm6_gc_thresh)
+$ git merge ipsec-next/master
+Already up-to-date.
+Merging wireless-drivers-next/master (0ba3ac03c1f3 Merge ath-next from ath.git)
+$ git merge wireless-drivers-next/master
+Already up-to-date.
+Merging bluetooth/master (c258b966b5d6 Bluetooth: bt3c_cs: clean up obsolete functions)
+$ git merge bluetooth/master
+Merge made by the 'recursive' strategy.
+ Documentation/networking/ieee802154.txt |   8 +-
+ drivers/bluetooth/bt3c_cs.c             |  12 +-
+ drivers/bluetooth/btintel.c             |  46 +++
+ drivers/bluetooth/btintel.h             |  10 +-
+ drivers/bluetooth/btmrvl_main.c         |  14 -
+ drivers/bluetooth/btusb.c               |  51 +--
+ drivers/bluetooth/hci_bcm.c             | 222 +++++++++---
+ drivers/bluetooth/hci_intel.c           | 590 ++++++++++++++++++++++++++++----
+ drivers/bluetooth/hci_qca.c             |   6 +-
+ drivers/net/ieee802154/Kconfig          |   7 +
+ drivers/net/ieee802154/at86rf230.c      | 195 ++++++++---
+ drivers/net/ieee802154/at86rf230.h      |   8 +
+ drivers/net/ieee802154/atusb.c          |  13 +-
+ include/linux/ieee802154.h              |  25 ++
+ include/net/6lowpan.h                   | 144 ++------
+ include/net/af_ieee802154.h             |   2 +-
+ include/net/bluetooth/bluetooth.h       |   7 +
+ include/net/bluetooth/hci_core.h        |   1 +
+ include/net/mac802154.h                 |  15 +
+ net/6lowpan/iphc.c                      |  13 +-
+ net/6lowpan/nhc_udp.c                   |  13 +-
+ net/bluetooth/hci_core.c                |   5 +-
+ net/bluetooth/hci_sock.c                |  11 +-
+ net/bluetooth/smp.c                     |  14 +-
+ net/ieee802154/6lowpan/6lowpan_i.h      |  14 +-
+ net/ieee802154/6lowpan/core.c           | 116 ++++---
+ net/ieee802154/6lowpan/reassembly.c     | 157 ++++++---
+ net/ieee802154/6lowpan/rx.c             | 352 ++++++++++++++-----
+ net/ieee802154/6lowpan/tx.c             |  51 +--
+ 29 files changed, 1567 insertions(+), 555 deletions(-)
+$ git am -3 ../patches/drivers-net-ieee802154-at86rf230c-seq_printf-now-returns-null.patch
+Applying: drivers/net/ieee802154/at86rf230.c: seq_printf() now returns NULL
+$ git reset HEAD^
+Unstaged changes after reset:
+M	drivers/net/ieee802154/at86rf230.c
+$ git add -A .
+$ git commit -v -a --amend
+[master f4063617ca0f] Merge remote-tracking branch 'bluetooth/master'
+ Date: Mon Sep 14 09:53:28 2015 +1000
+$ git am -3 ../patches/drivers-net-ieee802154-at86rf230c-seq_printf-now-returns-null-fix.patch
+Applying: drivers-net-ieee802154-at86rf230c-seq_printf-now-returns-null-fix
+$ git reset HEAD^
+Unstaged changes after reset:
+M	drivers/net/ieee802154/at86rf230.c
+$ git add -A .
+$ git commit -v -a --amend
+[master d0715ac5d271] Merge remote-tracking branch 'bluetooth/master'
+ Date: Mon Sep 14 09:53:28 2015 +1000
+Merging rdma/for-next (64291f7db5bd Linux 4.2)
+$ git merge rdma/for-next
+Already up-to-date.
+Merging mtd/master (2ff46e6fea62 mtd: spi-nor: fix NULL dereference when no match found in spi_nor_ids[])
+$ git merge mtd/master
+Already up-to-date.
+Merging l2-mtd/master (2ff46e6fea62 mtd: spi-nor: fix NULL dereference when no match found in spi_nor_ids[])
+$ git merge l2-mtd/master
+Already up-to-date.
+Merging crypto/master (bf433416e675 crypto: algif_aead - fix for multiple operations on AF_ALG sockets)
+$ git merge crypto/master
+Already up-to-date.
+Merging drm/drm-next (73bf1b7be7aa Merge branch 'drm-next-4.3' of git://people.freedesktop.org/~agd5f/linux into drm-next)
+$ git merge drm/drm-next
+Already up-to-date.
+Merging drm-panel/drm/panel/for-next (a33ee95f8f45 drm/bridge: Put Kconfig entries in a separate menu)
+$ git merge drm-panel/drm/panel/for-next
+Already up-to-date.
+Merging drm-intel/for-linux-next (824257857fd8 drm/i915: Allow DSI dual link to be configured on any pipe)
+$ git merge drm-intel/for-linux-next
+Already up-to-date.
+Merging drm-tegra/drm/tegra/for-next (459cc2c6800b drm/tegra: sor: Add HDMI support)
+$ git merge drm-tegra/drm/tegra/for-next
+Already up-to-date.
+Merging drm-misc/topic/drm-misc (216c59d65f99 drm/atomic-helper: Don't skip plane disabling on active CRTC)
+$ git merge drm-misc/topic/drm-misc
+Resolved 'drivers/gpu/drm/drm_dp_helper.c' using previous resolution.
+Auto-merging drivers/gpu/drm/i915/intel_display.c
+Auto-merging drivers/gpu/drm/i915/intel_audio.c
+Auto-merging drivers/gpu/drm/drm_dp_helper.c
+CONFLICT (content): Merge conflict in drivers/gpu/drm/drm_dp_helper.c
+Auto-merging drivers/gpu/drm/drm_atomic_helper.c
+Auto-merging drivers/gpu/drm/drm_atomic.c
+Auto-merging Documentation/kernel-parameters.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 9550c8524130] Merge remote-tracking branch 'drm-misc/topic/drm-misc'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/kernel-parameters.txt             |  15 +-
+ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |   4 +-
+ drivers/gpu/drm/drm_atomic.c                    |  25 ++++
+ drivers/gpu/drm/drm_atomic_helper.c             | 185 ++++++++++++++++++++----
+ drivers/gpu/drm/drm_crtc.c                      |  18 ++-
+ drivers/gpu/drm/drm_dp_helper.c                 |  43 +++++-
+ drivers/gpu/drm/drm_drv.c                       |   8 +-
+ drivers/gpu/drm/drm_edid.c                      |   8 +-
+ drivers/gpu/drm/drm_edid_load.c                 |  43 ++++--
+ drivers/gpu/drm/drm_fb_helper.c                 |  48 +++++-
+ drivers/gpu/drm/drm_internal.h                  |   2 +-
+ drivers/gpu/drm/drm_mm.c                        |   6 +-
+ drivers/gpu/drm/drm_modeset_lock.c              |   2 +
+ drivers/gpu/drm/drm_plane_helper.c              |   6 +-
+ drivers/gpu/drm/drm_sysfs.c                     |  49 +++----
+ drivers/gpu/drm/exynos/exynos_drm_drv.c         |   2 +-
+ drivers/gpu/drm/i2c/ch7006_drv.c                |   6 +-
+ drivers/gpu/drm/i2c/ch7006_mode.c               |  26 ++--
+ drivers/gpu/drm/i2c/ch7006_priv.h               |  12 +-
+ drivers/gpu/drm/i915/intel_audio.c              |   2 +-
+ drivers/gpu/drm/i915/intel_display.c            |   9 +-
+ drivers/gpu/drm/i915/intel_dp.c                 |   1 +
+ drivers/gpu/drm/i915/intel_drv.h                |   2 -
+ drivers/gpu/drm/i915/intel_tv.c                 |   4 +-
+ drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c       |  10 +-
+ drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c       |  10 +-
+ drivers/gpu/drm/msm/msm_atomic.c                |   2 +-
+ drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c  |   2 +-
+ drivers/gpu/drm/nouveau/dispnv04/tvnv17.h       |   2 +-
+ drivers/gpu/drm/omapdrm/omap_drv.c              |   2 +-
+ drivers/gpu/drm/omapdrm/omap_plane.c            |  10 +-
+ drivers/gpu/drm/radeon/atombios_dp.c            |   1 +
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c           |   2 +-
+ drivers/gpu/drm/sti/sti_drv.c                   |   2 +-
+ drivers/gpu/drm/tegra/dc.c                      |   2 -
+ drivers/gpu/drm/tegra/dpaux.c                   |   3 +-
+ drivers/gpu/drm/tegra/drm.c                     |   2 +-
+ include/drm/drm_atomic_helper.h                 |   6 +-
+ include/drm/drm_crtc.h                          |   4 +-
+ include/drm/drm_dp_helper.h                     |   2 +-
+ include/drm/drm_edid.h                          |   5 +-
+ include/drm/drm_fb_helper.h                     |   6 +-
+ include/drm/drm_modeset_lock.h                  |  10 +-
+ include/drm/drm_plane_helper.h                  |   2 -
+ include/uapi/drm/drm_mode.h                     |  42 ++++--
+ 45 files changed, 469 insertions(+), 184 deletions(-)
+Merging drm-exynos/exynos-drm/for-next (7d9071a09502 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs)
+$ git merge drm-exynos/exynos-drm/for-next
+Already up-to-date.
+Merging drm-msm/msm-next (d248b61f6114 drm/msm/dsi: Introduce DSI configuration module)
+$ git merge drm-msm/msm-next
+Already up-to-date.
+Merging sound/for-next (0052b7dcf9d9 ALSA: pcm: remove structure member of 'struct snd_pcm_hwptr_log *' type because this structure had been removed)
+$ git merge sound/for-next
+Merge made by the 'recursive' strategy.
+ include/sound/pcm.h      | 6 ------
+ sound/core/pcm.c         | 3 ---
+ sound/pci/rme9652/hdsp.c | 1 +
+ 3 files changed, 1 insertion(+), 9 deletions(-)
+Merging sound-asoc/for-next (d1abb17624f9 Merge remote-tracking branch 'asoc/fix/wm8960' into asoc-linus)
+$ git merge sound-asoc/for-next
+Merge made by the 'recursive' strategy.
+ sound/soc/codecs/rt5645.c                 |  7 +++++++
+ sound/soc/codecs/wm0010.c                 |  8 +++++++-
+ sound/soc/codecs/wm8960.c                 | 26 ++++++++++++++++++--------
+ sound/soc/fsl/fsl-asoc-card.c             |  3 ++-
+ sound/soc/intel/haswell/sst-haswell-ipc.c | 20 ++++++++++++--------
+ sound/soc/soc-dapm.c                      |  2 +-
+ sound/soc/soc-utils.c                     |  9 +++++++++
+ sound/soc/sti/uniperif_player.c           | 14 ++++++++++----
+ sound/soc/sti/uniperif_reader.c           |  6 +++++-
+ 9 files changed, 71 insertions(+), 24 deletions(-)
+Merging modules/modules-next (5cfb203a304d modpost: abort if a module symbol is too long)
+$ git merge modules/modules-next
+Merge made by the 'recursive' strategy.
+ scripts/mod/modpost.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+Merging input/next (ade9c1a47c81 Input: imx_keypad - remove obsolete comment)
+$ git merge input/next
+Already up-to-date.
+Merging block/for-next (3cb73014ad06 Merge branch 'for-4.3/core' into for-next)
+$ git merge block/for-next
+Merge made by the 'recursive' strategy.
+Merging device-mapper/for-next (9efb520a57f1 dm thin: disable discard support for thin devices if pool's is disabled)
+$ git merge device-mapper/for-next
+Auto-merging drivers/md/dm-thin.c
+Merge made by the 'recursive' strategy.
+ drivers/md/dm-thin.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+Merging pcmcia/master (e8e68fd86d22 pcmcia: do not break rsrc_nonstatic when handling anonymous cards)
+$ git merge pcmcia/master
+Already up-to-date.
+Merging mmc/mmc-next (11bc9381b277 mmc: sdhci-s3c: use mmc_of_parse and remove the card_tasklet)
+$ git merge mmc/mmc-next
+Already up-to-date.
+Merging mmc-uh/next (b8889c4fc6ba Merge tag 'tty-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty)
+$ git merge mmc-uh/next
+Already up-to-date.
+Merging kgdb/kgdb-next (2d289f14f00a kdb: Fix handling of kallsyms_symbol_next() return value)
+$ git merge kgdb/kgdb-next
+Merge made by the 'recursive' strategy.
+ kernel/debug/kdb/kdb_io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Merging md/for-next (e89c6fdf9e0e Merge linux-block/for-4.3/core into md/for-linux)
+$ git merge md/for-next
+Already up-to-date.
+Merging mfd/for-mfd-next (5a688c455066 mfd: jz4740-adc: Init mask cache in generic IRQ chip)
+$ git merge mfd/for-mfd-next
+Already up-to-date.
+Merging backlight/for-backlight-next (13d20b3b618a backlight: tosa: Export I2C module alias information)
+$ git merge backlight/for-backlight-next
+Already up-to-date.
+Merging battery/master (e11fc21e756e twl4030_charger: fix another compile error)
+$ git merge battery/master
+Merge made by the 'recursive' strategy.
+ drivers/power/twl4030_charger.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+Merging omap_dss2/for-next (7b554088d56e video: fbdev: pxa168fb: Use devm_clk_get)
+$ git merge omap_dss2/for-next
+Already up-to-date.
+Merging regulator/for-next (f39628069744 Merge remote-tracking branch 'regulator/fix/pbias' into regulator-linus)
+$ git merge regulator/for-next
+Auto-merging drivers/regulator/core.c
+Merge made by the 'recursive' strategy.
+ .../bindings/regulator/pbias-regulator.txt         |  7 ++-
+ drivers/regulator/core.c                           |  5 +-
+ drivers/regulator/pbias-regulator.c                | 56 +++++++++++++++++++---
+ 3 files changed, 58 insertions(+), 10 deletions(-)
+Merging security/next (07f081fb5057 PKCS#7: Add OIDs for sha224, sha284 and sha512 hash algos and use them)
+$ git merge security/next
+Already up-to-date.
+Merging integrity/next (24fd03c87695 ima: update builtin policies)
+$ git merge integrity/next
+Already up-to-date.
+Merging selinux/next (fda4d578ed0a selinux: explicitly declare the role "base_r")
+$ git merge selinux/next
+Already up-to-date.
+Merging lblnet/next (b2776bf7149b Linux 3.18)
+$ git merge lblnet/next
+Already up-to-date.
+Merging watchdog/master (330de3d85671 Watchdog: Fix parent of watchdog_devices)
+$ git merge watchdog/master
+Merge made by the 'recursive' strategy.
+Merging iommu/next (4ad79562577a Merge branches 'arm/omap', 'arm/msm', 'arm/smmu', 'arm/tegra', 'x86/vt-d', 'x86/amd', 'ppc/pamu' and 'core' into next)
+$ git merge iommu/next
+Already up-to-date.
+Merging dwmw2-iommu/master (5dbaf90a6780 iommu/vt-d: Add initial shell of SVM support)
+$ git merge dwmw2-iommu/master
+Auto-merging include/linux/intel-iommu.h
+Auto-merging drivers/iommu/intel-iommu.c
+Auto-merging drivers/iommu/Kconfig
+Merge made by the 'recursive' strategy.
+ drivers/iommu/Kconfig       |  10 +++-
+ drivers/iommu/Makefile      |   1 +
+ drivers/iommu/intel-iommu.c |  19 +++++--
+ drivers/iommu/intel-svm.c   |  71 ++++++++++++++++++++++++++
+ drivers/iommu/iova.c        | 120 +++++++++++++++++++++++++-------------------
+ include/linux/intel-iommu.h |  15 ++++++
+ include/linux/iova.h        |   4 +-
+ 7 files changed, 183 insertions(+), 57 deletions(-)
+ create mode 100644 drivers/iommu/intel-svm.c
+Merging vfio/next (a714ea5fa416 MAINTAINERS: Add vfio-platform sub-maintainer)
+$ git merge vfio/next
+Already up-to-date.
+Merging jc_docs/docs-next (4d73270192ec scripts/kernel-doc: Replacing highlights hash by an array)
+$ git merge jc_docs/docs-next
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ Documentation/DocBook/.gitignore            |   2 +
+ Documentation/filesystems/sysfs-tagging.txt |  14 ++--
+ Documentation/filesystems/sysfs.txt         |   9 ++-
+ Documentation/locking/lockstat.txt          |   2 +-
+ Documentation/rbtree.txt                    |   2 +-
+ Documentation/zh_CN/filesystems/sysfs.txt   |   2 +-
+ MAINTAINERS                                 |   2 +
+ scripts/kernel-doc                          | 115 ++++++++++++++++------------
+ 8 files changed, 85 insertions(+), 63 deletions(-)
+Merging trivial/for-next (e5f6450c3f40 MAINTAINERS: update my e-mail address)
+$ git merge trivial/for-next
+Already up-to-date.
+Merging audit/next (15ce414b82b0 fixup: audit: implement audit by executable)
+$ git merge audit/next
+Already up-to-date.
+Merging devicetree/devicetree/next (48a9b733e644 of/irq: Rename "intc_desc" to "of_intc_desc" to fix OF on sh)
+$ git merge devicetree/devicetree/next
+Already up-to-date.
+Merging dt-rh/for-next (c8fb70a3e8dd MAINTAINERS: Add Frank Rowand as DT maintainer)
+$ git merge dt-rh/for-next
+Already up-to-date.
+Merging mailbox/mailbox-for-next (86e488adaab7 mailbox: arm_mhu: reduce txpoll_period from 10ms to 1 ms)
+$ git merge mailbox/mailbox-for-next
+Already up-to-date.
+Merging spi/for-next (4509c0452261 Merge remote-tracking branches 'spi/fix/atmel', 'spi/fix/bcm2835', 'spi/fix/doc', 'spi/fix/mediatek', 'spi/fix/mtk', 'spi/fix/pxa2xx' and 'spi/fix/spidev' into spi-linus)
+$ git merge spi/for-next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/spi/spi-mt65xx.txt         | 16 ++++---
+ drivers/spi/spi-atmel.c                            |  2 +
+ drivers/spi/spi-bcm2835.c                          |  6 +--
+ drivers/spi/spi-mt65xx.c                           | 51 ++++++++++------------
+ drivers/spi/spi-pxa2xx.c                           |  4 ++
+ drivers/spi/spi.c                                  |  3 +-
+ drivers/spi/spidev.c                               |  3 +-
+ 7 files changed, 44 insertions(+), 41 deletions(-)
+Merging tip/auto-latest (b84834af3560 Merge branch 'x86/urgent')
+$ git merge tip/auto-latest
+Auto-merging init/Kconfig
+Merge made by the 'recursive' strategy.
+ Documentation/atomic_ops.txt                       |   4 +
+ Documentation/static-keys.txt                      |   2 +-
+ arch/powerpc/perf/core-book3s.c                    |  36 +-
+ arch/powerpc/perf/hv-24x7.c                        | 166 +++-
+ arch/s390/kernel/perf_cpum_cf.c                    |  35 +-
+ arch/sparc/kernel/perf_event.c                     |  32 +-
+ arch/x86/ia32/ia32_signal.c                        |   8 +-
+ arch/x86/include/asm/cpufeature.h                  |   1 +
+ arch/x86/include/asm/fpu/signal.h                  |   2 +-
+ arch/x86/include/asm/ia32.h                        |   4 +-
+ arch/x86/include/asm/processor.h                   |   2 +-
+ arch/x86/include/asm/qspinlock.h                   |  19 +-
+ arch/x86/include/asm/sigcontext.h                  |  75 +-
+ arch/x86/include/asm/sigframe.h                    |   8 +-
+ arch/x86/include/asm/signal.h                      |   2 +-
+ arch/x86/include/asm/uv/uv_hub.h                   |   2 +-
+ arch/x86/include/uapi/asm/sigcontext.h             | 456 +++++++----
+ arch/x86/include/uapi/asm/sigcontext32.h           |  73 +-
+ arch/x86/kernel/alternative.c                      |   5 +
+ arch/x86/kernel/asm-offsets.c                      |  18 +-
+ arch/x86/kernel/cpu/common.c                       |   4 +-
+ arch/x86/kernel/cpu/perf_event.c                   |  39 +-
+ arch/x86/kernel/cpu/perf_event.h                   |   2 +-
+ arch/x86/kernel/cpu/perf_event_intel.c             |   5 +-
+ arch/x86/kernel/cpu/perf_event_intel_bts.c         |  14 +
+ arch/x86/kernel/cpu/perf_event_intel_ds.c          |  40 +-
+ arch/x86/kernel/cpu/perf_event_intel_lbr.c         |   5 +-
+ arch/x86/kernel/cpu/perf_event_intel_pt.c          |   7 +-
+ arch/x86/kernel/fpu/signal.c                       |   4 +-
+ arch/x86/kernel/signal.c                           |   4 +-
+ arch/x86/kernel/tsc.c                              |  24 +-
+ arch/x86/kernel/vm86_32.c                          |  27 +
+ arch/x86/lib/x86-opcode-map.txt                    |  24 +-
+ arch/x86/math-emu/fpu_emu.h                        |   2 +-
+ arch/x86/mm/srat.c                                 |   5 +-
+ arch/x86/platform/uv/uv_nmi.c                      |  53 +-
+ drivers/net/ethernet/sfc/mcdi.c                    |   2 +-
+ drivers/phy/phy-rcar-gen2.c                        |   3 +-
+ drivers/staging/speakup/selection.c                |   2 +-
+ include/asm-generic/qspinlock.h                    |   4 +-
+ include/linux/jump_label.h                         |   2 +-
+ include/linux/perf_event.h                         | 120 ++-
+ include/linux/sched.h                              |   8 +-
+ include/linux/tick.h                               |   9 +
+ init/Kconfig                                       |   3 +
+ kernel/cpu.c                                       |   8 +-
+ kernel/events/core.c                               | 218 +++--
+ kernel/locking/qspinlock.c                         |   2 +-
+ kernel/sched/core.c                                |  68 +-
+ kernel/sched/fair.c                                | 386 ++++-----
+ kernel/sched/features.h                            |  21 +-
+ kernel/sched/sched.h                               |  25 +-
+ kernel/time/clocksource.c                          |   2 +-
+ kernel/time/hrtimer.c                              |   2 +-
+ kernel/time/tick-sched.c                           |  15 +-
+ kernel/time/timekeeping.c                          |   6 +-
+ security/device_cgroup.c                           |   2 +-
+ tools/include/linux/filter.h                       | 231 ++++++
+ tools/lib/api/fs/Build                             |   1 +
+ tools/lib/api/fs/debugfs.c                         |  52 --
+ tools/lib/api/fs/fs.c                              | 117 ++-
+ tools/lib/api/fs/fs.h                              |  26 +-
+ tools/lib/api/fs/tracing_path.c                    | 137 ++++
+ tools/lib/api/fs/tracing_path.h                    |  16 +
+ tools/lib/traceevent/event-parse.c                 |  56 +-
+ tools/lib/traceevent/event-parse.h                 |   1 +
+ tools/perf/MANIFEST                                |   1 +
+ tools/perf/arch/x86/util/intel-pt.c                |  55 +-
+ tools/perf/builtin-probe.c                         | 110 ++-
+ tools/perf/builtin-script.c                        |   4 +-
+ tools/perf/builtin-stat.c                          |   2 +-
+ tools/perf/builtin-trace.c                         |   5 +-
+ tools/perf/perf.c                                  |  12 +-
+ tools/perf/tests/Build                             |   3 +
+ tools/perf/tests/builtin-test.c                    |   8 +
+ tools/perf/tests/gen-insn-x86-dat.awk              |  75 ++
+ tools/perf/tests/gen-insn-x86-dat.sh               |  43 +
+ tools/perf/tests/insn-x86-dat-32.c                 | 658 ++++++++++++++++
+ tools/perf/tests/insn-x86-dat-64.c                 | 768 ++++++++++++++++++
+ tools/perf/tests/insn-x86-dat-src.c                | 877 +++++++++++++++++++++
+ tools/perf/tests/insn-x86.c                        | 184 +++++
+ tools/perf/tests/tests.h                           |   1 +
+ tools/perf/trace/strace/groups/file                |   2 +
+ tools/perf/util/cpumap.c                           |  51 +-
+ tools/perf/util/cpumap.h                           |   2 +
+ tools/perf/util/header.c                           |  94 ++-
+ tools/perf/util/header.h                           |   6 +
+ tools/perf/util/intel-bts.c                        |   2 +-
+ tools/perf/util/intel-pt-decoder/Build             |  13 +-
+ .../perf/util/intel-pt-decoder/x86-opcode-map.txt  |  24 +-
+ tools/perf/util/intel-pt.c                         | 131 ++-
+ tools/perf/util/parse-events.c                     |   2 +-
+ tools/perf/util/parse-events.y                     |   2 +-
+ tools/perf/util/probe-event.c                      |  97 +--
+ tools/perf/util/probe-event.h                      |   9 +
+ tools/perf/util/probe-file.c                       |  41 +-
+ tools/perf/util/probe-file.h                       |   4 +
+ .../perf/util/scripting-engines/trace-event-perl.c |   1 +
+ .../util/scripting-engines/trace-event-python.c    |   1 +
+ tools/perf/util/session.c                          |   3 +-
+ tools/perf/util/sort.c                             |   4 +-
+ tools/perf/util/srcline.c                          |  29 +-
+ tools/perf/util/trace-event-info.c                 |   2 +-
+ tools/perf/util/trace-event.c                      |   1 +
+ tools/perf/util/util.c                             |  70 --
+ tools/perf/util/util.h                             |   8 +-
+ tools/testing/selftests/x86/entry_from_vm86.c      |   5 +-
+ 107 files changed, 5107 insertions(+), 1057 deletions(-)
+ create mode 100644 tools/include/linux/filter.h
+ create mode 100644 tools/lib/api/fs/tracing_path.c
+ create mode 100644 tools/lib/api/fs/tracing_path.h
+ create mode 100644 tools/perf/tests/gen-insn-x86-dat.awk
+ create mode 100755 tools/perf/tests/gen-insn-x86-dat.sh
+ create mode 100644 tools/perf/tests/insn-x86-dat-32.c
+ create mode 100644 tools/perf/tests/insn-x86-dat-64.c
+ create mode 100644 tools/perf/tests/insn-x86-dat-src.c
+ create mode 100644 tools/perf/tests/insn-x86.c
+Merging clockevents/clockevents/next (e4485500949c clocksource/drivers/mediatek: Use GPT as sched clock source)
+$ git merge clockevents/clockevents/next
+Merge made by the 'recursive' strategy.
+ drivers/clocksource/mtk_timer.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+Merging edac/linux_next (12f0721c5a70 sb_edac: correctly fetch DIMM width on Ivy Bridge and Haswell)
+$ git merge edac/linux_next
+Already up-to-date.
+Merging edac-amd/for-next (99e1dfb7d209 EDAC, mce_amd: Don't emit 'CE' for Deferred error)
+$ git merge edac-amd/for-next
+Already up-to-date.
+Merging irqchip/irqchip/for-next (a8bcdc32fafb Merge branch 'irqchip/core' into irqchip/for-next)
+$ git merge irqchip/irqchip/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging tiny/tiny/next (f114040e3ea6 Linux 3.18-rc1)
+$ git merge tiny/tiny/next
+Already up-to-date.
+Merging ftrace/for-next (b7dc42fd7939 ring-buffer: Revert "ring-buffer: Get timestamp after event is allocated")
+$ git merge ftrace/for-next
+Already up-to-date.
+Merging rcu/rcu/next (dc3a04d551b5 security/device_cgroup: Fix RCU_LOCKDEP_WARN() condition)
+$ git merge rcu/rcu/next
+Already up-to-date.
+Merging kvm/linux-next (ba60c41ae392 kvm: irqchip: fix memory leak)
+$ git merge kvm/linux-next
+Already up-to-date.
+Merging kvm-arm/next (0c0672922dcc arm/arm64: KVM: Fix PSCI affinity info return value for non valid cores)
+$ git merge kvm-arm/next
+Merge made by the 'recursive' strategy.
+ arch/arm/kvm/psci.c              | 12 ++++++++----
+ arch/arm64/include/asm/kvm_arm.h | 10 +++++++---
+ virt/kvm/arm/arch_timer.c        |  8 ++++++++
+ virt/kvm/arm/vgic.c              | 42 +++++++++++++++++++++++++---------------
+ 4 files changed, 49 insertions(+), 23 deletions(-)
+Merging kvm-ppc/kvm-ppc-next (c63517c2e381 KVM: PPC: Book3S: correct width in XER handling)
+$ git merge kvm-ppc/kvm-ppc-next
+Already up-to-date.
+Merging kvm-ppc-paulus/kvm-ppc-next (4e33d1f0a145 KVM: PPC: Book3S: Fix typo in top comment about locking)
+$ git merge kvm-ppc-paulus/kvm-ppc-next
+Already up-to-date.
+Merging kvms390/next (152b28392a8d KVM: s390: Fix assumption that kvm_set_irq_routing is always run successfully)
+$ git merge kvms390/next
+Already up-to-date.
+Merging xen-tip/linux-next (3e64472c1c74 xen: switch extra memory accounting to use pfns)
+$ git merge xen-tip/linux-next
+Resolved 'arch/x86/include/asm/xen/page.h' using previous resolution.
+Auto-merging arch/x86/include/asm/xen/page.h
+CONFLICT (content): Merge conflict in arch/x86/include/asm/xen/page.h
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 82578c320ad8] Merge remote-tracking branch 'xen-tip/linux-next'
+$ git diff -M --stat --summary HEAD^..
+Merging percpu/for-next (292c24a073ee percpu: clean up of schunk->map[] assignment in pcpu_setup_first_chunk)
+$ git merge percpu/for-next
+Already up-to-date.
+Merging workqueues/for-next (355c06633e23 workqueue: fix some docbook warnings)
+$ git merge workqueues/for-next
+Already up-to-date.
+Merging drivers-x86/for-next (85b4e4eb2f9a wmi: Remove private %pUL implementation)
+$ git merge drivers-x86/for-next
+Merge made by the 'recursive' strategy.
+ drivers/platform/x86/asus-nb-wmi.c | 18 ++++++++++++++
+ drivers/platform/x86/wmi.c         | 51 +++++---------------------------------
+ 2 files changed, 24 insertions(+), 45 deletions(-)
+Merging chrome-platform/for-next (1d95e6f10fd8 platform/chrome: cros_ec: Fix possible leak in led_rgb_store())
+$ git merge chrome-platform/for-next
+Merge made by the 'recursive' strategy.
+ drivers/platform/chrome/Kconfig            |  5 +++--
+ drivers/platform/chrome/cros_ec_dev.c      |  6 ++++++
+ drivers/platform/chrome/cros_ec_lightbar.c | 31 ++++++++++++++++--------------
+ drivers/platform/chrome/cros_ec_lpc.c      | 21 +++++++++-----------
+ 4 files changed, 35 insertions(+), 28 deletions(-)
+Merging regmap/for-next (072502a67c91 Merge remote-tracking branches 'regmap/topic/lockdep' and 'regmap/topic/seq-delay' into regmap-next)
+$ git merge regmap/for-next
+Already up-to-date.
+$ git am -3 ../patches/mfd__Fixup_clients_of_multi_reg_write_register_patch.patch
+Applying: mfd: Fixup clients of multi_reg_write/register_patch
+$ git reset HEAD^
+Unstaged changes after reset:
+M	drivers/mfd/wm5110-tables.c
+M	drivers/mfd/wm8998-tables.c
+$ git add -A .
+$ git commit -v -a --amend
+[master 31175f108caf] Merge remote-tracking branch 'chrome-platform/for-next'
+ Date: Mon Sep 14 10:44:25 2015 +1000
+Merging hsi/for-next (d770e558e219 Linux 4.2-rc1)
+$ git merge hsi/for-next
+Already up-to-date.
+Merging leds/for-next (b0ba362c611f leds:lp55xx: Correct Kconfig dependency for f/w user helper)
+$ git merge leds/for-next
+Auto-merging drivers/leds/leds-max77693.c
+Auto-merging drivers/leds/Kconfig
+Merge made by the 'recursive' strategy.
+ drivers/leds/Kconfig            |  3 ++-
+ drivers/leds/leds-aat1290.c     |  3 ++-
+ drivers/leds/leds-bcm6328.c     |  1 +
+ drivers/leds/leds-bcm6358.c     |  1 +
+ drivers/leds/leds-cobalt-qube.c | 23 +----------------------
+ drivers/leds/leds-hp6xx.c       | 17 ++---------------
+ drivers/leds/leds-ipaq-micro.c  | 27 ++++++++++-----------------
+ drivers/leds/leds-ktd2692.c     |  1 +
+ drivers/leds/leds-max77693.c    |  1 +
+ drivers/leds/leds-ns2.c         |  1 +
+ drivers/leds/leds-ot200.c       | 21 ++-------------------
+ 11 files changed, 24 insertions(+), 75 deletions(-)
+Merging ipmi/for-next (bf2d087749d9 ipmi:ssif: Add a module parm to specify that SMBus alerts don't work)
+$ git merge ipmi/for-next
+Already up-to-date.
+Merging driver-core/driver-core-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge driver-core/driver-core-next
+Already up-to-date.
+Merging tty/tty-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge tty/tty-next
+Already up-to-date.
+Merging usb/usb-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge usb/usb-next
+Already up-to-date.
+Merging usb-gadget/next (2f3cc24f07b8 usb: musb: gadget: fix build break by adding missing 'break')
+$ git merge usb-gadget/next
+Already up-to-date.
+Merging usb-serial/usb-next (26c78daade0f USB: io_ti: Add heartbeat to keep idle EP/416 ports from disconnecting)
+$ git merge usb-serial/usb-next
+Already up-to-date.
+Merging staging/staging-next (e714b7eab150 staging: fbtft: change log level)
+$ git merge staging/staging-next
+Removing drivers/staging/wilc1000/wilc_memory.h
+Removing drivers/staging/wilc1000/wilc_memory.c
+Removing drivers/staging/wilc1000/wilc_exported_buf.c
+Auto-merging drivers/staging/fbtft/flexfb.c
+Auto-merging drivers/staging/fbtft/fbtft-core.c
+Auto-merging drivers/staging/fbtft/fb_watterott.c
+Auto-merging drivers/staging/fbtft/fb_uc1611.c
+Removing drivers/staging/comedi/drivers/unioxx5.c
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ MAINTAINERS                                        |    4 +-
+ drivers/staging/android/Kconfig                    |    2 +-
+ drivers/staging/android/ashmem.c                   |   18 +-
+ drivers/staging/android/sw_sync.c                  |    6 +-
+ drivers/staging/comedi/Kconfig                     |    8 -
+ drivers/staging/comedi/drivers/Makefile            |    1 -
+ drivers/staging/comedi/drivers/addi_apci_3120.c    |    5 -
+ drivers/staging/comedi/drivers/mpc624.c            |   30 +-
+ drivers/staging/comedi/drivers/s526.c              |  560 +++++----
+ drivers/staging/comedi/drivers/serial2002.c        |   51 +-
+ drivers/staging/comedi/drivers/ssv_dnp.c           |   57 +-
+ drivers/staging/comedi/drivers/unioxx5.c           |  506 --------
+ drivers/staging/comedi/drivers/usbdux.c            |  100 +-
+ drivers/staging/comedi/drivers/usbduxfast.c        |  274 ++---
+ drivers/staging/comedi/drivers/usbduxsigma.c       |   72 +-
+ drivers/staging/comedi/drivers/vmk80xx.c           |  127 +-
+ .../staging/comedi/kcomedilib/kcomedilib_main.c    |   32 +-
+ drivers/staging/dgap/dgap.c                        |   32 +-
+ drivers/staging/emxx_udc/emxx_udc.c                |   96 +-
+ drivers/staging/emxx_udc/emxx_udc.h                |   30 -
+ drivers/staging/fbtft/fb_agm1264k-fl.c             |    9 +-
+ drivers/staging/fbtft/fb_bd663474.c                |    7 +-
+ drivers/staging/fbtft/fb_hx8340bn.c                |   16 +-
+ drivers/staging/fbtft/fb_hx8347d.c                 |   12 +-
+ drivers/staging/fbtft/fb_hx8353d.c                 |   15 +-
+ drivers/staging/fbtft/fb_hx8357d.c                 |    8 +-
+ drivers/staging/fbtft/fb_ili9163.c                 |    7 +-
+ drivers/staging/fbtft/fb_ili9320.c                 |   15 +-
+ drivers/staging/fbtft/fb_ili9325.c                 |   14 +-
+ drivers/staging/fbtft/fb_ili9340.c                 |   10 +-
+ drivers/staging/fbtft/fb_ili9341.c                 |   14 +-
+ drivers/staging/fbtft/fb_ili9481.c                 |    8 +-
+ drivers/staging/fbtft/fb_ili9486.c                 |   10 +-
+ drivers/staging/fbtft/fb_pcd8544.c                 |   17 +-
+ drivers/staging/fbtft/fb_ra8875.c                  |   36 +-
+ drivers/staging/fbtft/fb_s6d02a1.c                 |   14 +-
+ drivers/staging/fbtft/fb_s6d1121.c                 |   12 +-
+ drivers/staging/fbtft/fb_ssd1289.c                 |   14 +-
+ drivers/staging/fbtft/fb_ssd1306.c                 |   17 +-
+ drivers/staging/fbtft/fb_ssd1331.c                 |    5 -
+ drivers/staging/fbtft/fb_ssd1351.c                 |   19 +-
+ drivers/staging/fbtft/fb_st7735r.c                 |   18 +-
+ drivers/staging/fbtft/fb_tinylcd.c                 |   10 +-
+ drivers/staging/fbtft/fb_tls8204.c                 |   16 +-
+ drivers/staging/fbtft/fb_uc1611.c                  |    4 -
+ drivers/staging/fbtft/fb_uc1701.c                  |   19 +-
+ drivers/staging/fbtft/fb_upd161704.c               |    7 +-
+ drivers/staging/fbtft/fb_watterott.c               |   24 +-
+ drivers/staging/fbtft/fbtft-bus.c                  |   13 +-
+ drivers/staging/fbtft/fbtft-core.c                 |   91 +-
+ drivers/staging/fbtft/fbtft-sysfs.c                |    6 +-
+ drivers/staging/fbtft/fbtft.h                      |    9 -
+ drivers/staging/fbtft/fbtft_device.c               |   96 +-
+ drivers/staging/fbtft/flexfb.c                     |   10 -
+ drivers/staging/fsl-mc/bus/mc-bus.c                |    6 +-
+ drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c |   19 +-
+ drivers/staging/gdm72xx/gdm_qos.c                  |    2 +-
+ drivers/staging/gdm72xx/gdm_sdio.c                 |   20 +-
+ drivers/staging/gdm72xx/gdm_usb.c                  |   16 +-
+ drivers/staging/gdm72xx/gdm_wimax.c                |    4 +-
+ drivers/staging/gdm72xx/sdio_boot.c                |    4 +-
+ drivers/staging/gdm72xx/usb_boot.c                 |    8 +-
+ drivers/staging/goldfish/goldfish_nand.c           |    4 +-
+ drivers/staging/goldfish/goldfish_nand_reg.h       |   10 +-
+ drivers/staging/iio/addac/adt7316.c                |   14 +-
+ drivers/staging/iio/cdc/ad7746.c                   |    8 +-
+ drivers/staging/iio/meter/ade7753.c                |    8 +-
+ drivers/staging/iio/meter/ade7754.c                |    6 +-
+ drivers/staging/iio/meter/ade7758_core.c           |    6 +-
+ drivers/staging/iio/meter/ade7759.c                |    8 +-
+ drivers/staging/iio/meter/ade7854.c                |    6 +-
+ drivers/staging/lustre/include/linux/lnet/types.h  |    2 +-
+ .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h    |  284 ++---
+ .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    5 +-
+ .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |    8 +-
+ .../lustre/lnet/klnds/socklnd/socklnd_lib.c        |    6 +-
+ drivers/staging/lustre/lnet/lnet/lib-ptl.c         |    4 +-
+ drivers/staging/lustre/lnet/selftest/conrpc.h      |    4 +-
+ drivers/staging/lustre/lnet/selftest/console.c     |   16 +-
+ drivers/staging/lustre/lnet/selftest/selftest.h    |    2 +-
+ drivers/staging/lustre/lustre/include/cl_object.h  |   14 +-
+ .../lustre/lustre/include/linux/lustre_lite.h      |    2 +-
+ .../staging/lustre/lustre/include/lprocfs_status.h |    3 +-
+ drivers/staging/lustre/lustre/include/lu_object.h  |   16 +-
+ .../lustre/lustre/include/lustre/lustre_idl.h      |   12 +-
+ .../lustre/lustre/include/lustre/lustre_user.h     |    7 +-
+ .../staging/lustre/lustre/include/lustre_capa.h    |    2 +-
+ .../staging/lustre/lustre/include/lustre_disk.h    |    2 +-
+ drivers/staging/lustre/lustre/include/lustre_dlm.h |    6 +-
+ .../lustre/lustre/include/lustre_dlm_flags.h       |  152 +--
+ drivers/staging/lustre/lustre/include/lustre_lib.h |    6 +-
+ drivers/staging/lustre/lustre/include/lustre_net.h |    2 +-
+ drivers/staging/lustre/lustre/include/obd.h        |    2 +-
+ .../staging/lustre/lustre/include/obd_support.h    |    2 +-
+ drivers/staging/lustre/lustre/ldlm/ldlm_flock.c    |    8 +-
+ drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 +-
+ drivers/staging/lustre/lustre/libcfs/fail.c        |    4 +-
+ drivers/staging/lustre/lustre/libcfs/hash.c        |   14 +-
+ drivers/staging/lustre/lustre/libcfs/libcfs_lock.c |    6 +-
+ drivers/staging/lustre/lustre/libcfs/libcfs_mem.c  |   10 +-
+ .../lustre/lustre/libcfs/linux/linux-crypto.c      |    5 +-
+ drivers/staging/lustre/lustre/libcfs/tracefile.c   |    4 +-
+ drivers/staging/lustre/lustre/libcfs/workitem.c    |   12 +-
+ drivers/staging/lustre/lustre/llite/dir.c          |   10 +-
+ drivers/staging/lustre/lustre/llite/file.c         |   14 +-
+ drivers/staging/lustre/lustre/llite/llite_close.c  |    5 +-
+ .../staging/lustre/lustre/llite/llite_internal.h   |    2 +-
+ drivers/staging/lustre/lustre/llite/llite_lib.c    |    7 +-
+ drivers/staging/lustre/lustre/llite/lproc_llite.c  |    2 +-
+ drivers/staging/lustre/lustre/llite/rw.c           |    6 +-
+ drivers/staging/lustre/lustre/llite/statahead.c    |    4 +-
+ drivers/staging/lustre/lustre/llite/vvp_io.c       |    2 +-
+ drivers/staging/lustre/lustre/lmv/lmv_obd.c        |    2 +-
+ drivers/staging/lustre/lustre/lov/lov_io.c         |    2 +
+ drivers/staging/lustre/lustre/lov/lov_obd.c        |    6 +-
+ drivers/staging/lustre/lustre/mdc/mdc_locks.c      |    2 +-
+ drivers/staging/lustre/lustre/obdclass/capa.c      |    2 +-
+ drivers/staging/lustre/lustre/obdclass/cl_io.c     |   10 +-
+ drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    6 +-
+ drivers/staging/lustre/lustre/obdclass/cl_object.c |   11 +-
+ drivers/staging/lustre/lustre/obdclass/class_obd.c |   12 +-
+ drivers/staging/lustre/lustre/obdclass/dt_object.c |    5 +-
+ drivers/staging/lustre/lustre/obdclass/genops.c    |   73 +-
+ .../lustre/lustre/obdclass/linux/linux-module.c    |    2 -
+ drivers/staging/lustre/lustre/obdclass/llog.c      |    4 +-
+ .../lustre/lustre/obdclass/lprocfs_counters.c      |    2 +-
+ drivers/staging/lustre/lustre/obdclass/lu_object.c |   14 +-
+ .../staging/lustre/lustre/obdclass/obd_config.c    |   43 +-
+ drivers/staging/lustre/lustre/osc/osc_page.c       |    2 +-
+ drivers/staging/lustre/lustre/osc/osc_request.c    |   16 +-
+ drivers/staging/lustre/lustre/ptlrpc/client.c      |    7 +-
+ drivers/staging/lustre/lustre/ptlrpc/import.c      |   31 +-
+ drivers/staging/lustre/lustre/ptlrpc/layout.c      |    6 +-
+ .../staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c    |    2 +-
+ .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    2 +-
+ drivers/staging/lustre/lustre/ptlrpc/sec_plain.c   |    1 +
+ drivers/staging/most/aim-cdev/cdev.c               |   22 +-
+ drivers/staging/most/aim-network/networking.c      |    2 +-
+ drivers/staging/most/aim-sound/sound.c             |    5 +-
+ drivers/staging/most/aim-v4l2/Makefile             |    1 -
+ drivers/staging/most/aim-v4l2/video.c              |    2 +-
+ drivers/staging/most/hdm-dim2/dim2_hal.c           |    5 -
+ drivers/staging/most/hdm-dim2/dim2_hal.h           |    5 -
+ drivers/staging/most/hdm-dim2/dim2_hdm.c           |   19 +-
+ drivers/staging/most/hdm-usb/hdm_usb.c             |   13 +-
+ drivers/staging/most/mostcore/core.c               |   10 +-
+ drivers/staging/mt29f_spinand/mt29f_spinand.c      |    1 +
+ drivers/staging/octeon-usb/octeon-hcd.c            |    1 +
+ drivers/staging/panel/panel.c                      |   63 +-
+ drivers/staging/rtl8188eu/core/rtw_mlme_ext.c      |    5 +-
+ drivers/staging/rtl8188eu/core/rtw_sta_mgt.c       |    6 +-
+ .../staging/rtl8188eu/hal/Hal8188ERateAdaptive.c   |   14 +-
+ drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c       |    4 +-
+ drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c     |    2 +-
+ drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c     |    2 +-
+ drivers/staging/rtl8188eu/include/wifi.h           |    5 -
+ drivers/staging/rtl8188eu/os_dep/mlme_linux.c      |    4 +-
+ drivers/staging/rtl8188eu/os_dep/osdep_service.c   |    2 +-
+ drivers/staging/rtl8188eu/os_dep/recv_linux.c      |    2 +-
+ drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c     |    3 -
+ drivers/staging/rtl8192e/rtl8192e/rtl_core.c       |    4 -
+ drivers/staging/rtl8192e/rtl8192e/rtl_wx.c         |    3 +-
+ .../staging/rtl8192u/ieee80211/ieee80211_module.c  |    2 +-
+ .../staging/rtl8192u/ieee80211/ieee80211_softmac.c |    2 +-
+ .../rtl8192u/ieee80211/ieee80211_softmac_wx.c      |   28 +-
+ drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c  |    2 +-
+ drivers/staging/rtl8192u/r8192U.h                  |    4 +-
+ drivers/staging/rtl8192u/r8192U_core.c             | 1230 ++++++++++----------
+ drivers/staging/rtl8712/osdep_service.h            |    4 -
+ drivers/staging/rtl8712/wifi.h                     |    9 -
+ drivers/staging/rtl8723au/core/rtw_mlme_ext.c      |    7 +-
+ drivers/staging/rtl8723au/core/rtw_security.c      |   17 +-
+ drivers/staging/rtl8723au/hal/usb_halinit.c        |    5 +-
+ drivers/staging/rtl8723au/include/rtw_cmd.h        |    2 -
+ drivers/staging/speakup/devsynth.c                 |    4 +-
+ drivers/staging/speakup/kobjects.c                 |   16 +-
+ drivers/staging/speakup/serialio.c                 |    4 +-
+ drivers/staging/speakup/speakup_dectlk.c           |    3 +-
+ drivers/staging/speakup/varhandlers.c              |   18 +-
+ drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c      |    1 -
+ .../Documentation/ABI/sysfs-platform-visorchipset  |    2 +
+ drivers/staging/unisys/Documentation/overview.txt  |  458 +++++---
+ drivers/staging/unisys/TODO                        |   25 +-
+ drivers/staging/vt6655/card.c                      |   14 +-
+ drivers/staging/vt6655/desc.h                      |   58 +-
+ drivers/staging/vt6655/device.h                    |   10 +-
+ drivers/staging/vt6655/device_main.c               |   87 +-
+ drivers/staging/vt6655/dpc.c                       |    8 +-
+ drivers/staging/vt6655/dpc.h                       |    2 +-
+ drivers/staging/wilc1000/Kconfig                   |    1 -
+ drivers/staging/wilc1000/Makefile                  |    9 +-
+ drivers/staging/wilc1000/coreconfigurator.c        | 1055 +----------------
+ drivers/staging/wilc1000/host_interface.c          |  496 +++++---
+ drivers/staging/wilc1000/host_interface.h          |    2 +
+ drivers/staging/wilc1000/linux_mon.c               |  106 +-
+ drivers/staging/wilc1000/linux_wlan.c              |  517 +-------
+ drivers/staging/wilc1000/linux_wlan_common.h       |    7 +-
+ drivers/staging/wilc1000/linux_wlan_sdio.c         |    9 +-
+ drivers/staging/wilc1000/linux_wlan_spi.c          |   79 +-
+ drivers/staging/wilc1000/wilc_errorsupport.h       |    2 -
+ drivers/staging/wilc1000/wilc_exported_buf.c       |   71 --
+ drivers/staging/wilc1000/wilc_memory.c             |   16 -
+ drivers/staging/wilc1000/wilc_memory.h             |   66 --
+ drivers/staging/wilc1000/wilc_msgqueue.c           |   53 +-
+ drivers/staging/wilc1000/wilc_msgqueue.h           |    9 +-
+ drivers/staging/wilc1000/wilc_oswrapper.h          |    4 -
+ drivers/staging/wilc1000/wilc_sdio.c               |    3 -
+ drivers/staging/wilc1000/wilc_spi.c                |    7 +-
+ drivers/staging/wilc1000/wilc_wfi_cfgoperations.c  |  110 +-
+ drivers/staging/wilc1000/wilc_wfi_cfgoperations.h  |    5 -
+ drivers/staging/wilc1000/wilc_wfi_netdevice.h      |   10 +-
+ drivers/staging/wilc1000/wilc_wlan.c               |  267 ++---
+ drivers/staging/wilc1000/wilc_wlan.h               |    7 -
+ drivers/staging/wilc1000/wilc_wlan_cfg.c           |   39 +-
+ drivers/staging/wilc1000/wilc_wlan_if.h            |   28 +-
+ drivers/staging/wlan-ng/p80211conv.c               |   50 +-
+ drivers/staging/wlan-ng/p80211conv.h               |    7 +-
+ 217 files changed, 3094 insertions(+), 5871 deletions(-)
+ delete mode 100644 drivers/staging/comedi/drivers/unioxx5.c
+ delete mode 100644 drivers/staging/wilc1000/wilc_exported_buf.c
+ delete mode 100644 drivers/staging/wilc1000/wilc_memory.c
+ delete mode 100644 drivers/staging/wilc1000/wilc_memory.h
+Merging char-misc/char-misc-next (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge char-misc/char-misc-next
+Already up-to-date.
+Merging extcon/extcon-next (722b9c505ea5 extcon: Export OF module alias information in missing drivers)
+$ git merge extcon/extcon-next
+Merge made by the 'recursive' strategy.
+ drivers/extcon/extcon-rt8973a.c | 1 +
+ drivers/extcon/extcon-sm5502.c  | 1 +
+ drivers/extcon/extcon.c         | 2 +-
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+Merging kdbus/kdbus (a36324913ff2 kdbus: selftests: add more name registry tests)
+$ git merge kdbus/kdbus
+Recorded preimage for 'tools/testing/selftests/Makefile'
+Auto-merging tools/testing/selftests/Makefile
+CONFLICT (content): Merge conflict in tools/testing/selftests/Makefile
+Auto-merging init/Kconfig
+Auto-merging include/uapi/linux/Kbuild
+Auto-merging Makefile
+Auto-merging MAINTAINERS
+Auto-merging Documentation/ioctl/ioctl-number.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+Recorded resolution for 'tools/testing/selftests/Makefile'.
+[master 2b1cd3931b3d] Merge remote-tracking branch 'kdbus/kdbus'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/Makefile                           |    2 +-
+ Documentation/ioctl/ioctl-number.txt             |    1 +
+ Documentation/kdbus/.gitignore                   |    2 +
+ Documentation/kdbus/Makefile                     |   44 +
+ Documentation/kdbus/kdbus.bus.xml                |  344 ++++
+ Documentation/kdbus/kdbus.connection.xml         | 1244 ++++++++++++
+ Documentation/kdbus/kdbus.endpoint.xml           |  429 +++++
+ Documentation/kdbus/kdbus.fs.xml                 |  124 ++
+ Documentation/kdbus/kdbus.item.xml               |  839 ++++++++
+ Documentation/kdbus/kdbus.match.xml              |  555 ++++++
+ Documentation/kdbus/kdbus.message.xml            | 1276 +++++++++++++
+ Documentation/kdbus/kdbus.name.xml               |  711 +++++++
+ Documentation/kdbus/kdbus.policy.xml             |  406 ++++
+ Documentation/kdbus/kdbus.pool.xml               |  326 ++++
+ Documentation/kdbus/kdbus.xml                    | 1012 ++++++++++
+ Documentation/kdbus/stylesheet.xsl               |   16 +
+ MAINTAINERS                                      |   13 +
+ Makefile                                         |    1 +
+ include/uapi/linux/Kbuild                        |    1 +
+ include/uapi/linux/kdbus.h                       |  984 ++++++++++
+ include/uapi/linux/magic.h                       |    2 +
+ init/Kconfig                                     |   13 +
+ ipc/Makefile                                     |    2 +-
+ ipc/kdbus/Makefile                               |   33 +
+ ipc/kdbus/bus.c                                  |  514 +++++
+ ipc/kdbus/bus.h                                  |  101 +
+ ipc/kdbus/connection.c                           | 2227 ++++++++++++++++++++++
+ ipc/kdbus/connection.h                           |  260 +++
+ ipc/kdbus/domain.c                               |  296 +++
+ ipc/kdbus/domain.h                               |   77 +
+ ipc/kdbus/endpoint.c                             |  303 +++
+ ipc/kdbus/endpoint.h                             |   70 +
+ ipc/kdbus/fs.c                                   |  508 +++++
+ ipc/kdbus/fs.h                                   |   28 +
+ ipc/kdbus/handle.c                               |  691 +++++++
+ ipc/kdbus/handle.h                               |  103 +
+ ipc/kdbus/item.c                                 |  293 +++
+ ipc/kdbus/item.h                                 |   61 +
+ ipc/kdbus/limits.h                               |   61 +
+ ipc/kdbus/main.c                                 |  114 ++
+ ipc/kdbus/match.c                                |  546 ++++++
+ ipc/kdbus/match.h                                |   35 +
+ ipc/kdbus/message.c                              | 1040 ++++++++++
+ ipc/kdbus/message.h                              |  120 ++
+ ipc/kdbus/metadata.c                             | 1347 +++++++++++++
+ ipc/kdbus/metadata.h                             |   86 +
+ ipc/kdbus/names.c                                |  854 +++++++++
+ ipc/kdbus/names.h                                |  105 +
+ ipc/kdbus/node.c                                 |  897 +++++++++
+ ipc/kdbus/node.h                                 |   86 +
+ ipc/kdbus/notify.c                               |  204 ++
+ ipc/kdbus/notify.h                               |   30 +
+ ipc/kdbus/policy.c                               |  489 +++++
+ ipc/kdbus/policy.h                               |   51 +
+ ipc/kdbus/pool.c                                 |  728 +++++++
+ ipc/kdbus/pool.h                                 |   46 +
+ ipc/kdbus/queue.c                                |  363 ++++
+ ipc/kdbus/queue.h                                |   84 +
+ ipc/kdbus/reply.c                                |  252 +++
+ ipc/kdbus/reply.h                                |   68 +
+ ipc/kdbus/util.c                                 |  156 ++
+ ipc/kdbus/util.h                                 |   73 +
+ samples/Kconfig                                  |    7 +
+ samples/Makefile                                 |    3 +-
+ samples/kdbus/.gitignore                         |    1 +
+ samples/kdbus/Makefile                           |    9 +
+ samples/kdbus/kdbus-api.h                        |  114 ++
+ samples/kdbus/kdbus-workers.c                    | 1346 +++++++++++++
+ tools/testing/selftests/Makefile                 |    1 +
+ tools/testing/selftests/kdbus/.gitignore         |    1 +
+ tools/testing/selftests/kdbus/Makefile           |   49 +
+ tools/testing/selftests/kdbus/kdbus-enum.c       |   94 +
+ tools/testing/selftests/kdbus/kdbus-enum.h       |   15 +
+ tools/testing/selftests/kdbus/kdbus-test.c       |  905 +++++++++
+ tools/testing/selftests/kdbus/kdbus-test.h       |   84 +
+ tools/testing/selftests/kdbus/kdbus-util.c       | 1612 ++++++++++++++++
+ tools/testing/selftests/kdbus/kdbus-util.h       |  218 +++
+ tools/testing/selftests/kdbus/test-activator.c   |  318 +++
+ tools/testing/selftests/kdbus/test-benchmark.c   |  451 +++++
+ tools/testing/selftests/kdbus/test-bus.c         |  175 ++
+ tools/testing/selftests/kdbus/test-chat.c        |  124 ++
+ tools/testing/selftests/kdbus/test-connection.c  |  597 ++++++
+ tools/testing/selftests/kdbus/test-daemon.c      |   65 +
+ tools/testing/selftests/kdbus/test-endpoint.c    |  352 ++++
+ tools/testing/selftests/kdbus/test-fd.c          |  789 ++++++++
+ tools/testing/selftests/kdbus/test-free.c        |   64 +
+ tools/testing/selftests/kdbus/test-match.c       |  441 +++++
+ tools/testing/selftests/kdbus/test-message.c     |  734 +++++++
+ tools/testing/selftests/kdbus/test-metadata-ns.c |  500 +++++
+ tools/testing/selftests/kdbus/test-monitor.c     |  176 ++
+ tools/testing/selftests/kdbus/test-names.c       |  272 +++
+ tools/testing/selftests/kdbus/test-policy-ns.c   |  632 ++++++
+ tools/testing/selftests/kdbus/test-policy-priv.c | 1285 +++++++++++++
+ tools/testing/selftests/kdbus/test-policy.c      |   80 +
+ tools/testing/selftests/kdbus/test-sync.c        |  369 ++++
+ tools/testing/selftests/kdbus/test-timeout.c     |   99 +
+ 96 files changed, 33726 insertions(+), 3 deletions(-)
+ create mode 100644 Documentation/kdbus/.gitignore
+ create mode 100644 Documentation/kdbus/Makefile
+ create mode 100644 Documentation/kdbus/kdbus.bus.xml
+ create mode 100644 Documentation/kdbus/kdbus.connection.xml
+ create mode 100644 Documentation/kdbus/kdbus.endpoint.xml
+ create mode 100644 Documentation/kdbus/kdbus.fs.xml
+ create mode 100644 Documentation/kdbus/kdbus.item.xml
+ create mode 100644 Documentation/kdbus/kdbus.match.xml
+ create mode 100644 Documentation/kdbus/kdbus.message.xml
+ create mode 100644 Documentation/kdbus/kdbus.name.xml
+ create mode 100644 Documentation/kdbus/kdbus.policy.xml
+ create mode 100644 Documentation/kdbus/kdbus.pool.xml
+ create mode 100644 Documentation/kdbus/kdbus.xml
+ create mode 100644 Documentation/kdbus/stylesheet.xsl
+ create mode 100644 include/uapi/linux/kdbus.h
+ create mode 100644 ipc/kdbus/Makefile
+ create mode 100644 ipc/kdbus/bus.c
+ create mode 100644 ipc/kdbus/bus.h
+ create mode 100644 ipc/kdbus/connection.c
+ create mode 100644 ipc/kdbus/connection.h
+ create mode 100644 ipc/kdbus/domain.c
+ create mode 100644 ipc/kdbus/domain.h
+ create mode 100644 ipc/kdbus/endpoint.c
+ create mode 100644 ipc/kdbus/endpoint.h
+ create mode 100644 ipc/kdbus/fs.c
+ create mode 100644 ipc/kdbus/fs.h
+ create mode 100644 ipc/kdbus/handle.c
+ create mode 100644 ipc/kdbus/handle.h
+ create mode 100644 ipc/kdbus/item.c
+ create mode 100644 ipc/kdbus/item.h
+ create mode 100644 ipc/kdbus/limits.h
+ create mode 100644 ipc/kdbus/main.c
+ create mode 100644 ipc/kdbus/match.c
+ create mode 100644 ipc/kdbus/match.h
+ create mode 100644 ipc/kdbus/message.c
+ create mode 100644 ipc/kdbus/message.h
+ create mode 100644 ipc/kdbus/metadata.c
+ create mode 100644 ipc/kdbus/metadata.h
+ create mode 100644 ipc/kdbus/names.c
+ create mode 100644 ipc/kdbus/names.h
+ create mode 100644 ipc/kdbus/node.c
+ create mode 100644 ipc/kdbus/node.h
+ create mode 100644 ipc/kdbus/notify.c
+ create mode 100644 ipc/kdbus/notify.h
+ create mode 100644 ipc/kdbus/policy.c
+ create mode 100644 ipc/kdbus/policy.h
+ create mode 100644 ipc/kdbus/pool.c
+ create mode 100644 ipc/kdbus/pool.h
+ create mode 100644 ipc/kdbus/queue.c
+ create mode 100644 ipc/kdbus/queue.h
+ create mode 100644 ipc/kdbus/reply.c
+ create mode 100644 ipc/kdbus/reply.h
+ create mode 100644 ipc/kdbus/util.c
+ create mode 100644 ipc/kdbus/util.h
+ create mode 100644 samples/kdbus/.gitignore
+ create mode 100644 samples/kdbus/Makefile
+ create mode 100644 samples/kdbus/kdbus-api.h
+ create mode 100644 samples/kdbus/kdbus-workers.c
+ create mode 100644 tools/testing/selftests/kdbus/.gitignore
+ create mode 100644 tools/testing/selftests/kdbus/Makefile
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-enum.c
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-enum.h
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-test.c
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-test.h
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-util.c
+ create mode 100644 tools/testing/selftests/kdbus/kdbus-util.h
+ create mode 100644 tools/testing/selftests/kdbus/test-activator.c
+ create mode 100644 tools/testing/selftests/kdbus/test-benchmark.c
+ create mode 100644 tools/testing/selftests/kdbus/test-bus.c
+ create mode 100644 tools/testing/selftests/kdbus/test-chat.c
+ create mode 100644 tools/testing/selftests/kdbus/test-connection.c
+ create mode 100644 tools/testing/selftests/kdbus/test-daemon.c
+ create mode 100644 tools/testing/selftests/kdbus/test-endpoint.c
+ create mode 100644 tools/testing/selftests/kdbus/test-fd.c
+ create mode 100644 tools/testing/selftests/kdbus/test-free.c
+ create mode 100644 tools/testing/selftests/kdbus/test-match.c
+ create mode 100644 tools/testing/selftests/kdbus/test-message.c
+ create mode 100644 tools/testing/selftests/kdbus/test-metadata-ns.c
+ create mode 100644 tools/testing/selftests/kdbus/test-monitor.c
+ create mode 100644 tools/testing/selftests/kdbus/test-names.c
+ create mode 100644 tools/testing/selftests/kdbus/test-policy-ns.c
+ create mode 100644 tools/testing/selftests/kdbus/test-policy-priv.c
+ create mode 100644 tools/testing/selftests/kdbus/test-policy.c
+ create mode 100644 tools/testing/selftests/kdbus/test-sync.c
+ create mode 100644 tools/testing/selftests/kdbus/test-timeout.c
+Merging cgroup/for-next (eacb1e7d4bfa Merge branch 'for-4.3' into for-next)
+$ git merge cgroup/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging scsi/for-next (294ab783ad98 scsi_dh: fix randconfig build error)
+$ git merge scsi/for-next
+Already up-to-date.
+Merging target-updates/for-next (ac64a2ce5091 target: use stringify.h instead of own definition)
+$ git merge target-updates/for-next
+Already up-to-date.
+Merging target-merge/for-next-merge (8edb1554f7c2 mpt3sas: Fix unprotected list lookup in v4.3-rc0 changes)
+$ git merge target-merge/for-next-merge
+Merge made by the 'recursive' strategy.
+ drivers/scsi/mpt3sas/mpt3sas_base.h      |  25 +-
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c     | 595 ++++++++++++++++++++++---------
+ drivers/scsi/mpt3sas/mpt3sas_transport.c |  18 +-
+ 3 files changed, 458 insertions(+), 180 deletions(-)
+Merging pinctrl/for-next (3249524451f1 pinctrl: samsung: s3c24xx: fix syntax error)
+$ git merge pinctrl/for-next
+Merge made by the 'recursive' strategy.
+ drivers/pinctrl/core.c                    | 3 +++
+ drivers/pinctrl/pinctrl-digicolor.c       | 4 ++--
+ drivers/pinctrl/pinmux.c                  | 3 +--
+ drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c  | 4 ++--
+ drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c   | 4 ++--
+ drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 2 +-
+ 6 files changed, 11 insertions(+), 9 deletions(-)
+Merging vhost/linux-next (997e120843e8 virtio_balloon: do not change memory amount visible via /proc/meminfo)
+$ git merge vhost/linux-next
+Already up-to-date.
+Merging remoteproc/for-next (8de3dbd0895b remoteproc: fix !CONFIG_OF build breakage)
+$ git merge remoteproc/for-next
+Already up-to-date.
+Merging rpmsg/for-next (b1b9891441fa rpmsg: use less buffers when vrings are small)
+$ git merge rpmsg/for-next
+Already up-to-date.
+Merging gpio/for-next (1fd19dd13a80 gpio: omap: Fix GPIO numbering for deferred probe)
+$ git merge gpio/for-next
+Merge made by the 'recursive' strategy.
+ Documentation/gpio/board.txt    | 40 +++++++++++++++++++++++++---------------
+ Documentation/gpio/consumer.txt |  3 +++
+ drivers/gpio/Kconfig            |  2 +-
+ drivers/gpio/gpio-mxc.c         | 12 ++++++++++--
+ drivers/gpio/gpio-mxs.c         | 13 +++++++++++--
+ drivers/gpio/gpio-omap.c        |  9 +++++++--
+ drivers/gpio/gpio-sx150x.c      |  1 -
+ drivers/gpio/gpiolib.c          | 21 ++++++++++++++-------
+ 8 files changed, 71 insertions(+), 30 deletions(-)
+Merging dma-mapping/dma-mapping-next (d770e558e219 Linux 4.2-rc1)
+$ git merge dma-mapping/dma-mapping-next
+Already up-to-date.
+Merging pwm/for-next (7a5938201834 ARM: at91: pwm: atmel-hlcdc: Add at91sam9n12 errata)
+$ git merge pwm/for-next
+Already up-to-date.
+Merging dma-buf/for-next (86ea07ca846a Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux)
+$ git merge dma-buf/for-next
+Already up-to-date.
+Merging userns/for-next (4b75de861505 fs: Set the size of empty dirs to 0.)
+$ git merge userns/for-next
+Already up-to-date.
+Merging ktest/for-next (b953c0d234bc Linux 4.1)
+$ git merge ktest/for-next
+Already up-to-date.
+Merging clk/clk-next (3bba75a2ec32 clk: rockchip: Add pclk_peri to critical clocks on RK3066/RK3188)
+$ git merge clk/clk-next
+Merge made by the 'recursive' strategy.
+ drivers/clk/hisilicon/Kconfig     | 8 +++++++-
+ drivers/clk/hisilicon/Makefile    | 3 ++-
+ drivers/clk/rockchip/clk-rk3188.c | 9 +++++++--
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+Merging random/dev (7185ad2672a7 crypto: memzero_explicit - make sure to clear out sensitive data)
+$ git merge random/dev
+Already up-to-date.
+Merging aio/master (6ff33f3902c3 Linux 4.3-rc1)
+$ git merge aio/master
+Already up-to-date.
+Merging llvmlinux/for-next (25d4aee23af2 arm: LLVMLinux: Use global stack register variable for percpu)
+$ git merge llvmlinux/for-next
+Merge made by the 'recursive' strategy.
+Merging kselftest/next (7eba7d90d482 selftests/zram: Makefile fix)
+$ git merge kselftest/next
+Already up-to-date.
+Merging y2038/y2038 (ed8c2241c1ae coredump: Use 64bit time for unix time of coredump)
+$ git merge y2038/y2038
+Resolved 'drivers/staging/media/lirc/lirc_parallel.c' using previous resolution.
+Auto-merging kernel/cpuset.c
+Auto-merging fs/coredump.c
+Auto-merging drivers/staging/media/lirc/lirc_serial.c
+Auto-merging drivers/staging/media/lirc/lirc_sasem.c
+Auto-merging drivers/staging/media/lirc/lirc_parallel.c
+CONFLICT (content): Merge conflict in drivers/staging/media/lirc/lirc_parallel.c
+Auto-merging drivers/staging/gdm72xx/gdm_sdio.c
+Auto-merging drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+Auto-merging drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
+Auto-merging drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master e8d53db06c2a] Merge remote-tracking branch 'y2038/y2038'
+$ git diff -M --stat --summary HEAD^..
+ drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c |  4 +-
+ drivers/staging/ft1000/ft1000-usb/ft1000_debug.c |  4 +-
+ drivers/staging/ft1000/ft1000-usb/ft1000_hw.c    |  4 +-
+ drivers/staging/ft1000/ft1000.h                  |  4 +-
+ drivers/staging/gdm72xx/gdm_sdio.c               | 13 +++---
+ drivers/staging/gdm72xx/gdm_sdio.h               |  4 +-
+ drivers/staging/media/lirc/lirc_parallel.c       | 35 +++++++----------
+ drivers/staging/media/lirc/lirc_sasem.c          | 20 +++++-----
+ drivers/staging/media/lirc/lirc_serial.c         | 50 ++++++++----------------
+ fs/coredump.c                                    |  8 ++--
+ kernel/cpuset.c                                  | 12 ++++--
+ 11 files changed, 68 insertions(+), 90 deletions(-)
+Merging luto-misc/next (a6c5170d1ede Merge branch 'for-4.0' of git://linux-nfs.org/~bfields/linux)
+$ git merge luto-misc/next
+Already up-to-date.
+Merging access_once/linux-next (c231afa3ccf1 compiler.h: cast away attributes in WRITE_ONCE magic)
+$ git merge access_once/linux-next
+Merge made by the 'recursive' strategy.
+Merging livepatching/for-next (07d42d41dfc4 Merge branch 'for-4.3/upstream' into for-next)
+$ git merge livepatching/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging coresight/next (8503d45d4f27 Coresight: ETMv4: Prevent TRCRSCTLR0&1 from being accessed)
+$ git merge coresight/next
+Auto-merging drivers/hwtracing/coresight/coresight-etm4x.c
+Merge made by the 'recursive' strategy.
+ drivers/hwtracing/coresight/coresight-etm4x.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+Merging rtc/rtc-next (5f1b2f77646f rtc: abx80x: fix RTC write bit)
+$ git merge rtc/rtc-next
+Already up-to-date.
+Merging hwspinlock/for-next (bd5717a4632c hwspinlock: qcom: Correct msb in regmap_field)
+$ git merge hwspinlock/for-next
+Already up-to-date.
+Merging nvdimm/libnvdimm-for-next (004f1afbe199 libnvdimm, pmem: direct map legacy pmem by default)
+$ git merge nvdimm/libnvdimm-for-next
+Already up-to-date.
+Merging akpm-current/current (fadfe9f50067 ipc/msg.c: use freezable blocking call)
+$ git merge --no-ff akpm-current/current
+Recorded preimage for 'arch/x86/entry/syscalls/syscall_32.tbl'
+Recorded preimage for 'arch/x86/entry/syscalls/syscall_64.tbl'
+Recorded preimage for 'include/linux/syscalls.h'
+Recorded preimage for 'include/uapi/asm-generic/unistd.h'
+Auto-merging mm/swap.c
+Auto-merging mm/rmap.c
+Auto-merging mm/mmap.c
+Auto-merging mm/migrate.c
+Auto-merging mm/memory.c
+Auto-merging mm/memory-failure.c
+Auto-merging mm/huge_memory.c
+Auto-merging mm/debug.c
+Auto-merging lib/string_helpers.c
+Auto-merging kernel/sys_ni.c
+Auto-merging init/Kconfig
+Auto-merging include/uapi/asm-generic/unistd.h
+CONFLICT (content): Merge conflict in include/uapi/asm-generic/unistd.h
+Auto-merging include/linux/syscalls.h
+CONFLICT (content): Merge conflict in include/linux/syscalls.h
+Auto-merging include/linux/poison.h
+Auto-merging include/linux/page-flags.h
+Auto-merging include/linux/mm.h
+Auto-merging include/linux/kexec.h
+Auto-merging fs/proc/task_mmu.c
+Auto-merging fs/cifs/file.c
+Auto-merging arch/x86/entry/syscalls/syscall_64.tbl
+CONFLICT (content): Merge conflict in arch/x86/entry/syscalls/syscall_64.tbl
+Auto-merging arch/x86/entry/syscalls/syscall_32.tbl
+CONFLICT (content): Merge conflict in arch/x86/entry/syscalls/syscall_32.tbl
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+Recorded resolution for 'arch/x86/entry/syscalls/syscall_32.tbl'.
+Recorded resolution for 'arch/x86/entry/syscalls/syscall_64.tbl'.
+Recorded resolution for 'include/linux/syscalls.h'.
+Recorded resolution for 'include/uapi/asm-generic/unistd.h'.
+[master 9bf585c61099] Merge branch 'akpm-current/current'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/devicetree/bindings/w1/omap-hdq.txt |   7 +-
+ Documentation/filesystems/proc.txt                |  37 +-
+ Documentation/filesystems/vfat.txt                |  10 +
+ Documentation/printk-formats.txt                  |   8 +
+ Documentation/w1/masters/omap-hdq                 |   6 +
+ arch/alpha/include/uapi/asm/mman.h                |   4 +
+ arch/arm/include/asm/pgtable-3level.h             |   1 +
+ arch/arm64/include/asm/pgtable.h                  |   2 +
+ arch/mips/include/uapi/asm/mman.h                 |   7 +
+ arch/mips/include/uapi/asm/unistd.h               |  15 +-
+ arch/mips/kernel/scall32-o32.S                    |   1 +
+ arch/mips/kernel/scall64-64.S                     |   1 +
+ arch/mips/kernel/scall64-n32.S                    |   1 +
+ arch/mips/kernel/scall64-o32.S                    |   1 +
+ arch/parisc/include/uapi/asm/mman.h               |   4 +
+ arch/powerpc/include/asm/pgtable-ppc64.h          |   2 +
+ arch/powerpc/include/uapi/asm/mman.h              |   1 +
+ arch/sparc/include/asm/pgtable_64.h               |   9 +
+ arch/sparc/include/uapi/asm/mman.h                |   1 +
+ arch/tile/include/uapi/asm/mman.h                 |   1 +
+ arch/x86/entry/syscalls/syscall_32.tbl            |   1 +
+ arch/x86/entry/syscalls/syscall_64.tbl            |   1 +
+ arch/x86/include/asm/pgtable.h                    |   5 +
+ arch/x86/kernel/machine_kexec_64.c                |   1 +
+ arch/xtensa/include/uapi/asm/mman.h               |   7 +
+ block/genhd.c                                     |   2 +-
+ drivers/gpu/drm/drm_vm.c                          |   8 +-
+ drivers/w1/masters/omap_hdq.c                     | 224 ++++++--
+ fs/9p/vfs_file.c                                  |   3 +-
+ fs/cifs/file.c                                    |   8 +-
+ fs/ext4/fsync.c                                   |   5 +-
+ fs/fat/cache.c                                    |  79 ++-
+ fs/fat/dir.c                                      |   2 +-
+ fs/fat/fat.h                                      |   6 +-
+ fs/fat/file.c                                     |  61 ++
+ fs/fat/inode.c                                    |  75 ++-
+ fs/hugetlbfs/inode.c                              |  12 +
+ fs/mpage.c                                        |  23 +-
+ fs/ocfs2/alloc.c                                  | 101 ++--
+ fs/proc/task_mmu.c                                |  31 +
+ fs/super.c                                        |   8 +-
+ include/linux/crc64_ecma.h                        |  56 ++
+ include/linux/huge_mm.h                           |   4 +
+ include/linux/hugetlb.h                           |  36 ++
+ include/linux/kexec.h                             |   2 +
+ include/linux/mm.h                                |  42 +-
+ include/linux/mm_types.h                          |   7 +
+ include/linux/page-flags.h                        | 237 +++++---
+ include/linux/pagemap.h                           |  25 +-
+ include/linux/poison.h                            |   6 +-
+ include/linux/rmap.h                              |   9 +-
+ include/linux/string.h                            |   1 +
+ include/linux/swap.h                              |   3 +-
+ include/linux/syscalls.h                          |   2 +
+ include/linux/vm_event_item.h                     |   1 +
+ include/uapi/asm-generic/mman-common.h            |   6 +
+ include/uapi/asm-generic/mman.h                   |   1 +
+ include/uapi/asm-generic/unistd.h                 |   4 +-
+ init/Kconfig                                      |   1 +
+ ipc/msg.c                                         |   5 +-
+ kernel/fork.c                                     |   6 +-
+ kernel/sys_ni.c                                   |   1 +
+ lib/Kconfig                                       |   7 +
+ lib/Makefile                                      |   1 +
+ lib/crc64_ecma.c                                  | 341 +++++++++++
+ lib/string_helpers.c                              |   2 +-
+ lib/vsprintf.c                                    |  20 +-
+ mm/debug.c                                        |   1 +
+ mm/filemap.c                                      |  15 +-
+ mm/gup.c                                          |  10 +-
+ mm/huge_memory.c                                  |  39 +-
+ mm/hugetlb.c                                      |  50 +-
+ mm/ksm.c                                          |   2 +-
+ mm/madvise.c                                      | 176 ++++++
+ mm/memory-failure.c                               |   2 +-
+ mm/memory.c                                       |   2 +-
+ mm/memory_hotplug.c                               |  11 +-
+ mm/migrate.c                                      |   2 +-
+ mm/mlock.c                                        |  87 ++-
+ mm/mmap.c                                         |   3 +-
+ mm/page_alloc.c                                   |   7 +
+ mm/page_isolation.c                               |   7 +-
+ mm/rmap.c                                         |  56 +-
+ mm/shmem.c                                        |   4 +-
+ mm/slab.c                                         |   2 +-
+ mm/slub.c                                         |   2 +
+ mm/swap.c                                         |  44 ++
+ mm/swap_state.c                                   |   4 +-
+ mm/util.c                                         |  40 +-
+ mm/vmscan.c                                       | 157 ++++--
+ mm/vmstat.c                                       |   1 +
+ tools/testing/selftests/vm/Makefile               |   4 +-
+ tools/testing/selftests/vm/mlock2-tests.c         | 657 ++++++++++++++++++++++
+ tools/testing/selftests/vm/on-fault-limit.c       |  47 ++
+ tools/testing/selftests/vm/run_vmtests            |  22 +
+ tools/testing/selftests/vm/userfaultfd.c          |   4 +-
+ 96 files changed, 2653 insertions(+), 413 deletions(-)
+ create mode 100644 include/linux/crc64_ecma.h
+ create mode 100644 lib/crc64_ecma.c
+ create mode 100644 tools/testing/selftests/vm/mlock2-tests.c
+ create mode 100644 tools/testing/selftests/vm/on-fault-limit.c
+$ git reset --hard HEAD^
+HEAD is now at 3efacbfd37d3 Merge remote-tracking branch 'coresight/next'
+$ git clone -s -l -n -q . ../rebase-tmp
+$ cd ../rebase-tmp
+$ git checkout -b akpm remotes/origin/akpm/master
+Switched to a new branch 'akpm'
+$ git rebase --onto master remotes/origin/akpm/master-base
+First, rewinding head to replay your work on top of it...
+Applying: drivers/w1/w1_int.c: call put_device if device_register fails
+$ cd ../next
+$ git fetch -f ../rebase-tmp akpm:akpm/master
+From ../rebase-tmp
+ + 4768dceb84d5...09b0ea9865a4 akpm       -> akpm/master  (forced update)
+$ rm -rf ../rebase-tmp
+Merging akpm/master (09b0ea9865a4 drivers/w1/w1_int.c: call put_device if device_register fails)
+$ git merge --no-ff akpm/master
+Merge made by the 'recursive' strategy.
+ drivers/w1/w1_int.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Next/quilt-import.log b/Next/quilt-import.log
new file mode 100644
index 000000000000..feafe02b3052
--- /dev/null
+++ b/Next/quilt-import.log
@@ -0,0 +1,4 @@
+Importing jdelvare-hwmon based on 4.2-rc2
+Unchanged quilt series jdelvare-hwmon
+Importing dmi based on 1dc51b8288007753ad7cd7d08bb8fa930fc8bb10
+Unchanged quilt series dmi
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7451b447cc2d..2c2b28ee4811 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -54,6 +54,14 @@ AS		+= -EL
 LD		+= -EL
 endif
 
+#
+# The Scalar Replacement of Aggregates (SRA) optimization pass in GCC 4.9 and
+# later may result in code being generated that handles signed short and signed
+# char struct members incorrectly. So disable it.
+# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932)
+#
+KBUILD_CFLAGS	+= $(call cc-option,-fno-ipa-sra)
+
 # This selects which instruction set is used.
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644
index 000000000000..99d4f147605f
--- /dev/null
+++ b/arch/arm/arm-soc-for-next-contents.txt
@@ -0,0 +1,303 @@
+next/fixes-non-critical
+	samsung/non-critical
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-non-critical-1
+	brcm/maintainers
+		http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/maintainers
+	mvebu/fixes
+		git://git.infradead.org/linux-mvebu tags/mvebu-fixes-4.2-1
+
+next/cleanup
+	renesas/cleanup
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup-for-v4.3
+	renesas/pm-domain
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-pm-domain-for-v4.3
+	clkevt/set-state
+		git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux ARM/clkevt/set-state-4.3
+	mvebu/cleanup
+		git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.3-1
+	brcm/soc
+		http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/soc
+	ep93xx/cleanup
+		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator tags/ep93xx-cleanup
+	omap/legacy-removal
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/legacy-v2-signed
+	renesas/cleanup2
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup2-for-v4.3
+	patch
+		ARM: appropriate __init annotation for const data
+		ARM: kill off set_irq_flags usage
+	generic/cleanup-irq
+		git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip queue/irq/arm
+	renesas/marzen-removal
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-marzen-board-removal-for-v4.3
+	<no branch> (bf64dd262eaaece2ff560e86fabf94c6725f3b5c)
+		Merge branch 'fixes' into next/cleanup
+	patch
+		ARM: ux500: simplify secondary CPU boot
+		ARM: shmobile: Fix mismerges
+	samsung/cleanup
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-cleanup
+	patch
+		ARM: nomadik: move hog code to use DT hogs
+		ARM: nomadik: selectively enable UART0 on boards
+		ARM: nomadik: move l2x0 setup to device tree
+		ARM: nomadik: push accelerometer down to boards
+		ARM: ep93xx/timer: Migrate to new 'set-state' interface
+		ARM: gemini: Add missing register definitions for gemini timer
+		ARM: gemini: Use timer1 for clockevent
+		ARM: gemini: Setup timer3 as free running timer
+		ARM/fb: ep93xx: switch framebuffer to use modedb only
+	tegra/cleanup
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-cleanup
+
+next/soc
+	rockchip/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-soc1
+	sti/soc
+		https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-soc-for-v4.3-1
+	reneass/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-soc-for-v4.3
+	omap/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/soc-signed
+	pxa/soc
+		https://github.com/rjarzmik/linux tags/pxa-for-4.3-v2
+	patch
+		MAINTAINERS: add entries for UniPhier device trees and drivers
+	mtk/soc
+		https://github.com/mbgg/linux-mediatek tags/v4.2-next-soc
+	socfpga/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_updates_for_v4.3
+	patch
+		ARM: zx: Add power domains for ZX296702
+		ARM: at91/soc: add basic support for new sama5d2 SoC
+	zynq/soc
+		https://github.com/Xilinx/linux-xlnx tags/zynq-soc-for-4.3
+	mvebu/soc
+		git://git.infradead.org/linux-mvebu tags/mvebu-soc-4.3-1
+	patch
+		soc: mediatek: Fix SCPSYS compilation
+		ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead of irq_set_wake callback
+		ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
+		ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE
+		ARM: uniphier: drop v7_invalidate_l1 call at secondary entry
+	rockchip/soc2
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-soc2
+	patch
+		clk: ti: fix for definition movement
+	imx/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-soc-4.3
+	omap/soc2
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/soc-pt2
+	patch
+		ARM: imx: mach-imx6ul: Fix allmodconfig build
+	rockchip/soc3
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-soc3
+
+next/boards
+
+next/dt
+	patch
+		ARM: digicolor: enable watchdog device
+		ARM: digicolor: dts: use stdout-path for console configuration
+		ARM: dts: UniPhier: add on-chip UART device nodes
+		ARM: dts: UniPhier: add USB EHCI device nodes
+	renesas/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt-for-v4.3
+	omap/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt1
+	lpc18xx/dt
+		https://github.com/manabian/linux-lpc lpc18xx_43xx_dts_4.3
+	mvebu/dt
+		git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.3-1
+	brcm/dts
+		http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/dts
+	rockchip/dts
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-dts1
+	pxa/dt
+		https://github.com/rjarzmik/linux tags/tags/pxa-dt-4.3
+	omap/dt2
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt2
+	sti/dt
+		https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-dt-for-v4.3-1
+	stm32/dt
+		https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32 tags/stm32-dt-for-v4.3-1b
+	renesas/dt2
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt2-for-v4.3
+	omap/dt-dm814x
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-dm814x
+	patch
+		ARM: dts: UniPhier: add pinctrl device nodes
+		ARM: dts: UniPhier: add UART and USB pinmux nodes
+	mtk/dt
+		https://github.com/mbgg/linux-mediatek tags/v4.2-next-dts
+	socfgpa/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.3
+	at91/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 tags/at91-dt
+	qcom/dt
+		git://codeaurora.org/quic/kernel/agross-msm tags/qcom-dt-for-4.3
+	zynq/dt
+		https://github.com/Xilinx/linux-xlnx tags/zynq-dt-for-4.3
+	mvevu/dt
+		git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.3-2
+	patch
+		ARM: dts: lpc18xx: add usb otg phy node
+		ARM: dts: lpc18xx: add pl111 lcd controller node
+		ARM: dts: lpc18xx: add pl172 memory-controller node
+		ARM: dts: lpc4357-ea4357: add usb0
+		ARM: dts: lpc4357-ea4357: add emc pins and static memory devices
+		ARM: dts: lpc4357-ea4357: add mmio-gpio leds
+		ARM: dts: lpc4350-hitex-eval: add pinctrl and uart0 muxing
+		ARM: dts: lpc4350-hitex-eval: add ethernet
+		ARM: dts: lpc4350-hitex-eval: add emc pins and static memory devices
+	sunxi/dt
+		https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.3
+	samsung/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-dt-1
+	patch
+		ARM: dts: uniphier: add I2C controller device nodes
+		ARM: dts: uniphier: add PH1-Pro5 SoC support
+		ARM: dts: uniphier: add ProXstream2 and PH1-LD6b SoC/board support
+	csr/sirf-dts
+		git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux tags/sirf-dts-for-4.3
+	patch
+		ARM: BCM5301X: activate some additional options in pl310 cache controller
+		ARM: BCM5301X: Add profiling support
+		ARM: dts: brcmstb: add BCM7445 GPIO nodes
+		ARM: dts: UniPhier: add reference daughter board
+	omap/dt3
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt3
+	renesas/dt3
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt3-for-v4.3
+	at91/dt2
+		git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-dt2
+	mvebu/dt3
+		git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.3-3
+	rockchip/dt2
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-dts2
+	socfpga/dts2
+		git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.3_part_2
+	brcm/rpi-dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi tags/rpi-dt-for-armsoc-4.3
+	imx/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-dt-4.3
+	patch
+		ARM: dts: vexpress: Use assigned-clock-parents for sp810
+	renesas/dt4
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt4-for-v4.3
+		contains renesas/clk
+	omap/dt4
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt4-v2
+	patch
+		ARM: dts: UniPhier: fix PPI interrupt CPU mask of timer nodes
+		ARM: dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.
+	tegra/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-dt
+	rockchip/dt3
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.3-rockchip32-dts3
+
+next/drivers
+	patch
+		memory: add ARM PL172 MultiPort Memory Controller driver
+		doc: dt: add documentation for pl172 memory bindings
+		memory: pl172: fix modular build
+	mvebu/soc2
+		git://git.infradead.org/linux-mvebu tags/mvebu-soc-4.3-2
+		contains mvebu/soc
+	qcom/soc
+		git://codeaurora.org/quic/kernel/agross-msm tags/qcom-soc-for-4.3
+	renesas/clk
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-clk-for-v4.3
+	drivers/reset
+		git://git.pengutronix.de/git/pza/linux tags/reset-for-4.3
+	tegra/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-soc
+	tegra/cpufreq
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-cpufreq
+	tegra/memory
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-memory
+
+next/defconfig
+	patch
+		ARM: multi_v7_defconfig: enable Conexant Digicolor watchdog
+		ARM: multi_v7_defconfig: enable UniPhier UART driver
+	mvebu/config
+		git://git.infradead.org/linux-mvebu tags/mvebu-config-4.3-1
+	ep93xx/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator tags/ep93xx-defconfig
+	omap/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/defconfig-signed
+	sti/defconfig
+		https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-defconfig-for-v4.3-1
+	renesas/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig-for-v4.3
+	prima2/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux tags/prima2-defconfig-for-4.2
+	patch
+		ARM: multi_v7_defconfig: Select MX6UL and MX7D
+	renesas/defconfig2
+		git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig2-for-v4.3
+	patch
+		ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support
+	qcom/defconfig
+		git://codeaurora.org/quic/kernel/agross-msm tags/qcom-defconfig-for-4.3
+	mvebu/config2
+		git://git.infradead.org/linux-mvebu tags/mvebu-config-4.3-2
+	sunxi/defconfig
+		https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-defconfig-for-4.3
+	patch
+		ARM: at91/defconfig: at91_dt: enable DRM hlcdc support
+		ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER
+	imx/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-defconfig-4.3
+	patch
+		ARM: add TC2 PM support to multi_v7_defconfig
+	tegra/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.3-defconfig
+
+next/arm64
+	patch
+		arm64: dts: sprd: adding ETM entries to Spreadtrum SC9836
+		arm64: Split out platform options to separate Kconfig
+		arm64: add Rockchip architecture entry
+		arm64: defconfig: enable ARCH_ROCKCHIP
+	depends/clk-rk3368
+		Merge branch 'depends/clk-rk3368' into next/arm64
+	patch
+		arm64: dts: add Rockchip rk3368 core dtsi and board dts for the r88 board
+		arm64: fix Kconfig include path
+	mtk/arm64
+		https://github.com/mbgg/linux-mediatek tags/v4.2-next-arm64
+	patch
+		PCI: iproc: enable arm64 support for iProc PCIe
+		PCI: iproc: Fix ARM64 dependency in Kconfig
+		arm64: Add Broadcom iProc family support
+		arm64: dts: Add Broadcom North Star 2 support
+		PCI: iproc: Fix BCMA dependency in Kconfig
+	qcom/arm64
+		git://codeaurora.org/quic/kernel/agross-msm tags/qcom-arm64-for-4.3
+	zynq/mp-dt
+		https://github.com/Xilinx/linux-xlnx tags/zynqmp-dt-for-4.3
+	patch
+		arm64: Enable Marvell Berlin SoC family in Kconfig
+		arm64: Enable Marvell Berlin SoC family in defconfig
+	mtk/arm64-2
+		https://github.com/mbgg/linux-mediatek tags/v4.2-next-arm64-2
+	mvebu/berlin64-dts
+		git://git.infradead.org/users/hesselba/linux-berlin tags/berlin64-for-v4.3-1
+	patch
+		ARM64: dts: vexpress: Use assigned-clock-parents for sp810
+
+next/late
+	samsung/clk-driver
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-clk-driver
+	samsung/late-dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-late-dt
+		contains samsung/dt
+	samsung/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-soc
+	samsung/late-cpufreq
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-late-cpufreq-driver
+	samsung/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-defconfig-new
+
diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
index b4031fa4a567..504cf45d3cb8 100644
--- a/arch/arm/boot/dts/efm32gg-dk3750.dts
+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
@@ -26,7 +26,7 @@
 		};
 
 		i2c@4000a000 {
-			efm32,location = <3>;
+			energymicro,location = <3>;
 			status = "ok";
 
 			temp@48 {
@@ -43,7 +43,7 @@
 
 		spi0: spi@4000c000 { /* USART0 */
 			cs-gpios = <&gpio 68 1>; // E4
-			location = <1>;
+			energymicro,location = <1>;
 			status = "ok";
 
 			microsd@0 {
@@ -57,7 +57,7 @@
 
 		spi1: spi@4000c400 { /* USART1 */
 			cs-gpios = <&gpio 51 1>; // D3
-			location = <1>;
+			energymicro,location = <1>;
 			status = "ok";
 
 			ks8851@0 {
@@ -70,7 +70,7 @@
 		};
 
 		uart4: uart@4000e400 { /* UART1 */
-			location = <2>;
+			energymicro,location = <2>;
 			status = "ok";
 		};
 
diff --git a/arch/arm/boot/dts/efm32gg.dtsi b/arch/arm/boot/dts/efm32gg.dtsi
index 106d505c5d3d..c747983771c7 100644
--- a/arch/arm/boot/dts/efm32gg.dtsi
+++ b/arch/arm/boot/dts/efm32gg.dtsi
@@ -23,7 +23,7 @@
 
 	soc {
 		adc: adc@40002000 {
-			compatible = "efm32,adc";
+			compatible = "energymicro,efm32-adc";
 			reg = <0x40002000 0x400>;
 			interrupts = <7>;
 			clocks = <&cmu clk_HFPERCLKADC0>;
@@ -31,7 +31,7 @@
 		};
 
 		gpio: gpio@40006000 {
-			compatible = "efm32,gpio";
+			compatible = "energymicro,efm32-gpio";
 			reg = <0x40006000 0x1000>;
 			interrupts = <1 11>;
 			gpio-controller;
@@ -45,7 +45,7 @@
 		i2c0: i2c@4000a000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "efm32,i2c";
+			compatible = "energymicro,efm32-i2c";
 			reg = <0x4000a000 0x400>;
 			interrupts = <9>;
 			clocks = <&cmu clk_HFPERCLKI2C0>;
@@ -56,7 +56,7 @@
 		i2c1: i2c@4000a400 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "efm32,i2c";
+			compatible = "energymicro,efm32-i2c";
 			reg = <0x4000a400 0x400>;
 			interrupts = <10>;
 			clocks = <&cmu clk_HFPERCLKI2C1>;
@@ -67,7 +67,7 @@
 		spi0: spi@4000c000 { /* USART0 */
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "efm32,spi";
+			compatible = "energymicro,efm32-spi";
 			reg = <0x4000c000 0x400>;
 			interrupts = <3 4>;
 			clocks = <&cmu clk_HFPERCLKUSART0>;
@@ -77,7 +77,7 @@
 		spi1: spi@4000c400 { /* USART1 */
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "efm32,spi";
+			compatible = "energymicro,efm32-spi";
 			reg = <0x4000c400 0x400>;
 			interrupts = <15 16>;
 			clocks = <&cmu clk_HFPERCLKUSART1>;
@@ -87,7 +87,7 @@
 		spi2: spi@4000c800 { /* USART2 */
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "efm32,spi";
+			compatible = "energymicro,efm32-spi";
 			reg = <0x4000c800 0x400>;
 			interrupts = <18 19>;
 			clocks = <&cmu clk_HFPERCLKUSART2>;
@@ -95,7 +95,7 @@
 		};
 
 		uart0: uart@4000c000 { /* USART0 */
-			compatible = "efm32,uart";
+			compatible = "energymicro,efm32-uart";
 			reg = <0x4000c000 0x400>;
 			interrupts = <3 4>;
 			clocks = <&cmu clk_HFPERCLKUSART0>;
@@ -103,7 +103,7 @@
 		};
 
 		uart1: uart@4000c400 { /* USART1 */
-			compatible = "efm32,uart";
+			compatible = "energymicro,efm32-uart";
 			reg = <0x4000c400 0x400>;
 			interrupts = <15 16>;
 			clocks = <&cmu clk_HFPERCLKUSART1>;
@@ -111,7 +111,7 @@
 		};
 
 		uart2: uart@4000c800 { /* USART2 */
-			compatible = "efm32,uart";
+			compatible = "energymicro,efm32-uart";
 			reg = <0x4000c800 0x400>;
 			interrupts = <18 19>;
 			clocks = <&cmu clk_HFPERCLKUSART2>;
@@ -119,7 +119,7 @@
 		};
 
 		uart3: uart@4000e000 { /* UART0 */
-			compatible = "efm32,uart";
+			compatible = "energymicro,efm32-uart";
 			reg = <0x4000e000 0x400>;
 			interrupts = <20 21>;
 			clocks = <&cmu clk_HFPERCLKUART0>;
@@ -127,7 +127,7 @@
 		};
 
 		uart4: uart@4000e400 { /* UART1 */
-			compatible = "efm32,uart";
+			compatible = "energymicro,efm32-uart";
 			reg = <0x4000e400 0x400>;
 			interrupts = <22 23>;
 			clocks = <&cmu clk_HFPERCLKUART1>;
@@ -135,28 +135,28 @@
 		};
 
 		timer0: timer@40010000 {
-			compatible = "efm32,timer";
+			compatible = "energymicro,efm32-timer";
 			reg = <0x40010000 0x400>;
 			interrupts = <2>;
 			clocks = <&cmu clk_HFPERCLKTIMER0>;
 		};
 
 		timer1: timer@40010400 {
-			compatible = "efm32,timer";
+			compatible = "energymicro,efm32-timer";
 			reg = <0x40010400 0x400>;
 			interrupts = <12>;
 			clocks = <&cmu clk_HFPERCLKTIMER1>;
 		};
 
 		timer2: timer@40010800 {
-			compatible = "efm32,timer";
+			compatible = "energymicro,efm32-timer";
 			reg = <0x40010800 0x400>;
 			interrupts = <13>;
 			clocks = <&cmu clk_HFPERCLKTIMER2>;
 		};
 
 		timer3: timer@40010c00 {
-			compatible = "efm32,timer";
+			compatible = "energymicro,efm32-timer";
 			reg = <0x40010c00 0x400>;
 			interrupts = <14>;
 			clocks = <&cmu clk_HFPERCLKTIMER3>;
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 98c0a368b777..3184e10f260a 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -431,6 +431,8 @@
 		interrupts = <0 52 0>;
 		clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
 		clock-names = "uart", "clk_uart_baud0";
+		dmas = <&pdma0 15>, <&pdma0 16>;
+		dma-names = "rx", "tx";
 		status = "disabled";
 	};
 
@@ -440,6 +442,8 @@
 		interrupts = <0 53 0>;
 		clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
 		clock-names = "uart", "clk_uart_baud0";
+		dmas = <&pdma1 15>, <&pdma1 16>;
+		dma-names = "rx", "tx";
 		status = "disabled";
 	};
 
@@ -449,6 +453,8 @@
 		interrupts = <0 54 0>;
 		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
 		clock-names = "uart", "clk_uart_baud0";
+		dmas = <&pdma0 17>, <&pdma0 18>;
+		dma-names = "rx", "tx";
 		status = "disabled";
 	};
 
@@ -458,6 +464,8 @@
 		interrupts = <0 55 0>;
 		clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
 		clock-names = "uart", "clk_uart_baud0";
+		dmas = <&pdma1 17>, <&pdma1 18>;
+		dma-names = "rx", "tx";
 		status = "disabled";
 	};
 
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 8632f35c6c26..1e6ef99eef59 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -32,6 +32,49 @@
 			linux,default-trigger = "heartbeat";
 		};
 	};
+
+	fan0: pwm-fan {
+		compatible = "pwm-fan";
+		pwms = <&pwm 0 10000 0>;
+		cooling-min-state = <0>;
+		cooling-max-state = <3>;
+		#cooling-cells = <2>;
+		cooling-levels = <0 102 170 230>;
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			cooling-maps {
+				map0 {
+				     trip = <&cpu_alert1>;
+				     cooling-device = <&cpu0 7 7>;
+				};
+				map1 {
+				     trip = <&cpu_alert2>;
+				     cooling-device = <&cpu0 13 13>;
+				};
+				map2 {
+				     trip = <&cpu_alert0>;
+				     cooling-device = <&fan0 0 1>;
+				};
+				map3 {
+				     trip = <&cpu_alert1>;
+				     cooling-device = <&fan0 1 2>;
+				};
+				map4 {
+				     trip = <&cpu_alert2>;
+				     cooling-device = <&fan0 2 3>;
+				};
+			};
+		};
+	};
+};
+
+&pwm {
+	pinctrl-0 = <&pwm0_out>;
+	pinctrl-names = "default";
+	samsung,pwm-outputs = <0>;
+	status = "okay";
 };
 
 &usb3503 {
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 15aea760c1da..c625e71217aa 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -197,6 +197,7 @@
 				regulator-name = "P1.8V_LDO_OUT10";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
 			};
 
 			ldo11_reg: LDO11 {
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 79ffdfe712aa..90d298dce851 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -160,6 +160,7 @@
 		s2mps11,buck2-ramp-enable = <1>;
 		s2mps11,buck3-ramp-enable = <1>;
 		s2mps11,buck4-ramp-enable = <1>;
+		samsung,s2mps11-acokb-ground;
 
 		interrupt-parent = <&gpx0>;
 		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
@@ -472,7 +473,6 @@
 	 */
 	pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
 	pinctrl-names = "default";
-	samsung,pwm-outputs = <0>;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index a0b2a79cbfbd..4624d0f2a754 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -1627,6 +1627,7 @@
 				"mix.0", "mix.1",
 				"dvc.0", "dvc.1",
 				"clk_a", "clk_b", "clk_c", "clk_i";
+		power-domains = <&cpg_clocks>;
 
 		status = "disabled";
 
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 831525dd39a6..1666c8a6b143 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -1677,6 +1677,7 @@
 				"mix.0", "mix.1",
 				"dvc.0", "dvc.1",
 				"clk_a", "clk_b", "clk_c", "clk_i";
+		power-domains = <&cpg_clocks>;
 
 		status = "disabled";
 
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 1ff2bfa2e183..711cb0a3893d 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -135,7 +135,6 @@ CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
-CONFIG_FB_SIMPLE=y
 CONFIG_EXYNOS_VIDEO=y
 CONFIG_EXYNOS_MIPI_DSI=y
 CONFIG_LCD_CLASS_DEVICE=y
@@ -158,8 +157,10 @@ CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_EXYNOS=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
 CONFIG_USB_HSIC_USB3503=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_SDHCI=y
@@ -168,6 +169,12 @@ CONFIG_MMC_SDHCI_S3C_DMA=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_EXYNOS=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX77686=y
 CONFIG_RTC_DRV_MAX77802=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 03deb7fb35e8..960b38f03871 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -507,6 +507,7 @@ CONFIG_USB_R8A66597_HCD=m
 CONFIG_USB_RENESAS_USBHS=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=m
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_AB8500_USB=y
@@ -518,6 +519,7 @@ CONFIG_USB_MXS_PHY=y
 CONFIG_USB_RCAR_PHY=m
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_ARMMMCI=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7bbf325a4f31..b2bc8e11471d 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -491,11 +491,6 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 #endif
 	.endm
 
-	.macro	uaccess_save_and_disable, tmp
-	uaccess_save \tmp
-	uaccess_disable \tmp
-	.endm
-
 	.irp	c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
 	.macro	ret\c, reg
 #if __LINUX_ARM_ARCH__ < 6
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index b274bde24905..e7335a92144e 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -40,6 +40,7 @@ do {								\
 		"2:\t.asciz " #__file "\n" 			\
 		".popsection\n" 				\
 		".pushsection __bug_table,\"a\"\n"		\
+		".align 2\n"					\
 		"3:\t.word 1b, 2b\n"				\
 		"\t.hword " #__line ", 0\n"			\
 		".popsection");					\
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index e878129f2fee..fc8ba1663601 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -12,6 +12,7 @@
 
 #ifndef __ASSEMBLY__
 #include <asm/barrier.h>
+#include <asm/thread_info.h>
 #endif
 
 /*
@@ -89,7 +90,8 @@ static inline unsigned int get_domain(void)
 
 	asm(
 	"mrc	p15, 0, %0, c3, c0	@ get domain"
-	 : "=r" (domain));
+	 : "=r" (domain)
+	 : "m" (current_thread_info()->cpu_domain));
 
 	return domain;
 }
@@ -98,7 +100,7 @@ static inline void set_domain(unsigned val)
 {
 	asm volatile(
 	"mcr	p15, 0, %0, c3, c0	@ set domain"
-	  : : "r" (val));
+	  : : "r" (val) : "memory");
 	isb();
 }
 
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index d0a1119dcaf3..776757d1604a 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -25,7 +25,6 @@
 struct task_struct;
 
 #include <asm/types.h>
-#include <asm/domain.h>
 
 typedef unsigned long mm_segment_t;
 
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index a3089bacb8d8..7a7c4cea5523 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -226,6 +226,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 
+#ifdef CONFIG_CPU_USE_DOMAINS
 	/*
 	 * Copy the initial value of the domain access control register
 	 * from the current thread: thread->addr_limit will have been
@@ -233,6 +234,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
 	 * kernel/fork.c
 	 */
 	thread->cpu_domain = get_domain();
+#endif
 
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 4b94b513168d..ad6f6424f1d1 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -126,7 +126,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 
 static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
 {
-	int i;
+	int i, matching_cpus = 0;
 	unsigned long mpidr;
 	unsigned long target_affinity;
 	unsigned long target_affinity_mask;
@@ -151,12 +151,16 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
 	 */
 	kvm_for_each_vcpu(i, tmp, kvm) {
 		mpidr = kvm_vcpu_get_mpidr_aff(tmp);
-		if (((mpidr & target_affinity_mask) == target_affinity) &&
-		    !tmp->arch.pause) {
-			return PSCI_0_2_AFFINITY_LEVEL_ON;
+		if ((mpidr & target_affinity_mask) == target_affinity) {
+			matching_cpus++;
+			if (!tmp->arch.pause)
+				return PSCI_0_2_AFFINITY_LEVEL_ON;
 		}
 	}
 
+	if (!matching_cpus)
+		return PSCI_RET_INVALID_PARAMS;
+
 	return PSCI_0_2_AFFINITY_LEVEL_OFF;
 }
 
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 71df43547659..39c20afad7ed 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -95,9 +95,10 @@ emulate:
 	reteq	r4			@ no, return failure
 
 next:
+	uaccess_enable r3
 .Lx1:	ldrt	r6, [r5], #4		@ get the next instruction and
 					@ increment PC
-
+	uaccess_disable r3
 	and	r2, r6, #0x0F000000	@ test for FP insns
 	teq	r2, #0x0C000000
 	teqne	r2, #0x0D000000
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index f00e08075938..10fd99c568c6 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -98,8 +98,23 @@ ENTRY(privcmd_call)
 	mov r1, r2
 	mov r2, r3
 	ldr r3, [sp, #8]
+	/*
+	 * Privcmd calls are issued by the userspace. We need to allow the
+	 * kernel to access the userspace memory before issuing the hypercall.
+	 */
+	uaccess_enable r4
+
+	/* r4 is loaded now as we use it as scratch register before */
 	ldr r4, [sp, #4]
 	__HVC(XEN_IMM)
+
+	/*
+	 * Disable userspace access from kernel. This is fine to do it
+	 * unconditionally as no set_fs(KERNEL_DS)/set_fs(get_ds()) is
+	 * called before.
+	 */
+	uaccess_disable r4
+
 	ldm sp!, {r4}
 	ret lr
 ENDPROC(privcmd_call);
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
new file mode 100644
index 000000000000..c56bbf8f76ab
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
@@ -0,0 +1,698 @@
+/*
+ * Samsung's Exynos5433 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos5433 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+&pinctrl_alive {
+	gpa0: gpa0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+			     <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa1: gpa1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa2: gpa2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpa3: gpa3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_aud {
+	gpz0: gpz0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpz1: gpz1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	i2s0_bus: i2s0-bus {
+		samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
+				"gpz0-4", "gpz0-5", "gpz0-6";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <0>;
+	};
+
+	pcm0_bus: pcm0-bus {
+		samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <0>;
+	};
+};
+
+&pinctrl_cpif {
+	gpv6: gpv6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_ese {
+	gpj2: gpj2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_finger {
+	gpd5: gpd5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpd5-0", "gpd5-2", "gpd5-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus {
+		samsung,pins = "gpd5-3", "gpd5-2";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+};
+
+&pinctrl_fsys {
+	gph1: gph1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpr4: gpr4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpr0: gpr0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpr1: gpr1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpr2: gpr2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpr3: gpr3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	sd0_clk: sd0-clk {
+		samsung,pins = "gpr0-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpr0-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_rdqs: sd0-rdqs {
+		samsung,pins = "gpr0-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_qrdy: sd0-qrdy {
+		samsung,pins = "gpr0-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus1: sd0-bus-width1 {
+		samsung,pins = "gpr1-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus4: sd0-bus-width4 {
+		samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus8: sd0-bus-width8 {
+		samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd1_clk: sd1-clk {
+		samsung,pins = "gpr2-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd1_cmd: sd1-cmd {
+		samsung,pins = "gpr2-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd1_bus1: sd1-bus-width1 {
+		samsung,pins = "gpr3-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd1_bus4: sd1-bus-width4 {
+		samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd1_bus8: sd1-bus-width8 {
+		samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	pcie_bus: pcie_bus {
+		samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <3>;
+	};
+
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpr4-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpr4-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_cd: sd2-cd {
+		samsung,pins = "gpr4-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpr4-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_clk_output: sd2-clk-output {
+		samsung,pins = "gpr4-0";
+		samsung,pin-function = <1>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_cmd_output: sd2-cmd-output {
+		samsung,pins = "gpr4-1";
+		samsung,pin-function = <1>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <2>;
+	};
+};
+
+&pinctrl_imem {
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_nfc {
+	gpj0: gpj0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus {
+		samsung,pins = "gpj0-1", "gpj0-0";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+};
+
+&pinctrl_peric {
+	gpv7: gpv7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc0: gpc0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc1: gpc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc2: gpc2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc3: gpc3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd4: gpd4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd8: gpd8 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd6: gpd6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd7: gpd7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	hs_i2c8_bus: hs-i2c8-bus {
+		samsung,pins = "gpb0-1", "gpb0-0";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c9_bus: hs-i2c9-bus {
+		samsung,pins = "gpb0-3", "gpb0-2";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2s1_bus: i2s1-bus {
+		samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
+				"gpd4-3", "gpd4-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <0>;
+	};
+
+	pcm1_bus: pcm1-bus {
+		samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
+				"gpd4-3", "gpd4-4";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <0>;
+	};
+
+	spdif_bus: spdif-bus {
+		samsung,pins = "gpd4-3", "gpd4-4";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <1>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_spi_pin0: fimc-is-spi-pin0 {
+		samsung,pins = "gpc3-3", "gpc3-2", "gpc3-1", "gpc3-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_spi_pin1: fimc-is-spi-pin1 {
+		samsung,pins = "gpc3-7", "gpc3-6", "gpc3-5", "gpc3-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	uart0_bus: uart0-bus {
+		samsung,pins = "gpd0-3", "gpd0-2", "gpd0-1", "gpd0-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus {
+		samsung,pins = "gpd0-3", "gpd0-2";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	uart2_bus: uart2-bus {
+		samsung,pins = "gpd1-5", "gpd1-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+	};
+
+	uart1_bus: uart1-bus {
+		samsung,pins = "gpd1-3", "gpd1-2", "gpd1-1", "gpd1-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus {
+		samsung,pins = "gpd1-3", "gpd1-2";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+
+	hs_i2c0_bus: hs-i2c0-bus {
+		samsung,pins = "gpd2-1", "gpd2-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus {
+		samsung,pins = "gpd2-3", "gpd2-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpd6-2", "gpd6-4", "gpd6-5";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus {
+		samsung,pins = "gpd2-7", "gpd2-6";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpd8-0", "gpd6-0", "gpd6-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c10_bus: hs-i2c10-bus {
+		samsung,pins = "gpg3-1", "gpg3-0";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	hs_i2c11_bus: hs-i2c11-bus {
+		samsung,pins = "gpg3-3", "gpg3-2";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi3_bus: spi3-bus {
+		samsung,pins = "gpg3-4", "gpg3-6", "gpg3-7";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi4_bus: spi4-bus {
+		samsung,pins = "gpv7-1", "gpv7-3", "gpv7-4";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_uart: fimc-is-uart {
+		samsung,pins = "gpc1-1", "gpc0-7";
+		samsung,pin-function = <3>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch0_i2c: fimc-is-ch0_i2c {
+		samsung,pins = "gpc2-1", "gpc2-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch0_mclk: fimc-is-ch0_mclk {
+		samsung,pins = "gpd7-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch1_i2c: fimc-is-ch1-i2c {
+		samsung,pins = "gpc2-3", "gpc2-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch1_mclk: fimc-is-ch1-mclk {
+		samsung,pins = "gpd7-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch2_i2c: fimc-is-ch2-i2c {
+		samsung,pins = "gpc2-5", "gpc2-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
+	fimc_is_ch2_mclk: fimc-is-ch2-mclk {
+		samsung,pins = "gpd7-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+};
+
+&pinctrl_touch {
+	gpj1: gpj1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus {
+		samsung,pins = "gpj1-1", "gpj1-0";
+		samsung,pin-function = <4>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
new file mode 100644
index 000000000000..396e60f3a4af
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
@@ -0,0 +1,22 @@
+/*
+ * Device tree sources for Exynos5433 TMU sensor configuration
+ *
+ * Copyright (c) 2015 Chanwoo Choi <cw00.choi@samsung.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 <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <8>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <75>;
+samsung,tmu_min_efuse_value = <40>;
+samsung,tmu_max_efuse_value = <150>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <85>;
+samsung,tmu_default_temp_offset = <50>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi
new file mode 100644
index 000000000000..7ff7b0e024a5
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi
@@ -0,0 +1,231 @@
+/*
+ * Device tree sources for Exynos5433 thermal zone
+ *
+ * Copyright (c) 2015 Chanwoo Choi <cw00.choi@samsung.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 <dt-bindings/thermal/thermal.h>
+
+/ {
+thermal-zones {
+	atlas0_thermal: atlas0-thermal {
+		thermal-sensors = <&tmu_atlas0>;
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		trips {
+			atlas0_alert_0: atlas0-alert-0 {
+				temperature = <80000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_1: atlas0-alert-1 {
+				temperature = <85000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_2: atlas0-alert-2 {
+				temperature = <90000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_3: atlas0-alert-3 {
+				temperature = <95000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_4: atlas0-alert-4 {
+				temperature = <100000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_5: atlas0-alert-5 {
+				temperature = <105000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas0_alert_6: atlas0-alert-6 {
+				temperature = <110000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+		};
+	};
+
+	atlas1_thermal: atlas1-thermal {
+		thermal-sensors = <&tmu_atlas1>;
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		trips {
+			atlas1_alert_0: atlas1-alert-0 {
+				temperature = <80000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_1: atlas1-alert-1 {
+				temperature = <85000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_2: atlas1-alert-2 {
+				temperature = <90000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_3: atlas1-alert-3 {
+				temperature = <95000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_4: atlas1-alert-4 {
+				temperature = <100000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_5: atlas1-alert-5 {
+				temperature = <105000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			atlas1_alert_6: atlas1-alert-6 {
+				temperature = <110000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+		};
+	};
+
+	g3d_thermal: g3d-thermal {
+		thermal-sensors = <&tmu_g3d>;
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		trips {
+			g3d_alert_0: g3d-alert-0 {
+				temperature = <80000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_1: g3d-alert-1 {
+				temperature = <85000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_2: g3d-alert-2 {
+				temperature = <90000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_3: g3d-alert-3 {
+				temperature = <95000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_4: g3d-alert-4 {
+				temperature = <100000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_5: g3d-alert-5 {
+				temperature = <105000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			g3d_alert_6: g3d-alert-6 {
+				temperature = <110000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+		};
+
+	};
+
+	apollo_thermal: apollo-thermal {
+		thermal-sensors = <&tmu_apollo>;
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		trips {
+			apollo_alert_0: apollo-alert-0 {
+				temperature = <80000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_1: apollo-alert-1 {
+				temperature = <85000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_2: apollo-alert-2 {
+				temperature = <90000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_3: apollo-alert-3 {
+				temperature = <95000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_4: apollo-alert-4 {
+				temperature = <100000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_5: apollo-alert-5 {
+				temperature = <105000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			apollo_alert_6: apollo-alert-6 {
+				temperature = <110000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+		};
+	};
+
+	isp_thermal: isp-thermal {
+		thermal-sensors = <&tmu_isp>;
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		trips {
+			isp_alert_0: isp-alert-0 {
+				temperature = <80000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_1: isp-alert-1 {
+				temperature = <85000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_2: isp-alert-2 {
+				temperature = <90000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_3: isp-alert-3 {
+				temperature = <95000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_4: isp-alert-4 {
+				temperature = <100000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_5: isp-alert-5 {
+				temperature = <105000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+			isp_alert_6: isp-alert-6 {
+				temperature = <110000>;	/* millicelsius */
+				hysteresis = <10000>;	/* millicelsius */
+				type = "active";
+			};
+		};
+	};
+};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
new file mode 100644
index 000000000000..59e21b68b28f
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -0,0 +1,931 @@
+/*
+ * Samsung's Exynos5433 SoC device tree source
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos5433 SoC device nodes are listed in this file. Exynos5433
+ * based board files can include this file and provide values for board
+ * specific bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos5433 SoC. As device tree coverage for Exynos5433 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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 <dt-bindings/clock/exynos5433.h>
+
+/ {
+	compatible = "samsung,exynos5433";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x100>;
+		};
+
+		cpu1: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x101>;
+		};
+
+		cpu2: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x102>;
+		};
+
+		cpu3: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x103>;
+		};
+
+		cpu4: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a57", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x0>;
+		};
+
+		cpu5: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a57", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x1>;
+		};
+
+		cpu6: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a57", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x2>;
+		};
+
+		cpu7: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a57", "arm,armv8";
+			enable-method = "psci";
+			reg = <0x3>;
+		};
+	};
+
+	psci {
+		compatible = "arm,psci";
+		method = "smc";
+		cpu_off = <0x84000002>;
+		cpu_on = <0xC4000003>;
+	};
+
+	soc: soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x18000000>;
+
+		chipid@10000000 {
+			compatible = "samsung,exynos4210-chipid";
+			reg = <0x10000000 0x100>;
+		};
+
+		xxti: xxti {
+			compatible = "fixed-clock";
+			clock-output-names = "oscclk";
+			#clock-cells = <0>;
+		};
+
+		cmu_top: clock-controller@10030000 {
+			compatible = "samsung,exynos5433-cmu-top";
+			reg = <0x10030000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_mphy_pll",
+				"sclk_mfc_pll",
+				"sclk_bus_pll";
+			clocks = <&xxti>,
+				 <&cmu_cpif CLK_SCLK_MPHY_PLL>,
+				 <&cmu_mif CLK_SCLK_MFC_PLL>,
+				 <&cmu_mif CLK_SCLK_BUS_PLL>;
+		};
+
+		cmu_cpif: clock-controller@10fc0000 {
+			compatible = "samsung,exynos5433-cmu-cpif";
+			reg = <0x10fc0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk";
+			clocks = <&xxti>;
+		};
+
+		cmu_mif: clock-controller@105b0000 {
+			compatible = "samsung,exynos5433-cmu-mif";
+			reg = <0x105b0000 0x2000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_mphy_pll";
+			clocks = <&xxti>,
+				 <&cmu_cpif CLK_SCLK_MPHY_PLL>;
+		};
+
+		cmu_peric: clock-controller@14c80000 {
+			compatible = "samsung,exynos5433-cmu-peric";
+			reg = <0x14c80000 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		cmu_peris: clock-controller@0x10040000 {
+			compatible = "samsung,exynos5433-cmu-peris";
+			reg = <0x10040000 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		cmu_fsys: clock-controller@156e0000 {
+			compatible = "samsung,exynos5433-cmu-fsys";
+			reg = <0x156e0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_ufs_mphy",
+				"div_aclk_fsys_200",
+				"sclk_pcie_100_fsys",
+				"sclk_ufsunipro_fsys",
+				"sclk_mmc2_fsys",
+				"sclk_mmc1_fsys",
+				"sclk_mmc0_fsys",
+				"sclk_usbhost30_fsys",
+				"sclk_usbdrd30_fsys";
+			clocks = <&xxti>,
+				 <&cmu_cpif CLK_SCLK_UFS_MPHY>,
+				 <&cmu_top CLK_DIV_ACLK_FSYS_200>,
+				 <&cmu_top CLK_SCLK_PCIE_100_FSYS>,
+				 <&cmu_top CLK_SCLK_UFSUNIPRO_FSYS>,
+				 <&cmu_top CLK_SCLK_MMC2_FSYS>,
+				 <&cmu_top CLK_SCLK_MMC1_FSYS>,
+				 <&cmu_top CLK_SCLK_MMC0_FSYS>,
+				 <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
+				 <&cmu_top CLK_SCLK_USBDRD30_FSYS>;
+		};
+
+		cmu_g2d: clock-controller@12460000 {
+			compatible = "samsung,exynos5433-cmu-g2d";
+			reg = <0x12460000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"aclk_g2d_266",
+				"aclk_g2d_400";
+			clocks = <&xxti>,
+				 <&cmu_top CLK_ACLK_G2D_266>,
+				 <&cmu_top CLK_ACLK_G2D_400>;
+		};
+
+		cmu_disp: clock-controller@13b90000 {
+			compatible = "samsung,exynos5433-cmu-disp";
+			reg = <0x13b90000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_dsim1_disp",
+				"sclk_dsim0_disp",
+				"sclk_dsd_disp",
+				"sclk_decon_tv_eclk_disp",
+				"sclk_decon_vclk_disp",
+				"sclk_decon_eclk_disp",
+				"sclk_decon_tv_vclk_disp",
+				"aclk_disp_333";
+			clocks = <&xxti>,
+				 <&cmu_mif CLK_SCLK_DSIM1_DISP>,
+				 <&cmu_mif CLK_SCLK_DSIM0_DISP>,
+				 <&cmu_mif CLK_SCLK_DSD_DISP>,
+				 <&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>,
+				 <&cmu_mif CLK_SCLK_DECON_VCLK_DISP>,
+				 <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
+				 <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
+				 <&cmu_mif CLK_ACLK_DISP_333>;
+		};
+
+		cmu_aud: clock-controller@114c0000 {
+			compatible = "samsung,exynos5433-cmu-aud";
+			reg = <0x114c0000 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		cmu_bus0: clock-controller@13600000 {
+			compatible = "samsung,exynos5433-cmu-bus0";
+			reg = <0x13600000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "aclk_bus0_400";
+			clocks = <&cmu_top CLK_ACLK_BUS0_400>;
+		};
+
+		cmu_bus1: clock-controller@14800000 {
+			compatible = "samsung,exynos5433-cmu-bus1";
+			reg = <0x14800000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "aclk_bus1_400";
+			clocks = <&cmu_top CLK_ACLK_BUS1_400>;
+		};
+
+		cmu_bus2: clock-controller@13400000 {
+			compatible = "samsung,exynos5433-cmu-bus2";
+			reg = <0x13400000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "aclk_bus2_400";
+			clocks = <&xxti>, <&cmu_mif CLK_ACLK_BUS2_400>;
+		};
+
+		cmu_g3d: clock-controller@14aa0000 {
+			compatible = "samsung,exynos5433-cmu-g3d";
+			reg = <0x14aa0000 0x2000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "aclk_g3d_400";
+			clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
+		};
+
+		cmu_gscl: clock-controller@13cf0000 {
+			compatible = "samsung,exynos5433-cmu-gscl";
+			reg = <0x13cf0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"aclk_gscl_111",
+				"aclk_gscl_333";
+			clocks = <&xxti>,
+				<&cmu_top CLK_ACLK_GSCL_111>,
+				<&cmu_top CLK_ACLK_GSCL_333>;
+		};
+
+		cmu_apollo: clock-controller@11900000 {
+			compatible = "samsung,exynos5433-cmu-apollo";
+			reg = <0x11900000 0x2000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "sclk_bus_pll_apollo";
+			clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>;
+		};
+
+		cmu_atlas: clock-controller@11800000 {
+			compatible = "samsung,exynos5433-cmu-atlas";
+			reg = <0x11800000 0x2000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "sclk_bus_pll_atlas";
+			clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>;
+		};
+
+		cmu_mscl: clock-controller@105d0000 {
+			compatible = "samsung,exynos5433-cmu-mscl";
+			reg = <0x150d0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_jpeg_mscl",
+				"aclk_mscl_400";
+			clocks = <&xxti>,
+				 <&cmu_top CLK_SCLK_JPEG_MSCL>,
+				 <&cmu_top CLK_ACLK_MSCL_400>;
+		};
+
+		cmu_mfc: clock-controller@15280000 {
+			compatible = "samsung,exynos5433-cmu-mfc";
+			reg = <0x15280000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "aclk_mfc_400";
+			clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
+		};
+
+		cmu_hevc: clock-controller@14f80000 {
+			compatible = "samsung,exynos5433-cmu-hevc";
+			reg = <0x14f80000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk", "aclk_hevc_400";
+			clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
+		};
+
+		cmu_isp: clock-controller@146d0000 {
+			compatible = "samsung,exynos5433-cmu-isp";
+			reg = <0x146d0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"aclk_isp_dis_400",
+				"aclk_isp_400";
+			clocks = <&xxti>,
+				 <&cmu_top CLK_ACLK_ISP_DIS_400>,
+				 <&cmu_top CLK_ACLK_ISP_400>;
+		};
+
+		cmu_cam0: clock-controller@120d0000 {
+			compatible = "samsung,exynos5433-cmu-cam0";
+			reg = <0x120d0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"aclk_cam0_333",
+				"aclk_cam0_400",
+				"aclk_cam0_552";
+			clocks = <&xxti>,
+				 <&cmu_top CLK_ACLK_CAM0_333>,
+				 <&cmu_top CLK_ACLK_CAM0_400>,
+				 <&cmu_top CLK_ACLK_CAM0_552>;
+		};
+
+		cmu_cam1: clock-controller@145d0000 {
+			compatible = "samsung,exynos5433-cmu-cam1";
+			reg = <0x145d0000 0x1000>;
+			#clock-cells = <1>;
+
+			clock-names = "oscclk",
+				"sclk_isp_uart_cam1",
+				"sclk_isp_spi1_cam1",
+				"sclk_isp_spi0_cam1",
+				"aclk_cam1_333",
+				"aclk_cam1_400",
+				"aclk_cam1_552";
+			clocks = <&xxti>,
+				 <&cmu_top CLK_SCLK_ISP_UART_CAM1>,
+				 <&cmu_top CLK_SCLK_ISP_SPI1_CAM1>,
+				 <&cmu_top CLK_SCLK_ISP_SPI0_CAM1>,
+				 <&cmu_top CLK_ACLK_CAM1_333>,
+				 <&cmu_top CLK_ACLK_CAM1_400>,
+				 <&cmu_top CLK_ACLK_CAM1_552>;
+		};
+
+		mct@101c0000 {
+			compatible = "samsung,exynos5433-mct",
+				     "samsung,exynos4210-mct";
+			reg = <0x101c0000 0x800>;
+			interrupts = <0 102 0>, <0 103 0>, <0 104 0>, <0 105 0>,
+				<0 106 0>, <0 107 0>, <0 108 0>, <0 109 0>,
+				<0 110 0>, <0 111 0>, <0 112 0>, <0 113 0>;
+			clocks = <&xxti>,
+				 <&cmu_peris CLK_PCLK_MCT>;
+			clock-names = "fin_pll", "mct";
+		};
+
+		gic:interrupt-controller@11001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x11001000 0x1000>,
+				<0x11002000 0x2000>,
+				<0x11004000 0x2000>,
+				<0x11006000 0x2000>;
+			interrupts = <1 9 0xf04>;
+		};
+
+		amba {
+			compatible = "arm,amba-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			pdma0: pdma@15610000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x15610000 0x1000>;
+				interrupts = <0 228 0>;
+				clocks = <&cmu_fsys CLK_PDMA0>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <32>;
+			};
+
+			pdma1: pdma@15600000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x15600000 0x1000>;
+				interrupts = <0 246 0>;
+				clocks = <&cmu_fsys CLK_PDMA1>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <32>;
+			};
+
+			adma: adma@11420000 {
+				compatible = "arm,pl330", "arm,primecell";
+				reg = <0x11420000 0x1000>;
+				interrupts = <0 73 0>;
+				clocks = <&cmu_aud CLK_ACLK_DMAC>;
+				clock-names = "apb_pclk";
+				#dma-cells = <1>;
+				#dma-channels = <8>;
+				#dma-requests = <32>;
+			};
+		};
+
+		serial_0: serial@14c10000 {
+			compatible = "samsung,exynos5433-uart";
+			reg = <0x14c10000 0x100>;
+			interrupts = <0 421 0>;
+			clocks = <&cmu_peric CLK_PCLK_UART0>,
+				 <&cmu_peric CLK_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_bus>;
+			status = "disabled";
+		};
+
+		serial_1: serial@14c20000 {
+			compatible = "samsung,exynos5433-uart";
+			reg = <0x14c20000 0x100>;
+			interrupts = <0 422 0>;
+			clocks = <&cmu_peric CLK_PCLK_UART1>,
+				 <&cmu_peric CLK_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart1_bus>;
+			status = "disabled";
+		};
+
+		serial_2: serial@14c30000 {
+			compatible = "samsung,exynos5433-uart";
+			reg = <0x14c30000 0x100>;
+			interrupts = <0 423 0>;
+			clocks = <&cmu_peric CLK_PCLK_UART2>,
+				 <&cmu_peric CLK_SCLK_UART2>;
+			clock-names = "uart", "clk_uart_baud0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart2_bus>;
+			status = "disabled";
+		};
+
+		i2s0: i2s0@11440000 {
+			compatible = "samsung,exynos7-i2s";
+			reg = <0x11440000 0x100>;
+			dmas = <&adma 0 &adma 2>;
+			dma-names = "tx", "rx";
+			interrupts = <0 70 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
+				 <&cmu_aud CLK_SCLK_AUD_I2S>,
+				 <&cmu_aud CLK_SCLK_I2S_BCLK>;
+			clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2s0_bus>;
+			status = "disabled";
+		};
+
+		pinctrl_alive: pinctrl@10580000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x10580000 0x1000>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos7-wakeup-eint";
+				interrupts = <0 16 0>;
+			};
+		};
+
+		pinctrl_aud: pinctrl@114b0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x114b0000 0x1000>;
+			interrupts = <0 68 0>;
+		};
+
+		pinctrl_cpif: pinctrl@10fe0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x10fe0000 0x1000>;
+			interrupts = <0 179 0>;
+		};
+
+		pinctrl_ese: pinctrl@14ca0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x14ca0000 0x1000>;
+			interrupts = <0 413 0>;
+		};
+
+		pinctrl_finger: pinctrl@14cb0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x14cb0000 0x1000>;
+			interrupts = <0 414 0>;
+		};
+
+		pinctrl_fsys: pinctrl@15690000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x15690000 0x1000>;
+			interrupts = <0 229 0>;
+		};
+
+		pinctrl_imem: pinctrl@11090000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x11090000 0x1000>;
+			interrupts = <0 325 0>;
+		};
+
+		pinctrl_nfc: pinctrl@14cd0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x14cd0000 0x1000>;
+			interrupts = <0 441 0>;
+		};
+
+		pinctrl_peric: pinctrl@14cc0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x14cc0000 0x1100>;
+			interrupts = <0 440 0>;
+		};
+
+		pinctrl_touch: pinctrl@14ce0000 {
+			compatible = "samsung,exynos5433-pinctrl";
+			reg = <0x14ce0000 0x1100>;
+			interrupts = <0 442 0>;
+		};
+
+		spi_0: spi@14d20000 {
+			compatible = "samsung,exynos7-spi";
+			reg = <0x14d20000 0x100>;
+			interrupts = <0 432 0>;
+			dmas = <&pdma0 9>, <&pdma0 8>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_peric CLK_PCLK_SPI0>,
+				 <&cmu_top CLK_SCLK_SPI0_PERIC>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_bus>;
+			status = "disabled";
+		};
+
+		spi_1: spi@14d30000 {
+			compatible = "samsung,exynos7-spi";
+			reg = <0x14d30000 0x100>;
+			interrupts = <0 433 0>;
+			dmas = <&pdma0 11>, <&pdma0 10>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_peric CLK_PCLK_SPI1>,
+				 <&cmu_top CLK_SCLK_SPI1_PERIC>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_bus>;
+			status = "disabled";
+		};
+
+		spi_2: spi@14d40000 {
+			compatible = "samsung,exynos7-spi";
+			reg = <0x14d40000 0x100>;
+			interrupts = <0 434 0>;
+			dmas = <&pdma0 13>, <&pdma0 12>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_peric CLK_PCLK_SPI2>,
+				 <&cmu_top CLK_SCLK_SPI2_PERIC>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi2_bus>;
+			status = "disabled";
+		};
+
+		spi_3: spi@14d50000 {
+			compatible = "samsung,exynos7-spi";
+			reg = <0x14d50000 0x100>;
+			interrupts = <0 447 0>;
+			dmas = <&pdma0 23>, <&pdma0 22>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_peric CLK_PCLK_SPI3>,
+				 <&cmu_top CLK_SCLK_SPI3_PERIC>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi3_bus>;
+			status = "disabled";
+		};
+
+		spi_4: spi@14d00000 {
+			compatible = "samsung,exynos7-spi";
+			reg = <0x14d00000 0x100>;
+			interrupts = <0 412 0>;
+			dmas = <&pdma0 25>, <&pdma0 24>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_peric CLK_PCLK_SPI4>,
+				 <&cmu_top CLK_SCLK_SPI4_PERIC>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi4_bus>;
+			status = "disabled";
+		};
+
+		hsi2c_0: hsi2c@14e40000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14e40000 0x1000>;
+			interrupts = <0 428 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: hsi2c@14e50000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14e50000 0x1000>;
+			interrupts = <0 429 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: hsi2c@14e60000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14e60000 0x1000>;
+			interrupts = <0 430 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: hsi2c@14e70000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14e70000 0x1000>;
+			interrupts = <0 431 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: hsi2c@14ec0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14ec0000 0x1000>;
+			interrupts = <0 424 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: hsi2c@14ed0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14ed0000 0x1000>;
+			interrupts = <0 425 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: hsi2c@14ee0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14ee0000 0x1000>;
+			interrupts = <0 426 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: hsi2c@14ef0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14ef0000 0x1000>;
+			interrupts = <0 427 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_8: hsi2c@14d90000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14d90000 0x1000>;
+			interrupts = <0 443 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c8_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C8>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_9: hsi2c@14da0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14da0000 0x1000>;
+			interrupts = <0 444 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c9_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C9>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_10: hsi2c@14de0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14de0000 0x1000>;
+			interrupts = <0 445 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c10_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C10>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_11: hsi2c@14df0000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x14df0000 0x1000>;
+			interrupts = <0 446 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c11_bus>;
+			clocks = <&cmu_peric CLK_PCLK_HSI2C11>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		mshc_0: mshc@15540000 {
+			compatible = "samsung,exynos7-dw-mshc-smu";
+			interrupts = <0 225 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x15540000 0x2000>;
+			clocks = <&cmu_fsys CLK_ACLK_MMC0>,
+				 <&cmu_fsys CLK_SCLK_MMC0>;
+			clock-names = "biu", "ciu";
+			fifo-depth = <0x40>;
+			status = "disabled";
+		};
+
+		mshc_1: mshc@15550000 {
+			compatible = "samsung,exynos7-dw-mshc-smu";
+			interrupts = <0 226 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x15550000 0x2000>;
+			clocks = <&cmu_fsys CLK_ACLK_MMC1>,
+				 <&cmu_fsys CLK_SCLK_MMC1>;
+			clock-names = "biu", "ciu";
+			fifo-depth = <0x40>;
+			status = "disabled";
+		};
+
+		mshc_2: mshc@15560000 {
+			compatible = "samsung,exynos7-dw-mshc-smu";
+			interrupts = <0 227 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x15560000 0x2000>;
+			clocks = <&cmu_fsys CLK_ACLK_MMC2>,
+				 <&cmu_fsys CLK_SCLK_MMC2>;
+			clock-names = "biu", "ciu";
+			fifo-depth = <0x40>;
+			status = "disabled";
+		};
+
+		tmu_atlas0: tmu@10060000 {
+			compatible = "samsung,exynos5433-tmu";
+			reg = <0x10060000 0x200>;
+			interrupts = <0 95 0>;
+			clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
+				 <&cmu_peris CLK_SCLK_TMU0>;
+			clock-names = "tmu_apbif", "tmu_sclk";
+			#include "exynos5433-tmu-sensor-conf.dtsi"
+			status = "disabled";
+		};
+
+		tmu_atlas1: tmu@10068000 {
+			compatible = "samsung,exynos5433-tmu";
+			reg = <0x10068000 0x200>;
+			interrupts = <0 96 0>;
+			clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
+				 <&cmu_peris CLK_SCLK_TMU0>;
+			clock-names = "tmu_apbif", "tmu_sclk";
+			#include "exynos5433-tmu-sensor-conf.dtsi"
+			status = "disabled";
+		};
+
+		tmu_g3d: tmu@10070000 {
+			compatible = "samsung,exynos5433-tmu";
+			reg = <0x10070000 0x200>;
+			interrupts = <0 99 0>;
+			clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+				 <&cmu_peris CLK_SCLK_TMU1>;
+			clock-names = "tmu_apbif", "tmu_sclk";
+			#include "exynos5433-tmu-sensor-conf.dtsi"
+			status = "disabled";
+		};
+
+		tmu_apollo: tmu@10078000 {
+			compatible = "samsung,exynos5433-tmu";
+			reg = <0x10078000 0x200>;
+			interrupts = <0 115 0>;
+			clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+				 <&cmu_peris CLK_SCLK_TMU1>;
+			clock-names = "tmu_apbif", "tmu_sclk";
+			#include "exynos5433-tmu-sensor-conf.dtsi"
+			status = "disabled";
+		};
+
+		tmu_isp: tmu@1007c000 {
+			compatible = "samsung,exynos5433-tmu";
+			reg = <0x1007c000 0x200>;
+			interrupts = <0 94 0>;
+			clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+				 <&cmu_peris CLK_SCLK_TMU1>;
+			clock-names = "tmu_apbif", "tmu_sclk";
+			#include "exynos5433-tmu-sensor-conf.dtsi"
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller@105c0000 {
+			compatible = "samsung,exynos5433-pmu", "syscon";
+			reg = <0x105c0000 0x5008>;
+			#clock-cells = <1>;
+			clock-names = "clkout16";
+			clocks = <&xxti>;
+		};
+
+		rtc: rtc@10590000 {
+			compatible = "samsung,exynos3250-rtc";
+			reg = <0x10590000 0x100>;
+			interrupts = <0 385 0>, <0 386 0>;
+			status = "disabled";
+		};
+
+		adc: adc@14d10000 {
+			compatible = "samsung,exynos7-adc";
+			reg = <0x14d10000 0x100>;
+			interrupts = <0 438 0>;
+			clock-names = "adc";
+			clocks = <&cmu_peric CLK_PCLK_ADCIF>;
+			#io-channel-cells = <1>;
+			io-channel-ranges;
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff04>,
+			     <1 14 0xff04>,
+			     <1 11 0xff04>,
+			     <1 10 0xff04>;
+	};
+};
+
+#include "exynos5433-pinctrl.dtsi"
+#include "exynos5433-tmu.dtsi"
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index 2eef4a279131..96be6e3efd7e 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -586,3 +586,114 @@
 		samsung,pin-drv = <2>;
 	};
 };
+
+&pinctrl_bus1 {
+	etc1: etc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gph1: gph1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpv6: gpv6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	spi5_bus: spi5-bus {
+		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	ufs_refclk_out: ufs-refclk-out {
+		samsung,pins = "gpg2-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <2>;
+	};
+
+	ufs_rst_n: ufs-rst-n {
+		samsung,pins = "gph1-5";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index d7a37c3a6b52..f9c5a549c2c0 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -26,6 +26,7 @@
 		pinctrl5 = &pinctrl_ese;
 		pinctrl6 = &pinctrl_fsys0;
 		pinctrl7 = &pinctrl_fsys1;
+		pinctrl8 = &pinctrl_bus1;
 	};
 
 	cpus {
@@ -278,6 +279,12 @@
 			interrupts = <0 203 0>;
 		};
 
+		pinctrl_bus1: pinctrl@14870000 {
+			compatible = "samsung,exynos7-pinctrl";
+			reg = <0x14870000 0x1000>;
+			interrupts = <0 384 0>;
+		};
+
 		hsi2c_0: hsi2c@13640000 {
 			compatible = "samsung,exynos7-hsi2c";
 			reg = <0x13640000 0x1000>;
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 7605e095217f..cbc5e1a0ea8f 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -95,6 +95,7 @@
 			 SCTLR_EL2_SA | SCTLR_EL2_I)
 
 /* TCR_EL2 Registers bits */
+#define TCR_EL2_RES1	((1 << 31) | (1 << 23))
 #define TCR_EL2_TBI	(1 << 20)
 #define TCR_EL2_PS	(7 << 16)
 #define TCR_EL2_PS_40B	(2 << 16)
@@ -106,9 +107,10 @@
 #define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
 			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
 
-#define TCR_EL2_FLAGS	(TCR_EL2_PS_40B)
+#define TCR_EL2_FLAGS	(TCR_EL2_RES1 | TCR_EL2_PS_40B)
 
 /* VTCR_EL2 Registers bits */
+#define VTCR_EL2_RES1		(1 << 31)
 #define VTCR_EL2_PS_MASK	(7 << 16)
 #define VTCR_EL2_TG0_MASK	(1 << 14)
 #define VTCR_EL2_TG0_4K		(0 << 14)
@@ -147,7 +149,8 @@
  */
 #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
+				 VTCR_EL2_RES1)
 #define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
 #else
 /*
@@ -158,7 +161,8 @@
  */
 #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
+				 VTCR_EL2_RES1)
 #define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
 #endif
 
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 77ea09b8bce1..e0fe4ddd2b79 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -8,6 +8,7 @@ config C6X
 	select CLKDEV_LOOKUP
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
+	select HANDLE_DOMAIN_IRQ
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_MEMBLOCK
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 247e0eb5e467..a7f73bc765ac 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -58,22 +58,13 @@ static struct irq_chip core_chip = {
 };
 
 static int prio_to_virq[NR_PRIORITY_IRQS];
+static struct irq_domain *core_domain;
 
 asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
 {
-	struct pt_regs *old_regs = set_irq_regs(regs);
-
-	irq_enter();
-
-	generic_handle_irq(prio_to_virq[prio]);
-
-	irq_exit();
-
-	set_irq_regs(old_regs);
+	__handle_domain_irq(core_domain, prio, true, regs);
 }
 
-static struct irq_domain *core_domain;
-
 static int core_domain_map(struct irq_domain *h, unsigned int virq,
 			   irq_hw_number_t hw)
 {
diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c
index c86ac37d1983..cfe9aa422343 100644
--- a/arch/m68k/sun3/idprom.c
+++ b/arch/m68k/sun3/idprom.c
@@ -125,8 +125,5 @@ void __init idprom_init(void)
 
 	display_system_type(idprom->id_machtype);
 
-	printk("Ethernet address: %x:%x:%x:%x:%x:%x\n",
-		    idprom->id_ethaddr[0], idprom->id_ethaddr[1],
-		    idprom->id_ethaddr[2], idprom->id_ethaddr[3],
-		    idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
+	printk("Ethernet address: %pM\n", idprom->id_ethaddr);
 }
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 71f2b3f02cf8..4d65499ee1c1 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -368,3 +368,4 @@ SYSCALL_SPU(memfd_create)
 SYSCALL_SPU(bpf)
 COMPAT_SYS(execveat)
 PPC64ONLY(switch_endian)
+SYSCALL_SPU(userfaultfd)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index f4f8b667d75b..4a055b6c2a64 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls		364
+#define __NR_syscalls		365
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index e4aa173dae62..6ad58d4c879b 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -386,5 +386,6 @@
 #define __NR_bpf		361
 #define __NR_execveat		362
 #define __NR_switch_endian	363
+#define __NR_userfaultfd	364
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index b0382f3f1095..d1e65ce545b3 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -48,7 +48,7 @@ struct cpu_hw_events {
 	unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
 	unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
 
-	unsigned int group_flag;
+	unsigned int txn_flags;
 	int n_txn_start;
 
 	/* BHRB bits */
@@ -1441,7 +1441,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags)
 	 * skip the schedulability test here, it will be performed
 	 * at commit time(->commit_txn) as a whole
 	 */
-	if (cpuhw->group_flag & PERF_EVENT_TXN)
+	if (cpuhw->txn_flags & PERF_PMU_TXN_ADD)
 		goto nocheck;
 
 	if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
@@ -1586,13 +1586,22 @@ static void power_pmu_stop(struct perf_event *event, int ef_flags)
  * Start group events scheduling transaction
  * Set the flag to make pmu::enable() not perform the
  * schedulability test, it will be performed at commit time
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
  */
-static void power_pmu_start_txn(struct pmu *pmu)
+static void power_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
 {
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 
+	WARN_ON_ONCE(cpuhw->txn_flags);		/* txn already in flight */
+
+	cpuhw->txn_flags = txn_flags;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_disable(pmu);
-	cpuhw->group_flag |= PERF_EVENT_TXN;
 	cpuhw->n_txn_start = cpuhw->n_events;
 }
 
@@ -1604,8 +1613,15 @@ static void power_pmu_start_txn(struct pmu *pmu)
 static void power_pmu_cancel_txn(struct pmu *pmu)
 {
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+	unsigned int txn_flags;
+
+	WARN_ON_ONCE(!cpuhw->txn_flags);	/* no txn in flight */
+
+	txn_flags = cpuhw->txn_flags;
+	cpuhw->txn_flags = 0;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
 
-	cpuhw->group_flag &= ~PERF_EVENT_TXN;
 	perf_pmu_enable(pmu);
 }
 
@@ -1621,7 +1637,15 @@ static int power_pmu_commit_txn(struct pmu *pmu)
 
 	if (!ppmu)
 		return -EAGAIN;
+
 	cpuhw = this_cpu_ptr(&cpu_hw_events);
+	WARN_ON_ONCE(!cpuhw->txn_flags);	/* no txn in flight */
+
+	if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
+		cpuhw->txn_flags = 0;
+		return 0;
+	}
+
 	n = cpuhw->n_events;
 	if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
 		return -EAGAIN;
@@ -1632,7 +1656,7 @@ static int power_pmu_commit_txn(struct pmu *pmu)
 	for (i = cpuhw->n_txn_start; i < n; ++i)
 		cpuhw->event[i]->hw.config = cpuhw->events[i];
 
-	cpuhw->group_flag &= ~PERF_EVENT_TXN;
+	cpuhw->txn_flags = 0;
 	perf_pmu_enable(pmu);
 	return 0;
 }
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 527c8b98e97e..9f9dfda9ed2c 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -142,6 +142,15 @@ static struct attribute_group event_long_desc_group = {
 
 static struct kmem_cache *hv_page_cache;
 
+DEFINE_PER_CPU(int, hv_24x7_txn_flags);
+DEFINE_PER_CPU(int, hv_24x7_txn_err);
+
+struct hv_24x7_hw {
+	struct perf_event *events[255];
+};
+
+DEFINE_PER_CPU(struct hv_24x7_hw, hv_24x7_hw);
+
 /*
  * request_buffer and result_buffer are not required to be 4k aligned,
  * but are not allowed to cross any 4k boundary. Aligning them to 4k is
@@ -1231,9 +1240,48 @@ static void update_event_count(struct perf_event *event, u64 now)
 static void h_24x7_event_read(struct perf_event *event)
 {
 	u64 now;
+	struct hv_24x7_request_buffer *request_buffer;
+	struct hv_24x7_hw *h24x7hw;
+	int txn_flags;
+
+	txn_flags = __this_cpu_read(hv_24x7_txn_flags);
+
+	/*
+	 * If in a READ transaction, add this counter to the list of
+	 * counters to read during the next HCALL (i.e commit_txn()).
+	 * If not in a READ transaction, go ahead and make the HCALL
+	 * to read this counter by itself.
+	 */
+
+	if (txn_flags & PERF_PMU_TXN_READ) {
+		int i;
+		int ret;
 
-	now = h_24x7_get_value(event);
-	update_event_count(event, now);
+		if (__this_cpu_read(hv_24x7_txn_err))
+			return;
+
+		request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+
+		ret = add_event_to_24x7_request(event, request_buffer);
+		if (ret) {
+			__this_cpu_write(hv_24x7_txn_err, ret);
+		} else {
+			/*
+			 * Assoicate the event with the HCALL request index,
+			 * so ->commit_txn() can quickly find/update count.
+			 */
+			i = request_buffer->num_requests - 1;
+
+			h24x7hw = &get_cpu_var(hv_24x7_hw);
+			h24x7hw->events[i] = event;
+			put_cpu_var(h24x7hw);
+		}
+
+		put_cpu_var(hv_24x7_reqb);
+	} else {
+		now = h_24x7_get_value(event);
+		update_event_count(event, now);
+	}
 }
 
 static void h_24x7_event_start(struct perf_event *event, int flags)
@@ -1255,6 +1303,117 @@ static int h_24x7_event_add(struct perf_event *event, int flags)
 	return 0;
 }
 
+/*
+ * 24x7 counters only support READ transactions. They are
+ * always counting and dont need/support ADD transactions.
+ * Cache the flags, but otherwise ignore transactions that
+ * are not PERF_PMU_TXN_READ.
+ */
+static void h_24x7_event_start_txn(struct pmu *pmu, unsigned int flags)
+{
+	struct hv_24x7_request_buffer *request_buffer;
+	struct hv_24x7_data_result_buffer *result_buffer;
+
+	/* We should not be called if we are already in a txn */
+	WARN_ON_ONCE(__this_cpu_read(hv_24x7_txn_flags));
+
+	__this_cpu_write(hv_24x7_txn_flags, flags);
+	if (flags & ~PERF_PMU_TXN_READ)
+		return;
+
+	request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+	result_buffer = (void *)get_cpu_var(hv_24x7_resb);
+
+	init_24x7_request(request_buffer, result_buffer);
+
+	put_cpu_var(hv_24x7_resb);
+	put_cpu_var(hv_24x7_reqb);
+}
+
+/*
+ * Clean up transaction state.
+ *
+ * NOTE: Ignore state of request and result buffers for now.
+ *	 We will initialize them during the next read/txn.
+ */
+static void reset_txn(void)
+{
+	__this_cpu_write(hv_24x7_txn_flags, 0);
+	__this_cpu_write(hv_24x7_txn_err, 0);
+}
+
+/*
+ * 24x7 counters only support READ transactions. They are always counting
+ * and dont need/support ADD transactions. Clear ->txn_flags but otherwise
+ * ignore transactions that are not of type PERF_PMU_TXN_READ.
+ *
+ * For READ transactions, submit all pending 24x7 requests (i.e requests
+ * that were queued by h_24x7_event_read()), to the hypervisor and update
+ * the event counts.
+ */
+static int h_24x7_event_commit_txn(struct pmu *pmu)
+{
+	struct hv_24x7_request_buffer *request_buffer;
+	struct hv_24x7_data_result_buffer *result_buffer;
+	struct hv_24x7_result *resb;
+	struct perf_event *event;
+	u64 count;
+	int i, ret, txn_flags;
+	struct hv_24x7_hw *h24x7hw;
+
+	txn_flags = __this_cpu_read(hv_24x7_txn_flags);
+	WARN_ON_ONCE(!txn_flags);
+
+	ret = 0;
+	if (txn_flags & ~PERF_PMU_TXN_READ)
+		goto out;
+
+	ret = __this_cpu_read(hv_24x7_txn_err);
+	if (ret)
+		goto out;
+
+	request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+	result_buffer = (void *)get_cpu_var(hv_24x7_resb);
+
+	ret = make_24x7_request(request_buffer, result_buffer);
+	if (ret) {
+		log_24x7_hcall(request_buffer, result_buffer, ret);
+		goto put_reqb;
+	}
+
+	h24x7hw = &get_cpu_var(hv_24x7_hw);
+
+	/* Update event counts from hcall */
+	for (i = 0; i < request_buffer->num_requests; i++) {
+		resb = &result_buffer->results[i];
+		count = be64_to_cpu(resb->elements[0].element_data[0]);
+		event = h24x7hw->events[i];
+		h24x7hw->events[i] = NULL;
+		update_event_count(event, count);
+	}
+
+	put_cpu_var(hv_24x7_hw);
+
+put_reqb:
+	put_cpu_var(hv_24x7_resb);
+	put_cpu_var(hv_24x7_reqb);
+out:
+	reset_txn();
+	return ret;
+}
+
+/*
+ * 24x7 counters only support READ transactions. They are always counting
+ * and dont need/support ADD transactions. However, regardless of type
+ * of transaction, all we need to do is cleanup, so we don't have to check
+ * the type of transaction.
+ */
+static void h_24x7_event_cancel_txn(struct pmu *pmu)
+{
+	WARN_ON_ONCE(!__this_cpu_read(hv_24x7_txn_flags));
+	reset_txn();
+}
+
 static struct pmu h_24x7_pmu = {
 	.task_ctx_nr = perf_invalid_context,
 
@@ -1266,6 +1425,9 @@ static struct pmu h_24x7_pmu = {
 	.start       = h_24x7_event_start,
 	.stop        = h_24x7_event_stop,
 	.read        = h_24x7_event_read,
+	.start_txn   = h_24x7_event_start_txn,
+	.commit_txn  = h_24x7_event_commit_txn,
+	.cancel_txn  = h_24x7_event_cancel_txn,
 };
 
 static int hv_24x7_init(void)
diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c
index e66ef1943338..b304a9fe55cc 100644
--- a/arch/powerpc/platforms/pasemi/msi.c
+++ b/arch/powerpc/platforms/pasemi/msi.c
@@ -63,6 +63,7 @@ static struct irq_chip mpic_pasemi_msi_chip = {
 static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
 {
 	struct msi_desc *entry;
+	irq_hw_number_t hwirq;
 
 	pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);
 
@@ -70,10 +71,10 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
 		if (entry->irq == NO_IRQ)
 			continue;
 
+		hwirq = virq_to_hw(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
-		msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
-				       virq_to_hw(entry->irq), ALLOC_CHUNK);
 		irq_dispose_mapping(entry->irq);
+		msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, ALLOC_CHUNK);
 	}
 
 	return;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2927cd5c8303..414fd1a00fda 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2049,9 +2049,23 @@ static long pnv_pci_ioda2_setup_default_config(struct pnv_ioda_pe *pe)
 	struct iommu_table *tbl = NULL;
 	long rc;
 
+	/*
+	 * crashkernel= specifies the kdump kernel's maximum memory at
+	 * some offset and there is no guaranteed the result is a power
+	 * of 2, which will cause errors later.
+	 */
+	const u64 max_memory = __rounddown_pow_of_two(memory_hotplug_max());
+
+	/*
+	 * In memory constrained environments, e.g. kdump kernel, the
+	 * DMA window can be larger than available memory, which will
+	 * cause errors later.
+	 */
+	const u64 window_size = min((u64)pe->table_group.tce32_size, max_memory);
+
 	rc = pnv_pci_ioda2_create_table(&pe->table_group, 0,
 			IOMMU_PAGE_SHIFT_4K,
-			pe->table_group.tce32_size,
+			window_size,
 			POWERNV_IOMMU_DEFAULT_LEVELS, &tbl);
 	if (rc) {
 		pe_err(pe, "Failed to create 32-bit TCE table, err %ld",
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 9b2480b265c0..f2dd77234240 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -99,6 +99,7 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev)
 	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
 	struct pnv_phb *phb = hose->private_data;
 	struct msi_desc *entry;
+	irq_hw_number_t hwirq;
 
 	if (WARN_ON(!phb))
 		return;
@@ -106,10 +107,10 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev)
 	for_each_pci_msi_entry(entry, pdev) {
 		if (entry->irq == NO_IRQ)
 			continue;
+		hwirq = virq_to_hw(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
-		msi_bitmap_free_hwirqs(&phb->msi_bmp,
-			virq_to_hw(entry->irq) - phb->msi_base, 1);
 		irq_dispose_mapping(entry->irq);
+		msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq - phb->msi_base, 1);
 	}
 }
 #endif /* CONFIG_PCI_MSI */
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 47d9cebe7159..db17827eb746 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -422,8 +422,10 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
 
 	dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
 	of_node_put(parent);
-	if (!dn)
+	if (!dn) {
+		dlpar_release_drc(drc_index);
 		return -EINVAL;
+	}
 
 	rc = dlpar_attach_node(dn);
 	if (rc) {
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 5916da1856a7..48a576aa47b9 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -128,15 +128,16 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
 {
 	struct msi_desc *entry;
 	struct fsl_msi *msi_data;
+	irq_hw_number_t hwirq;
 
 	for_each_pci_msi_entry(entry, pdev) {
 		if (entry->irq == NO_IRQ)
 			continue;
+		hwirq = virq_to_hw(entry->irq);
 		msi_data = irq_get_chip_data(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
-		msi_bitmap_free_hwirqs(&msi_data->bitmap,
-				       virq_to_hw(entry->irq), 1);
 		irq_dispose_mapping(entry->irq);
+		msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
 	}
 
 	return;
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index 70fbd5694a8b..2cbc7e29b85f 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -107,15 +107,16 @@ static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
 static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
 {
 	struct msi_desc *entry;
+	irq_hw_number_t hwirq;
 
 	for_each_pci_msi_entry(entry, pdev) {
 		if (entry->irq == NO_IRQ)
 			continue;
 
+		hwirq = virq_to_hw(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
-		msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
-				       virq_to_hw(entry->irq), 1);
 		irq_dispose_mapping(entry->irq);
+		msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
 	}
 
 	return;
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 24d0470c1698..8fb806135043 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -124,16 +124,17 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)
 {
 	struct msi_desc *entry;
 	struct ppc4xx_msi *msi_data = &ppc4xx_msi;
+	irq_hw_number_t hwirq;
 
 	dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");
 
 	for_each_pci_msi_entry(entry, dev) {
 		if (entry->irq == NO_IRQ)
 			continue;
+		hwirq = virq_to_hw(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
-		msi_bitmap_free_hwirqs(&msi_data->bitmap,
-				virq_to_hw(entry->irq), 1);
 		irq_dispose_mapping(entry->irq);
+		msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
 	}
 }
 
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index eb4664238613..e0f9d270b30f 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -48,6 +48,19 @@ typedef struct
 	struct ucontext32 uc;
 } rt_sigframe32;
 
+static inline void sigset_to_sigset32(unsigned long *set64,
+				      compat_sigset_word *set32)
+{
+	set32[0] = (compat_sigset_word) set64[0];
+	set32[1] = (compat_sigset_word)(set64[0] >> 32);
+}
+
+static inline void sigset32_to_sigset(compat_sigset_word *set32,
+				      unsigned long *set64)
+{
+	set64[0] = (unsigned long) set32[0] | ((unsigned long) set32[1] << 32);
+}
+
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 {
 	int err;
@@ -281,10 +294,12 @@ COMPAT_SYSCALL_DEFINE0(sigreturn)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
+	compat_sigset_t cset;
 	sigset_t set;
 
-	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
+	if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
 		goto badframe;
+	sigset32_to_sigset(cset.sig, set.sig);
 	set_current_blocked(&set);
 	save_fpu_regs();
 	if (restore_sigregs32(regs, &frame->sregs))
@@ -302,10 +317,12 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
+	compat_sigset_t cset;
 	sigset_t set;
 
-	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+	if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset)))
 		goto badframe;
+	sigset32_to_sigset(cset.sig, set.sig);
 	set_current_blocked(&set);
 	if (compat_restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
@@ -377,7 +394,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 
 	/* Create struct sigcontext32 on the signal stack */
-	memcpy(&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32);
+	sigset_to_sigset32(set->sig, sc.oldmask);
 	sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
 	if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
 		return -EFAULT;
@@ -438,6 +455,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
 			    struct pt_regs *regs)
 {
+	compat_sigset_t cset;
 	rt_sigframe32 __user *frame;
 	unsigned long restorer;
 	size_t frame_size;
@@ -485,11 +503,12 @@ static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
 	store_sigregs();
 
 	/* Create ucontext on the signal stack. */
+	sigset_to_sigset32(set->sig, cset.sig);
 	if (__put_user(uc_flags, &frame->uc.uc_flags) ||
 	    __put_user(0, &frame->uc.uc_link) ||
 	    __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
 	    save_sigregs32(regs, &frame->uc.uc_mcontext) ||
-	    __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)) ||
+	    __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)) ||
 	    save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
 		return -EFAULT;
 
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 247b7aae4c6d..09b039d7983d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -1191,6 +1191,7 @@ cleanup_critical:
 	clg	%r9,BASED(.Lcleanup_save_fpu_fpc_end)
 	jhe	1f
 	lg	%r2,__LC_CURRENT
+	aghi	%r2,__TASK_thread
 0:	# Store floating-point controls
 	stfpc	__THREAD_FPU_fpc(%r2)
 1:	# Load register save area and check if VX is active
@@ -1252,6 +1253,7 @@ cleanup_critical:
 	clg	%r9,BASED(.Lcleanup_load_fpu_regs_vx_ctl)
 	jhe	6f
 	lg	%r4,__LC_CURRENT
+	aghi	%r4,__TASK_thread
 	lfpc	__THREAD_FPU_fpc(%r4)
 	tm	__THREAD_FPU_flags+3(%r4),FPU_USE_VX	# VX-enabled task ?
 	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 56fdad479115..cb774ff6e749 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -72,6 +72,7 @@ struct cpu_hw_events {
 	atomic_t		ctr_set[CPUMF_CTR_SET_MAX];
 	u64			state, tx_state;
 	unsigned int		flags;
+	unsigned int		txn_flags;
 };
 static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
 	.ctr_set = {
@@ -82,6 +83,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
 	},
 	.state = 0,
 	.flags = 0,
+	.txn_flags = 0,
 };
 
 static int get_counter_set(u64 event)
@@ -534,7 +536,7 @@ static int cpumf_pmu_add(struct perf_event *event, int flags)
 	 * For group events transaction, the authorization check is
 	 * done in cpumf_pmu_commit_txn().
 	 */
-	if (!(cpuhw->flags & PERF_EVENT_TXN))
+	if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD))
 		if (validate_ctr_auth(&event->hw))
 			return -EPERM;
 
@@ -572,13 +574,22 @@ static void cpumf_pmu_del(struct perf_event *event, int flags)
 /*
  * Start group events scheduling transaction.
  * Set flags to perform a single test at commit time.
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
  */
-static void cpumf_pmu_start_txn(struct pmu *pmu)
+static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
 {
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 
+	WARN_ON_ONCE(cpuhw->txn_flags);		/* txn already in flight */
+
+	cpuhw->txn_flags = txn_flags;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_disable(pmu);
-	cpuhw->flags |= PERF_EVENT_TXN;
 	cpuhw->tx_state = cpuhw->state;
 }
 
@@ -589,11 +600,18 @@ static void cpumf_pmu_start_txn(struct pmu *pmu)
  */
 static void cpumf_pmu_cancel_txn(struct pmu *pmu)
 {
+	unsigned int txn_flags;
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 
+	WARN_ON_ONCE(!cpuhw->txn_flags);	/* no txn in flight */
+
+	txn_flags = cpuhw->txn_flags;
+	cpuhw->txn_flags = 0;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	WARN_ON(cpuhw->tx_state != cpuhw->state);
 
-	cpuhw->flags &= ~PERF_EVENT_TXN;
 	perf_pmu_enable(pmu);
 }
 
@@ -607,13 +625,20 @@ static int cpumf_pmu_commit_txn(struct pmu *pmu)
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 	u64 state;
 
+	WARN_ON_ONCE(!cpuhw->txn_flags);	/* no txn in flight */
+
+	if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
+		cpuhw->txn_flags = 0;
+		return 0;
+	}
+
 	/* check if the updated state can be scheduled */
 	state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
 	state >>= CPUMF_LCCTL_ENABLE_SHIFT;
 	if ((state & cpuhw->info.auth_ctl) != state)
 		return -EPERM;
 
-	cpuhw->flags &= ~PERF_EVENT_TXN;
+	cpuhw->txn_flags = 0;
 	perf_pmu_enable(pmu);
 	return 0;
 }
diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S
index ca6294645dd3..2d6b6e81f812 100644
--- a/arch/s390/kernel/swsusp.S
+++ b/arch/s390/kernel/swsusp.S
@@ -30,6 +30,9 @@ ENTRY(swsusp_arch_suspend)
 	aghi	%r15,-STACK_FRAME_OVERHEAD
 	stg	%r1,__SF_BACKCHAIN(%r15)
 
+	/* Store FPU registers */
+	brasl	%r14,save_fpu_regs
+
 	/* Deactivate DAT */
 	stnsm	__SF_EMPTY(%r15),0xfb
 
@@ -47,23 +50,6 @@ ENTRY(swsusp_arch_suspend)
 
 	/* Store registers */
 	mvc	0x318(4,%r1),__SF_EMPTY(%r15)	/* move prefix to lowcore */
-	stfpc	0x31c(%r1)			/* store fpu control */
-	std	0,0x200(%r1)			/* store f0 */
-	std	1,0x208(%r1)			/* store f1 */
-	std	2,0x210(%r1)			/* store f2 */
-	std	3,0x218(%r1)			/* store f3 */
-	std	4,0x220(%r1)			/* store f4 */
-	std	5,0x228(%r1)			/* store f5 */
-	std	6,0x230(%r1)			/* store f6 */
-	std	7,0x238(%r1)			/* store f7 */
-	std	8,0x240(%r1)			/* store f8 */
-	std	9,0x248(%r1)			/* store f9 */
-	std	10,0x250(%r1)			/* store f10 */
-	std	11,0x258(%r1)			/* store f11 */
-	std	12,0x260(%r1)			/* store f12 */
-	std	13,0x268(%r1)			/* store f13 */
-	std	14,0x270(%r1)			/* store f14 */
-	std	15,0x278(%r1)			/* store f15 */
 	stam	%a0,%a15,0x340(%r1)		/* store access registers */
 	stctg	%c0,%c15,0x380(%r1)		/* store control registers */
 	stmg	%r0,%r15,0x280(%r1)		/* store general registers */
@@ -249,24 +235,6 @@ restore_registers:
 	lctlg	%c0,%c15,0x380(%r13)	/* load control registers */
 	lam	%a0,%a15,0x340(%r13)	/* load access registers */
 
-	lfpc	0x31c(%r13)		/* load fpu control */
-	ld	0,0x200(%r13)		/* load f0 */
-	ld	1,0x208(%r13)		/* load f1 */
-	ld	2,0x210(%r13)		/* load f2 */
-	ld	3,0x218(%r13)		/* load f3 */
-	ld	4,0x220(%r13)		/* load f4 */
-	ld	5,0x228(%r13)		/* load f5 */
-	ld	6,0x230(%r13)		/* load f6 */
-	ld	7,0x238(%r13)		/* load f7 */
-	ld	8,0x240(%r13)		/* load f8 */
-	ld	9,0x248(%r13)		/* load f9 */
-	ld	10,0x250(%r13)		/* load f10 */
-	ld	11,0x258(%r13)		/* load f11 */
-	ld	12,0x260(%r13)		/* load f12 */
-	ld	13,0x268(%r13)		/* load f13 */
-	ld	14,0x270(%r13)		/* load f14 */
-	ld	15,0x278(%r13)		/* load f15 */
-
 	/* Load old stack */
 	lg	%r15,0x2f8(%r13)
 
diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c
index 7de4e2f780d7..f92f946d9b56 100644
--- a/arch/s390/numa/mode_emu.c
+++ b/arch/s390/numa/mode_emu.c
@@ -436,9 +436,15 @@ static void emu_update_cpu_topology(void)
  */
 static unsigned long emu_setup_size_adjust(unsigned long size)
 {
+	unsigned long size_new;
+
 	size = size ? : CONFIG_EMU_SIZE;
-	size = roundup(size, memory_block_size_bytes());
-	return size;
+	size_new = roundup(size, memory_block_size_bytes());
+	if (size_new == size)
+		return size;
+	pr_warn("Increasing memory stripe size from %ld MB to %ld MB\n",
+		size, size_new);
+	return size_new;
 }
 
 /*
diff --git a/arch/sparc/include/uapi/asm/asi.h b/arch/sparc/include/uapi/asm/asi.h
index aace6f313716..7ad7203deaec 100644
--- a/arch/sparc/include/uapi/asm/asi.h
+++ b/arch/sparc/include/uapi/asm/asi.h
@@ -279,7 +279,7 @@
 				      * Most-Recently-Used, primary,
 				      * implicit
 				      */
-#define ASI_ST_BLKINIT_MRU_S	0xf2 /* (NG4) init-store, twin load,
+#define ASI_ST_BLKINIT_MRU_S	0xf3 /* (NG4) init-store, twin load,
 				      * Most-Recently-Used, secondary,
 				      * implicit
 				      */
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 689db65f8529..b0da5aedb336 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -108,7 +108,7 @@ struct cpu_hw_events {
 	/* Enabled/disable state.  */
 	int			enabled;
 
-	unsigned int		group_flag;
+	unsigned int		txn_flags;
 };
 static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
 
@@ -1379,7 +1379,7 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags)
 	 * skip the schedulability test here, it will be performed
 	 * at commit time(->commit_txn) as a whole
 	 */
-	if (cpuc->group_flag & PERF_EVENT_TXN)
+	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
 		goto nocheck;
 
 	if (check_excludes(cpuc->event, n0, 1))
@@ -1494,12 +1494,17 @@ static int sparc_pmu_event_init(struct perf_event *event)
  * Set the flag to make pmu::enable() not perform the
  * schedulability test, it will be performed at commit time
  */
-static void sparc_pmu_start_txn(struct pmu *pmu)
+static void sparc_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
 {
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
 
+	WARN_ON_ONCE(cpuhw->txn_flags);		/* txn already in flight */
+
+	cpuhw->txn_flags = txn_flags;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_disable(pmu);
-	cpuhw->group_flag |= PERF_EVENT_TXN;
 }
 
 /*
@@ -1510,8 +1515,15 @@ static void sparc_pmu_start_txn(struct pmu *pmu)
 static void sparc_pmu_cancel_txn(struct pmu *pmu)
 {
 	struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+	unsigned int txn_flags;
+
+	WARN_ON_ONCE(!cpuhw->txn_flags);	/* no txn in flight */
+
+	txn_flags = cpuhw->txn_flags;
+	cpuhw->txn_flags = 0;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
 
-	cpuhw->group_flag &= ~PERF_EVENT_TXN;
 	perf_pmu_enable(pmu);
 }
 
@@ -1528,14 +1540,20 @@ static int sparc_pmu_commit_txn(struct pmu *pmu)
 	if (!sparc_pmu)
 		return -EINVAL;
 
-	cpuc = this_cpu_ptr(&cpu_hw_events);
+	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
+
+	if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
+		cpuc->txn_flags = 0;
+		return 0;
+	}
+
 	n = cpuc->n_events;
 	if (check_excludes(cpuc->event, 0, n))
 		return -EINVAL;
 	if (sparc_check_constraints(cpuc->event, cpuc->events, n))
 		return -EAGAIN;
 
-	cpuc->group_flag &= ~PERF_EVENT_TXN;
+	cpuc->txn_flags = 0;
 	perf_pmu_enable(pmu);
 	return 0;
 }
diff --git a/arch/sparc/lib/VISsave.S b/arch/sparc/lib/VISsave.S
index a063d84336d6..62c2647bd5ce 100644
--- a/arch/sparc/lib/VISsave.S
+++ b/arch/sparc/lib/VISsave.S
@@ -6,24 +6,23 @@
  * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
+#include <linux/linkage.h>
+
 #include <asm/asi.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/visasm.h>
 #include <asm/thread_info.h>
 
-	.text
-	.globl		VISenter, VISenterhalf
-
 	/* On entry: %o5=current FPRS value, %g7 is callers address */
 	/* May clobber %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
 
 	/* Nothing special need be done here to handle pre-emption, this
 	 * FPU save/restore mechanism is already preemption safe.
 	 */
-
+	.text
 	.align		32
-VISenter:
+ENTRY(VISenter)
 	ldub		[%g6 + TI_FPDEPTH], %g1
 	brnz,a,pn	%g1, 1f
 	 cmp		%g1, 1
@@ -79,3 +78,4 @@ vis1:	ldub		[%g6 + TI_FPSAVED], %g3
 	.align		32
 80:	jmpl		%g7 + %g0, %g0
 	 nop
+ENDPROC(VISenter)
diff --git a/arch/tile/kernel/usb.c b/arch/tile/kernel/usb.c
index f0da5a237e94..9f1e05e12255 100644
--- a/arch/tile/kernel/usb.c
+++ b/arch/tile/kernel/usb.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/tilegx.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/types.h>
 
 static u64 ehci_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 098ab3333e7c..e3abe6f3156d 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -70,8 +70,8 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE)
 
 USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
 		$(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
-		-D_FILE_OFFSET_BITS=64 -idirafter include \
-		-D__KERNEL__ -D__UM_HOST__
+		-D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
+		-idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__
 
 #This will adjust *FLAGS accordingly to the platform.
 include $(ARCH_DIR)/Makefile-os-$(OS)
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index d8a9fce6ee2e..98783dd0fa2e 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 		show_regs(container_of(regs, struct pt_regs, regs));
 		panic("Segfault with no mm");
 	}
-	else if (!is_user && address < TASK_SIZE) {
+	else if (!is_user && address > PAGE_SIZE && address < TASK_SIZE) {
 		show_regs(container_of(regs, struct pt_regs, regs));
 		panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
 		       address, ip);
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index e3ee4a51ef63..3f02d4232812 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -96,7 +96,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
 			       "ret = %d\n", -n);
 			ret = n;
 		}
-		CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
+		CATCH_EINTR(waitpid(pid, NULL, __WALL));
 	}
 
 out_free2:
@@ -129,7 +129,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
 		return err;
 	}
 	if (stack_out == NULL) {
-		CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
+		CATCH_EINTR(pid = waitpid(pid, &status, __WALL));
 		if (pid < 0) {
 			err = -errno;
 			printk(UM_KERN_ERR "run_helper_thread - wait failed, "
@@ -148,7 +148,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
 int helper_wait(int pid)
 {
 	int ret, status;
-	int wflags = __WCLONE;
+	int wflags = __WALL;
 
 	CATCH_EINTR(ret = waitpid(pid, &status, wflags));
 	if (ret < 0) {
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7aef2d52daa0..1104ddcb9b4c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -636,7 +636,7 @@ config X86_32_IRIS
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
-	prompt "Single-depth WCHAN output"
+	prompt "Single-depth WCHAN output" if !LTO && !FRAME_POINTER
 	depends on X86
 	---help---
 	  Calculate simpler /proc/<PID>/wchan values. If this option
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index a0a19b7ba22d..5959042fae8d 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -26,7 +26,7 @@
 #include <asm/ptrace.h>
 #include <asm/ia32_unistd.h>
 #include <asm/user32.h>
-#include <asm/sigcontext32.h>
+#include <uapi/asm/sigcontext.h>
 #include <asm/proto.h>
 #include <asm/vdso.h>
 #include <asm/sigframe.h>
@@ -68,7 +68,7 @@
 }
 
 static int ia32_restore_sigcontext(struct pt_regs *regs,
-				   struct sigcontext_ia32 __user *sc)
+				   struct sigcontext_32 __user *sc)
 {
 	unsigned int tmpflags, err = 0;
 	void __user *buf;
@@ -170,7 +170,7 @@ badframe:
  * Set up a signal frame.
  */
 
-static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
+static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc,
 				 void __user *fpstate,
 				 struct pt_regs *regs, unsigned int mask)
 {
@@ -234,7 +234,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
 		unsigned long fx_aligned, math_size;
 
 		sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
-		*fpstate = (struct _fpstate_ia32 __user *) sp;
+		*fpstate = (struct _fpstate_32 __user *) sp;
 		if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
 				    math_size) < 0)
 			return (void __user *) -1L;
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 477fc28050e4..e6cf2ad350d1 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -241,6 +241,7 @@
 #define X86_FEATURE_AVX512PF	( 9*32+26) /* AVX-512 Prefetch */
 #define X86_FEATURE_AVX512ER	( 9*32+27) /* AVX-512 Exponential and Reciprocal */
 #define X86_FEATURE_AVX512CD	( 9*32+28) /* AVX-512 Conflict Detection */
+#define X86_FEATURE_SHA_NI	( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
 
 /* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
 #define X86_FEATURE_XSAVEOPT	(10*32+ 0) /* XSAVEOPT */
diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h
index 7358e9d61f1e..0e970d00dfcd 100644
--- a/arch/x86/include/asm/fpu/signal.h
+++ b/arch/x86/include/asm/fpu/signal.h
@@ -5,7 +5,7 @@
 #define _ASM_X86_FPU_SIGNAL_H
 
 #ifdef CONFIG_X86_64
-# include <asm/sigcontext32.h>
+# include <uapi/asm/sigcontext.h>
 # include <asm/user32.h>
 struct ksignal;
 int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 28019765442e..a9bdf5569ab3 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -10,7 +10,7 @@
  * 32 bit structures for IA32 support.
  */
 
-#include <asm/sigcontext32.h>
+#include <uapi/asm/sigcontext.h>
 
 /* signal.h */
 
@@ -18,7 +18,7 @@ struct ucontext_ia32 {
 	unsigned int	  uc_flags;
 	unsigned int 	  uc_link;
 	compat_stack_t	  uc_stack;
-	struct sigcontext_ia32 uc_mcontext;
+	struct sigcontext_32 uc_mcontext;
 	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 19577dd325fa..bb911e718330 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -11,7 +11,7 @@ struct vm86;
 #include <asm/math_emu.h>
 #include <asm/segment.h>
 #include <asm/types.h>
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
 #include <asm/current.h>
 #include <asm/cpufeature.h>
 #include <asm/page.h>
diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index 9d51fae1cba3..eaba08076030 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -39,18 +39,27 @@ static inline void queued_spin_unlock(struct qspinlock *lock)
 }
 #endif
 
-#define virt_queued_spin_lock virt_queued_spin_lock
-
-static inline bool virt_queued_spin_lock(struct qspinlock *lock)
+#ifdef CONFIG_PARAVIRT
+#define virt_spin_lock virt_spin_lock
+static inline bool virt_spin_lock(struct qspinlock *lock)
 {
 	if (!static_cpu_has(X86_FEATURE_HYPERVISOR))
 		return false;
 
-	while (atomic_cmpxchg(&lock->val, 0, _Q_LOCKED_VAL) != 0)
-		cpu_relax();
+	/*
+	 * On hypervisors without PARAVIRT_SPINLOCKS support we fall
+	 * back to a Test-and-Set spinlock, because fair locks have
+	 * horrible lock 'holder' preemption issues.
+	 */
+
+	do {
+		while (atomic_read(&lock->val) != 0)
+			cpu_relax();
+	} while (atomic_cmpxchg(&lock->val, 0, _Q_LOCKED_VAL) != 0);
 
 	return true;
 }
+#endif /* CONFIG_PARAVIRT */
 
 #include <asm-generic/qspinlock.h>
 
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index 9dfce4e0417d..e6cd2c489dbb 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -1,79 +1,8 @@
 #ifndef _ASM_X86_SIGCONTEXT_H
 #define _ASM_X86_SIGCONTEXT_H
 
-#include <uapi/asm/sigcontext.h>
-
-#ifdef __i386__
-struct sigcontext {
-	unsigned short gs, __gsh;
-	unsigned short fs, __fsh;
-	unsigned short es, __esh;
-	unsigned short ds, __dsh;
-	unsigned long di;
-	unsigned long si;
-	unsigned long bp;
-	unsigned long sp;
-	unsigned long bx;
-	unsigned long dx;
-	unsigned long cx;
-	unsigned long ax;
-	unsigned long trapno;
-	unsigned long err;
-	unsigned long ip;
-	unsigned short cs, __csh;
-	unsigned long flags;
-	unsigned long sp_at_signal;
-	unsigned short ss, __ssh;
+/* This is a legacy header - all kernel code includes <uapi/asm/sigcontext.h> directly. */
 
-	/*
-	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
-	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
-	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the definition of
-	 * (struct _fpx_sw_bytes)
-	 */
-	void __user *fpstate;		/* zero when no FPU/extended context */
-	unsigned long oldmask;
-	unsigned long cr2;
-};
-#else /* __i386__ */
-struct sigcontext {
-	unsigned long r8;
-	unsigned long r9;
-	unsigned long r10;
-	unsigned long r11;
-	unsigned long r12;
-	unsigned long r13;
-	unsigned long r14;
-	unsigned long r15;
-	unsigned long di;
-	unsigned long si;
-	unsigned long bp;
-	unsigned long bx;
-	unsigned long dx;
-	unsigned long ax;
-	unsigned long cx;
-	unsigned long sp;
-	unsigned long ip;
-	unsigned long flags;
-	unsigned short cs;
-	unsigned short gs;
-	unsigned short fs;
-	unsigned short __pad0;
-	unsigned long err;
-	unsigned long trapno;
-	unsigned long oldmask;
-	unsigned long cr2;
+#include <uapi/asm/sigcontext.h>
 
-	/*
-	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
-	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
-	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the definition of
-	 * (struct _fpx_sw_bytes)
-	 */
-	void __user *fpstate;		/* zero when no FPU/extended context */
-	unsigned long reserved1[8];
-};
-#endif /* !__i386__ */
 #endif /* _ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h
index 1f3175bb994e..34edd1650bae 100644
--- a/arch/x86/include/asm/sigframe.h
+++ b/arch/x86/include/asm/sigframe.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_X86_SIGFRAME_H
 #define _ASM_X86_SIGFRAME_H
 
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
 #include <asm/siginfo.h>
 #include <asm/ucontext.h>
 #include <linux/compat.h>
@@ -9,8 +9,6 @@
 #ifdef CONFIG_X86_32
 #define sigframe_ia32		sigframe
 #define rt_sigframe_ia32	rt_sigframe
-#define sigcontext_ia32		sigcontext
-#define _fpstate_ia32		_fpstate
 #define ucontext_ia32		ucontext
 #else /* !CONFIG_X86_32 */
 
@@ -24,7 +22,7 @@
 struct sigframe_ia32 {
 	u32 pretcode;
 	int sig;
-	struct sigcontext_ia32 sc;
+	struct sigcontext_32 sc;
 	/*
 	 * fpstate is unused. fpstate is moved/allocated after
 	 * retcode[] below. This movement allows to have the FP state and the
@@ -33,7 +31,7 @@ struct sigframe_ia32 {
 	 * the offset of extramask[] in the sigframe and thus prevent any
 	 * legacy application accessing/modifying it.
 	 */
-	struct _fpstate_ia32 fpstate_unused;
+	struct _fpstate_32 fpstate_unused;
 #ifdef CONFIG_IA32_EMULATION
 	unsigned int extramask[_COMPAT_NSIG_WORDS-1];
 #else /* !CONFIG_IA32_EMULATION */
diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h
index c481be78fcf1..2138c9ae19ee 100644
--- a/arch/x86/include/asm/signal.h
+++ b/arch/x86/include/asm/signal.h
@@ -34,7 +34,7 @@ extern void do_signal(struct pt_regs *regs);
 
 #define __ARCH_HAS_SA_RESTORER
 
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
 
 #ifdef __i386__
 
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index a00ad8f2a657..ea7074784cc4 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -609,7 +609,7 @@ struct uv_cpu_nmi_s {
 
 DECLARE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi);
 
-#define uv_hub_nmi			(uv_cpu_nmi.hub)
+#define uv_hub_nmi			this_cpu_read(uv_cpu_nmi.hub)
 #define uv_cpu_nmi_per(cpu)		(per_cpu(uv_cpu_nmi, cpu))
 #define uv_hub_nmi_per(cpu)		(uv_cpu_nmi_per(cpu).hub)
 
diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h
index 40836a9a7250..4411e6a8f8e7 100644
--- a/arch/x86/include/uapi/asm/sigcontext.h
+++ b/arch/x86/include/uapi/asm/sigcontext.h
@@ -1,221 +1,355 @@
 #ifndef _UAPI_ASM_X86_SIGCONTEXT_H
 #define _UAPI_ASM_X86_SIGCONTEXT_H
 
+/*
+ * Linux signal context definitions. The sigcontext includes a complex hierarchy of CPU
+ * and FPU state, available to user-space (on the stack) when a signal handler is
+ * executed.
+ *
+ * As over the years this ABI grew from its very simple roots towards supporting more and
+ * more CPU state organically, some of the details (which were rather clever hacks back
+ * in the days) became a bit quirky by today.
+ *
+ * The current ABI includes flexible provisions for future extensions, so we won't have
+ * to grow new quirks for quite some time. Promise!
+ */
+
 #include <linux/compiler.h>
 #include <linux/types.h>
 
-#define FP_XSTATE_MAGIC1	0x46505853U
-#define FP_XSTATE_MAGIC2	0x46505845U
-#define FP_XSTATE_MAGIC2_SIZE	sizeof(FP_XSTATE_MAGIC2)
+#define FP_XSTATE_MAGIC1		0x46505853U
+#define FP_XSTATE_MAGIC2		0x46505845U
+#define FP_XSTATE_MAGIC2_SIZE		sizeof(FP_XSTATE_MAGIC2)
 
 /*
- * bytes 464..511 in the current 512byte layout of fxsave/fxrstor frame
- * are reserved for SW usage. On cpu's supporting xsave/xrstor, these bytes
- * are used to extended the fpstate pointer in the sigcontext, which now
+ * Bytes 464..511 in the current 512-byte layout of the FXSAVE/FXRSTOR frame
+ * are reserved for SW usage. On CPUs supporting XSAVE/XRSTOR, these bytes
+ * are used to extend the fpstate pointer in the sigcontext, which now
  * includes the extended state information along with fpstate information.
  *
- * Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved
- * area and FP_XSTATE_MAGIC2 at the end of memory layout
- * (extended_size - FP_XSTATE_MAGIC2_SIZE) indicates the presence of the
- * extended state information in the memory layout pointed by the fpstate
- * pointer in sigcontext.
+ * If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then there's a sw_reserved.extended_size
+ * bytes large extended context area present. (The last 32-bit word of this extended
+ * area (at the fpstate+extended_size-FP_XSTATE_MAGIC2_SIZE address) is set to
+ * FP_XSTATE_MAGIC2 so that you can sanity check your size calculations.)
+ *
+ * This extended area typically grows with newer CPUs that have larger and larger
+ * XSAVE areas.
  */
 struct _fpx_sw_bytes {
-	__u32 magic1;		/* FP_XSTATE_MAGIC1 */
-	__u32 extended_size;	/* total size of the layout referred by
-				 * fpstate pointer in the sigcontext.
-				 */
-	__u64 xfeatures;
-				/* feature bit mask (including fp/sse/extended
-				 * state) that is present in the memory
-				 * layout.
-				 */
-	__u32 xstate_size;	/* actual xsave state size, based on the
-				 * features saved in the layout.
-				 * 'extended_size' will be greater than
-				 * 'xstate_size'.
-				 */
-	__u32 padding[7];	/*  for future use. */
+	/* If set to FP_XSTATE_MAGIC1 then this is an xstate context. 0 if a legacy frame. */
+	__u32				magic1;
+
+	/*
+	 * Total size of the fpstate area:
+	 *
+	 *  - if magic1 == 0 then it's sizeof(struct _fpstate)
+	 *  - if magic1 == FP_XSTATE_MAGIC1 then it's sizeof(struct _xstate) plus extensions (if any)
+	 */
+	__u32				extended_size;
+
+	/*
+	 * Feature bit mask (including FP/SSE/extended state) that is present
+	 * in the memory layout:
+	 */
+	__u64				xfeatures;
+
+	/*
+	 * Actual XSAVE state size, based on the xfeatures saved in the layout.
+	 * 'extended_size' is greater than 'xstate_size':
+	 */
+	__u32				xstate_size;
+
+	/* For future use: */
+	__u32				padding[7];
 };
 
-#ifdef __i386__
 /*
- * As documented in the iBCS2 standard..
+ * As documented in the iBCS2 standard:
  *
  * The first part of "struct _fpstate" is just the normal i387
  * hardware setup, the extra "status" word is used to save the
  * coprocessor status word before entering the handler.
  *
- * Pentium III FXSR, SSE support
- *	Gareth Hughes <gareth@valinux.com>, May 2000
- *
  * The FPU state data structure has had to grow to accommodate the
  * extended FPU state required by the Streaming SIMD Extensions.
  * There is no documented standard to accomplish this at the moment.
  */
+
+/* 10-byte legacy floating point register: */
 struct _fpreg {
-	unsigned short significand[4];
-	unsigned short exponent;
+	__u16				significand[4];
+	__u16				exponent;
 };
 
+/* 16-byte floating point register: */
 struct _fpxreg {
-	unsigned short significand[4];
-	unsigned short exponent;
-	unsigned short padding[3];
+	__u16				significand[4];
+	__u16				exponent;
+	__u16				padding[3];
 };
 
+/* 16-byte XMM register: */
 struct _xmmreg {
-	unsigned long element[4];
+	__u32				element[4];
 };
 
-struct _fpstate {
-	/* Regular FPU environment */
-	unsigned long	cw;
-	unsigned long	sw;
-	unsigned long	tag;
-	unsigned long	ipoff;
-	unsigned long	cssel;
-	unsigned long	dataoff;
-	unsigned long	datasel;
-	struct _fpreg	_st[8];
-	unsigned short	status;
-	unsigned short	magic;		/* 0xffff = regular FPU data only */
+#define X86_FXSR_MAGIC			0x0000
+
+/*
+ * The 32-bit FPU frame:
+ */
+struct _fpstate_32 {
+	/* Legacy FPU environment: */
+	__u32				cw;
+	__u32				sw;
+	__u32				tag;
+	__u32				ipoff;
+	__u32				cssel;
+	__u32				dataoff;
+	__u32				datasel;
+	struct _fpreg			_st[8];
+	__u16				status;
+	__u16				magic;		/* 0xffff: regular FPU data only */
+							/* 0x0000: FXSR FPU data */
 
 	/* FXSR FPU environment */
-	unsigned long	_fxsr_env[6];	/* FXSR FPU env is ignored */
-	unsigned long	mxcsr;
-	unsigned long	reserved;
-	struct _fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */
-	struct _xmmreg	_xmm[8];
-	unsigned long	padding1[44];
+	__u32				_fxsr_env[6];	/* FXSR FPU env is ignored */
+	__u32				mxcsr;
+	__u32				reserved;
+	struct _fpxreg			_fxsr_st[8];	/* FXSR FPU reg data is ignored */
+	struct _xmmreg			_xmm[8];	/* First 8 XMM registers */
+	union {
+		__u32			padding1[44];	/* Second 8 XMM registers plus padding */
+		__u32			padding[44];	/* Alias name for old user-space */
+	};
 
 	union {
-		unsigned long	padding2[12];
-		struct _fpx_sw_bytes sw_reserved; /* represents the extended
-						   * state info */
+		__u32			padding2[12];
+		struct _fpx_sw_bytes	sw_reserved;	/* Potential extended state is encoded here */
 	};
 };
 
-#define X86_FXSR_MAGIC		0x0000
-
-#ifndef __KERNEL__
 /*
- * User-space might still rely on the old definition:
+ * The 64-bit FPU frame. (FXSAVE format and later)
+ *
+ * Note1: If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then the structure is
+ *        larger: 'struct _xstate'. Note that 'struct _xstate' embedds
+ *        'struct _fpstate' so that you can always assume the _fpstate portion
+ *        exists so that you can check the magic value.
+ *
+ * Note2: Reserved fields may someday contain valuable data. Always save/restore
+ *        them when you change signal frames.
  */
-struct sigcontext {
-	unsigned short gs, __gsh;
-	unsigned short fs, __fsh;
-	unsigned short es, __esh;
-	unsigned short ds, __dsh;
-	unsigned long edi;
-	unsigned long esi;
-	unsigned long ebp;
-	unsigned long esp;
-	unsigned long ebx;
-	unsigned long edx;
-	unsigned long ecx;
-	unsigned long eax;
-	unsigned long trapno;
-	unsigned long err;
-	unsigned long eip;
-	unsigned short cs, __csh;
-	unsigned long eflags;
-	unsigned long esp_at_signal;
-	unsigned short ss, __ssh;
-	struct _fpstate __user *fpstate;
-	unsigned long oldmask;
-	unsigned long cr2;
-};
-#endif /* !__KERNEL__ */
-
-#else /* __i386__ */
-
-/* FXSAVE frame */
-/* Note: reserved1/2 may someday contain valuable data. Always save/restore
-   them when you change signal frames. */
-struct _fpstate {
-	__u16	cwd;
-	__u16	swd;
-	__u16	twd;		/* Note this is not the same as the
-				   32bit/x87/FSAVE twd */
-	__u16	fop;
-	__u64	rip;
-	__u64	rdp;
-	__u32	mxcsr;
-	__u32	mxcsr_mask;
-	__u32	st_space[32];	/* 8*16 bytes for each FP-reg */
-	__u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg  */
-	__u32	reserved2[12];
+struct _fpstate_64 {
+	__u16				cwd;
+	__u16				swd;
+	/* Note this is not the same as the 32-bit/x87/FSAVE twd: */
+	__u16				twd;
+	__u16				fop;
+	__u64				rip;
+	__u64				rdp;
+	__u32				mxcsr;
+	__u32				mxcsr_mask;
+	__u32				st_space[32];	/*  8x  FP registers, 16 bytes each */
+	__u32				xmm_space[64];	/* 16x XMM registers, 16 bytes each */
+	__u32				reserved2[12];
 	union {
-		__u32	reserved3[12];
-		struct _fpx_sw_bytes sw_reserved; /* represents the extended
-						   * state information */
+		__u32			reserved3[12];
+		struct _fpx_sw_bytes	sw_reserved;	/* Potential extended state is encoded here */
 	};
 };
 
-#ifndef __KERNEL__
-/*
- * User-space might still rely on the old definition:
- */
-struct sigcontext {
-	__u64 r8;
-	__u64 r9;
-	__u64 r10;
-	__u64 r11;
-	__u64 r12;
-	__u64 r13;
-	__u64 r14;
-	__u64 r15;
-	__u64 rdi;
-	__u64 rsi;
-	__u64 rbp;
-	__u64 rbx;
-	__u64 rdx;
-	__u64 rax;
-	__u64 rcx;
-	__u64 rsp;
-	__u64 rip;
-	__u64 eflags;		/* RFLAGS */
-	__u16 cs;
-	__u16 gs;
-	__u16 fs;
-	__u16 __pad0;
-	__u64 err;
-	__u64 trapno;
-	__u64 oldmask;
-	__u64 cr2;
-	struct _fpstate __user *fpstate;	/* zero when no FPU context */
-#ifdef __ILP32__
-	__u32 __fpstate_pad;
+#ifdef __i386__
+# define _fpstate _fpstate_32
+#else
+# define _fpstate _fpstate_64
 #endif
-	__u64 reserved1[8];
-};
-#endif /* !__KERNEL__ */
-
-#endif /* !__i386__ */
 
 struct _header {
-	__u64 xfeatures;
-	__u64 reserved1[2];
-	__u64 reserved2[5];
+	__u64				xfeatures;
+	__u64				reserved1[2];
+	__u64				reserved2[5];
 };
 
 struct _ymmh_state {
-	/* 16 * 16 bytes for each YMMH-reg */
-	__u32 ymmh_space[64];
+	/* 16x YMM registers, 16 bytes each: */
+	__u32				ymmh_space[64];
 };
 
 /*
- * Extended state pointed by the fpstate pointer in the sigcontext.
- * In addition to the fpstate, information encoded in the xstate_hdr
- * indicates the presence of other extended state information
- * supported by the processor and OS.
+ * Extended state pointed to by sigcontext::fpstate.
+ *
+ * In addition to the fpstate, information encoded in _xstate::xstate_hdr
+ * indicates the presence of other extended state information supported
+ * by the CPU and kernel:
  */
 struct _xstate {
-	struct _fpstate fpstate;
-	struct _header xstate_hdr;
-	struct _ymmh_state ymmh;
-	/* new processor state extensions go here */
+	struct _fpstate			fpstate;
+	struct _header			xstate_hdr;
+	struct _ymmh_state		ymmh;
+	/* New processor state extensions go here: */
+};
+
+/*
+ * The 32-bit signal frame:
+ */
+struct sigcontext_32 {
+	__u16				gs, __gsh;
+	__u16				fs, __fsh;
+	__u16				es, __esh;
+	__u16				ds, __dsh;
+	__u32				di;
+	__u32				si;
+	__u32				bp;
+	__u32				sp;
+	__u32				bx;
+	__u32				dx;
+	__u32				cx;
+	__u32				ax;
+	__u32				trapno;
+	__u32				err;
+	__u32				ip;
+	__u16				cs, __csh;
+	__u32				flags;
+	__u32				sp_at_signal;
+	__u16				ss, __ssh;
+
+	/*
+	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
+	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
+	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
+	 * of extended memory layout. See comments at the definition of
+	 * (struct _fpx_sw_bytes)
+	 */
+	__u32				fpstate; /* Zero when no FPU/extended context */
+	__u32				oldmask;
+	__u32				cr2;
+};
+
+/*
+ * The 64-bit signal frame:
+ */
+struct sigcontext_64 {
+	__u64				r8;
+	__u64				r9;
+	__u64				r10;
+	__u64				r11;
+	__u64				r12;
+	__u64				r13;
+	__u64				r14;
+	__u64				r15;
+	__u64				di;
+	__u64				si;
+	__u64				bp;
+	__u64				bx;
+	__u64				dx;
+	__u64				ax;
+	__u64				cx;
+	__u64				sp;
+	__u64				ip;
+	__u64				flags;
+	__u16				cs;
+	__u16				gs;
+	__u16				fs;
+	__u16				__pad0;
+	__u64				err;
+	__u64				trapno;
+	__u64				oldmask;
+	__u64				cr2;
+
+	/*
+	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
+	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
+	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
+	 * of extended memory layout. See comments at the definition of
+	 * (struct _fpx_sw_bytes)
+	 */
+	__u64				fpstate; /* Zero when no FPU/extended context */
+	__u64				reserved1[8];
+};
+
+/*
+ * Create the real 'struct sigcontext' type:
+ */
+#ifdef __KERNEL__
+# ifdef __i386__
+#  define sigcontext sigcontext_32
+# else
+#  define sigcontext sigcontext_64
+# endif
+#endif
+
+/*
+ * The old user-space sigcontext definition, just in case user-space still
+ * relies on it. The kernel definition (in asm/sigcontext.h) has unified
+ * field names but otherwise the same layout.
+ */
+#ifndef __KERNEL__
+
+#define _fpstate_ia32			_fpstate_32
+#define sigcontext_ia32			sigcontext_32
+
+
+# ifdef __i386__
+struct sigcontext {
+	__u16				gs, __gsh;
+	__u16				fs, __fsh;
+	__u16				es, __esh;
+	__u16				ds, __dsh;
+	__u32				edi;
+	__u32				esi;
+	__u32				ebp;
+	__u32				esp;
+	__u32				ebx;
+	__u32				edx;
+	__u32				ecx;
+	__u32				eax;
+	__u32				trapno;
+	__u32				err;
+	__u32				eip;
+	__u16				cs, __csh;
+	__u32				eflags;
+	__u32				esp_at_signal;
+	__u16				ss, __ssh;
+	struct _fpstate __user		*fpstate;
+	__u32				oldmask;
+	__u32				cr2;
 };
+# else /* __x86_64__: */
+struct sigcontext {
+	__u64				r8;
+	__u64				r9;
+	__u64				r10;
+	__u64				r11;
+	__u64				r12;
+	__u64				r13;
+	__u64				r14;
+	__u64				r15;
+	__u64				rdi;
+	__u64				rsi;
+	__u64				rbp;
+	__u64				rbx;
+	__u64				rdx;
+	__u64				rax;
+	__u64				rcx;
+	__u64				rsp;
+	__u64				rip;
+	__u64				eflags;		/* RFLAGS */
+	__u16				cs;
+	__u16				gs;
+	__u16				fs;
+	__u16				__pad0;
+	__u64				err;
+	__u64				trapno;
+	__u64				oldmask;
+	__u64				cr2;
+	struct _fpstate __user		*fpstate;	/* Zero when no FPU context */
+#  ifdef __ILP32__
+	__u32				__fpstate_pad;
+#  endif
+	__u64				reserved1[8];
+};
+# endif /* __x86_64__ */
+#endif /* !__KERNEL__ */
 
 #endif /* _UAPI_ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/uapi/asm/sigcontext32.h b/arch/x86/include/uapi/asm/sigcontext32.h
index ad1478c4ae12..a92b0f0dc09e 100644
--- a/arch/x86/include/uapi/asm/sigcontext32.h
+++ b/arch/x86/include/uapi/asm/sigcontext32.h
@@ -1,77 +1,8 @@
 #ifndef _ASM_X86_SIGCONTEXT32_H
 #define _ASM_X86_SIGCONTEXT32_H
 
-#include <linux/types.h>
+/* This is a legacy file - all the type definitions are in sigcontext.h: */
 
-/* signal context for 32bit programs. */
-
-#define X86_FXSR_MAGIC		0x0000
-
-struct _fpreg {
-	unsigned short significand[4];
-	unsigned short exponent;
-};
-
-struct _fpxreg {
-	unsigned short significand[4];
-	unsigned short exponent;
-	unsigned short padding[3];
-};
-
-struct _xmmreg {
-	__u32	element[4];
-};
-
-/* FSAVE frame with extensions */
-struct _fpstate_ia32 {
-	/* Regular FPU environment */
-	__u32 	cw;
-	__u32	sw;
-	__u32	tag;	/* not compatible to 64bit twd */
-	__u32	ipoff;
-	__u32	cssel;
-	__u32	dataoff;
-	__u32	datasel;
-	struct _fpreg	_st[8];
-	unsigned short	status;
-	unsigned short	magic;		/* 0xffff = regular FPU data only */
-
-	/* FXSR FPU environment */
-	__u32	_fxsr_env[6];
-	__u32	mxcsr;
-	__u32	reserved;
-	struct _fpxreg	_fxsr_st[8];
-	struct _xmmreg	_xmm[8];	/* It's actually 16 */
-	__u32	padding[44];
-	union {
-		__u32 padding2[12];
-		struct _fpx_sw_bytes sw_reserved;
-	};
-};
-
-struct sigcontext_ia32 {
-       unsigned short gs, __gsh;
-       unsigned short fs, __fsh;
-       unsigned short es, __esh;
-       unsigned short ds, __dsh;
-       unsigned int di;
-       unsigned int si;
-       unsigned int bp;
-       unsigned int sp;
-       unsigned int bx;
-       unsigned int dx;
-       unsigned int cx;
-       unsigned int ax;
-       unsigned int trapno;
-       unsigned int err;
-       unsigned int ip;
-       unsigned short cs, __csh;
-       unsigned int flags;
-       unsigned int sp_at_signal;
-       unsigned short ss, __ssh;
-       unsigned int fpstate;		/* really (struct _fpstate_ia32 *) */
-       unsigned int oldmask;
-       unsigned int cr2;
-};
+#include <asm/sigcontext.h>
 
 #endif /* _ASM_X86_SIGCONTEXT32_H */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index c42827eb86cf..25f909362b7a 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -338,10 +338,15 @@ done:
 
 static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr)
 {
+	unsigned long flags;
+
 	if (instr[0] != 0x90)
 		return;
 
+	local_irq_save(flags);
 	add_nops(instr + (a->instrlen - a->padlen), a->padlen);
+	sync_core();
+	local_irq_restore(flags);
 
 	DUMP_BYTES(instr, a->instrlen, "%p: [%d:%d) optimized NOPs: ",
 		   instr, a->instrlen - a->padlen, a->padlen);
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 8e3d22a1af94..bc9f4afa889a 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -43,15 +43,15 @@ void common(void) {
 
 #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
 	BLANK();
-	OFFSET(IA32_SIGCONTEXT_ax, sigcontext_ia32, ax);
-	OFFSET(IA32_SIGCONTEXT_bx, sigcontext_ia32, bx);
-	OFFSET(IA32_SIGCONTEXT_cx, sigcontext_ia32, cx);
-	OFFSET(IA32_SIGCONTEXT_dx, sigcontext_ia32, dx);
-	OFFSET(IA32_SIGCONTEXT_si, sigcontext_ia32, si);
-	OFFSET(IA32_SIGCONTEXT_di, sigcontext_ia32, di);
-	OFFSET(IA32_SIGCONTEXT_bp, sigcontext_ia32, bp);
-	OFFSET(IA32_SIGCONTEXT_sp, sigcontext_ia32, sp);
-	OFFSET(IA32_SIGCONTEXT_ip, sigcontext_ia32, ip);
+	OFFSET(IA32_SIGCONTEXT_ax, sigcontext_32, ax);
+	OFFSET(IA32_SIGCONTEXT_bx, sigcontext_32, bx);
+	OFFSET(IA32_SIGCONTEXT_cx, sigcontext_32, cx);
+	OFFSET(IA32_SIGCONTEXT_dx, sigcontext_32, dx);
+	OFFSET(IA32_SIGCONTEXT_si, sigcontext_32, si);
+	OFFSET(IA32_SIGCONTEXT_di, sigcontext_32, di);
+	OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
+	OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
+	OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
 
 	BLANK();
 	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 07ce52c22ec8..de22ea7ff82f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1110,10 +1110,10 @@ void print_cpu_info(struct cpuinfo_x86 *c)
 	else
 		printk(KERN_CONT "%d86", c->x86);
 
-	printk(KERN_CONT " (fam: %02x, model: %02x", c->x86, c->x86_model);
+	printk(KERN_CONT " (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
 
 	if (c->x86_mask || c->cpuid_level >= 0)
-		printk(KERN_CONT ", stepping: %02x)\n", c->x86_mask);
+		printk(KERN_CONT ", stepping: 0x%x)\n", c->x86_mask);
 	else
 		printk(KERN_CONT ")\n");
 
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 66dd3fe99b82..4562cf070c27 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1175,7 +1175,7 @@ static int x86_pmu_add(struct perf_event *event, int flags)
 	 * skip the schedulability test here, it will be performed
 	 * at commit time (->commit_txn) as a whole.
 	 */
-	if (cpuc->group_flag & PERF_EVENT_TXN)
+	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
 		goto done_collect;
 
 	ret = x86_pmu.schedule_events(cpuc, n, assign);
@@ -1326,7 +1326,7 @@ static void x86_pmu_del(struct perf_event *event, int flags)
 	 * XXX assumes any ->del() called during a TXN will only be on
 	 * an event added during that same TXN.
 	 */
-	if (cpuc->group_flag & PERF_EVENT_TXN)
+	if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
 		return;
 
 	/*
@@ -1748,11 +1748,22 @@ static inline void x86_pmu_read(struct perf_event *event)
  * Start group events scheduling transaction
  * Set the flag to make pmu::enable() not perform the
  * schedulability test, it will be performed at commit time
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
  */
-static void x86_pmu_start_txn(struct pmu *pmu)
+static void x86_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
 {
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	WARN_ON_ONCE(cpuc->txn_flags);		/* txn already in flight */
+
+	cpuc->txn_flags = txn_flags;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_disable(pmu);
-	__this_cpu_or(cpu_hw_events.group_flag, PERF_EVENT_TXN);
 	__this_cpu_write(cpu_hw_events.n_txn, 0);
 }
 
@@ -1763,7 +1774,16 @@ static void x86_pmu_start_txn(struct pmu *pmu)
  */
 static void x86_pmu_cancel_txn(struct pmu *pmu)
 {
-	__this_cpu_and(cpu_hw_events.group_flag, ~PERF_EVENT_TXN);
+	unsigned int txn_flags;
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
+
+	txn_flags = cpuc->txn_flags;
+	cpuc->txn_flags = 0;
+	if (txn_flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	/*
 	 * Truncate collected array by the number of events added in this
 	 * transaction. See x86_pmu_add() and x86_pmu_*_txn().
@@ -1786,6 +1806,13 @@ static int x86_pmu_commit_txn(struct pmu *pmu)
 	int assign[X86_PMC_IDX_MAX];
 	int n, ret;
 
+	WARN_ON_ONCE(!cpuc->txn_flags);	/* no txn in flight */
+
+	if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
+		cpuc->txn_flags = 0;
+		return 0;
+	}
+
 	n = cpuc->n_events;
 
 	if (!x86_pmu_initialized())
@@ -1801,7 +1828,7 @@ static int x86_pmu_commit_txn(struct pmu *pmu)
 	 */
 	memcpy(cpuc->assign, assign, n*sizeof(int));
 
-	cpuc->group_flag &= ~PERF_EVENT_TXN;
+	cpuc->txn_flags = 0;
 	perf_pmu_enable(pmu);
 	return 0;
 }
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 5edf6d868fc1..953a0e4e3284 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -195,7 +195,7 @@ struct cpu_hw_events {
 
 	int			n_excl; /* the number of exclusive events */
 
-	unsigned int		group_flag;
+	unsigned int		txn_flags;
 	int			is_fake;
 
 	/*
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index cd9b6d0b10bf..3fefebfbdf4b 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2316,9 +2316,12 @@ static struct event_constraint *
 intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
 			    struct perf_event *event)
 {
-	struct event_constraint *c1 = cpuc->event_constraint[idx];
+	struct event_constraint *c1 = NULL;
 	struct event_constraint *c2;
 
+	if (idx >= 0) /* fake does < 0 */
+		c1 = cpuc->event_constraint[idx];
+
 	/*
 	 * first time only
 	 * - static constraint: no change across incremental scheduling calls
diff --git a/arch/x86/kernel/cpu/perf_event_intel_bts.c b/arch/x86/kernel/cpu/perf_event_intel_bts.c
index 54690e885759..2cad71d1b14c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_bts.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_bts.c
@@ -222,6 +222,7 @@ static void __bts_event_start(struct perf_event *event)
 	if (!buf || bts_buffer_is_full(buf, bts))
 		return;
 
+	event->hw.itrace_started = 1;
 	event->hw.state = 0;
 
 	if (!buf->snapshot)
@@ -494,6 +495,19 @@ static int bts_event_init(struct perf_event *event)
 	if (x86_add_exclusive(x86_lbr_exclusive_bts))
 		return -EBUSY;
 
+	/*
+	 * BTS leaks kernel addresses even when CPL0 tracing is
+	 * disabled, so disallow intel_bts driver for unprivileged
+	 * users on paranoid systems since it provides trace data
+	 * to the user in a zero-copy fashion.
+	 *
+	 * Note that the default paranoia setting permits unprivileged
+	 * users to profile the kernel.
+	 */
+	if (event->attr.exclude_kernel && perf_paranoid_kernel() &&
+	    !capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
 	ret = x86_reserve_hardware();
 	if (ret) {
 		x86_del_exclusive(x86_lbr_exclusive_bts);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 84f236ab96b0..5db1c7755548 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -510,10 +510,11 @@ int intel_pmu_drain_bts_buffer(void)
 		u64	flags;
 	};
 	struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
-	struct bts_record *at, *top;
+	struct bts_record *at, *base, *top;
 	struct perf_output_handle handle;
 	struct perf_event_header header;
 	struct perf_sample_data data;
+	unsigned long skip = 0;
 	struct pt_regs regs;
 
 	if (!event)
@@ -522,10 +523,10 @@ int intel_pmu_drain_bts_buffer(void)
 	if (!x86_pmu.bts_active)
 		return 0;
 
-	at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-	top = (struct bts_record *)(unsigned long)ds->bts_index;
+	base = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+	top  = (struct bts_record *)(unsigned long)ds->bts_index;
 
-	if (top <= at)
+	if (top <= base)
 		return 0;
 
 	memset(&regs, 0, sizeof(regs));
@@ -535,16 +536,43 @@ int intel_pmu_drain_bts_buffer(void)
 	perf_sample_data_init(&data, 0, event->hw.last_period);
 
 	/*
+	 * BTS leaks kernel addresses in branches across the cpl boundary,
+	 * such as traps or system calls, so unless the user is asking for
+	 * kernel tracing (and right now it's not possible), we'd need to
+	 * filter them out. But first we need to count how many of those we
+	 * have in the current batch. This is an extra O(n) pass, however,
+	 * it's much faster than the other one especially considering that
+	 * n <= 2560 (BTS_BUFFER_SIZE / BTS_RECORD_SIZE * 15/16; see the
+	 * alloc_bts_buffer()).
+	 */
+	for (at = base; at < top; at++) {
+		/*
+		 * Note that right now *this* BTS code only works if
+		 * attr::exclude_kernel is set, but let's keep this extra
+		 * check here in case that changes.
+		 */
+		if (event->attr.exclude_kernel &&
+		    (kernel_ip(at->from) || kernel_ip(at->to)))
+			skip++;
+	}
+
+	/*
 	 * Prepare a generic sample, i.e. fill in the invariant fields.
 	 * We will overwrite the from and to address before we output
 	 * the sample.
 	 */
 	perf_prepare_sample(&header, &data, event, &regs);
 
-	if (perf_output_begin(&handle, event, header.size * (top - at)))
+	if (perf_output_begin(&handle, event, header.size *
+			      (top - base - skip)))
 		return 1;
 
-	for (; at < top; at++) {
+	for (at = base; at < top; at++) {
+		/* Filter out any records that contain kernel addresses. */
+		if (event->attr.exclude_kernel &&
+		    (kernel_ip(at->from) || kernel_ip(at->to)))
+			continue;
+
 		data.ip		= at->from;
 		data.addr	= at->to;
 
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index b2c9475b7ff2..a1d07c71d3b6 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -151,10 +151,9 @@ static void __intel_pmu_lbr_enable(bool pmi)
 	 * No need to reprogram LBR_SELECT in a PMI, as it
 	 * did not change.
 	 */
-	if (cpuc->lbr_sel && !pmi) {
-		lbr_select = cpuc->lbr_sel->config;
+	lbr_select = cpuc->lbr_sel->config;
+	if (cpuc->lbr_sel && !pmi)
 		wrmsrl(MSR_LBR_SELECT, lbr_select);
-	}
 
 	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
 	orig_debugctl = debugctl;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c
index 42169283448b..868e1194337f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_pt.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_pt.c
@@ -139,9 +139,6 @@ static int __init pt_pmu_hw_init(void)
 	long i;
 
 	attrs = NULL;
-	ret = -ENODEV;
-	if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
-		goto fail;
 
 	for (i = 0; i < PT_CPUID_LEAVES; i++) {
 		cpuid_count(20, i,
@@ -1130,6 +1127,10 @@ static __init int pt_init(void)
 	int ret, cpu, prior_warn = 0;
 
 	BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
+
+	if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
+		return -ENODEV;
+
 	get_online_cpus();
 	for_each_online_cpu(cpu) {
 		u64 ctl;
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 50ec9af1bd51..24aac16603a2 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -56,7 +56,7 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
 	if (use_fxsr()) {
 		struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;
 		struct user_i387_ia32_struct env;
-		struct _fpstate_ia32 __user *fp = buf;
+		struct _fpstate_32 __user *fp = buf;
 
 		convert_from_fxsr(&env, tsk);
 
@@ -165,7 +165,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
 	if (!static_cpu_has(X86_FEATURE_FPU))
 		return fpregs_soft_get(current, NULL, 0,
 			sizeof(struct user_i387_ia32_struct), NULL,
-			(struct _fpstate_ia32 __user *) buf) ? -1 : 1;
+			(struct _fpstate_32 __user *) buf) ? -1 : 1;
 
 	if (fpregs_active()) {
 		/* Save the live register state to the user directly. */
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index da52e6bb5c7f..3724ff38033e 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -63,6 +63,7 @@
 
 int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
+	unsigned long buf_val;
 	void __user *buf;
 	unsigned int tmpflags;
 	unsigned int err = 0;
@@ -107,7 +108,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
 		regs->orig_ax = -1;		/* disable syscall checks */
 
-		get_user_ex(buf, &sc->fpstate);
+		get_user_ex(buf_val, &sc->fpstate);
+		buf = (void __user *)buf_val;
 	} get_user_catch(err);
 
 	err |= fpu__restore_sig(buf, config_enabled(CONFIG_X86_32));
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index c8d52cb4cb6e..39ec3d07affd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -167,21 +167,20 @@ static void cyc2ns_write_end(int cpu, struct cyc2ns_data *data)
  *              ns = cycles * cyc2ns_scale / SC
  *
  *      And since SC is a constant power of two, we can convert the div
- *  into a shift.
+ *  into a shift. The larger SC is, the more accurate the conversion, but
+ *  cyc2ns_scale needs to be a 32-bit value so that 32-bit multiplication
+ *  (64-bit result) can be used.
  *
- *  We can use khz divisor instead of mhz to keep a better precision, since
- *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ *  We can use khz divisor instead of mhz to keep a better precision.
  *  (mathieu.desnoyers@polymtl.ca)
  *
  *                      -johnstul@us.ibm.com "math is hard, lets go shopping!"
  */
 
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
 static void cyc2ns_data_init(struct cyc2ns_data *data)
 {
 	data->cyc2ns_mul = 0;
-	data->cyc2ns_shift = CYC2NS_SCALE_FACTOR;
+	data->cyc2ns_shift = 0;
 	data->cyc2ns_offset = 0;
 	data->__count = 0;
 }
@@ -215,14 +214,14 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 
 	if (likely(data == tail)) {
 		ns = data->cyc2ns_offset;
-		ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+		ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, data->cyc2ns_shift);
 	} else {
 		data->__count++;
 
 		barrier();
 
 		ns = data->cyc2ns_offset;
-		ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+		ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, data->cyc2ns_shift);
 
 		barrier();
 
@@ -256,12 +255,11 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	 * time function is continuous; see the comment near struct
 	 * cyc2ns_data.
 	 */
-	data->cyc2ns_mul =
-		DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR,
-				  cpu_khz);
-	data->cyc2ns_shift = CYC2NS_SCALE_FACTOR;
+	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz,
+			       NSEC_PER_MSEC, 0);
+
 	data->cyc2ns_offset = ns_now -
-		mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+		mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, data->cyc2ns_shift);
 
 	cyc2ns_write_end(cpu, data);
 
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index abd8b856bd2b..524619351961 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -45,6 +45,7 @@
 #include <linux/audit.h>
 #include <linux/stddef.h>
 #include <linux/slab.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -232,6 +233,32 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 	struct pt_regs *regs = current_pt_regs();
 	unsigned long err = 0;
 
+	err = security_mmap_addr(0);
+	if (err) {
+		/*
+		 * vm86 cannot virtualize the address space, so vm86 users
+		 * need to manage the low 1MB themselves using mmap.  Given
+		 * that BIOS places important data in the first page, vm86
+		 * is essentially useless if mmap_min_addr != 0.  DOSEMU,
+		 * for example, won't even bother trying to use vm86 if it
+		 * can't map a page at virtual address 0.
+		 *
+		 * To reduce the available kernel attack surface, simply
+		 * disallow vm86(old) for users who cannot mmap at va 0.
+		 *
+		 * The implementation of security_mmap_addr will allow
+		 * suitably privileged users to map va 0 even if
+		 * vm.mmap_min_addr is set above 0, and we want this
+		 * behavior for vm86 as well, as it ensures that legacy
+		 * tools like vbetool will not fail just because of
+		 * vm.mmap_min_addr.
+		 */
+		pr_info_once("Denied a call to vm86(old) from %s[%d] (uid: %d).  Set the vm.mmap_min_addr sysctl to 0 and/or adjust LSM mmap_min_addr policy to enable vm86 if you are using a vm86-based DOS emulator.\n",
+			     current->comm, task_pid_nr(current),
+			     from_kuid_munged(&init_user_ns, current_uid()));
+		return -EPERM;
+	}
+
 	if (!vm86) {
 		if (!(vm86 = kzalloc(sizeof(*vm86), GFP_KERNEL)))
 			return -ENOMEM;
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 816488c0b97e..d388de72eaca 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -353,8 +353,12 @@ AVXcode: 1
 17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
 18: Grp16 (1A)
 19:
-1a: BNDCL Ev,Gv | BNDCU Ev,Gv | BNDMOV Gv,Ev | BNDLDX Gv,Ev,Gv
-1b: BNDCN Ev,Gv | BNDMOV Ev,Gv | BNDMK Gv,Ev | BNDSTX Ev,GV,Gv
+# Intel SDM opcode map does not list MPX instructions. For now using Gv for
+# bnd registers and Ev for everything else is OK because the instruction
+# decoder does not use the information except as an indication that there is
+# a ModR/M byte.
+1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
+1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
 1c:
 1d:
 1e:
@@ -732,6 +736,12 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
 be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
 bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
 # 0x0f 0x38 0xc0-0xff
+c8: sha1nexte Vdq,Wdq
+c9: sha1msg1 Vdq,Wdq
+ca: sha1msg2 Vdq,Wdq
+cb: sha256rnds2 Vdq,Wdq
+cc: sha256msg1 Vdq,Wdq
+cd: sha256msg2 Vdq,Wdq
 db: VAESIMC Vdq,Wdq (66),(v1)
 dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
 dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -790,6 +800,7 @@ AVXcode: 3
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
+cc: sha1rnds4 Vdq,Wdq,Ib
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
 f0: RORX Gy,Ey,Ib (F2),(v)
 EndTable
@@ -874,7 +885,7 @@ GrpTable: Grp7
 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
-5:
+5: rdpkru (110),(11B) | wrpkru (111),(11B)
 6: LMSW Ew
 7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
 EndTable
@@ -888,6 +899,9 @@ EndTable
 
 GrpTable: Grp9
 1: CMPXCHG8B/16B Mq/Mdq
+3: xrstors
+4: xsavec
+5: xsaves
 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
 EndTable
@@ -932,8 +946,8 @@ GrpTable: Grp15
 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
 4: XSAVE
 5: XRSTOR | lfence (11B)
-6: XSAVEOPT | mfence (11B)
-7: clflush | sfence (11B)
+6: XSAVEOPT | clwb (66) | mfence (11B)
+7: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B)
 EndTable
 
 GrpTable: Grp16
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index 4dae511c85ad..afbc4d805d66 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -71,7 +71,7 @@
 
 #include "fpu_system.h"
 
-#include <asm/sigcontext.h>	/* for struct _fpstate */
+#include <uapi/asm/sigcontext.h>	/* for struct _fpstate */
 #include <asm/math_emu.h>
 #include <linux/linkage.h>
 
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
index 66338a60aa6e..c2aea63bee20 100644
--- a/arch/x86/mm/srat.c
+++ b/arch/x86/mm/srat.c
@@ -192,10 +192,11 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
 
 	node_set(node, numa_nodes_parsed);
 
-	pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s\n",
+	pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s%s\n",
 		node, pxm,
 		(unsigned long long) start, (unsigned long long) end - 1,
-		hotpluggable ? " hotplug" : "");
+		hotpluggable ? " hotplug" : "",
+		ma->flags & ACPI_SRAT_MEM_NON_VOLATILE ? " non-volatile" : "");
 
 	/* Mark hotplug range in memblock. */
 	if (hotpluggable && memblock_mark_hotplug(start, ma->length))
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 5c9f63fa6abf..327f21c3bde1 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -376,38 +376,42 @@ static void uv_nmi_wait(int master)
 		atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus());
 }
 
+/* Dump Instruction Pointer header */
 static void uv_nmi_dump_cpu_ip_hdr(void)
 {
-	printk(KERN_DEFAULT
-		"\nUV: %4s %6s %-32s %s   (Note: PID 0 not listed)\n",
+	pr_info("\nUV: %4s %6s %-32s %s   (Note: PID 0 not listed)\n",
 		"CPU", "PID", "COMMAND", "IP");
 }
 
+/* Dump Instruction Pointer info */
 static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs)
 {
-	printk(KERN_DEFAULT "UV: %4d %6d %-32.32s ",
-		cpu, current->pid, current->comm);
-
+	pr_info("UV: %4d %6d %-32.32s ", cpu, current->pid, current->comm);
 	printk_address(regs->ip);
 }
 
-/* Dump this cpu's state */
+/*
+ * Dump this CPU's state.  If action was set to "kdump" and the crash_kexec
+ * failed, then we provide "dump" as an alternate action.  Action "dump" now
+ * also includes the show "ips" (instruction pointers) action whereas the
+ * action "ips" only displays instruction pointers for the non-idle CPU's.
+ * This is an abbreviated form of the "ps" command.
+ */
 static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs)
 {
 	const char *dots = " ................................. ";
 
-	if (uv_nmi_action_is("ips")) {
-		if (cpu == 0)
-			uv_nmi_dump_cpu_ip_hdr();
+	if (cpu == 0)
+		uv_nmi_dump_cpu_ip_hdr();
 
-		if (current->pid != 0)
-			uv_nmi_dump_cpu_ip(cpu, regs);
+	if (current->pid != 0 || !uv_nmi_action_is("ips"))
+		uv_nmi_dump_cpu_ip(cpu, regs);
 
-	} else if (uv_nmi_action_is("dump")) {
-		printk(KERN_DEFAULT
-			"UV:%sNMI process trace for CPU %d\n", dots, cpu);
+	if (uv_nmi_action_is("dump")) {
+		pr_info("UV:%sNMI process trace for CPU %d\n", dots, cpu);
 		show_regs(regs);
 	}
+
 	this_cpu_write(uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE);
 }
 
@@ -469,8 +473,7 @@ static void uv_nmi_dump_state(int cpu, struct pt_regs *regs, int master)
 				uv_nmi_trigger_dump(tcpu);
 		}
 		if (ignored)
-			printk(KERN_DEFAULT "UV: %d CPUs ignored NMI\n",
-				ignored);
+			pr_alert("UV: %d CPUs ignored NMI\n", ignored);
 
 		console_loglevel = saved_console_loglevel;
 		pr_alert("UV: process trace complete\n");
@@ -492,8 +495,9 @@ static void uv_nmi_touch_watchdogs(void)
 	touch_nmi_watchdog();
 }
 
-#if defined(CONFIG_KEXEC_CORE)
 static atomic_t uv_nmi_kexec_failed;
+
+#if defined(CONFIG_KEXEC_CORE)
 static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
 {
 	/* Call crash to dump system state */
@@ -502,10 +506,9 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
 		crash_kexec(regs);
 
 		pr_emerg("UV: crash_kexec unexpectedly returned, ");
+		atomic_set(&uv_nmi_kexec_failed, 1);
 		if (!kexec_crash_image) {
 			pr_cont("crash kernel not loaded\n");
-			atomic_set(&uv_nmi_kexec_failed, 1);
-			uv_nmi_sync_exit(1);
 			return;
 		}
 		pr_cont("kexec busy, stalling cpus while waiting\n");
@@ -514,9 +517,6 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
 	/* If crash exec fails the slaves should return, otherwise stall */
 	while (atomic_read(&uv_nmi_kexec_failed) == 0)
 		mdelay(10);
-
-	/* Crash kernel most likely not loaded, return in an orderly fashion */
-	uv_nmi_sync_exit(0);
 }
 
 #else /* !CONFIG_KEXEC_CORE */
@@ -524,6 +524,7 @@ static inline void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
 {
 	if (master)
 		pr_err("UV: NMI kdump: KEXEC not supported in this kernel\n");
+	atomic_set(&uv_nmi_kexec_failed, 1);
 }
 #endif /* !CONFIG_KEXEC_CORE */
 
@@ -613,9 +614,14 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
 	master = (atomic_read(&uv_nmi_cpu) == cpu);
 
 	/* If NMI action is "kdump", then attempt to do it */
-	if (uv_nmi_action_is("kdump"))
+	if (uv_nmi_action_is("kdump")) {
 		uv_nmi_kdump(cpu, master, regs);
 
+		/* Unexpected return, revert action to "dump" */
+		if (master)
+			strncpy(uv_nmi_action, "dump", strlen(uv_nmi_action));
+	}
+
 	/* Pause as all cpus enter the NMI handler */
 	uv_nmi_wait(master);
 
@@ -640,6 +646,7 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
 		atomic_set(&uv_nmi_cpus_in_nmi, -1);
 		atomic_set(&uv_nmi_cpu, -1);
 		atomic_set(&uv_in_nmi, 0);
+		atomic_set(&uv_nmi_kexec_failed, 0);
 	}
 
 	uv_nmi_touch_watchdogs();
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c
index 9701a4fd7bf2..836a1eb5df43 100644
--- a/arch/x86/um/ldt.c
+++ b/arch/x86/um/ldt.c
@@ -12,7 +12,10 @@
 #include <skas.h>
 #include <sysdep/tls.h>
 
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
+static inline int modify_ldt (int func, void *ptr, unsigned long bytecount)
+{
+	return syscall(__NR_modify_ldt, func, ptr, bytecount);
+}
 
 static long write_ldt_entry(struct mm_id *mm_idp, int func,
 		     struct user_desc *desc, void **addr, int done)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 35c2de136971..fa18753f5c34 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -940,6 +940,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
 	char *xbuf[XBUFSIZE];
 	char *xoutbuf[XBUFSIZE];
 	int ret = -ENOMEM;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 
 	if (testmgr_alloc_buf(xbuf))
 		goto out_nobuf;
@@ -975,7 +976,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
 			continue;
 
 		if (template[i].iv)
-			memcpy(iv, template[i].iv, MAX_IVLEN);
+			memcpy(iv, template[i].iv, ivsize);
 		else
 			memset(iv, 0, MAX_IVLEN);
 
@@ -1051,7 +1052,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
 			continue;
 
 		if (template[i].iv)
-			memcpy(iv, template[i].iv, MAX_IVLEN);
+			memcpy(iv, template[i].iv, ivsize);
 		else
 			memset(iv, 0, MAX_IVLEN);
 
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 15e40ee62a94..6aaa3f81755b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -175,6 +175,15 @@ config AHCI_XGENE
 	help
 	 This option enables support for APM X-Gene SoC SATA host controller.
 
+config AHCI_QORIQ
+	tristate "Freescale QorIQ AHCI SATA support"
+	depends on OF
+	help
+	  This option enables support for the Freescale QorIQ AHCI SoC's
+	  onboard AHCI SATA.
+
+	  If unsure, say N.
+
 config SATA_FSL
 	tristate "Freescale 3.0Gbps SATA support"
 	depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index af70919f7dde..af45effac18c 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_AHCI_SUNXI)	+= ahci_sunxi.o libahci.o libahci_platform.o
 obj-$(CONFIG_AHCI_ST)		+= ahci_st.o libahci.o libahci_platform.o
 obj-$(CONFIG_AHCI_TEGRA)	+= ahci_tegra.o libahci.o libahci_platform.o
 obj-$(CONFIG_AHCI_XGENE)	+= ahci_xgene.o libahci.o libahci_platform.o
+obj-$(CONFIG_AHCI_QORIQ)	+= ahci_qoriq.o libahci.o libahci_platform.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 1befb114c384..04975b851c23 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -76,7 +76,6 @@ static const struct of_device_id ahci_of_match[] = {
 	{ .compatible = "ibm,476gtr-ahci", },
 	{ .compatible = "snps,dwc-ahci", },
 	{ .compatible = "hisilicon,hisi-ahci", },
-	{ .compatible = "fsl,qoriq-ahci", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
new file mode 100644
index 000000000000..e5e498812554
--- /dev/null
+++ b/drivers/ata/ahci_qoriq.c
@@ -0,0 +1,272 @@
+/*
+ * Freescale QorIQ AHCI SATA platform driver
+ *
+ * Copyright 2015 Freescale, Inc.
+ *   Tang Yuantian <Yuantian.Tang@freescale.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, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/ahci_platform.h>
+#include <linux/device.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include "ahci.h"
+
+#define DRV_NAME "ahci-qoriq"
+
+/* port register definition */
+#define PORT_PHY1	0xA8
+#define PORT_PHY2	0xAC
+#define PORT_PHY3	0xB0
+#define PORT_PHY4	0xB4
+#define PORT_PHY5	0xB8
+#define PORT_TRANS	0xC8
+
+/* port register default value */
+#define AHCI_PORT_PHY_1_CFG	0xa003fffe
+#define AHCI_PORT_PHY_2_CFG	0x28183411
+#define AHCI_PORT_PHY_3_CFG	0x0e081004
+#define AHCI_PORT_PHY_4_CFG	0x00480811
+#define AHCI_PORT_PHY_5_CFG	0x192c96a4
+#define AHCI_PORT_TRANS_CFG	0x08000025
+
+#define SATA_ECC_DISABLE	0x00020000
+
+enum ahci_qoriq_type {
+	AHCI_LS1021A,
+	AHCI_LS1043A,
+	AHCI_LS2085A,
+};
+
+struct ahci_qoriq_priv {
+	struct ccsr_ahci *reg_base;
+	enum ahci_qoriq_type type;
+	void __iomem *ecc_addr;
+};
+
+static const struct of_device_id ahci_qoriq_of_match[] = {
+	{ .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
+	{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
+	{ .compatible = "fsl,ls2085a-ahci", .data = (void *)AHCI_LS2085A},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
+
+static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
+			  unsigned long deadline)
+{
+	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+	void __iomem *port_mmio = ahci_port_base(link->ap);
+	u32 px_cmd, px_is, px_val;
+	struct ata_port *ap = link->ap;
+	struct ahci_port_priv *pp = ap->private_data;
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+	struct ahci_qoriq_priv *qoriq_priv = hpriv->plat_data;
+	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+	struct ata_taskfile tf;
+	bool online;
+	int rc;
+
+	DPRINTK("ENTER\n");
+
+	ahci_stop_engine(ap);
+
+	/*
+	 * There is a errata on ls1021a Rev1.0 and Rev2.0 which is:
+	 * A-009042: The device detection initialization sequence
+	 * mistakenly resets some registers.
+	 *
+	 * Workaround for this is:
+	 * The software should read and store PxCMD and PxIS values
+	 * before issuing the device detection initialization sequence.
+	 * After the sequence is complete, software should restore the
+	 * PxCMD and PxIS with the stored values.
+	 */
+	if (qoriq_priv->type == AHCI_LS1021A) {
+		px_cmd = readl(port_mmio + PORT_CMD);
+		px_is = readl(port_mmio + PORT_IRQ_STAT);
+	}
+
+	/* clear D2H reception area to properly wait for D2H FIS */
+	ata_tf_init(link->device, &tf);
+	tf.command = ATA_BUSY;
+	ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+	rc = sata_link_hardreset(link, timing, deadline, &online,
+				 ahci_check_ready);
+
+	/* restore the PxCMD and PxIS on ls1021 */
+	if (qoriq_priv->type == AHCI_LS1021A) {
+		px_val = readl(port_mmio + PORT_CMD);
+		if (px_val != px_cmd)
+			writel(px_cmd, port_mmio + PORT_CMD);
+
+		px_val = readl(port_mmio + PORT_IRQ_STAT);
+		if (px_val != px_is)
+			writel(px_is, port_mmio + PORT_IRQ_STAT);
+	}
+
+	hpriv->start_engine(ap);
+
+	if (online)
+		*class = ahci_dev_classify(ap);
+
+	DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+	return rc;
+}
+
+static struct ata_port_operations ahci_qoriq_ops = {
+	.inherits	= &ahci_ops,
+	.hardreset	= ahci_qoriq_hardreset,
+};
+
+static const struct ata_port_info ahci_qoriq_port_info = {
+	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
+	.pio_mask	= ATA_PIO4,
+	.udma_mask	= ATA_UDMA6,
+	.port_ops	= &ahci_qoriq_ops,
+};
+
+static struct scsi_host_template ahci_qoriq_sht = {
+	AHCI_SHT(DRV_NAME),
+};
+
+static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
+{
+	struct ahci_qoriq_priv *qpriv = hpriv->plat_data;
+	void __iomem *reg_base = hpriv->mmio;
+
+	switch (qpriv->type) {
+	case AHCI_LS1021A:
+		writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
+		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+		writel(AHCI_PORT_PHY_2_CFG, reg_base + PORT_PHY2);
+		writel(AHCI_PORT_PHY_3_CFG, reg_base + PORT_PHY3);
+		writel(AHCI_PORT_PHY_4_CFG, reg_base + PORT_PHY4);
+		writel(AHCI_PORT_PHY_5_CFG, reg_base + PORT_PHY5);
+		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+		break;
+
+	case AHCI_LS1043A:
+	case AHCI_LS2085A:
+		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+		break;
+	}
+
+	return 0;
+}
+
+static int ahci_qoriq_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct ahci_host_priv *hpriv;
+	struct ahci_qoriq_priv *qoriq_priv;
+	const struct of_device_id *of_id;
+	struct resource *res;
+	int rc;
+
+	hpriv = ahci_platform_get_resources(pdev);
+	if (IS_ERR(hpriv))
+		return PTR_ERR(hpriv);
+
+	of_id = of_match_node(ahci_qoriq_of_match, np);
+	if (!of_id)
+		return -ENODEV;
+
+	qoriq_priv = devm_kzalloc(dev, sizeof(*qoriq_priv), GFP_KERNEL);
+	if (!qoriq_priv)
+		return -ENOMEM;
+
+	qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
+
+	if (qoriq_priv->type == AHCI_LS1021A) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+				"sata-ecc");
+		qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
+		if (IS_ERR(qoriq_priv->ecc_addr))
+			return PTR_ERR(qoriq_priv->ecc_addr);
+	}
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		return rc;
+
+	hpriv->plat_data = qoriq_priv;
+	rc = ahci_qoriq_phy_init(hpriv);
+	if (rc)
+		goto disable_resources;
+
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_qoriq_port_info,
+				     &ahci_qoriq_sht);
+	if (rc)
+		goto disable_resources;
+
+	return 0;
+
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
+
+	return rc;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ahci_qoriq_resume(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	int rc;
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		return rc;
+
+	rc = ahci_qoriq_phy_init(hpriv);
+	if (rc)
+		goto disable_resources;
+
+	rc = ahci_platform_resume_host(dev);
+	if (rc)
+		goto disable_resources;
+
+	/* We resumed so update PM runtime state */
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	return 0;
+
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
+
+	return rc;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend,
+			 ahci_qoriq_resume);
+
+static struct platform_driver ahci_qoriq_driver = {
+	.probe = ahci_qoriq_probe,
+	.remove = ata_platform_remove_one,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = ahci_qoriq_of_match,
+		.pm = &ahci_qoriq_pm_ops,
+	},
+};
+module_platform_driver(ahci_qoriq_driver);
+
+MODULE_DESCRIPTION("Freescale QorIQ AHCI SATA platform driver");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c
index c36b3e6531d8..f6c46e9a4dc0 100644
--- a/drivers/ata/pata_pxa.c
+++ b/drivers/ata/pata_pxa.c
@@ -24,79 +24,36 @@
 #include <linux/ata.h>
 #include <linux/libata.h>
 #include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
 
 #include <scsi/scsi_host.h>
 
-#include <mach/pxa2xx-regs.h>
 #include <linux/platform_data/ata-pxa.h>
-#include <mach/dma.h>
 
 #define DRV_NAME	"pata_pxa"
 #define DRV_VERSION	"0.1"
 
 struct pata_pxa_data {
-	uint32_t		dma_channel;
-	struct pxa_dma_desc	*dma_desc;
-	dma_addr_t		dma_desc_addr;
-	uint32_t		dma_desc_id;
-
-	/* DMA IO physical address */
-	uint32_t		dma_io_addr;
-	/* PXA DREQ<0:2> pin selector */
-	uint32_t		dma_dreq;
-	/* DMA DCSR register value */
-	uint32_t		dma_dcsr;
-
+	struct dma_chan		*dma_chan;
+	dma_cookie_t		dma_cookie;
 	struct completion	dma_done;
 };
 
 /*
- * Setup the DMA descriptors. The size is transfer capped at 4k per descriptor,
- * if the transfer is longer, it is split into multiple chained descriptors.
+ * DMA interrupt handler.
  */
-static void pxa_load_dmac(struct scatterlist *sg, struct ata_queued_cmd *qc)
+static void pxa_ata_dma_irq(void *d)
 {
-	struct pata_pxa_data *pd = qc->ap->private_data;
-
-	uint32_t cpu_len, seg_len;
-	dma_addr_t cpu_addr;
-
-	cpu_addr = sg_dma_address(sg);
-	cpu_len = sg_dma_len(sg);
-
-	do {
-		seg_len = (cpu_len > 0x1000) ? 0x1000 : cpu_len;
-
-		pd->dma_desc[pd->dma_desc_id].ddadr = pd->dma_desc_addr +
-			((pd->dma_desc_id + 1) * sizeof(struct pxa_dma_desc));
-
-		pd->dma_desc[pd->dma_desc_id].dcmd = DCMD_BURST32 |
-					DCMD_WIDTH2 | (DCMD_LENGTH & seg_len);
-
-		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			pd->dma_desc[pd->dma_desc_id].dsadr = cpu_addr;
-			pd->dma_desc[pd->dma_desc_id].dtadr = pd->dma_io_addr;
-			pd->dma_desc[pd->dma_desc_id].dcmd |= DCMD_INCSRCADDR |
-						DCMD_FLOWTRG;
-		} else {
-			pd->dma_desc[pd->dma_desc_id].dsadr = pd->dma_io_addr;
-			pd->dma_desc[pd->dma_desc_id].dtadr = cpu_addr;
-			pd->dma_desc[pd->dma_desc_id].dcmd |= DCMD_INCTRGADDR |
-						DCMD_FLOWSRC;
-		}
-
-		cpu_len -= seg_len;
-		cpu_addr += seg_len;
-		pd->dma_desc_id++;
+	struct pata_pxa_data *pd = d;
+	enum dma_status status;
 
-	} while (cpu_len);
-
-	/* Should not happen */
-	if (seg_len & 0x1f)
-		DALGN |= (1 << pd->dma_dreq);
+	status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, NULL);
+	if (status == DMA_ERROR || status == DMA_COMPLETE)
+		complete(&pd->dma_done);
 }
 
 /*
@@ -105,28 +62,22 @@ static void pxa_load_dmac(struct scatterlist *sg, struct ata_queued_cmd *qc)
 static void pxa_qc_prep(struct ata_queued_cmd *qc)
 {
 	struct pata_pxa_data *pd = qc->ap->private_data;
-	int si = 0;
-	struct scatterlist *sg;
+	struct dma_async_tx_descriptor *tx;
+	enum dma_transfer_direction dir;
 
 	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
 		return;
 
-	pd->dma_desc_id = 0;
-
-	DCSR(pd->dma_channel) = 0;
-	DALGN &= ~(1 << pd->dma_dreq);
-
-	for_each_sg(qc->sg, sg, qc->n_elem, si)
-		pxa_load_dmac(sg, qc);
-
-	pd->dma_desc[pd->dma_desc_id - 1].ddadr = DDADR_STOP;
-
-	/* Fire IRQ only at the end of last block */
-	pd->dma_desc[pd->dma_desc_id - 1].dcmd |= DCMD_ENDIRQEN;
-
-	DDADR(pd->dma_channel) = pd->dma_desc_addr;
-	DRCMR(pd->dma_dreq) = DRCMR_MAPVLD | pd->dma_channel;
-
+	dir = (qc->dma_dir == DMA_TO_DEVICE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
+	tx = dmaengine_prep_slave_sg(pd->dma_chan, qc->sg, qc->n_elem, dir,
+				     DMA_PREP_INTERRUPT);
+	if (!tx) {
+		ata_dev_err(qc->dev, "prep_slave_sg() failed\n");
+		return;
+	}
+	tx->callback = pxa_ata_dma_irq;
+	tx->callback_param = pd;
+	pd->dma_cookie = dmaengine_submit(tx);
 }
 
 /*
@@ -145,7 +96,7 @@ static void pxa_bmdma_start(struct ata_queued_cmd *qc)
 {
 	struct pata_pxa_data *pd = qc->ap->private_data;
 	init_completion(&pd->dma_done);
-	DCSR(pd->dma_channel) = DCSR_RUN;
+	dma_async_issue_pending(pd->dma_chan);
 }
 
 /*
@@ -154,12 +105,14 @@ static void pxa_bmdma_start(struct ata_queued_cmd *qc)
 static void pxa_bmdma_stop(struct ata_queued_cmd *qc)
 {
 	struct pata_pxa_data *pd = qc->ap->private_data;
+	enum dma_status status;
 
-	if ((DCSR(pd->dma_channel) & DCSR_RUN) &&
-		wait_for_completion_timeout(&pd->dma_done, HZ))
-		dev_err(qc->ap->dev, "Timeout waiting for DMA completion!");
+	status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, NULL);
+	if (status != DMA_ERROR && status != DMA_COMPLETE &&
+	    wait_for_completion_timeout(&pd->dma_done, HZ))
+		ata_dev_err(qc->dev, "Timeout waiting for DMA completion!");
 
-	DCSR(pd->dma_channel) = 0;
+	dmaengine_terminate_all(pd->dma_chan);
 }
 
 /*
@@ -170,8 +123,11 @@ static unsigned char pxa_bmdma_status(struct ata_port *ap)
 {
 	struct pata_pxa_data *pd = ap->private_data;
 	unsigned char ret = ATA_DMA_INTR;
+	struct dma_tx_state state;
+	enum dma_status status;
 
-	if (pd->dma_dcsr & DCSR_BUSERR)
+	status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, &state);
+	if (status != DMA_COMPLETE)
 		ret |= ATA_DMA_ERR;
 
 	return ret;
@@ -213,21 +169,6 @@ static struct ata_port_operations pxa_ata_port_ops = {
 	.qc_prep		= pxa_qc_prep,
 };
 
-/*
- * DMA interrupt handler.
- */
-static void pxa_ata_dma_irq(int dma, void *port)
-{
-	struct ata_port *ap = port;
-	struct pata_pxa_data *pd = ap->private_data;
-
-	pd->dma_dcsr = DCSR(dma);
-	DCSR(dma) = pd->dma_dcsr;
-
-	if (pd->dma_dcsr & DCSR_STOPSTATE)
-		complete(&pd->dma_done);
-}
-
 static int pxa_ata_probe(struct platform_device *pdev)
 {
 	struct ata_host *host;
@@ -238,6 +179,9 @@ static int pxa_ata_probe(struct platform_device *pdev)
 	struct resource *dma_res;
 	struct resource *irq_res;
 	struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
+	struct dma_slave_config	config;
+	dma_cap_mask_t mask;
+	struct pxad_param param;
 	int ret = 0;
 
 	/*
@@ -333,29 +277,32 @@ static int pxa_ata_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	ap->private_data = data;
-	data->dma_dreq = pdata->dma_dreq;
-	data->dma_io_addr = dma_res->start;
 
-	/*
-	 * Allocate space for the DMA descriptors
-	 */
-	data->dma_desc = dmam_alloc_coherent(&pdev->dev, PAGE_SIZE,
-					&data->dma_desc_addr, GFP_KERNEL);
-	if (!data->dma_desc)
-		return -EINVAL;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	param.prio = PXAD_PRIO_LOWEST;
+	param.drcmr = pdata->dma_dreq;
+	memset(&config, 0, sizeof(config));
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+	config.src_addr = dma_res->start;
+	config.dst_addr = dma_res->start;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
 
 	/*
 	 * Request the DMA channel
 	 */
-	data->dma_channel = pxa_request_dma(DRV_NAME, DMA_PRIO_LOW,
-						pxa_ata_dma_irq, ap);
-	if (data->dma_channel < 0)
+	data->dma_chan =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &pdev->dev, "data");
+	if (!data->dma_chan)
 		return -EBUSY;
-
-	/*
-	 * Stop and clear the DMA channel
-	 */
-	DCSR(data->dma_channel) = 0;
+	ret = dmaengine_slave_config(data->dma_chan, &config);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "dma configuration failed: %d\n", ret);
+		return ret;
+	}
 
 	/*
 	 * Activate the ATA host
@@ -363,7 +310,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
 	ret = ata_host_activate(host, irq_res->start, ata_sff_interrupt,
 				pdata->irq_flags, &pxa_ata_sht);
 	if (ret)
-		pxa_free_dma(data->dma_channel);
+		dma_release_channel(data->dma_chan);
 
 	return ret;
 }
@@ -373,7 +320,7 @@ static int pxa_ata_remove(struct platform_device *pdev)
 	struct ata_host *host = platform_get_drvdata(pdev);
 	struct pata_pxa_data *data = host->ports[0]->private_data;
 
-	pxa_free_dma(data->dma_channel);
+	dma_release_channel(data->dma_chan);
 
 	ata_host_detach(host);
 
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index a00bb82eb7c6..772a2770710c 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -453,7 +453,8 @@ static int bt3c_load_firmware(struct bt3c_info *info,
 {
 	char *ptr = (char *) firmware;
 	char b[9];
-	unsigned int iobase, size, addr, fcs, tmp;
+	unsigned int iobase, tmp;
+	unsigned long size, addr, fcs;
 	int i, err = 0;
 
 	iobase = info->p_dev->resource[0]->start;
@@ -478,15 +479,18 @@ static int bt3c_load_firmware(struct bt3c_info *info,
 
 		memset(b, 0, sizeof(b));
 		memcpy(b, ptr + 2, 2);
-		size = simple_strtoul(b, NULL, 16);
+		if (kstrtoul(b, 16, &size) < 0)
+			return -EINVAL;
 
 		memset(b, 0, sizeof(b));
 		memcpy(b, ptr + 4, 8);
-		addr = simple_strtoul(b, NULL, 16);
+		if (kstrtoul(b, 16, &addr) < 0)
+			return -EINVAL;
 
 		memset(b, 0, sizeof(b));
 		memcpy(b, ptr + (size * 2) + 2, 2);
-		fcs = simple_strtoul(b, NULL, 16);
+		if (kstrtoul(b, 16, &fcs) < 0)
+			return -EINVAL;
 
 		memset(b, 0, sizeof(b));
 		for (tmp = 0, i = 0; i < size; i++) {
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 048423fd83bf..9e18988375eb 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -22,6 +22,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/firmware.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -169,6 +170,51 @@ int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
 }
 EXPORT_SYMBOL_GPL(btintel_secure_send);
 
+int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
+{
+	const struct firmware *fw;
+	struct sk_buff *skb;
+	const u8 *fw_ptr;
+	int err;
+
+	err = request_firmware_direct(&fw, ddc_name, &hdev->dev);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to load Intel DDC file %s (%d)",
+			   ddc_name, err);
+		return err;
+	}
+
+	bt_dev_info(hdev, "Found Intel DDC parameters: %s", ddc_name);
+
+	fw_ptr = fw->data;
+
+	/* DDC file contains one or more DDC structure which has
+	 * Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2).
+	 */
+	while (fw->size > fw_ptr - fw->data) {
+		u8 cmd_plen = fw_ptr[0] + sizeof(u8);
+
+		skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
+				     HCI_INIT_TIMEOUT);
+		if (IS_ERR(skb)) {
+			bt_dev_err(hdev, "Failed to send Intel_Write_DDC (%ld)",
+				   PTR_ERR(skb));
+			release_firmware(fw);
+			return PTR_ERR(skb);
+		}
+
+		fw_ptr += cmd_plen;
+		kfree_skb(skb);
+	}
+
+	release_firmware(fw);
+
+	bt_dev_info(hdev, "Applying Intel DDC parameters completed");
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_load_ddc_config);
+
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index b278d14758d5..52deaf2817cf 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -78,6 +78,7 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code);
 void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
 int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
 			const void *param);
+int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
 
 #else
 
@@ -95,7 +96,8 @@ static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
 {
 }
 
-static void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)
+static inline void btintel_version_info(struct hci_dev *hdev,
+					struct intel_version *ver)
 {
 }
 
@@ -105,4 +107,10 @@ static inline int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type,
 	return -EOPNOTSUPP;
 }
 
+static inline int btintel_load_ddc_config(struct hci_dev *hdev,
+					  const char *ddc_name)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index de05deb444ce..bc110f61c8b1 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -377,20 +377,6 @@ static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
 		return -EINVAL;
 	}
 
-	if (skb_headroom(skb) < BTM_HEADER_LEN) {
-		struct sk_buff *tmp = skb;
-
-		skb = skb_realloc_headroom(skb, BTM_HEADER_LEN);
-		if (!skb) {
-			BT_ERR("Tx Error: realloc_headroom failed %d",
-				BTM_HEADER_LEN);
-			skb = tmp;
-			return -EINVAL;
-		}
-
-		kfree_skb(tmp);
-	}
-
 	skb_push(skb, BTM_HEADER_LEN);
 
 	/* header type: byte[3]
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b6aceaf82aa8..dfaaea2efecb 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1277,6 +1277,20 @@ static void btusb_work(struct work_struct *work)
 			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 			usb_kill_anchored_urbs(&data->isoc_anchor);
 
+			/* When isochronous alternate setting needs to be
+			 * changed, because SCO connection has been added
+			 * or removed, a packet fragment may be left in the
+			 * reassembling state. This could lead to wrongly
+			 * assembled fragments.
+			 *
+			 * Clear outstanding fragment when selecting a new
+			 * alternate setting.
+			 */
+			spin_lock(&data->rxlock);
+			kfree_skb(data->sco_skb);
+			data->sco_skb = NULL;
+			spin_unlock(&data->rxlock);
+
 			if (__set_isoc_interface(hdev, new_alts) < 0)
 				return;
 		}
@@ -1348,7 +1362,9 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 
 	rp = (struct hci_rp_read_local_version *)skb->data;
 
-	if (le16_to_cpu(rp->manufacturer) != 10) {
+	/* Detect controllers which aren't real CSR ones. */
+	if (le16_to_cpu(rp->manufacturer) != 10 ||
+	    le16_to_cpu(rp->lmp_subver) == 0x0c5c) {
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
 		 */
@@ -2217,36 +2233,7 @@ done:
 	 * The device can work without DDC parameters, so even if it fails
 	 * to load the file, no need to fail the setup.
 	 */
-	err = request_firmware_direct(&fw, fwname, &hdev->dev);
-	if (err < 0)
-		return 0;
-
-	BT_INFO("%s: Found Intel DDC parameters: %s", hdev->name, fwname);
-
-	fw_ptr = fw->data;
-
-	/* DDC file contains one or more DDC structure which has
-	 * Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2).
-	 */
-	while (fw->size > fw_ptr - fw->data) {
-		u8 cmd_plen = fw_ptr[0] + sizeof(u8);
-
-		skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
-				     HCI_INIT_TIMEOUT);
-		if (IS_ERR(skb)) {
-			BT_ERR("%s: Failed to send Intel_Write_DDC (%ld)",
-			       hdev->name, PTR_ERR(skb));
-			release_firmware(fw);
-			return PTR_ERR(skb);
-		}
-
-		fw_ptr += cmd_plen;
-		kfree_skb(skb);
-	}
-
-	release_firmware(fw);
-
-	BT_INFO("%s: Applying Intel DDC parameters completed", hdev->name);
+	btintel_load_ddc_config(hdev, fwname);
 
 	return 0;
 }
@@ -2782,7 +2769,7 @@ static int btusb_probe(struct usb_interface *intf,
 			set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
 
 		/* Fake CSR devices with broken commands */
-		if (bcdDevice <= 0x100)
+		if (bcdDevice <= 0x100 || bcdDevice == 0x134)
 			hdev->setup = btusb_setup_csr;
 
 		set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 835bfab88ef5..f30654149c63 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
 #include <linux/tty.h>
+#include <linux/interrupt.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -51,6 +52,8 @@ struct bcm_device {
 	bool			clk_enabled;
 
 	u32			init_speed;
+	int			irq;
+	u8			irq_polarity;
 
 #ifdef CONFIG_PM_SLEEP
 	struct hci_uart		*hu;
@@ -66,7 +69,7 @@ struct bcm_data {
 };
 
 /* List of BCM BT UART devices */
-static DEFINE_SPINLOCK(bcm_device_lock);
+static DEFINE_MUTEX(bcm_device_lock);
 static LIST_HEAD(bcm_device_list);
 
 static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
@@ -80,7 +83,7 @@ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
 
 		clock.type = BCM_UART_CLOCK_48MHZ;
 
-		BT_DBG("%s: Set Controller clock (%d)", hdev->name, clock.type);
+		bt_dev_dbg(hdev, "Set Controller clock (%d)", clock.type);
 
 		/* This Broadcom specific command changes the UART's controller
 		 * clock for baud rate > 3000000.
@@ -88,15 +91,15 @@ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
 		skb = __hci_cmd_sync(hdev, 0xfc45, 1, &clock, HCI_INIT_TIMEOUT);
 		if (IS_ERR(skb)) {
 			int err = PTR_ERR(skb);
-			BT_ERR("%s: BCM: failed to write clock command (%d)",
-			       hdev->name, err);
+			bt_dev_err(hdev, "BCM: failed to write clock (%d)",
+				   err);
 			return err;
 		}
 
 		kfree_skb(skb);
 	}
 
-	BT_DBG("%s: Set Controller UART speed to %d bit/s", hdev->name, speed);
+	bt_dev_dbg(hdev, "Set Controller UART speed to %d bit/s", speed);
 
 	param.zero = cpu_to_le16(0);
 	param.baud_rate = cpu_to_le32(speed);
@@ -108,8 +111,8 @@ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
 			     HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
 		int err = PTR_ERR(skb);
-		BT_ERR("%s: BCM: failed to write update baudrate command (%d)",
-		       hdev->name, err);
+		bt_dev_err(hdev, "BCM: failed to write update baudrate (%d)",
+			   err);
 		return err;
 	}
 
@@ -149,12 +152,92 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static irqreturn_t bcm_host_wake(int irq, void *data)
+{
+	struct bcm_device *bdev = data;
+
+	bt_dev_dbg(bdev, "Host wake IRQ");
+
+	return IRQ_HANDLED;
+}
+
+static int bcm_request_irq(struct bcm_data *bcm)
+{
+	struct bcm_device *bdev = bcm->dev;
+	int err = 0;
+
+	/* If this is not a platform device, do not enable PM functionalities */
+	mutex_lock(&bcm_device_lock);
+	if (!bcm_device_exists(bdev)) {
+		err = -ENODEV;
+		goto unlock;
+	}
+
+	if (bdev->irq > 0) {
+		err = devm_request_irq(&bdev->pdev->dev, bdev->irq,
+				       bcm_host_wake, IRQF_TRIGGER_RISING,
+				       "host_wake", bdev);
+		if (err)
+			goto unlock;
+
+		device_init_wakeup(&bdev->pdev->dev, true);
+	}
+
+unlock:
+	mutex_unlock(&bcm_device_lock);
+
+	return err;
+}
+
+static const struct bcm_set_sleep_mode default_sleep_params = {
+	.sleep_mode = 1,	/* 0=Disabled, 1=UART, 2=Reserved, 3=USB */
+	.idle_host = 2,		/* idle threshold HOST, in 300ms */
+	.idle_dev = 2,		/* idle threshold device, in 300ms */
+	.bt_wake_active = 1,	/* BT_WAKE active mode: 1 = high, 0 = low */
+	.host_wake_active = 0,	/* HOST_WAKE active mode: 1 = high, 0 = low */
+	.allow_host_sleep = 1,	/* Allow host sleep in SCO flag */
+	.combine_modes = 0,	/* Combine sleep and LPM flag */
+	.tristate_control = 0,	/* Allow tri-state control of UART tx flag */
+	/* Irrelevant USB flags */
+	.usb_auto_sleep = 0,
+	.usb_resume_timeout = 0,
+	.pulsed_host_wake = 0,
+	.break_to_host = 0
+};
+
+static int bcm_setup_sleep(struct hci_uart *hu)
+{
+	struct bcm_data *bcm = hu->priv;
+	struct sk_buff *skb;
+	struct bcm_set_sleep_mode sleep_params = default_sleep_params;
+
+	sleep_params.host_wake_active = !bcm->dev->irq_polarity;
+
+	skb = __hci_cmd_sync(hu->hdev, 0xfc27, sizeof(sleep_params),
+			     &sleep_params, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		int err = PTR_ERR(skb);
+		bt_dev_err(hu->hdev, "Sleep VSC failed (%d)", err);
+		return err;
+	}
+	kfree_skb(skb);
+
+	bt_dev_dbg(hu->hdev, "Set Sleep Parameters VSC succeeded");
+
+	return 0;
+}
+#else
+static inline int bcm_request_irq(struct bcm_data *bcm) { return 0; }
+static inline int bcm_setup_sleep(struct hci_uart *hu) { return 0; }
+#endif
+
 static int bcm_open(struct hci_uart *hu)
 {
 	struct bcm_data *bcm;
 	struct list_head *p;
 
-	BT_DBG("hu %p", hu);
+	bt_dev_dbg(hu->hdev, "hu %p", hu);
 
 	bcm = kzalloc(sizeof(*bcm), GFP_KERNEL);
 	if (!bcm)
@@ -164,7 +247,7 @@ static int bcm_open(struct hci_uart *hu)
 
 	hu->priv = bcm;
 
-	spin_lock(&bcm_device_lock);
+	mutex_lock(&bcm_device_lock);
 	list_for_each(p, &bcm_device_list) {
 		struct bcm_device *dev = list_entry(p, struct bcm_device, list);
 
@@ -178,14 +261,12 @@ static int bcm_open(struct hci_uart *hu)
 #ifdef CONFIG_PM_SLEEP
 			dev->hu = hu;
 #endif
+			bcm_gpio_set_power(bcm->dev, true);
 			break;
 		}
 	}
 
-	if (bcm->dev)
-		bcm_gpio_set_power(bcm->dev, true);
-
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	return 0;
 }
@@ -193,18 +274,24 @@ static int bcm_open(struct hci_uart *hu)
 static int bcm_close(struct hci_uart *hu)
 {
 	struct bcm_data *bcm = hu->priv;
+	struct bcm_device *bdev = bcm->dev;
 
-	BT_DBG("hu %p", hu);
+	bt_dev_dbg(hu->hdev, "hu %p", hu);
 
 	/* Protect bcm->dev against removal of the device or driver */
-	spin_lock(&bcm_device_lock);
-	if (bcm_device_exists(bcm->dev)) {
-		bcm_gpio_set_power(bcm->dev, false);
+	mutex_lock(&bcm_device_lock);
+	if (bcm_device_exists(bdev)) {
+		bcm_gpio_set_power(bdev, false);
 #ifdef CONFIG_PM_SLEEP
-		bcm->dev->hu = NULL;
+		if (device_can_wakeup(&bdev->pdev->dev)) {
+			devm_free_irq(&bdev->pdev->dev, bdev->irq, bdev);
+			device_init_wakeup(&bdev->pdev->dev, false);
+		}
+
+		bdev->hu = NULL;
 #endif
 	}
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	skb_queue_purge(&bcm->txq);
 	kfree_skb(bcm->rx_skb);
@@ -218,7 +305,7 @@ static int bcm_flush(struct hci_uart *hu)
 {
 	struct bcm_data *bcm = hu->priv;
 
-	BT_DBG("hu %p", hu);
+	bt_dev_dbg(hu->hdev, "hu %p", hu);
 
 	skb_queue_purge(&bcm->txq);
 
@@ -227,12 +314,13 @@ static int bcm_flush(struct hci_uart *hu)
 
 static int bcm_setup(struct hci_uart *hu)
 {
+	struct bcm_data *bcm = hu->priv;
 	char fw_name[64];
 	const struct firmware *fw;
 	unsigned int speed;
 	int err;
 
-	BT_DBG("hu %p", hu);
+	bt_dev_dbg(hu->hdev, "hu %p", hu);
 
 	hu->hdev->set_bdaddr = btbcm_set_bdaddr;
 
@@ -242,13 +330,13 @@ static int bcm_setup(struct hci_uart *hu)
 
 	err = request_firmware(&fw, fw_name, &hu->hdev->dev);
 	if (err < 0) {
-		BT_INFO("%s: BCM: Patch %s not found", hu->hdev->name, fw_name);
+		bt_dev_info(hu->hdev, "BCM: Patch %s not found", fw_name);
 		return 0;
 	}
 
 	err = btbcm_patchram(hu->hdev, fw);
 	if (err) {
-		BT_INFO("%s: BCM: Patch failed (%d)", hu->hdev->name, err);
+		bt_dev_info(hu->hdev, "BCM: Patch failed (%d)", err);
 		goto finalize;
 	}
 
@@ -281,6 +369,12 @@ finalize:
 	release_firmware(fw);
 
 	err = btbcm_finalize(hu->hdev);
+	if (err)
+		return err;
+
+	err = bcm_request_irq(bcm);
+	if (!err)
+		err = bcm_setup_sleep(hu);
 
 	return err;
 }
@@ -302,7 +396,7 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
 				  bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts));
 	if (IS_ERR(bcm->rx_skb)) {
 		int err = PTR_ERR(bcm->rx_skb);
-		BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
+		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
 		bcm->rx_skb = NULL;
 		return err;
 	}
@@ -314,7 +408,7 @@ static int bcm_enqueue(struct hci_uart *hu, struct sk_buff *skb)
 {
 	struct bcm_data *bcm = hu->priv;
 
-	BT_DBG("hu %p skb %p", hu, skb);
+	bt_dev_dbg(hu->hdev, "hu %p skb %p", hu, skb);
 
 	/* Prepend skb with frame type */
 	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
@@ -335,10 +429,11 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
 static int bcm_suspend(struct device *dev)
 {
 	struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev));
+	int error;
 
-	BT_DBG("suspend (%p): is_suspended %d", bdev, bdev->is_suspended);
+	bt_dev_dbg(bdev, "suspend: is_suspended %d", bdev->is_suspended);
 
-	spin_lock(&bcm_device_lock);
+	mutex_lock(&bcm_device_lock);
 
 	if (!bdev->hu)
 		goto unlock;
@@ -353,12 +448,18 @@ static int bcm_suspend(struct device *dev)
 	/* Suspend the device */
 	if (bdev->device_wakeup) {
 		gpiod_set_value(bdev->device_wakeup, false);
-		BT_DBG("suspend, delaying 15 ms");
+		bt_dev_dbg(bdev, "suspend, delaying 15 ms");
 		mdelay(15);
 	}
 
+	if (device_may_wakeup(&bdev->pdev->dev)) {
+		error = enable_irq_wake(bdev->irq);
+		if (!error)
+			bt_dev_dbg(bdev, "BCM irq: enabled");
+	}
+
 unlock:
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	return 0;
 }
@@ -368,16 +469,21 @@ static int bcm_resume(struct device *dev)
 {
 	struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev));
 
-	BT_DBG("resume (%p): is_suspended %d", bdev, bdev->is_suspended);
+	bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
 
-	spin_lock(&bcm_device_lock);
+	mutex_lock(&bcm_device_lock);
 
 	if (!bdev->hu)
 		goto unlock;
 
+	if (device_may_wakeup(&bdev->pdev->dev)) {
+		disable_irq_wake(bdev->irq);
+		bt_dev_dbg(bdev, "BCM irq: disabled");
+	}
+
 	if (bdev->device_wakeup) {
 		gpiod_set_value(bdev->device_wakeup, true);
-		BT_DBG("resume, delaying 15 ms");
+		bt_dev_dbg(bdev, "resume, delaying 15 ms");
 		mdelay(15);
 	}
 
@@ -389,7 +495,7 @@ static int bcm_resume(struct device *dev)
 	}
 
 unlock:
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	return 0;
 }
@@ -397,10 +503,12 @@ unlock:
 
 static const struct acpi_gpio_params device_wakeup_gpios = { 0, 0, false };
 static const struct acpi_gpio_params shutdown_gpios = { 1, 0, false };
+static const struct acpi_gpio_params host_wakeup_gpios = { 2, 0, false };
 
 static const struct acpi_gpio_mapping acpi_bcm_default_gpios[] = {
 	{ "device-wakeup-gpios", &device_wakeup_gpios, 1 },
 	{ "shutdown-gpios", &shutdown_gpios, 1 },
+	{ "host-wakeup-gpios", &host_wakeup_gpios, 1 },
 	{ },
 };
 
@@ -408,13 +516,30 @@ static const struct acpi_gpio_mapping acpi_bcm_default_gpios[] = {
 static int bcm_resource(struct acpi_resource *ares, void *data)
 {
 	struct bcm_device *dev = data;
-
-	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
-		struct acpi_resource_uart_serialbus *sb;
-
+	struct acpi_resource_extended_irq *irq;
+	struct acpi_resource_gpio *gpio;
+	struct acpi_resource_uart_serialbus *sb;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		irq = &ares->data.extended_irq;
+		dev->irq_polarity = irq->polarity;
+		break;
+
+	case ACPI_RESOURCE_TYPE_GPIO:
+		gpio = &ares->data.gpio;
+		if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT)
+			dev->irq_polarity = gpio->polarity;
+		break;
+
+	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
 		sb = &ares->data.uart_serial_bus;
 		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_UART)
 			dev->init_speed = sb->default_baud_rate;
+		break;
+
+	default:
+		break;
 	}
 
 	/* Always tell the ACPI core to skip this resource */
@@ -453,6 +578,21 @@ static int bcm_acpi_probe(struct bcm_device *dev)
 	if (IS_ERR(dev->shutdown))
 		return PTR_ERR(dev->shutdown);
 
+	/* IRQ can be declared in ACPI table as Interrupt or GpioInt */
+	dev->irq = platform_get_irq(pdev, 0);
+	if (dev->irq <= 0) {
+		struct gpio_desc *gpio;
+
+		gpio = devm_gpiod_get_optional(&pdev->dev, "host-wakeup",
+					       GPIOD_IN);
+		if (IS_ERR(gpio))
+			return PTR_ERR(gpio);
+
+		dev->irq = gpiod_to_irq(gpio);
+	}
+
+	dev_info(&pdev->dev, "BCM irq: %d\n", dev->irq);
+
 	/* Make sure at-least one of the GPIO is defined and that
 	 * a name is specified for this instance
 	 */
@@ -504,9 +644,9 @@ static int bcm_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev, "%s device registered.\n", dev->name);
 
 	/* Place this instance on the device list */
-	spin_lock(&bcm_device_lock);
+	mutex_lock(&bcm_device_lock);
 	list_add_tail(&dev->list, &bcm_device_list);
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	bcm_gpio_set_power(dev, false);
 
@@ -517,9 +657,9 @@ static int bcm_remove(struct platform_device *pdev)
 {
 	struct bcm_device *dev = platform_get_drvdata(pdev);
 
-	spin_lock(&bcm_device_lock);
+	mutex_lock(&bcm_device_lock);
 	list_del(&dev->list);
-	spin_unlock(&bcm_device_lock);
+	mutex_unlock(&bcm_device_lock);
 
 	acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
 
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index cf07d1121956..49e25409de67 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -31,6 +31,8 @@
 #include <linux/platform_device.h>
 #include <linux/gpio/consumer.h>
 #include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -43,19 +45,45 @@
 #define STATE_FIRMWARE_LOADED	2
 #define STATE_FIRMWARE_FAILED	3
 #define STATE_BOOTING		4
+#define STATE_LPM_ENABLED	5
+#define STATE_TX_ACTIVE		6
+#define STATE_SUSPENDED		7
+#define STATE_LPM_TRANSACTION	8
+
+#define HCI_LPM_WAKE_PKT 0xf0
+#define HCI_LPM_PKT 0xf1
+#define HCI_LPM_MAX_SIZE 10
+#define HCI_LPM_HDR_SIZE HCI_EVENT_HDR_SIZE
+
+#define LPM_OP_TX_NOTIFY 0x00
+#define LPM_OP_SUSPEND_ACK 0x02
+#define LPM_OP_RESUME_ACK 0x03
+
+#define LPM_SUSPEND_DELAY_MS 1000
+
+struct hci_lpm_pkt {
+	__u8 opcode;
+	__u8 dlen;
+	__u8 data[0];
+} __packed;
 
 struct intel_device {
 	struct list_head list;
 	struct platform_device *pdev;
 	struct gpio_desc *reset;
+	struct hci_uart *hu;
+	struct mutex hu_lock;
+	int irq;
 };
 
 static LIST_HEAD(intel_device_list);
-static DEFINE_SPINLOCK(intel_device_list_lock);
+static DEFINE_MUTEX(intel_device_list_lock);
 
 struct intel_data {
 	struct sk_buff *rx_skb;
 	struct sk_buff_head txq;
+	struct work_struct busy_work;
+	struct hci_uart *hu;
 	unsigned long flags;
 };
 
@@ -101,24 +129,185 @@ static int intel_wait_booting(struct hci_uart *hu)
 				  msecs_to_jiffies(1000));
 
 	if (err == 1) {
-		BT_ERR("%s: Device boot interrupted", hu->hdev->name);
+		bt_dev_err(hu->hdev, "Device boot interrupted");
 		return -EINTR;
 	}
 
 	if (err) {
-		BT_ERR("%s: Device boot timeout", hu->hdev->name);
+		bt_dev_err(hu->hdev, "Device boot timeout");
 		return -ETIMEDOUT;
 	}
 
 	return err;
 }
 
+#ifdef CONFIG_PM
+static int intel_wait_lpm_transaction(struct hci_uart *hu)
+{
+	struct intel_data *intel = hu->priv;
+	int err;
+
+	err = wait_on_bit_timeout(&intel->flags, STATE_LPM_TRANSACTION,
+				  TASK_INTERRUPTIBLE,
+				  msecs_to_jiffies(1000));
+
+	if (err == 1) {
+		bt_dev_err(hu->hdev, "LPM transaction interrupted");
+		return -EINTR;
+	}
+
+	if (err) {
+		bt_dev_err(hu->hdev, "LPM transaction timeout");
+		return -ETIMEDOUT;
+	}
+
+	return err;
+}
+
+static int intel_lpm_suspend(struct hci_uart *hu)
+{
+	static const u8 suspend[] = { 0x01, 0x01, 0x01 };
+	struct intel_data *intel = hu->priv;
+	struct sk_buff *skb;
+
+	if (!test_bit(STATE_LPM_ENABLED, &intel->flags) ||
+	    test_bit(STATE_SUSPENDED, &intel->flags))
+		return 0;
+
+	if (test_bit(STATE_TX_ACTIVE, &intel->flags))
+		return -EAGAIN;
+
+	bt_dev_dbg(hu->hdev, "Suspending");
+
+	skb = bt_skb_alloc(sizeof(suspend), GFP_KERNEL);
+	if (!skb) {
+		bt_dev_err(hu->hdev, "Failed to alloc memory for LPM packet");
+		return -ENOMEM;
+	}
+
+	memcpy(skb_put(skb, sizeof(suspend)), suspend, sizeof(suspend));
+	bt_cb(skb)->pkt_type = HCI_LPM_PKT;
+
+	set_bit(STATE_LPM_TRANSACTION, &intel->flags);
+
+	/* LPM flow is a priority, enqueue packet at list head */
+	skb_queue_head(&intel->txq, skb);
+	hci_uart_tx_wakeup(hu);
+
+	intel_wait_lpm_transaction(hu);
+	/* Even in case of failure, continue and test the suspended flag */
+
+	clear_bit(STATE_LPM_TRANSACTION, &intel->flags);
+
+	if (!test_bit(STATE_SUSPENDED, &intel->flags)) {
+		bt_dev_err(hu->hdev, "Device suspend error");
+		return -EINVAL;
+	}
+
+	bt_dev_dbg(hu->hdev, "Suspended");
+
+	hci_uart_set_flow_control(hu, true);
+
+	return 0;
+}
+
+static int intel_lpm_resume(struct hci_uart *hu)
+{
+	struct intel_data *intel = hu->priv;
+	struct sk_buff *skb;
+
+	if (!test_bit(STATE_LPM_ENABLED, &intel->flags) ||
+	    !test_bit(STATE_SUSPENDED, &intel->flags))
+		return 0;
+
+	bt_dev_dbg(hu->hdev, "Resuming");
+
+	hci_uart_set_flow_control(hu, false);
+
+	skb = bt_skb_alloc(0, GFP_KERNEL);
+	if (!skb) {
+		bt_dev_err(hu->hdev, "Failed to alloc memory for LPM packet");
+		return -ENOMEM;
+	}
+
+	bt_cb(skb)->pkt_type = HCI_LPM_WAKE_PKT;
+
+	set_bit(STATE_LPM_TRANSACTION, &intel->flags);
+
+	/* LPM flow is a priority, enqueue packet at list head */
+	skb_queue_head(&intel->txq, skb);
+	hci_uart_tx_wakeup(hu);
+
+	intel_wait_lpm_transaction(hu);
+	/* Even in case of failure, continue and test the suspended flag */
+
+	clear_bit(STATE_LPM_TRANSACTION, &intel->flags);
+
+	if (test_bit(STATE_SUSPENDED, &intel->flags)) {
+		bt_dev_err(hu->hdev, "Device resume error");
+		return -EINVAL;
+	}
+
+	bt_dev_dbg(hu->hdev, "Resumed");
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static int intel_lpm_host_wake(struct hci_uart *hu)
+{
+	static const u8 lpm_resume_ack[] = { LPM_OP_RESUME_ACK, 0x00 };
+	struct intel_data *intel = hu->priv;
+	struct sk_buff *skb;
+
+	hci_uart_set_flow_control(hu, false);
+
+	clear_bit(STATE_SUSPENDED, &intel->flags);
+
+	skb = bt_skb_alloc(sizeof(lpm_resume_ack), GFP_KERNEL);
+	if (!skb) {
+		bt_dev_err(hu->hdev, "Failed to alloc memory for LPM packet");
+		return -ENOMEM;
+	}
+
+	memcpy(skb_put(skb, sizeof(lpm_resume_ack)), lpm_resume_ack,
+	       sizeof(lpm_resume_ack));
+	bt_cb(skb)->pkt_type = HCI_LPM_PKT;
+
+	/* LPM flow is a priority, enqueue packet at list head */
+	skb_queue_head(&intel->txq, skb);
+	hci_uart_tx_wakeup(hu);
+
+	bt_dev_dbg(hu->hdev, "Resumed by controller");
+
+	return 0;
+}
+
+static irqreturn_t intel_irq(int irq, void *dev_id)
+{
+	struct intel_device *idev = dev_id;
+
+	dev_info(&idev->pdev->dev, "hci_intel irq\n");
+
+	mutex_lock(&idev->hu_lock);
+	if (idev->hu)
+		intel_lpm_host_wake(idev->hu);
+	mutex_unlock(&idev->hu_lock);
+
+	/* Host/Controller are now LPM resumed, trigger a new delayed suspend */
+	pm_runtime_get(&idev->pdev->dev);
+	pm_runtime_mark_last_busy(&idev->pdev->dev);
+	pm_runtime_put_autosuspend(&idev->pdev->dev);
+
+	return IRQ_HANDLED;
+}
+
 static int intel_set_power(struct hci_uart *hu, bool powered)
 {
 	struct list_head *p;
 	int err = -ENODEV;
 
-	spin_lock(&intel_device_list_lock);
+	mutex_lock(&intel_device_list_lock);
 
 	list_for_each(p, &intel_device_list) {
 		struct intel_device *idev = list_entry(p, struct intel_device,
@@ -139,13 +328,73 @@ static int intel_set_power(struct hci_uart *hu, bool powered)
 			hu, dev_name(&idev->pdev->dev), powered);
 
 		gpiod_set_value(idev->reset, powered);
+
+		/* Provide to idev a hu reference which is used to run LPM
+		 * transactions (lpm suspend/resume) from PM callbacks.
+		 * hu needs to be protected against concurrent removing during
+		 * these PM ops.
+		 */
+		mutex_lock(&idev->hu_lock);
+		idev->hu = powered ? hu : NULL;
+		mutex_unlock(&idev->hu_lock);
+
+		if (idev->irq < 0)
+			break;
+
+		if (powered && device_can_wakeup(&idev->pdev->dev)) {
+			err = devm_request_threaded_irq(&idev->pdev->dev,
+							idev->irq, NULL,
+							intel_irq,
+							IRQF_ONESHOT,
+							"bt-host-wake", idev);
+			if (err) {
+				BT_ERR("hu %p, unable to allocate irq-%d",
+				       hu, idev->irq);
+				break;
+			}
+
+			device_wakeup_enable(&idev->pdev->dev);
+
+			pm_runtime_set_active(&idev->pdev->dev);
+			pm_runtime_use_autosuspend(&idev->pdev->dev);
+			pm_runtime_set_autosuspend_delay(&idev->pdev->dev,
+							 LPM_SUSPEND_DELAY_MS);
+			pm_runtime_enable(&idev->pdev->dev);
+		} else if (!powered && device_may_wakeup(&idev->pdev->dev)) {
+			devm_free_irq(&idev->pdev->dev, idev->irq, idev);
+			device_wakeup_disable(&idev->pdev->dev);
+
+			pm_runtime_disable(&idev->pdev->dev);
+		}
 	}
 
-	spin_unlock(&intel_device_list_lock);
+	mutex_unlock(&intel_device_list_lock);
 
 	return err;
 }
 
+static void intel_busy_work(struct work_struct *work)
+{
+	struct list_head *p;
+	struct intel_data *intel = container_of(work, struct intel_data,
+						busy_work);
+
+	/* Link is busy, delay the suspend */
+	mutex_lock(&intel_device_list_lock);
+	list_for_each(p, &intel_device_list) {
+		struct intel_device *idev = list_entry(p, struct intel_device,
+						       list);
+
+		if (intel->hu->tty->dev->parent == idev->pdev->dev.parent) {
+			pm_runtime_get(&idev->pdev->dev);
+			pm_runtime_mark_last_busy(&idev->pdev->dev);
+			pm_runtime_put_autosuspend(&idev->pdev->dev);
+			break;
+		}
+	}
+	mutex_unlock(&intel_device_list_lock);
+}
+
 static int intel_open(struct hci_uart *hu)
 {
 	struct intel_data *intel;
@@ -157,6 +406,9 @@ static int intel_open(struct hci_uart *hu)
 		return -ENOMEM;
 
 	skb_queue_head_init(&intel->txq);
+	INIT_WORK(&intel->busy_work, intel_busy_work);
+
+	intel->hu = hu;
 
 	hu->priv = intel;
 
@@ -172,6 +424,8 @@ static int intel_close(struct hci_uart *hu)
 
 	BT_DBG("hu %p", hu);
 
+	cancel_work_sync(&intel->busy_work);
+
 	intel_set_power(hu, false);
 
 	skb_queue_purge(&intel->txq);
@@ -237,11 +491,11 @@ static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
 	if (err && err != ETIMEDOUT)
 		return err;
 
-	BT_INFO("%s: Change controller speed to %d", hdev->name, speed);
+	bt_dev_info(hdev, "Change controller speed to %d", speed);
 
 	speed_cmd[3] = intel_convert_speed(speed);
 	if (speed_cmd[3] == 0xff) {
-		BT_ERR("%s: Unsupported speed", hdev->name);
+		bt_dev_err(hdev, "Unsupported speed");
 		return -EINVAL;
 	}
 
@@ -250,16 +504,15 @@ static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
 	 */
 	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
-		BT_ERR("%s: Reading Intel version information failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
+		bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
+			   PTR_ERR(skb));
 		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
 	skb = bt_skb_alloc(sizeof(speed_cmd), GFP_KERNEL);
 	if (!skb) {
-		BT_ERR("%s: Failed to allocate memory for baudrate packet",
-		       hdev->name);
+		bt_dev_err(hdev, "Failed to alloc memory for baudrate packet");
 		return -ENOMEM;
 	}
 
@@ -284,11 +537,14 @@ static int intel_setup(struct hci_uart *hu)
 {
 	static const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01,
 					  0x00, 0x08, 0x04, 0x00 };
+	static const u8 lpm_param[] = { 0x03, 0x07, 0x01, 0x0b };
 	struct intel_data *intel = hu->priv;
+	struct intel_device *idev = NULL;
 	struct hci_dev *hdev = hu->hdev;
 	struct sk_buff *skb;
 	struct intel_version *ver;
 	struct intel_boot_params *params;
+	struct list_head *p;
 	const struct firmware *fw;
 	const u8 *fw_ptr;
 	char fwname[64];
@@ -299,7 +555,7 @@ static int intel_setup(struct hci_uart *hu)
 	int speed_change = 0;
 	int err;
 
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "start intel_setup");
 
 	hu->hdev->set_bdaddr = btintel_set_bdaddr;
 
@@ -335,21 +591,21 @@ static int intel_setup(struct hci_uart *hu)
 	 */
 	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
-		BT_ERR("%s: Reading Intel version information failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
+		bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
+			   PTR_ERR(skb));
 		return PTR_ERR(skb);
 	}
 
 	if (skb->len != sizeof(*ver)) {
-		BT_ERR("%s: Intel version event size mismatch", hdev->name);
+		bt_dev_err(hdev, "Intel version event size mismatch");
 		kfree_skb(skb);
 		return -EILSEQ;
 	}
 
 	ver = (struct intel_version *)skb->data;
 	if (ver->status) {
-		BT_ERR("%s: Intel version command failure (%02x)",
-		       hdev->name, ver->status);
+		bt_dev_err(hdev, "Intel version command failure (%02x)",
+			   ver->status);
 		err = -bt_to_errno(ver->status);
 		kfree_skb(skb);
 		return err;
@@ -359,8 +615,8 @@ static int intel_setup(struct hci_uart *hu)
 	 * for now only accept this single value.
 	 */
 	if (ver->hw_platform != 0x37) {
-		BT_ERR("%s: Unsupported Intel hardware platform (%u)",
-		       hdev->name, ver->hw_platform);
+		bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
+			   ver->hw_platform);
 		kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -371,8 +627,8 @@ static int intel_setup(struct hci_uart *hu)
 	 * when newer hardware variants come along.
 	 */
 	if (ver->hw_variant != 0x0b) {
-		BT_ERR("%s: Unsupported Intel hardware variant (%u)",
-		       hdev->name, ver->hw_variant);
+		bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
+			   ver->hw_variant);
 		kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -403,8 +659,8 @@ static int intel_setup(struct hci_uart *hu)
 	 * choice is to return an error and abort the device initialization.
 	 */
 	if (ver->fw_variant != 0x06) {
-		BT_ERR("%s: Unsupported Intel firmware variant (%u)",
-		       hdev->name, ver->fw_variant);
+		bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
+			   ver->fw_variant);
 		kfree_skb(skb);
 		return -ENODEV;
 	}
@@ -416,33 +672,33 @@ static int intel_setup(struct hci_uart *hu)
 	 */
 	skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
-		BT_ERR("%s: Reading Intel boot parameters failed (%ld)",
-		       hdev->name, PTR_ERR(skb));
+		bt_dev_err(hdev, "Reading Intel boot parameters failed (%ld)",
+			   PTR_ERR(skb));
 		return PTR_ERR(skb);
 	}
 
 	if (skb->len != sizeof(*params)) {
-		BT_ERR("%s: Intel boot parameters size mismatch", hdev->name);
+		bt_dev_err(hdev, "Intel boot parameters size mismatch");
 		kfree_skb(skb);
 		return -EILSEQ;
 	}
 
 	params = (struct intel_boot_params *)skb->data;
 	if (params->status) {
-		BT_ERR("%s: Intel boot parameters command failure (%02x)",
-		       hdev->name, params->status);
+		bt_dev_err(hdev, "Intel boot parameters command failure (%02x)",
+			   params->status);
 		err = -bt_to_errno(params->status);
 		kfree_skb(skb);
 		return err;
 	}
 
-	BT_INFO("%s: Device revision is %u", hdev->name,
-		le16_to_cpu(params->dev_revid));
+	bt_dev_info(hdev, "Device revision is %u",
+		    le16_to_cpu(params->dev_revid));
 
-	BT_INFO("%s: Secure boot is %s", hdev->name,
-		params->secure_boot ? "enabled" : "disabled");
+	bt_dev_info(hdev, "Secure boot is %s",
+		    params->secure_boot ? "enabled" : "disabled");
 
-	BT_INFO("%s: Minimum firmware build %u week %u %u", hdev->name,
+	bt_dev_info(hdev, "Minimum firmware build %u week %u %u",
 		params->min_fw_build_nn, params->min_fw_build_cw,
 		2000 + params->min_fw_build_yy);
 
@@ -451,8 +707,8 @@ static int intel_setup(struct hci_uart *hu)
 	 * that this bootloader does not send them, then abort the setup.
 	 */
 	if (params->limited_cce != 0x00) {
-		BT_ERR("%s: Unsupported Intel firmware loading method (%u)",
-		       hdev->name, params->limited_cce);
+		bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
+			   params->limited_cce);
 		kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -461,7 +717,7 @@ static int intel_setup(struct hci_uart *hu)
 	 * also be no valid address for the operational firmware.
 	 */
 	if (!bacmp(&params->otp_bdaddr, BDADDR_ANY)) {
-		BT_INFO("%s: No device address configured", hdev->name);
+		bt_dev_info(hdev, "No device address configured");
 		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
 	}
 
@@ -476,19 +732,23 @@ static int intel_setup(struct hci_uart *hu)
 
 	err = request_firmware(&fw, fwname, &hdev->dev);
 	if (err < 0) {
-		BT_ERR("%s: Failed to load Intel firmware file (%d)",
-		       hdev->name, err);
+		bt_dev_err(hdev, "Failed to load Intel firmware file (%d)",
+			   err);
 		kfree_skb(skb);
 		return err;
 	}
 
-	BT_INFO("%s: Found device firmware: %s", hdev->name, fwname);
+	bt_dev_info(hdev, "Found device firmware: %s", fwname);
+
+	/* Save the DDC file name for later */
+	snprintf(fwname, sizeof(fwname), "intel/ibt-11-%u.ddc",
+		 le16_to_cpu(params->dev_revid));
 
 	kfree_skb(skb);
 
 	if (fw->size < 644) {
-		BT_ERR("%s: Invalid size of firmware file (%zu)",
-		       hdev->name, fw->size);
+		bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
+			   fw->size);
 		err = -EBADF;
 		goto done;
 	}
@@ -500,8 +760,7 @@ static int intel_setup(struct hci_uart *hu)
 	 */
 	err = btintel_secure_send(hdev, 0x00, 128, fw->data);
 	if (err < 0) {
-		BT_ERR("%s: Failed to send firmware header (%d)",
-		       hdev->name, err);
+		bt_dev_err(hdev, "Failed to send firmware header (%d)", err);
 		goto done;
 	}
 
@@ -510,8 +769,8 @@ static int intel_setup(struct hci_uart *hu)
 	 */
 	err = btintel_secure_send(hdev, 0x03, 256, fw->data + 128);
 	if (err < 0) {
-		BT_ERR("%s: Failed to send firmware public key (%d)",
-		       hdev->name, err);
+		bt_dev_err(hdev, "Failed to send firmware public key (%d)",
+			   err);
 		goto done;
 	}
 
@@ -520,8 +779,8 @@ static int intel_setup(struct hci_uart *hu)
 	 */
 	err = btintel_secure_send(hdev, 0x02, 256, fw->data + 388);
 	if (err < 0) {
-		BT_ERR("%s: Failed to send firmware signature (%d)",
-		       hdev->name, err);
+		bt_dev_err(hdev, "Failed to send firmware signature (%d)",
+			   err);
 		goto done;
 	}
 
@@ -533,8 +792,8 @@ static int intel_setup(struct hci_uart *hu)
 
 		frag_len += sizeof(*cmd) + cmd->plen;
 
-		BT_DBG("%s: patching %td/%zu", hdev->name,
-		       (fw_ptr - fw->data), fw->size);
+		bt_dev_dbg(hdev, "Patching %td/%zu", (fw_ptr - fw->data),
+			   fw->size);
 
 		/* The parameter length of the secure send command requires
 		 * a 4 byte alignment. It happens so that the firmware file
@@ -552,8 +811,8 @@ static int intel_setup(struct hci_uart *hu)
 		 */
 		err = btintel_secure_send(hdev, 0x01, frag_len, fw_ptr);
 		if (err < 0) {
-			BT_ERR("%s: Failed to send firmware data (%d)",
-			       hdev->name, err);
+			bt_dev_err(hdev, "Failed to send firmware data (%d)",
+				   err);
 			goto done;
 		}
 
@@ -563,7 +822,7 @@ static int intel_setup(struct hci_uart *hu)
 
 	set_bit(STATE_FIRMWARE_LOADED, &intel->flags);
 
-	BT_INFO("%s: Waiting for firmware download to complete", hdev->name);
+	bt_dev_info(hdev, "Waiting for firmware download to complete");
 
 	/* Before switching the device into operational mode and with that
 	 * booting the loaded firmware, wait for the bootloader notification
@@ -580,19 +839,19 @@ static int intel_setup(struct hci_uart *hu)
 				  TASK_INTERRUPTIBLE,
 				  msecs_to_jiffies(5000));
 	if (err == 1) {
-		BT_ERR("%s: Firmware loading interrupted", hdev->name);
+		bt_dev_err(hdev, "Firmware loading interrupted");
 		err = -EINTR;
 		goto done;
 	}
 
 	if (err) {
-		BT_ERR("%s: Firmware loading timeout", hdev->name);
+		bt_dev_err(hdev, "Firmware loading timeout");
 		err = -ETIMEDOUT;
 		goto done;
 	}
 
 	if (test_bit(STATE_FIRMWARE_FAILED, &intel->flags)) {
-		BT_ERR("%s: Firmware loading failed", hdev->name);
+		bt_dev_err(hdev, "Firmware loading failed");
 		err = -ENOEXEC;
 		goto done;
 	}
@@ -601,7 +860,7 @@ static int intel_setup(struct hci_uart *hu)
 	delta = ktime_sub(rettime, calltime);
 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
 
-	BT_INFO("%s: Firmware loaded in %llu usecs", hdev->name, duration);
+	bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
 
 done:
 	release_firmware(fw);
@@ -634,7 +893,7 @@ done:
 	 * 1 second. However if that happens, then just fail the setup
 	 * since something went wrong.
 	 */
-	BT_INFO("%s: Waiting for device to boot", hdev->name);
+	bt_dev_info(hdev, "Waiting for device to boot");
 
 	err = intel_wait_booting(hu);
 	if (err)
@@ -646,7 +905,39 @@ done:
 	delta = ktime_sub(rettime, calltime);
 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
 
-	BT_INFO("%s: Device booted in %llu usecs", hdev->name, duration);
+	bt_dev_info(hdev, "Device booted in %llu usecs", duration);
+
+	/* Enable LPM if matching pdev with wakeup enabled */
+	mutex_lock(&intel_device_list_lock);
+	list_for_each(p, &intel_device_list) {
+		struct intel_device *dev = list_entry(p, struct intel_device,
+						      list);
+		if (hu->tty->dev->parent == dev->pdev->dev.parent) {
+			if (device_may_wakeup(&dev->pdev->dev))
+				idev = dev;
+			break;
+		}
+	}
+	mutex_unlock(&intel_device_list_lock);
+
+	if (!idev)
+		goto no_lpm;
+
+	bt_dev_info(hdev, "Enabling LPM");
+
+	skb = __hci_cmd_sync(hdev, 0xfc8b, sizeof(lpm_param), lpm_param,
+			     HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Failed to enable LPM");
+		goto no_lpm;
+	}
+	kfree_skb(skb);
+
+	set_bit(STATE_LPM_ENABLED, &intel->flags);
+
+no_lpm:
+	/* Ignore errors, device can work without DDC parameters */
+	btintel_load_ddc_config(hdev, fwname);
 
 	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
 	if (IS_ERR(skb))
@@ -659,7 +950,7 @@ done:
 			return err;
 	}
 
-	BT_INFO("%s: Setup complete", hdev->name);
+	bt_dev_info(hdev, "Setup complete");
 
 	clear_bit(STATE_BOOTLOADER, &intel->flags);
 
@@ -708,10 +999,71 @@ recv:
 	return hci_recv_frame(hdev, skb);
 }
 
+static void intel_recv_lpm_notify(struct hci_dev *hdev, int value)
+{
+	struct hci_uart *hu = hci_get_drvdata(hdev);
+	struct intel_data *intel = hu->priv;
+
+	bt_dev_dbg(hdev, "TX idle notification (%d)", value);
+
+	if (value) {
+		set_bit(STATE_TX_ACTIVE, &intel->flags);
+		schedule_work(&intel->busy_work);
+	} else {
+		clear_bit(STATE_TX_ACTIVE, &intel->flags);
+	}
+}
+
+static int intel_recv_lpm(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_lpm_pkt *lpm = (void *)skb->data;
+	struct hci_uart *hu = hci_get_drvdata(hdev);
+	struct intel_data *intel = hu->priv;
+
+	switch (lpm->opcode) {
+	case LPM_OP_TX_NOTIFY:
+		if (lpm->dlen < 1) {
+			bt_dev_err(hu->hdev, "Invalid LPM notification packet");
+			break;
+		}
+		intel_recv_lpm_notify(hdev, lpm->data[0]);
+		break;
+	case LPM_OP_SUSPEND_ACK:
+		set_bit(STATE_SUSPENDED, &intel->flags);
+		if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) {
+			smp_mb__after_atomic();
+			wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION);
+		}
+		break;
+	case LPM_OP_RESUME_ACK:
+		clear_bit(STATE_SUSPENDED, &intel->flags);
+		if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) {
+			smp_mb__after_atomic();
+			wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION);
+		}
+		break;
+	default:
+		bt_dev_err(hdev, "Unknown LPM opcode (%02x)", lpm->opcode);
+		break;
+	}
+
+	kfree_skb(skb);
+
+	return 0;
+}
+
+#define INTEL_RECV_LPM \
+	.type = HCI_LPM_PKT, \
+	.hlen = HCI_LPM_HDR_SIZE, \
+	.loff = 1, \
+	.lsize = 1, \
+	.maxlen = HCI_LPM_MAX_SIZE
+
 static const struct h4_recv_pkt intel_recv_pkts[] = {
-	{ H4_RECV_ACL,   .recv = hci_recv_frame },
-	{ H4_RECV_SCO,   .recv = hci_recv_frame },
-	{ H4_RECV_EVENT, .recv = intel_recv_event },
+	{ H4_RECV_ACL,    .recv = hci_recv_frame   },
+	{ H4_RECV_SCO,    .recv = hci_recv_frame   },
+	{ H4_RECV_EVENT,  .recv = intel_recv_event },
+	{ INTEL_RECV_LPM, .recv = intel_recv_lpm   },
 };
 
 static int intel_recv(struct hci_uart *hu, const void *data, int count)
@@ -726,7 +1078,7 @@ static int intel_recv(struct hci_uart *hu, const void *data, int count)
 				    ARRAY_SIZE(intel_recv_pkts));
 	if (IS_ERR(intel->rx_skb)) {
 		int err = PTR_ERR(intel->rx_skb);
-		BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
+		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
 		intel->rx_skb = NULL;
 		return err;
 	}
@@ -737,9 +1089,27 @@ static int intel_recv(struct hci_uart *hu, const void *data, int count)
 static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb)
 {
 	struct intel_data *intel = hu->priv;
+	struct list_head *p;
 
 	BT_DBG("hu %p skb %p", hu, skb);
 
+	/* Be sure our controller is resumed and potential LPM transaction
+	 * completed before enqueuing any packet.
+	 */
+	mutex_lock(&intel_device_list_lock);
+	list_for_each(p, &intel_device_list) {
+		struct intel_device *idev = list_entry(p, struct intel_device,
+						       list);
+
+		if (hu->tty->dev->parent == idev->pdev->dev.parent) {
+			pm_runtime_get_sync(&idev->pdev->dev);
+			pm_runtime_mark_last_busy(&idev->pdev->dev);
+			pm_runtime_put_autosuspend(&idev->pdev->dev);
+			break;
+		}
+	}
+	mutex_unlock(&intel_device_list_lock);
+
 	skb_queue_tail(&intel->txq, skb);
 
 	return 0;
@@ -813,6 +1183,59 @@ static int intel_acpi_probe(struct intel_device *idev)
 }
 #endif
 
+#ifdef CONFIG_PM
+static int intel_suspend_device(struct device *dev)
+{
+	struct intel_device *idev = dev_get_drvdata(dev);
+
+	mutex_lock(&idev->hu_lock);
+	if (idev->hu)
+		intel_lpm_suspend(idev->hu);
+	mutex_unlock(&idev->hu_lock);
+
+	return 0;
+}
+
+static int intel_resume_device(struct device *dev)
+{
+	struct intel_device *idev = dev_get_drvdata(dev);
+
+	mutex_lock(&idev->hu_lock);
+	if (idev->hu)
+		intel_lpm_resume(idev->hu);
+	mutex_unlock(&idev->hu_lock);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int intel_suspend(struct device *dev)
+{
+	struct intel_device *idev = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(idev->irq);
+
+	return intel_suspend_device(dev);
+}
+
+static int intel_resume(struct device *dev)
+{
+	struct intel_device *idev = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(idev->irq);
+
+	return intel_resume_device(dev);
+}
+#endif
+
+static const struct dev_pm_ops intel_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
+	SET_RUNTIME_PM_OPS(intel_suspend_device, intel_resume_device, NULL)
+};
+
 static int intel_probe(struct platform_device *pdev)
 {
 	struct intel_device *idev;
@@ -821,6 +1244,8 @@ static int intel_probe(struct platform_device *pdev)
 	if (!idev)
 		return -ENOMEM;
 
+	mutex_init(&idev->hu_lock);
+
 	idev->pdev = pdev;
 
 	if (ACPI_HANDLE(&pdev->dev)) {
@@ -838,14 +1263,40 @@ static int intel_probe(struct platform_device *pdev)
 		return PTR_ERR(idev->reset);
 	}
 
+	idev->irq = platform_get_irq(pdev, 0);
+	if (idev->irq < 0) {
+		struct gpio_desc *host_wake;
+
+		dev_err(&pdev->dev, "No IRQ, falling back to gpio-irq\n");
+
+		host_wake = devm_gpiod_get_optional(&pdev->dev, "host-wake",
+						    GPIOD_IN);
+		if (IS_ERR(host_wake)) {
+			dev_err(&pdev->dev, "Unable to retrieve IRQ\n");
+			goto no_irq;
+		}
+
+		idev->irq = gpiod_to_irq(host_wake);
+		if (idev->irq < 0) {
+			dev_err(&pdev->dev, "No corresponding irq for gpio\n");
+			goto no_irq;
+		}
+	}
+
+	/* Only enable wake-up/irq when controller is powered */
+	device_set_wakeup_capable(&pdev->dev, true);
+	device_wakeup_disable(&pdev->dev);
+
+no_irq:
 	platform_set_drvdata(pdev, idev);
 
 	/* Place this instance on the device list */
-	spin_lock(&intel_device_list_lock);
+	mutex_lock(&intel_device_list_lock);
 	list_add_tail(&idev->list, &intel_device_list);
-	spin_unlock(&intel_device_list_lock);
+	mutex_unlock(&intel_device_list_lock);
 
-	dev_info(&pdev->dev, "registered.\n");
+	dev_info(&pdev->dev, "registered, gpio(%d)/irq(%d).\n",
+		 desc_to_gpio(idev->reset), idev->irq);
 
 	return 0;
 }
@@ -854,9 +1305,11 @@ static int intel_remove(struct platform_device *pdev)
 {
 	struct intel_device *idev = platform_get_drvdata(pdev);
 
-	spin_lock(&intel_device_list_lock);
+	device_wakeup_disable(&pdev->dev);
+
+	mutex_lock(&intel_device_list_lock);
 	list_del(&idev->list);
-	spin_unlock(&intel_device_list_lock);
+	mutex_unlock(&intel_device_list_lock);
 
 	dev_info(&pdev->dev, "unregistered.\n");
 
@@ -869,6 +1322,7 @@ static struct platform_driver intel_driver = {
 	.driver = {
 		.name = "hci_intel",
 		.acpi_match_table = ACPI_PTR(intel_acpi_match),
+		.pm = &intel_pm_ops,
 	},
 };
 
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 6b9b91267959..a8aa077f4055 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -41,13 +41,13 @@
 #define HCI_IBS_SLEEP_IND	0xFE
 #define HCI_IBS_WAKE_IND	0xFD
 #define HCI_IBS_WAKE_ACK	0xFC
-#define HCI_MAX_IBS_SIZE 	10
+#define HCI_MAX_IBS_SIZE	10
 
 /* Controller states */
 #define STATE_IN_BAND_SLEEP_ENABLED	1
 
-#define IBS_WAKE_RETRANS_TIMEOUT_MS 	100
-#define IBS_TX_IDLE_TIMEOUT_MS 		2000
+#define IBS_WAKE_RETRANS_TIMEOUT_MS	100
+#define IBS_TX_IDLE_TIMEOUT_MS		2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS	300
 
 /* HCI_IBS transmit side sleep protocol states */
diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c
index 2a38eb4a2552..6cf38dc1c929 100644
--- a/drivers/clk/h8300/clk-h8s2678.c
+++ b/drivers/clk/h8300/clk-h8s2678.c
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/of_address.h>
+#include <linux/slab.h>
 
 static DEFINE_SPINLOCK(clklock);
 
diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 2c16807341dc..e43485448612 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -1,6 +1,12 @@
 config COMMON_CLK_HI6220
 	bool "Hi6220 Clock Driver"
-	depends on (ARCH_HISI || COMPILE_TEST) && MAILBOX
+	depends on ARCH_HISI || COMPILE_TEST
 	default ARCH_HISI
 	help
 	  Build the Hisilicon Hi6220 clock driver based on the common clock framework.
+
+config STUB_CLK_HI6220
+	bool "Hi6220 Stub Clock Driver"
+	depends on COMMON_CLK_HI6220 && MAILBOX
+	help
+	  Build the Hisilicon Hi6220 stub clock driver.
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 4a1001a11f04..74dba31590f9 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -7,4 +7,5 @@ obj-y	+= clk.o clkgate-separated.o clkdivider-hi6220.o
 obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3620.o
 obj-$(CONFIG_ARCH_HIP04)	+= clk-hip04.o
 obj-$(CONFIG_ARCH_HIX5HD2)	+= clk-hix5hd2.o
-obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o clk-hi6220-stub.o
+obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o
+obj-$(CONFIG_STUB_CLK_HI6220)	+= clk-hi6220-stub.o
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index ed02bbc7b11f..abb47608713b 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -716,6 +716,8 @@ static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
 	"hclk_peri",
+	"pclk_cpu",
+	"pclk_peri",
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
@@ -744,8 +746,6 @@ static void __init rk3188_common_clk_init(struct device_node *np)
 
 	rockchip_clk_register_branches(common_clk_branches,
 				  ARRAY_SIZE(common_clk_branches));
-	rockchip_clk_protect_critical(rk3188_critical_clocks,
-				      ARRAY_SIZE(rk3188_critical_clocks));
 
 	rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
 				  ROCKCHIP_SOFTRST_HIWORD_MASK);
@@ -765,6 +765,8 @@ static void __init rk3066a_clk_init(struct device_node *np)
 			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
 			&rk3066_cpuclk_data, rk3066_cpuclk_rates,
 			ARRAY_SIZE(rk3066_cpuclk_rates));
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
 }
 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
 
@@ -801,6 +803,9 @@ static void __init rk3188a_clk_init(struct device_node *np)
 		pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n",
 			__func__);
 	}
+
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
 }
 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
 
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 50f0641c65b6..fbfc74685e6a 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 #include <linux/slab.h>
 
 #define GPT_IRQ_EN_REG		0x00
@@ -59,6 +60,13 @@ struct mtk_clock_event_device {
 	struct clock_event_device dev;
 };
 
+static void __iomem *gpt_sched_reg __read_mostly;
+
+static u64 notrace mtk_read_sched_clock(void)
+{
+	return readl_relaxed(gpt_sched_reg);
+}
+
 static inline struct mtk_clock_event_device *to_mtk_clk(
 				struct clock_event_device *c)
 {
@@ -141,14 +149,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
-{
-	/* Disable all interrupts */
-	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
-	/* Acknowledge all interrupts */
-	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
-}
-
 static void
 mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
 {
@@ -168,6 +168,12 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
 {
 	u32 val;
 
+	/* Disable all interrupts */
+	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
+
+	/* Acknowledge all spurious pending interrupts */
+	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
+
 	val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
 	writel(val | GPT_IRQ_ENABLE(timer),
 			evt->gpt_base + GPT_IRQ_EN_REG);
@@ -220,8 +226,6 @@ static void __init mtk_timer_init(struct device_node *node)
 	}
 	rate = clk_get_rate(clk);
 
-	mtk_timer_global_reset(evt);
-
 	if (request_irq(evt->dev.irq, mtk_timer_interrupt,
 			IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
 		pr_warn("failed to setup irq %d\n", evt->dev.irq);
@@ -234,6 +238,8 @@ static void __init mtk_timer_init(struct device_node *node)
 	mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
 	clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
 			node->name, rate, 300, 32, clocksource_mmio_readl_up);
+	gpt_sched_reg = evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC);
+	sched_clock_register(mtk_read_sched_clock, 32, rate);
 
 	/* Configure clock event */
 	mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 07bc7aa6b224..d234719065a5 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -461,7 +461,7 @@ config CRYPTO_DEV_QCE
 
 config CRYPTO_DEV_VMX
 	bool "Support for VMX cryptographic acceleration instructions"
-	depends on PPC64
+	depends on PPC64 && VSX
 	help
 	  Support for VMX cryptographic acceleration instructions.
 
diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
index e070c316e8b7..a19ee127edca 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
@@ -104,7 +104,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
 			sg_miter_next(&mo);
 			oo = 0;
 		}
-	} while (mo.length > 0);
+	} while (oleft > 0);
 
 	if (areq->info) {
 		for (i = 0; i < 4 && i < ivsize / 4; i++) {
diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c
index 11592e980bc1..3428b6aae1a2 100644
--- a/drivers/extcon/extcon-rt8973a.c
+++ b/drivers/extcon/extcon-rt8973a.c
@@ -658,6 +658,7 @@ static const struct of_device_id rt8973a_dt_match[] = {
 	{ .compatible = "richtek,rt8973a-muic" },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, rt8973a_dt_match);
 
 #ifdef CONFIG_PM_SLEEP
 static int rt8973a_muic_suspend(struct device *dev)
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index 0ffefefa2e26..92ae48415fb2 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -650,6 +650,7 @@ static const struct of_device_id sm5502_dt_match[] = {
 	{ .compatible = "siliconmitus,sm5502-muic" },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, sm5502_dt_match);
 
 #ifdef CONFIG_PM_SLEEP
 static int sm5502_muic_suspend(struct device *dev)
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index a07addde297b..8dd0af1d50bc 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -159,7 +159,7 @@ static int find_cable_index_by_name(struct extcon_dev *edev, const char *name)
 static bool is_extcon_changed(u32 prev, u32 new, int idx, bool *attached)
 {
 	if (((prev >> idx) & 0x1) != ((new >> idx) & 0x1)) {
-		*attached = new ? true : false;
+		*attached = ((new >> idx) & 0x1) ? true : false;
 		return true;
 	}
 
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index d8de6a8dd4de..665efca59487 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -139,6 +139,14 @@ config QCOM_SCM
 	bool
 	depends on ARM || ARM64
 
+config QCOM_SCM_32
+	def_bool y
+	depends on QCOM_SCM && ARM
+
+config QCOM_SCM_64
+	def_bool y
+	depends on QCOM_SCM && ARM64
+
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 000830fc6707..2ee83474a3c1 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -13,7 +13,8 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
-obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-32.o
+obj-$(CONFIG_QCOM_SCM_64)	+= qcom_scm-64.o
+obj-$(CONFIG_QCOM_SCM_32)	+= qcom_scm-32.o
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-y				+= broadcom/
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
new file mode 100644
index 000000000000..bb6555f6d63b
--- /dev/null
+++ b/drivers/firmware/qcom_scm-64.c
@@ -0,0 +1,63 @@
+/* Copyright (c) 2015, The Linux Foundation. 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 version 2 and
+ * only 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.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/qcom_scm.h>
+
+/**
+ * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
+ * @entry: Entry point function for the cpus
+ * @cpus: The cpumask of cpus that will use the entry point
+ *
+ * Set the cold boot address of the cpus. Any cpu outside the supported
+ * range would be removed from the cpu present mask.
+ */
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+{
+	return -ENOTSUPP;
+}
+
+/**
+ * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
+ * @entry: Entry point function for the cpus
+ * @cpus: The cpumask of cpus that will use the entry point
+ *
+ * Set the Linux entry point for the SCM to transfer control to when coming
+ * out of a power down. CPU power down may be executed on cpuidle or hotplug.
+ */
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+{
+	return -ENOTSUPP;
+}
+
+/**
+ * qcom_scm_cpu_power_down() - Power down the cpu
+ * @flags - Flags to flush cache
+ *
+ * This is an end point to power down cpu. If there was a pending interrupt,
+ * the control would return from this function, otherwise, the cpu jumps to the
+ * warm boot entry point set for this cpu upon reset.
+ */
+void __qcom_scm_cpu_power_down(u32 flags)
+{
+}
+
+int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
+{
+	return -ENOTSUPP;
+}
+
+int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+{
+	return -ENOTSUPP;
+}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b4fc9e4d24c6..8949b3f6f74d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -356,7 +356,7 @@ config GPIO_PXA
 
 config GPIO_RCAR
 	tristate "Renesas R-Car GPIO"
-	depends on ARM && (ARCH_SHMOBILE || COMPILE_TEST)
+	depends on ARCH_SHMOBILE || COMPILE_TEST
 	select GPIOLIB_IRQCHIP
 	help
 	  Say yes here to support GPIO on Renesas R-Car SoCs.
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index b752b560126e..8813abab9736 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -339,13 +339,15 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
 	return 0;
 }
 
-static void mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
+static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
 	gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,
 				    port->base, handle_level_irq);
+	if (!gc)
+		return -ENOMEM;
 	gc->private = port;
 
 	ct = gc->chip_types;
@@ -360,6 +362,8 @@ static void mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
 			       IRQ_NOREQUEST, 0);
+
+	return 0;
 }
 
 static void mxc_gpio_get_hw(struct platform_device *pdev)
@@ -477,12 +481,16 @@ static int mxc_gpio_probe(struct platform_device *pdev)
 	}
 
 	/* gpio-mxc can be a generic irq chip */
-	mxc_gpio_init_gc(port, irq_base);
+	err = mxc_gpio_init_gc(port, irq_base);
+	if (err < 0)
+		goto out_irqdomain_remove;
 
 	list_add_tail(&port->node, &mxc_gpio_ports);
 
 	return 0;
 
+out_irqdomain_remove:
+	irq_domain_remove(port->domain);
 out_irqdesc_free:
 	irq_free_descs(irq_base, 32);
 out_gpiochip_remove:
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index b7f383eb18d9..1387385e6697 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -196,13 +196,16 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
 	return 0;
 }
 
-static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
+static int __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
 	gc = irq_alloc_generic_chip("gpio-mxs", 1, irq_base,
 				    port->base, handle_level_irq);
+	if (!gc)
+		return -ENOMEM;
+
 	gc->private = port;
 
 	ct = gc->chip_types;
@@ -216,6 +219,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
 			       IRQ_NOREQUEST, 0);
+
+	return 0;
 }
 
 static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
@@ -317,7 +322,9 @@ static int mxs_gpio_probe(struct platform_device *pdev)
 	}
 
 	/* gpio-mxs can be a generic irq chip */
-	mxs_gpio_init_gc(port, irq_base);
+	err = mxs_gpio_init_gc(port, irq_base);
+	if (err < 0)
+		goto out_irqdomain_remove;
 
 	/* setup one handler for each entry */
 	irq_set_chained_handler_and_data(port->irq, mxs_gpio_irq_handler,
@@ -343,6 +350,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
 
 out_bgpio_remove:
 	bgpio_remove(&port->bgc);
+out_irqdomain_remove:
+	irq_domain_remove(port->domain);
 out_irqdesc_free:
 	irq_free_descs(irq_base, 32);
 	return err;
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 2ae0d47e9554..072af5239bc1 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1098,7 +1098,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
 	} else {
 		bank->chip.label = "gpio";
 		bank->chip.base = gpio;
-		gpio += bank->width;
 	}
 	bank->chip.ngpio = bank->width;
 
@@ -1108,6 +1107,9 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
 		return ret;
 	}
 
+	if (!bank->is_mpuio)
+		gpio += bank->width;
+
 #ifdef CONFIG_ARCH_OMAP1
 	/*
 	 * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
@@ -1253,8 +1255,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
 	omap_gpio_mod_init(bank);
 
 	ret = omap_gpio_chip_init(bank, irqc);
-	if (ret)
+	if (ret) {
+		pm_runtime_put_sync(bank->dev);
+		pm_runtime_disable(bank->dev);
 		return ret;
+	}
 
 	omap_gpio_show_rev(bank);
 
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c
index 458d9d7952b8..9c6b96707c9f 100644
--- a/drivers/gpio/gpio-sx150x.c
+++ b/drivers/gpio/gpio-sx150x.c
@@ -706,4 +706,3 @@ module_exit(sx150x_exit);
 MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
 MODULE_DESCRIPTION("Driver for Semtech SX150X I2C GPIO Expanders");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("i2c:sx150x");
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 980c1f87866a..5db3445552b1 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1174,15 +1174,16 @@ EXPORT_SYMBOL_GPL(gpiod_is_active_low);
  * that the GPIO was actually requested.
  */
 
-static bool _gpiod_get_raw_value(const struct gpio_desc *desc)
+static int _gpiod_get_raw_value(const struct gpio_desc *desc)
 {
 	struct gpio_chip	*chip;
-	bool value;
 	int offset;
+	int value;
 
 	chip = desc->chip;
 	offset = gpio_chip_hwgpio(desc);
-	value = chip->get ? chip->get(chip, offset) : false;
+	value = chip->get ? chip->get(chip, offset) : -EIO;
+	value = value < 0 ? value : !!value;
 	trace_gpio_value(desc_to_gpio(desc), 1, value);
 	return value;
 }
@@ -1192,7 +1193,7 @@ static bool _gpiod_get_raw_value(const struct gpio_desc *desc)
  * @desc: gpio whose value will be returned
  *
  * Return the GPIO's raw value, i.e. the value of the physical line disregarding
- * its ACTIVE_LOW status.
+ * its ACTIVE_LOW status, or negative errno on failure.
  *
  * This function should be called from contexts where we cannot sleep, and will
  * complain if the GPIO chip functions potentially sleep.
@@ -1212,7 +1213,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value);
  * @desc: gpio whose value will be returned
  *
  * Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
- * account.
+ * account, or negative errno on failure.
  *
  * This function should be called from contexts where we cannot sleep, and will
  * complain if the GPIO chip functions potentially sleep.
@@ -1226,6 +1227,9 @@ int gpiod_get_value(const struct gpio_desc *desc)
 	WARN_ON(desc->chip->can_sleep);
 
 	value = _gpiod_get_raw_value(desc);
+	if (value < 0)
+		return value;
+
 	if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 		value = !value;
 
@@ -1548,7 +1552,7 @@ EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq);
  * @desc: gpio whose value will be returned
  *
  * Return the GPIO's raw value, i.e. the value of the physical line disregarding
- * its ACTIVE_LOW status.
+ * its ACTIVE_LOW status, or negative errno on failure.
  *
  * This function is to be called from contexts that can sleep.
  */
@@ -1566,7 +1570,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value_cansleep);
  * @desc: gpio whose value will be returned
  *
  * Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
- * account.
+ * account, or negative errno on failure.
  *
  * This function is to be called from contexts that can sleep.
  */
@@ -1579,6 +1583,9 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc)
 		return 0;
 
 	value = _gpiod_get_raw_value(desc);
+	if (value < 0)
+		return value;
+
 	if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 		value = !value;
 
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index be9fa8220499..36fda86b3518 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -712,11 +712,13 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
 }
 
 static int atmel_hlcdc_plane_prepare_fb(struct drm_plane *p,
-					struct drm_framebuffer *fb,
 					const struct drm_plane_state *new_state)
 {
 	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
 
+	if (!new_state->fb)
+		return 0;
+
 	return atmel_hlcdc_layer_update_start(&plane->layer);
 }
 
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f7d5166f89b2..940f80bbf192 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -663,6 +663,25 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
 	return 0;
 }
 
+static bool
+plane_switching_crtc(struct drm_atomic_state *state,
+		     struct drm_plane *plane,
+		     struct drm_plane_state *plane_state)
+{
+	if (!plane->state->crtc || !plane_state->crtc)
+		return false;
+
+	if (plane->state->crtc == plane_state->crtc)
+		return false;
+
+	/* This could be refined, but currently there's no helper or driver code
+	 * to implement direct switching of active planes nor userspace to take
+	 * advantage of more direct plane switching without the intermediate
+	 * full OFF state.
+	 */
+	return true;
+}
+
 /**
  * drm_atomic_plane_check - check plane state
  * @plane: plane to check
@@ -734,6 +753,12 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
 		return -ENOSPC;
 	}
 
+	if (plane_switching_crtc(state->state, plane, state)) {
+		DRM_DEBUG_ATOMIC("[PLANE:%d] switching CRTC directly\n",
+				 plane->base.id);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index aecb5d69bc2d..9cc670bfd38c 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -42,14 +42,14 @@
  * add their own additional internal state.
  *
  * This library also provides default implementations for the check callback in
- * drm_atomic_helper_check and for the commit callback with
- * drm_atomic_helper_commit. But the individual stages and callbacks are expose
- * to allow drivers to mix and match and e.g. use the plane helpers only
+ * drm_atomic_helper_check() and for the commit callback with
+ * drm_atomic_helper_commit(). But the individual stages and callbacks are
+ * exposed to allow drivers to mix and match and e.g. use the plane helpers only
  * together with a driver private modeset implementation.
  *
  * This library also provides implementations for all the legacy driver
- * interfaces on top of the atomic interface. See drm_atomic_helper_set_config,
- * drm_atomic_helper_disable_plane, drm_atomic_helper_disable_plane and the
+ * interfaces on top of the atomic interface. See drm_atomic_helper_set_config(),
+ * drm_atomic_helper_disable_plane(), drm_atomic_helper_disable_plane() and the
  * various functions to implement set_property callbacks. New drivers must not
  * implement these functions themselves but must use the provided helpers.
  */
@@ -993,6 +993,22 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  * object. This can still fail when e.g. the framebuffer reservation fails. For
  * now this doesn't implement asynchronous commits.
  *
+ * Note that right now this function does not support async commits, and hence
+ * driver writers must implement their own version for now. Also note that the
+ * default ordering of how the various stages are called is to match the legacy
+ * modeset helper library closest. One peculiarity of that is that it doesn't
+ * mesh well with runtime PM at all.
+ *
+ * For drivers supporting runtime PM the recommended sequence is
+ *
+ *     drm_atomic_helper_commit_modeset_disables(dev, state);
+ *
+ *     drm_atomic_helper_commit_modeset_enables(dev, state);
+ *
+ *     drm_atomic_helper_commit_planes(dev, state, true);
+ *
+ * See the kerneldoc entries for these three functions for more details.
+ *
  * RETURNS
  * Zero for success or -errno.
  */
@@ -1037,7 +1053,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 
 	drm_atomic_helper_commit_modeset_disables(dev, state);
 
-	drm_atomic_helper_commit_planes(dev, state);
+	drm_atomic_helper_commit_planes(dev, state, false);
 
 	drm_atomic_helper_commit_modeset_enables(dev, state);
 
@@ -1077,7 +1093,7 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * work item, which allows nice concurrent updates on disjoint sets of crtcs.
  *
  * 3. The software state is updated synchronously with
- * drm_atomic_helper_swap_state. Doing this under the protection of all modeset
+ * drm_atomic_helper_swap_state(). Doing this under the protection of all modeset
  * locks means concurrent callers never see inconsistent state. And doing this
  * while it's guaranteed that no relevant async worker runs means that async
  * workers do not need grab any locks. Actually they must not grab locks, for
@@ -1111,17 +1127,14 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 		const struct drm_plane_helper_funcs *funcs;
 		struct drm_plane *plane = state->planes[i];
 		struct drm_plane_state *plane_state = state->plane_states[i];
-		struct drm_framebuffer *fb;
 
 		if (!plane)
 			continue;
 
 		funcs = plane->helper_private;
 
-		fb = plane_state->fb;
-
-		if (fb && funcs->prepare_fb) {
-			ret = funcs->prepare_fb(plane, fb, plane_state);
+		if (funcs->prepare_fb) {
+			ret = funcs->prepare_fb(plane, plane_state);
 			if (ret)
 				goto fail;
 		}
@@ -1134,17 +1147,14 @@ fail:
 		const struct drm_plane_helper_funcs *funcs;
 		struct drm_plane *plane = state->planes[i];
 		struct drm_plane_state *plane_state = state->plane_states[i];
-		struct drm_framebuffer *fb;
 
 		if (!plane)
 			continue;
 
 		funcs = plane->helper_private;
 
-		fb = state->plane_states[i]->fb;
-
-		if (fb && funcs->cleanup_fb)
-			funcs->cleanup_fb(plane, fb, plane_state);
+		if (funcs->cleanup_fb)
+			funcs->cleanup_fb(plane, plane_state);
 
 	}
 
@@ -1152,10 +1162,16 @@ fail:
 }
 EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
 
+bool plane_crtc_active(struct drm_plane_state *state)
+{
+	return state->crtc && state->crtc->state->active;
+}
+
 /**
  * drm_atomic_helper_commit_planes - commit plane state
  * @dev: DRM device
  * @old_state: atomic state object with old state structures
+ * @active_only: Only commit on active CRTC if set
  *
  * This function commits the new plane state using the plane and atomic helper
  * functions for planes and crtcs. It assumes that the atomic state has already
@@ -1168,9 +1184,26 @@ EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
  * Note that this function does all plane updates across all CRTCs in one step.
  * If the hardware can't support this approach look at
  * drm_atomic_helper_commit_planes_on_crtc() instead.
+ *
+ * Plane parameters can be updated by applications while the associated CRTC is
+ * disabled. The DRM/KMS core will store the parameters in the plane state,
+ * which will be available to the driver when the CRTC is turned on. As a result
+ * most drivers don't need to be immediately notified of plane updates for a
+ * disabled CRTC.
+ *
+ * Unless otherwise needed, drivers are advised to set the @active_only
+ * parameters to true in order not to receive plane update notifications related
+ * to a disabled CRTC. This avoids the need to manually ignore plane updates in
+ * driver code when the driver and/or hardware can't or just don't need to deal
+ * with updates on disabled CRTCs, for example when supporting runtime PM.
+ *
+ * The drm_atomic_helper_commit() default implementation only sets @active_only
+ * to false to most closely match the behaviour of the legacy helpers. This should
+ * not be copied blindly by drivers.
  */
 void drm_atomic_helper_commit_planes(struct drm_device *dev,
-				     struct drm_atomic_state *old_state)
+				     struct drm_atomic_state *old_state,
+				     bool active_only)
 {
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
@@ -1186,25 +1219,43 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 		if (!funcs || !funcs->atomic_begin)
 			continue;
 
+		if (active_only && !crtc->state->active)
+			continue;
+
 		funcs->atomic_begin(crtc, old_crtc_state);
 	}
 
 	for_each_plane_in_state(old_state, plane, old_plane_state, i) {
 		const struct drm_plane_helper_funcs *funcs;
+		bool disabling;
 
 		funcs = plane->helper_private;
 
 		if (!funcs)
 			continue;
 
+		disabling = drm_atomic_plane_disabling(plane, old_plane_state);
+
+		if (active_only) {
+			/*
+			 * Skip planes related to inactive CRTCs. If the plane
+			 * is enabled use the state of the current CRTC. If the
+			 * plane is being disabled use the state of the old
+			 * CRTC to avoid skipping planes being disabled on an
+			 * active CRTC.
+			 */
+			if (!disabling && !plane_crtc_active(plane->state))
+				continue;
+			if (disabling && !plane_crtc_active(old_plane_state))
+				continue;
+		}
+
 		/*
 		 * Special-case disabling the plane if drivers support it.
 		 */
-		if (drm_atomic_plane_disabling(plane, old_plane_state) &&
-		    funcs->atomic_disable)
+		if (disabling && funcs->atomic_disable)
 			funcs->atomic_disable(plane, old_plane_state);
-		else if (plane->state->crtc ||
-			 drm_atomic_plane_disabling(plane, old_plane_state))
+		else if (plane->state->crtc || disabling)
 			funcs->atomic_update(plane, old_plane_state);
 	}
 
@@ -1216,6 +1267,9 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 		if (!funcs || !funcs->atomic_flush)
 			continue;
 
+		if (active_only && !crtc->state->active)
+			continue;
+
 		funcs->atomic_flush(crtc, old_crtc_state);
 	}
 }
@@ -1300,14 +1354,11 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
 
 	for_each_plane_in_state(old_state, plane, plane_state, i) {
 		const struct drm_plane_helper_funcs *funcs;
-		struct drm_framebuffer *old_fb;
 
 		funcs = plane->helper_private;
 
-		old_fb = plane_state->fb;
-
-		if (old_fb && funcs->cleanup_fb)
-			funcs->cleanup_fb(plane, old_fb, plane_state);
+		if (funcs->cleanup_fb)
+			funcs->cleanup_fb(plane, plane_state);
 	}
 }
 EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
@@ -1334,7 +1385,7 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  *
  * 4. Actually commit the hardware state.
  *
- * 5. Call drm_atomic_helper_cleanup_planes with @state, which since step 3
+ * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
  */
 void drm_atomic_helper_swap_state(struct drm_device *dev,
@@ -2333,6 +2384,84 @@ drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
 
 /**
+ * drm_atomic_helper_duplicate_state - duplicate an atomic state object
+ * @dev: DRM device
+ * @ctx: lock acquisition context
+ *
+ * Makes a copy of the current atomic state by looping over all objects and
+ * duplicating their respective states.
+ *
+ * Note that this treats atomic state as persistent between save and restore.
+ * Drivers must make sure that this is possible and won't result in confusion
+ * or erroneous behaviour.
+ *
+ * Note that if callers haven't already acquired all modeset locks this might
+ * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
+ *
+ * Returns:
+ * A pointer to the copy of the atomic state object on success or an
+ * ERR_PTR()-encoded error code on failure.
+ */
+struct drm_atomic_state *
+drm_atomic_helper_duplicate_state(struct drm_device *dev,
+				  struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_atomic_state *state;
+	struct drm_connector *conn;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	int err = 0;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	state->acquire_ctx = ctx;
+
+	drm_for_each_crtc(crtc, dev) {
+		struct drm_crtc_state *crtc_state;
+
+		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(crtc_state)) {
+			err = PTR_ERR(crtc_state);
+			goto free;
+		}
+	}
+
+	drm_for_each_plane(plane, dev) {
+		struct drm_plane_state *plane_state;
+
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state)) {
+			err = PTR_ERR(plane_state);
+			goto free;
+		}
+	}
+
+	drm_for_each_connector(conn, dev) {
+		struct drm_connector_state *conn_state;
+
+		conn_state = drm_atomic_get_connector_state(state, conn);
+		if (IS_ERR(conn_state)) {
+			err = PTR_ERR(conn_state);
+			goto free;
+		}
+	}
+
+	/* clear the acquire context so that it isn't accidentally reused */
+	state->acquire_ctx = NULL;
+
+free:
+	if (err < 0) {
+		drm_atomic_state_free(state);
+		state = ERR_PTR(err);
+	}
+
+	return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);
+
+/**
  * __drm_atomic_helper_connector_destroy_state - release connector state
  * @connector: connector object
  * @state: connector state object to release
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 33d877c65ced..9b9c4b41422a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -538,7 +538,12 @@ EXPORT_SYMBOL(drm_framebuffer_reference);
  */
 void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
 {
-	struct drm_device *dev = fb->dev;
+	struct drm_device *dev;
+
+	if (!fb)
+		return;
+
+	dev = fb->dev;
 
 	mutex_lock(&dev->mode_config.fb_lock);
 	/* Mark fb as reaped and drop idr ref. */
@@ -589,12 +594,17 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
  */
 void drm_framebuffer_remove(struct drm_framebuffer *fb)
 {
-	struct drm_device *dev = fb->dev;
+	struct drm_device *dev;
 	struct drm_crtc *crtc;
 	struct drm_plane *plane;
 	struct drm_mode_set set;
 	int ret;
 
+	if (!fb)
+		return;
+
+	dev = fb->dev;
+
 	WARN_ON(!list_empty(&fb->filp_head));
 
 	/*
@@ -1509,7 +1519,7 @@ EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
  */
 int drm_mode_create_tv_properties(struct drm_device *dev,
 				  unsigned int num_modes,
-				  char *modes[])
+				  const char * const modes[])
 {
 	struct drm_property *tv_selector;
 	struct drm_property *tv_subconnector;
@@ -5732,7 +5742,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 	 */
 	WARN_ON(!list_empty(&dev->mode_config.fb_list));
 	list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
-		drm_framebuffer_remove(fb);
+		drm_framebuffer_free(&fb->refcount);
 	}
 
 	list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 291734e87fca..d43b75dedf5b 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -508,6 +508,19 @@ module_param_unsafe(dp_aux_i2c_speed_khz, int, 0644);
 MODULE_PARM_DESC(dp_aux_i2c_speed_khz,
 		 "Assumed speed of the i2c bus in kHz, (1-400, default 10)");
 
+static void drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg)
+{
+	/*
+	 * In case of i2c defer or short i2c ack reply to a write,
+	 * we need to switch to WRITE_STATUS_UPDATE to drain the
+	 * rest of the message
+	 */
+	if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) {
+		msg->request &= DP_AUX_I2C_MOT;
+		msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE;
+	}
+}
+
 /*
  * Transfer a single I2C-over-AUX message and handle various error conditions,
  * retrying the transaction as appropriate.  It is assumed that the
@@ -579,6 +592,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			 * Both native ACK and I2C ACK replies received. We
 			 * can assume the transfer was successful.
 			 */
+			if (ret != msg->size)
+				drm_dp_i2c_msg_write_status_update(msg);
 			return ret;
 
 		case DP_AUX_I2C_REPLY_NACK:
@@ -596,6 +611,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			if (defer_i2c < 7)
 				defer_i2c++;
 			usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
+			drm_dp_i2c_msg_write_status_update(msg);
 			continue;
 
 		default:
@@ -608,6 +624,14 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 	return -EREMOTEIO;
 }
 
+static void drm_dp_i2c_msg_set_request(struct drm_dp_aux_msg *msg,
+				       const struct i2c_msg *i2c_msg)
+{
+	msg->request = (i2c_msg->flags & I2C_M_RD) ?
+		DP_AUX_I2C_READ : DP_AUX_I2C_WRITE;
+	msg->request |= DP_AUX_I2C_MOT;
+}
+
 /*
  * Keep retrying drm_dp_i2c_do_msg until all data has been transferred.
  *
@@ -661,10 +685,7 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
 
 	for (i = 0; i < num; i++) {
 		msg.address = msgs[i].addr;
-		msg.request = (msgs[i].flags & I2C_M_RD) ?
-			DP_AUX_I2C_READ :
-			DP_AUX_I2C_WRITE;
-		msg.request |= DP_AUX_I2C_MOT;
+		drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
 		/* Send a bare address packet to start the transaction.
 		 * Zero sized messages specify an address only (bare
 		 * address) transaction.
@@ -672,6 +693,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
 		msg.buffer = NULL;
 		msg.size = 0;
 		err = drm_dp_i2c_do_msg(aux, &msg);
+
+		/*
+		 * Reset msg.request in case in case it got
+		 * changed into a WRITE_STATUS_UPDATE.
+		 */
+		drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
+
 		if (err < 0)
 			break;
 		/* We want each transaction to be as large as possible, but
@@ -684,6 +712,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
 			msg.size = min(transfer_size, msgs[i].len - j);
 
 			err = drm_dp_i2c_drain_msg(aux, &msg);
+
+			/*
+			 * Reset msg.request in case in case it got
+			 * changed into a WRITE_STATUS_UPDATE.
+			 */
+			drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
+
 			if (err < 0)
 				break;
 			transfer_size = err;
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 53d09a19f7e1..9ad823fcde87 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -55,7 +55,6 @@ module_param_named(debug, drm_debug, int, 0600);
 static DEFINE_SPINLOCK(drm_minor_lock);
 static struct idr drm_minors_idr;
 
-struct class *drm_class;
 static struct dentry *drm_debugfs_root;
 
 void drm_err(const char *format, ...)
@@ -566,6 +565,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 		ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
 		if (ret)
 			goto err_minors;
+
+		WARN_ON(driver->suspend || driver->resume);
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
@@ -839,10 +840,9 @@ static int __init drm_core_init(void)
 	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
 		goto err_p1;
 
-	drm_class = drm_sysfs_create(THIS_MODULE, "drm");
-	if (IS_ERR(drm_class)) {
+	ret = drm_sysfs_init();
+	if (ret < 0) {
 		printk(KERN_ERR "DRM: Error creating drm class.\n");
-		ret = PTR_ERR(drm_class);
 		goto err_p2;
 	}
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 05bb7311ac5d..d895556be4f0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2044,7 +2044,7 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
 static bool valid_inferred_mode(const struct drm_connector *connector,
 				const struct drm_display_mode *mode)
 {
-	struct drm_display_mode *m;
+	const struct drm_display_mode *m;
 	bool ok = false;
 
 	list_for_each_entry(m, &connector->probed_modes, head) {
@@ -3361,7 +3361,7 @@ EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
  * the sink doesn't support audio or video.
  */
 int drm_av_sync_delay(struct drm_connector *connector,
-		      struct drm_display_mode *mode)
+		      const struct drm_display_mode *mode)
 {
 	int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
 	int a, v;
@@ -3396,7 +3396,6 @@ EXPORT_SYMBOL(drm_av_sync_delay);
 /**
  * drm_select_eld - select one ELD from multiple HDMI/DP sinks
  * @encoder: the encoder just changed display mode
- * @mode: the adjusted display mode
  *
  * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
  * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
@@ -3404,8 +3403,7 @@ EXPORT_SYMBOL(drm_av_sync_delay);
  * Return: The connector associated with the first HDMI/DP sink that has ELD
  * attached to it.
  */
-struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode)
+struct drm_connector *drm_select_eld(struct drm_encoder *encoder)
 {
 	struct drm_connector *connector;
 	struct drm_device *dev = encoder->dev;
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index c5605fe4907e..698b8c3b09d9 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -32,7 +32,7 @@ MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
 	"from built-in data or /lib/firmware instead. ");
 
 #define GENERIC_EDIDS 6
-static const char *generic_edid_name[GENERIC_EDIDS] = {
+static const char * const generic_edid_name[GENERIC_EDIDS] = {
 	"edid/800x600.bin",
 	"edid/1024x768.bin",
 	"edid/1280x1024.bin",
@@ -264,20 +264,43 @@ out:
 int drm_load_edid_firmware(struct drm_connector *connector)
 {
 	const char *connector_name = connector->name;
-	char *edidname = edid_firmware, *last, *colon;
+	char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
 	int ret;
 	struct edid *edid;
 
-	if (*edidname == '\0')
+	if (edid_firmware[0] == '\0')
 		return 0;
 
-	colon = strchr(edidname, ':');
-	if (colon != NULL) {
-		if (strncmp(connector_name, edidname, colon - edidname))
-			return 0;
-		edidname = colon + 1;
-		if (*edidname == '\0')
+	/*
+	 * If there are multiple edid files specified and separated
+	 * by commas, search through the list looking for one that
+	 * matches the connector.
+	 *
+	 * If there's one or more that don't't specify a connector, keep
+	 * the last one found one as a fallback.
+	 */
+	fwstr = kstrdup(edid_firmware, GFP_KERNEL);
+	edidstr = fwstr;
+
+	while ((edidname = strsep(&edidstr, ","))) {
+		colon = strchr(edidname, ':');
+		if (colon != NULL) {
+			if (strncmp(connector_name, edidname, colon - edidname))
+				continue;
+			edidname = colon + 1;
+			break;
+		}
+
+		if (*edidname != '\0') /* corner case: multiple ',' */
+			fallback = edidname;
+	}
+
+	if (!edidname) {
+		if (!fallback) {
+			kfree(fwstr);
 			return 0;
+		}
+		edidname = fallback;
 	}
 
 	last = edidname + strlen(edidname) - 1;
@@ -285,6 +308,8 @@ int drm_load_edid_firmware(struct drm_connector *connector)
 		*last = '\0';
 
 	edid = edid_load(connector, edidname, connector_name);
+	kfree(fwstr);
+
 	if (IS_ERR_OR_NULL(edid))
 		return 0;
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 418d299f3b12..ba12f51f106f 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -39,6 +39,11 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 
+static bool drm_fbdev_emulation = true;
+module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600);
+MODULE_PARM_DESC(fbdev_emulation,
+		 "Enable legacy fbdev emulation [default=true]");
+
 static LIST_HEAD(kernel_fb_helper_list);
 
 /**
@@ -99,6 +104,9 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 	struct drm_connector *connector;
 	int i;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	mutex_lock(&dev->mode_config.mutex);
 	drm_for_each_connector(connector, dev) {
 		struct drm_fb_helper_connector *fb_helper_connector;
@@ -129,6 +137,9 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
 	struct drm_fb_helper_connector **temp;
 	struct drm_fb_helper_connector *fb_helper_connector;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
 	if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
 		temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector *) * (fb_helper->connector_count + 1), GFP_KERNEL);
@@ -184,6 +195,9 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 	struct drm_fb_helper_connector *fb_helper_connector;
 	int i, j;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
 
 	for (i = 0; i < fb_helper->connector_count; i++) {
@@ -320,11 +334,10 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
 }
 EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 
-static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
+static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
 {
 	struct drm_device *dev = fb_helper->dev;
 	struct drm_plane *plane;
-	bool error = false;
 	int i;
 
 	drm_warn_on_modeset_not_all_locked(dev);
@@ -348,14 +361,15 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
 		if (crtc->funcs->cursor_set) {
 			ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
 			if (ret)
-				error = true;
+				return ret;
 		}
 
 		ret = drm_mode_set_config_internal(mode_set);
 		if (ret)
-			error = true;
+			return ret;
 	}
-	return error;
+
+	return 0;
 }
 
 /**
@@ -365,12 +379,18 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
  * This should be called from driver's drm ->lastclose callback
  * when implementing an fbcon on top of kms using this helper. This ensures that
  * the user isn't greeted with a black screen when e.g. X dies.
+ *
+ * RETURNS:
+ * Zero if everything went ok, negative error code otherwise.
  */
-bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
+int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
 {
 	struct drm_device *dev = fb_helper->dev;
-	bool ret;
-	bool do_delayed = false;
+	bool do_delayed;
+	int ret;
+
+	if (!drm_fbdev_emulation)
+		return -ENODEV;
 
 	drm_modeset_lock_all(dev);
 	ret = restore_fbdev_mode(fb_helper);
@@ -588,6 +608,9 @@ int drm_fb_helper_init(struct drm_device *dev,
 	struct drm_crtc *crtc;
 	int i;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	if (!max_conn_count)
 		return -EINVAL;
 
@@ -710,6 +733,9 @@ EXPORT_SYMBOL(drm_fb_helper_release_fbi);
 
 void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 {
+	if (!drm_fbdev_emulation)
+		return;
+
 	if (!list_empty(&fb_helper->kernel_fb_list)) {
 		list_del(&fb_helper->kernel_fb_list);
 		if (list_empty(&kernel_fb_helper_list)) {
@@ -1930,6 +1956,9 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
 	struct drm_device *dev = fb_helper->dev;
 	int count = 0;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	mutex_lock(&dev->mode_config.mutex);
 	count = drm_fb_helper_probe_connector_modes(fb_helper,
 						    dev->mode_config.max_width,
@@ -1973,6 +2002,9 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 	struct drm_device *dev = fb_helper->dev;
 	u32 max_width, max_height;
 
+	if (!drm_fbdev_emulation)
+		return 0;
+
 	mutex_lock(&fb_helper->dev->mode_config.mutex);
 	if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
 		fb_helper->delayed_hotplug = true;
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 059af01bd07a..43cbda3306ac 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -73,7 +73,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
 /* drm_sysfs.c */
 extern struct class *drm_class;
 
-struct class *drm_sysfs_create(struct module *owner, char *name);
+int drm_sysfs_init(void);
 void drm_sysfs_destroy(void);
 struct device *drm_sysfs_minor_alloc(struct drm_minor *minor);
 int drm_sysfs_connector_add(struct drm_connector *connector);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 3427b115e2bb..04de6fd88f8c 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -267,12 +267,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
 	if (adj_end > end)
 		adj_end = end;
 
-	if (flags & DRM_MM_CREATE_TOP)
-		adj_start = adj_end - size;
-
 	if (mm->color_adjust)
 		mm->color_adjust(hole_node, color, &adj_start, &adj_end);
 
+	if (flags & DRM_MM_CREATE_TOP)
+		adj_start = adj_end - size;
+
 	if (alignment) {
 		u64 tmp = adj_start;
 		unsigned rem;
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index fba321ca4344..6675b1428410 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -307,6 +307,8 @@ static inline int modeset_lock(struct drm_modeset_lock *lock,
 	WARN_ON(ctx->contended);
 
 	if (ctx->trylock_only) {
+		lockdep_assert_held(&ctx->ww_ctx);
+
 		if (!ww_mutex_trylock(&lock->mutex))
 			return -EBUSY;
 		else
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 5e5a07af02c8..d384ebcf0aaf 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -426,7 +426,7 @@ int drm_plane_helper_commit(struct drm_plane *plane,
 
 	if (plane_funcs->prepare_fb && plane_state->fb &&
 	    plane_state->fb != old_fb) {
-		ret = plane_funcs->prepare_fb(plane, plane_state->fb,
+		ret = plane_funcs->prepare_fb(plane,
 					      plane_state);
 		if (ret)
 			goto out;
@@ -479,8 +479,8 @@ int drm_plane_helper_commit(struct drm_plane *plane,
 		ret = 0;
 	}
 
-	if (plane_funcs->cleanup_fb && old_fb)
-		plane_funcs->cleanup_fb(plane, old_fb, plane_state);
+	if (plane_funcs->cleanup_fb)
+		plane_funcs->cleanup_fb(plane, plane_state);
 out:
 	if (plane_state) {
 		if (plane->funcs->atomic_destroy_state)
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 0f6cd33b531f..f08873f6489c 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -30,6 +30,8 @@ static struct device_type drm_sysfs_device_minor = {
 	.name = "drm_minor"
 };
 
+struct class *drm_class;
+
 /**
  * __drm_class_suspend - internal DRM class suspend routine
  * @dev: Linux device to suspend
@@ -112,41 +114,34 @@ static CLASS_ATTR_STRING(version, S_IRUGO,
 		CORE_DATE);
 
 /**
- * drm_sysfs_create - create a struct drm_sysfs_class structure
- * @owner: pointer to the module that is to "own" this struct drm_sysfs_class
- * @name: pointer to a string for the name of this class.
+ * drm_sysfs_init - initialize sysfs helpers
+ *
+ * This is used to create the DRM class, which is the implicit parent of any
+ * other top-level DRM sysfs objects.
  *
- * This is used to create DRM class pointer that can then be used
- * in calls to drm_sysfs_device_add().
+ * You must call drm_sysfs_destroy() to release the allocated resources.
  *
- * Note, the pointer created here is to be destroyed when finished by making a
- * call to drm_sysfs_destroy().
+ * Return: 0 on success, negative error code on failure.
  */
-struct class *drm_sysfs_create(struct module *owner, char *name)
+int drm_sysfs_init(void)
 {
-	struct class *class;
 	int err;
 
-	class = class_create(owner, name);
-	if (IS_ERR(class)) {
-		err = PTR_ERR(class);
-		goto err_out;
-	}
-
-	class->pm = &drm_class_dev_pm_ops;
+	drm_class = class_create(THIS_MODULE, "drm");
+	if (IS_ERR(drm_class))
+		return PTR_ERR(drm_class);
 
-	err = class_create_file(class, &class_attr_version.attr);
-	if (err)
-		goto err_out_class;
+	drm_class->pm = &drm_class_dev_pm_ops;
 
-	class->devnode = drm_devnode;
-
-	return class;
+	err = class_create_file(drm_class, &class_attr_version.attr);
+	if (err) {
+		class_destroy(drm_class);
+		drm_class = NULL;
+		return err;
+	}
 
-err_out_class:
-	class_destroy(class);
-err_out:
-	return ERR_PTR(err);
+	drm_class->devnode = drm_devnode;
+	return 0;
 }
 
 /**
@@ -156,7 +151,7 @@ err_out:
  */
 void drm_sysfs_destroy(void)
 {
-	if ((drm_class == NULL) || (IS_ERR(drm_class)))
+	if (IS_ERR_OR_NULL(drm_class))
 		return;
 	class_remove_file(drm_class, &class_attr_version.attr);
 	class_destroy(drm_class);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 831d2e4cacf9..f0a5839bd226 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -105,7 +105,7 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
 		atomic_inc(&exynos_crtc->pending_update);
 	}
 
-	drm_atomic_helper_commit_planes(dev, state);
+	drm_atomic_helper_commit_planes(dev, state, false);
 
 	exynos_atomic_wait_for_commit(state);
 
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index 51fa32392029..d9a72c96e56c 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -119,8 +119,8 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
 	struct ch7006_encoder_params *params = &priv->params;
 	struct ch7006_state *state = &priv->state;
 	uint8_t *regs = state->regs;
-	struct ch7006_mode *mode = priv->mode;
-	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	const struct ch7006_mode *mode = priv->mode;
+	const struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
 	int start_active;
 
 	ch7006_dbg(client, "\n");
@@ -226,7 +226,7 @@ static int ch7006_encoder_get_modes(struct drm_encoder *encoder,
 				    struct drm_connector *connector)
 {
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
-	struct ch7006_mode *mode;
+	const struct ch7006_mode *mode;
 	int n = 0;
 
 	for (mode = ch7006_modes; mode->mode.clock; mode++) {
diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c
index 9b83574141a6..bb5f67f10edb 100644
--- a/drivers/gpu/drm/i2c/ch7006_mode.c
+++ b/drivers/gpu/drm/i2c/ch7006_mode.c
@@ -26,7 +26,7 @@
 
 #include "ch7006_priv.h"
 
-char *ch7006_tv_norm_names[] = {
+const char * const ch7006_tv_norm_names[] = {
 	[TV_NORM_PAL] = "PAL",
 	[TV_NORM_PAL_M] = "PAL-M",
 	[TV_NORM_PAL_N] = "PAL-N",
@@ -46,7 +46,7 @@ char *ch7006_tv_norm_names[] = {
 		.vtotal = 625,					\
 		.hvirtual = 810
 
-struct ch7006_tv_norm_info ch7006_tv_norms[] = {
+const struct ch7006_tv_norm_info ch7006_tv_norms[] = {
 	[TV_NORM_NTSC_M] = {
 		NTSC_LIKE_TIMINGS,
 		.black_level = 0.339 * fixed1,
@@ -142,7 +142,7 @@ struct ch7006_tv_norm_info ch7006_tv_norms[] = {
 
 #define PAL_LIKE (1 << TV_NORM_PAL | 1 << TV_NORM_PAL_N | 1 << TV_NORM_PAL_NC)
 
-struct ch7006_mode ch7006_modes[] = {
+const struct ch7006_mode ch7006_modes[] = {
 	MODE(21000, 512, 384, 840, 500, N, N, 181.797557582, 5_4, 0x6, PAL_LIKE),
 	MODE(26250, 512, 384, 840, 625, N, N, 145.438046066, 1_1, 0x1, PAL_LIKE),
 	MODE(20140, 512, 384, 800, 420, N, N, 213.257083791, 5_4, 0x4, NTSC_LIKE),
@@ -171,11 +171,11 @@ struct ch7006_mode ch7006_modes[] = {
 	{}
 };
 
-struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
-				       const struct drm_display_mode *drm_mode)
+const struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+					     const struct drm_display_mode *drm_mode)
 {
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
-	struct ch7006_mode *mode;
+	const struct ch7006_mode *mode;
 
 	for (mode = ch7006_modes; mode->mode.clock; mode++) {
 
@@ -202,7 +202,7 @@ void ch7006_setup_levels(struct drm_encoder *encoder)
 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
 	uint8_t *regs = priv->state.regs;
-	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	const struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
 	int gain;
 	int black_level;
 
@@ -233,8 +233,8 @@ void ch7006_setup_subcarrier(struct drm_encoder *encoder)
 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
 	struct ch7006_state *state = &priv->state;
-	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
-	struct ch7006_mode *mode = priv->mode;
+	const struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	const struct ch7006_mode *mode = priv->mode;
 	uint32_t subc_inc;
 
 	subc_inc = round_fixed((mode->subc_coeff >> 8)
@@ -257,7 +257,7 @@ void ch7006_setup_pll(struct drm_encoder *encoder)
 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
 	uint8_t *regs = priv->state.regs;
-	struct ch7006_mode *mode = priv->mode;
+	const struct ch7006_mode *mode = priv->mode;
 	int n, best_n = 0;
 	int m, best_m = 0;
 	int freq, best_freq = 0;
@@ -328,9 +328,9 @@ void ch7006_setup_properties(struct drm_encoder *encoder)
 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
 	struct ch7006_state *state = &priv->state;
-	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
-	struct ch7006_mode *ch_mode = priv->mode;
-	struct drm_display_mode *mode = &ch_mode->mode;
+	const struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	const struct ch7006_mode *ch_mode = priv->mode;
+	const struct drm_display_mode *mode = &ch_mode->mode;
 	uint8_t *regs = state->regs;
 	int flicker, contrast, hpos, vpos;
 	uint64_t scale, aspect;
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
index ce577841f931..dc6414af5d79 100644
--- a/drivers/gpu/drm/i2c/ch7006_priv.h
+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
@@ -78,7 +78,7 @@ struct ch7006_state {
 
 struct ch7006_priv {
 	struct ch7006_encoder_params params;
-	struct ch7006_mode *mode;
+	const struct ch7006_mode *mode;
 
 	struct ch7006_state state;
 	struct ch7006_state saved_state;
@@ -106,12 +106,12 @@ extern int ch7006_debug;
 extern char *ch7006_tv_norm;
 extern int ch7006_scale;
 
-extern char *ch7006_tv_norm_names[];
-extern struct ch7006_tv_norm_info ch7006_tv_norms[];
-extern struct ch7006_mode ch7006_modes[];
+extern const char * const ch7006_tv_norm_names[];
+extern const struct ch7006_tv_norm_info ch7006_tv_norms[];
+extern const struct ch7006_mode ch7006_modes[];
 
-struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
-				       const struct drm_display_mode *drm_mode);
+const struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+					     const struct drm_display_mode *drm_mode);
 
 void ch7006_setup_levels(struct drm_encoder *encoder);
 void ch7006_setup_subcarrier(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index 89c1a8ce1f98..f73de0bef584 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -404,7 +404,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	enum port port = intel_dig_port->port;
 
-	connector = drm_select_eld(encoder, mode);
+	connector = drm_select_eld(encoder);
 	if (!connector)
 		return;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8cc9264f7809..6aa7d12a551a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13313,10 +13313,10 @@ static void intel_shared_dpll_init(struct drm_device *dev)
  */
 int
 intel_prepare_plane_fb(struct drm_plane *plane,
-		       struct drm_framebuffer *fb,
 		       const struct drm_plane_state *new_state)
 {
 	struct drm_device *dev = plane->dev;
+	struct drm_framebuffer *fb = new_state->fb;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
@@ -13354,19 +13354,18 @@ intel_prepare_plane_fb(struct drm_plane *plane,
  */
 void
 intel_cleanup_plane_fb(struct drm_plane *plane,
-		       struct drm_framebuffer *fb,
 		       const struct drm_plane_state *old_state)
 {
 	struct drm_device *dev = plane->dev;
-	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	struct drm_i915_gem_object *obj = intel_fb_obj(old_state->fb);
 
-	if (WARN_ON(!obj))
+	if (!obj)
 		return;
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR ||
 	    !INTEL_INFO(dev)->cursor_needs_physical) {
 		mutex_lock(&dev->struct_mutex);
-		intel_unpin_fb_obj(fb, old_state);
+		intel_unpin_fb_obj(old_state->fb, old_state);
 		mutex_unlock(&dev->struct_mutex);
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0a2e33fbf20d..7bb96d5850de 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -974,6 +974,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_NATIVE_WRITE:
 	case DP_AUX_I2C_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
 		txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
 		rxsize = 2; /* 0 or 1 data bytes */
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2b9e6f9775c5..bfd1204217e2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1038,10 +1038,8 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe);
 void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
 void intel_check_page_flip(struct drm_device *dev, int pipe);
 int intel_prepare_plane_fb(struct drm_plane *plane,
-			   struct drm_framebuffer *fb,
 			   const struct drm_plane_state *new_state);
 void intel_cleanup_plane_fb(struct drm_plane *plane,
-			    struct drm_framebuffer *fb,
 			    const struct drm_plane_state *old_state);
 int intel_plane_atomic_get_property(struct drm_plane *plane,
 				    const struct drm_plane_state *state,
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 0568ae6ec9dd..590ceabe2d5e 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1579,7 +1579,7 @@ intel_tv_init(struct drm_device *dev)
 	struct intel_encoder *intel_encoder;
 	struct intel_connector *intel_connector;
 	u32 tv_dac_on, tv_dac_off, save_tv_dac;
-	char *tv_format_names[ARRAY_SIZE(tv_modes)];
+	const char *tv_format_names[ARRAY_SIZE(tv_modes)];
 	int i, initial_mode = 0;
 
 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
@@ -1677,7 +1677,7 @@ intel_tv_init(struct drm_device *dev)
 
 	/* Create TV properties then attach current values */
 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
-		tv_format_names[i] = (char *)tv_modes[i].name;
+		tv_format_names[i] = tv_modes[i].name;
 	drm_mode_create_tv_properties(dev,
 				      ARRAY_SIZE(tv_modes),
 				      tv_format_names);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index e9dee367b597..30d57e74c42f 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -99,22 +99,28 @@ static const struct drm_plane_funcs mdp4_plane_funcs = {
 };
 
 static int mdp4_plane_prepare_fb(struct drm_plane *plane,
-		struct drm_framebuffer *fb,
 		const struct drm_plane_state *new_state)
 {
 	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
 	struct mdp4_kms *mdp4_kms = get_kms(plane);
+	struct drm_framebuffer *fb = new_state->fb;
+
+	if (!fb)
+		return 0;
 
 	DBG("%s: prepare: FB[%u]", mdp4_plane->name, fb->base.id);
 	return msm_framebuffer_prepare(fb, mdp4_kms->id);
 }
 
 static void mdp4_plane_cleanup_fb(struct drm_plane *plane,
-		struct drm_framebuffer *fb,
 		const struct drm_plane_state *old_state)
 {
 	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
 	struct mdp4_kms *mdp4_kms = get_kms(plane);
+	struct drm_framebuffer *fb = old_state->fb;
+
+	if (!fb)
+		return;
 
 	DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id);
 	msm_framebuffer_cleanup(fb, mdp4_kms->id);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 07fb62fea6dc..a0f5ff0ce8dc 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -250,22 +250,28 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
 };
 
 static int mdp5_plane_prepare_fb(struct drm_plane *plane,
-		struct drm_framebuffer *fb,
 		const struct drm_plane_state *new_state)
 {
 	struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	struct drm_framebuffer *fb = new_state->fb;
+
+	if (!new_state->fb)
+		return 0;
 
 	DBG("%s: prepare: FB[%u]", mdp5_plane->name, fb->base.id);
 	return msm_framebuffer_prepare(fb, mdp5_kms->id);
 }
 
 static void mdp5_plane_cleanup_fb(struct drm_plane *plane,
-		struct drm_framebuffer *fb,
 		const struct drm_plane_state *old_state)
 {
 	struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	struct drm_framebuffer *fb = old_state->fb;
+
+	if (!fb)
+		return;
 
 	DBG("%s: cleanup: FB[%u]", mdp5_plane->name, fb->base.id);
 	msm_framebuffer_cleanup(fb, mdp5_kms->id);
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 1ceb4f22dd89..7eb253bc24df 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -125,7 +125,7 @@ static void complete_commit(struct msm_commit *c)
 
 	drm_atomic_helper_commit_modeset_disables(dev, state);
 
-	drm_atomic_helper_commit_planes(dev, state);
+	drm_atomic_helper_commit_planes(dev, state, false);
 
 	drm_atomic_helper_commit_modeset_enables(dev, state);
 
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c
index 08c6f5e50610..903c473d266f 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c
@@ -32,7 +32,7 @@
 #include "hw.h"
 #include "tvnv17.h"
 
-char *nv17_tv_norm_names[NUM_TV_NORMS] = {
+const char * const nv17_tv_norm_names[NUM_TV_NORMS] = {
 	[TV_NORM_PAL] = "PAL",
 	[TV_NORM_PAL_M] = "PAL-M",
 	[TV_NORM_PAL_N] = "PAL-N",
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h
index 459910b6bb32..1b07521cde0d 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h
@@ -85,7 +85,7 @@ struct nv17_tv_encoder {
 #define to_tv_enc(x) container_of(nouveau_encoder(x),		\
 				  struct nv17_tv_encoder, base)
 
-extern char *nv17_tv_norm_names[NUM_TV_NORMS];
+extern const char * const nv17_tv_norm_names[NUM_TV_NORMS];
 
 extern struct nv17_tv_norm_params {
 	enum {
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 419c2e49adf5..a5f9d8bf75ed 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -96,7 +96,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
 	dispc_runtime_get();
 
 	drm_atomic_helper_commit_modeset_disables(dev, old_state);
-	drm_atomic_helper_commit_planes(dev, old_state);
+	drm_atomic_helper_commit_planes(dev, old_state, false);
 	drm_atomic_helper_commit_modeset_enables(dev, old_state);
 
 	omap_atomic_wait_for_completion(dev, old_state);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 098904696a5c..09e363bb55f2 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -60,17 +60,19 @@ to_omap_plane_state(struct drm_plane_state *state)
 }
 
 static int omap_plane_prepare_fb(struct drm_plane *plane,
-				 struct drm_framebuffer *fb,
 				 const struct drm_plane_state *new_state)
 {
-	return omap_framebuffer_pin(fb);
+	if (!new_state->fb)
+		return 0;
+
+	return omap_framebuffer_pin(new_state->fb);
 }
 
 static void omap_plane_cleanup_fb(struct drm_plane *plane,
-				  struct drm_framebuffer *fb,
 				  const struct drm_plane_state *old_state)
 {
-	omap_framebuffer_unpin(fb);
+	if (old_state->fb)
+		omap_framebuffer_unpin(old_state->fb);
 }
 
 static void omap_plane_atomic_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 9cd49c584263..bd73b4069069 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -179,6 +179,7 @@ radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_NATIVE_WRITE:
 	case DP_AUX_I2C_WRITE:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
 		/* The atom implementation only supports writes with a max payload of
 		 * 12 bytes since it uses 4 bits for the total count (header + payload)
 		 * in the parameter space.  The atom interface supports 16 byte
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 56518eb1269a..ca12e8ca5552 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -456,7 +456,7 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit)
 	/* Apply the atomic update. */
 	drm_atomic_helper_commit_modeset_disables(dev, old_state);
 	drm_atomic_helper_commit_modeset_enables(dev, old_state);
-	drm_atomic_helper_commit_planes(dev, old_state);
+	drm_atomic_helper_commit_planes(dev, old_state, false);
 
 	drm_atomic_helper_wait_for_vblanks(dev, old_state);
 
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index 6f4af6a8ba1b..9f85988a43ce 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -59,7 +59,7 @@ static void sti_atomic_complete(struct sti_private *private,
 	 */
 
 	drm_atomic_helper_commit_modeset_disables(drm, state);
-	drm_atomic_helper_commit_planes(drm, state);
+	drm_atomic_helper_commit_planes(drm, state, false);
 	drm_atomic_helper_commit_modeset_enables(drm, state);
 
 	drm_atomic_helper_wait_for_vblanks(drm, state);
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ddefb85dc4f7..b4af4ab9ce6b 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -480,14 +480,12 @@ static const struct drm_plane_funcs tegra_primary_plane_funcs = {
 };
 
 static int tegra_plane_prepare_fb(struct drm_plane *plane,
-				  struct drm_framebuffer *fb,
 				  const struct drm_plane_state *new_state)
 {
 	return 0;
 }
 
 static void tegra_plane_cleanup_fb(struct drm_plane *plane,
-				   struct drm_framebuffer *fb,
 				   const struct drm_plane_state *old_fb)
 {
 }
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 224a7dc8e4ed..6aecb6647313 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -119,6 +119,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
 	 */
 	if (msg->size < 1) {
 		switch (msg->request & ~DP_AUX_I2C_MOT) {
+		case DP_AUX_I2C_WRITE_STATUS_UPDATE:
 		case DP_AUX_I2C_WRITE:
 		case DP_AUX_I2C_READ:
 			value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
@@ -149,7 +150,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
 
 		break;
 
-	case DP_AUX_I2C_STATUS:
+	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
 		if (msg->request & DP_AUX_I2C_MOT)
 			value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
 		else
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 6d88cf1fcd1c..2486bc24bff6 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -56,7 +56,7 @@ static void tegra_atomic_complete(struct tegra_drm *tegra,
 	 */
 
 	drm_atomic_helper_commit_modeset_disables(drm, state);
-	drm_atomic_helper_commit_planes(drm, state);
+	drm_atomic_helper_commit_planes(drm, state, false);
 	drm_atomic_helper_commit_modeset_enables(drm, state);
 
 	drm_atomic_helper_wait_for_vblanks(drm, state);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 500b262b89bb..796569eeaf1d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -840,6 +840,16 @@ config SENSORS_MAX6697
 	  This driver can also be built as a module.  If so, the module
 	  will be called max6697.
 
+config SENSORS_MAX31790
+	tristate "Maxim MAX31790 sensor chip"
+	depends on I2C
+	help
+	  If you say yes here you get support for 6-Channel PWM-Output
+	  Fan RPM Controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max31790.
+
 config SENSORS_HTU21
 	tristate "Measurement Specialties HTU21D humidity/temperature sensors"
 	depends on I2C
@@ -1140,8 +1150,8 @@ config SENSORS_NCT6775
 	help
 	  If you say yes here you get support for the hardware monitoring
 	  functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D,
-	  NCT6791D, NCT6792D and compatible Super-I/O chips. This driver
-	  replaces the w83627ehf driver for NCT6775F and NCT6776F.
+	  NCT6791D, NCT6792D, NCT6793D, and compatible Super-I/O chips. This
+	  driver replaces the w83627ehf driver for NCT6775F and NCT6776F.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called nct6775.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 9e0f3dd2841d..01855ee641d1 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_SENSORS_MAX6639)	+= max6639.o
 obj-$(CONFIG_SENSORS_MAX6642)	+= max6642.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_MAX6697)	+= max6697.o
+obj-$(CONFIG_SENSORS_MAX31790)	+= max31790.o
 obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
 obj-$(CONFIG_SENSORS_MCP3021)	+= mcp3021.o
 obj-$(CONFIG_SENSORS_MENF21BMC_HWMON) += menf21bmc_hwmon.o
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index 1e7bdcdcb295..9cdfde6515ad 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -60,7 +60,6 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
  * Control]
  */
 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET	0xd8200ca4
-#define PCI_DEVICE_ID_AMD_15H_M60H_NB_F3	0x1573
 
 static void amd_nb_smu_index_read(struct pci_dev *pdev, unsigned int devfn,
 				  int offset, u32 *val)
diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
new file mode 100644
index 000000000000..f1296680833a
--- /dev/null
+++ b/drivers/hwmon/max31790.c
@@ -0,0 +1,603 @@
+/*
+ * max31790.c - Part of lm_sensors, Linux kernel modules for hardware
+ *             monitoring.
+ *
+ * (C) 2015 by Il Han <corone.il.han@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/* MAX31790 registers */
+#define MAX31790_REG_GLOBAL_CONFIG	0x00
+#define MAX31790_REG_FAN_CONFIG(ch)	(0x02 + (ch))
+#define MAX31790_REG_FAN_DYNAMICS(ch)	(0x08 + (ch))
+#define MAX31790_REG_FAN_FAULT_STATUS2	0x10
+#define MAX31790_REG_FAN_FAULT_STATUS1	0x11
+#define MAX31790_REG_TACH_COUNT(ch)	(0x18 + (ch) * 2)
+#define MAX31790_REG_PWM_DUTY_CYCLE(ch)	(0x30 + (ch) * 2)
+#define MAX31790_REG_PWMOUT(ch)		(0x40 + (ch) * 2)
+#define MAX31790_REG_TARGET_COUNT(ch)	(0x50 + (ch) * 2)
+
+/* Fan Config register bits */
+#define MAX31790_FAN_CFG_RPM_MODE	0x80
+#define MAX31790_FAN_CFG_TACH_INPUT_EN	0x08
+#define MAX31790_FAN_CFG_TACH_INPUT	0x01
+
+/* Fan Dynamics register bits */
+#define MAX31790_FAN_DYN_SR_SHIFT	5
+#define MAX31790_FAN_DYN_SR_MASK	0xE0
+#define SR_FROM_REG(reg)		(((reg) & MAX31790_FAN_DYN_SR_MASK) \
+					 >> MAX31790_FAN_DYN_SR_SHIFT)
+
+#define FAN_RPM_MIN			120
+#define FAN_RPM_MAX			7864320
+
+#define RPM_FROM_REG(reg, sr)		(((reg) >> 4) ? \
+					 ((60 * (sr) * 8192) / ((reg) >> 4)) : \
+					 FAN_RPM_MAX)
+#define RPM_TO_REG(rpm, sr)		((60 * (sr) * 8192) / ((rpm) * 2))
+
+#define NR_CHANNEL			6
+
+/*
+ * Client data (each client gets its own)
+ */
+struct max31790_data {
+	struct i2c_client *client;
+	struct mutex update_lock;
+	bool valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* register values */
+	u8 fan_config[NR_CHANNEL];
+	u8 fan_dynamics[NR_CHANNEL];
+	u16 fault_status;
+	u16 tach[NR_CHANNEL * 2];
+	u16 pwm[NR_CHANNEL];
+	u16 target_count[NR_CHANNEL];
+};
+
+static struct max31790_data *max31790_update_device(struct device *dev)
+{
+	struct max31790_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	struct max31790_data *ret = data;
+	int i;
+	int rv;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		rv = i2c_smbus_read_byte_data(client,
+				MAX31790_REG_FAN_FAULT_STATUS1);
+		if (rv < 0)
+			goto abort;
+		data->fault_status = rv & 0x3F;
+
+		rv = i2c_smbus_read_byte_data(client,
+				MAX31790_REG_FAN_FAULT_STATUS2);
+		if (rv < 0)
+			goto abort;
+		data->fault_status |= (rv & 0x3F) << 6;
+
+		for (i = 0; i < NR_CHANNEL; i++) {
+			rv = i2c_smbus_read_word_swapped(client,
+					MAX31790_REG_TACH_COUNT(i));
+			if (rv < 0)
+				goto abort;
+			data->tach[i] = rv;
+
+			if (data->fan_config[i]
+			    & MAX31790_FAN_CFG_TACH_INPUT) {
+				rv = i2c_smbus_read_word_swapped(client,
+					MAX31790_REG_TACH_COUNT(NR_CHANNEL
+								+ i));
+				if (rv < 0)
+					goto abort;
+				data->tach[NR_CHANNEL + i] = rv;
+			} else {
+				rv = i2c_smbus_read_word_swapped(client,
+						MAX31790_REG_PWMOUT(i));
+				if (rv < 0)
+					goto abort;
+				data->pwm[i] = rv;
+
+				rv = i2c_smbus_read_word_swapped(client,
+						MAX31790_REG_TARGET_COUNT(i));
+				if (rv < 0)
+					goto abort;
+				data->target_count[i] = rv;
+			}
+		}
+
+		data->last_updated = jiffies;
+		data->valid = true;
+	}
+	goto done;
+
+abort:
+	data->valid = false;
+	ret = ERR_PTR(rv);
+
+done:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+static const u8 tach_period[8] = { 1, 2, 4, 8, 16, 32, 32, 32 };
+
+static u8 get_tach_period(u8 fan_dynamics)
+{
+	return tach_period[SR_FROM_REG(fan_dynamics)];
+}
+
+static u8 bits_for_tach_period(int rpm)
+{
+	u8 bits;
+
+	if (rpm < 500)
+		bits = 0x0;
+	else if (rpm < 1000)
+		bits = 0x1;
+	else if (rpm < 2000)
+		bits = 0x2;
+	else if (rpm < 4000)
+		bits = 0x3;
+	else if (rpm < 8000)
+		bits = 0x4;
+	else
+		bits = 0x5;
+
+	return bits;
+}
+
+static ssize_t get_fan(struct device *dev,
+		       struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = max31790_update_device(dev);
+	int sr = get_tach_period(data->fan_dynamics[attr->index]);
+	int rpm;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	rpm = RPM_FROM_REG(data->tach[attr->index], sr);
+
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t get_fan_target(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = max31790_update_device(dev);
+	int sr = get_tach_period(data->fan_dynamics[attr->index]);
+	int rpm;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	rpm = RPM_FROM_REG(data->target_count[attr->index], sr);
+
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_fan_target(struct device *dev,
+			      struct device_attribute *devattr,
+			      const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	u8 bits;
+	int sr;
+	int target_count;
+	unsigned long rpm;
+	int err;
+
+	err = kstrtoul(buf, 10, &rpm);
+	if (err)
+		return err;
+
+	mutex_lock(&data->update_lock);
+
+	rpm = clamp_val(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
+	bits = bits_for_tach_period(rpm);
+	data->fan_dynamics[attr->index] =
+			((data->fan_dynamics[attr->index]
+			  & ~MAX31790_FAN_DYN_SR_MASK)
+			 | (bits << MAX31790_FAN_DYN_SR_SHIFT));
+	err = i2c_smbus_write_byte_data(client,
+			MAX31790_REG_FAN_DYNAMICS(attr->index),
+			data->fan_dynamics[attr->index]);
+
+	if (err < 0) {
+		mutex_unlock(&data->update_lock);
+		return err;
+	}
+
+	sr = get_tach_period(data->fan_dynamics[attr->index]);
+	target_count = RPM_TO_REG(rpm, sr);
+	target_count = clamp_val(target_count, 0x1, 0x7FF);
+
+	data->target_count[attr->index] = target_count << 5;
+
+	err = i2c_smbus_write_word_swapped(client,
+			MAX31790_REG_TARGET_COUNT(attr->index),
+			data->target_count[attr->index]);
+
+	mutex_unlock(&data->update_lock);
+
+	if (err < 0)
+		return err;
+
+	return count;
+}
+
+static ssize_t get_pwm(struct device *dev,
+		       struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = max31790_update_device(dev);
+	int pwm;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	pwm = data->pwm[attr->index] >> 8;
+
+	return sprintf(buf, "%d\n", pwm);
+}
+
+static ssize_t set_pwm(struct device *dev,
+		       struct device_attribute *devattr,
+		       const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	unsigned long pwm;
+	int err;
+
+	err = kstrtoul(buf, 10, &pwm);
+	if (err)
+		return err;
+
+	if (pwm > 255)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+
+	data->pwm[attr->index] = pwm << 8;
+	err = i2c_smbus_write_word_swapped(client,
+			MAX31790_REG_PWMOUT(attr->index),
+			data->pwm[attr->index]);
+
+	mutex_unlock(&data->update_lock);
+
+	if (err < 0)
+		return err;
+
+	return count;
+}
+
+static ssize_t get_pwm_enable(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = max31790_update_device(dev);
+	int mode;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	if (data->fan_config[attr->index] & MAX31790_FAN_CFG_RPM_MODE)
+		mode = 2;
+	else if (data->fan_config[attr->index] & MAX31790_FAN_CFG_TACH_INPUT_EN)
+		mode = 1;
+	else
+		mode = 0;
+
+	return sprintf(buf, "%d\n", mode);
+}
+
+static ssize_t set_pwm_enable(struct device *dev,
+			      struct device_attribute *devattr,
+			      const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	unsigned long mode;
+	int err;
+
+	err = kstrtoul(buf, 10, &mode);
+	if (err)
+		return err;
+
+	switch (mode) {
+	case 0:
+		data->fan_config[attr->index] =
+			data->fan_config[attr->index]
+			& ~(MAX31790_FAN_CFG_TACH_INPUT_EN
+			    | MAX31790_FAN_CFG_RPM_MODE);
+		break;
+	case 1:
+		data->fan_config[attr->index] =
+			(data->fan_config[attr->index]
+			 | MAX31790_FAN_CFG_TACH_INPUT_EN)
+			& ~MAX31790_FAN_CFG_RPM_MODE;
+		break;
+	case 2:
+		data->fan_config[attr->index] =
+			data->fan_config[attr->index]
+			| MAX31790_FAN_CFG_TACH_INPUT_EN
+			| MAX31790_FAN_CFG_RPM_MODE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->update_lock);
+
+	err = i2c_smbus_write_byte_data(client,
+			MAX31790_REG_FAN_CONFIG(attr->index),
+			data->fan_config[attr->index]);
+
+	mutex_unlock(&data->update_lock);
+
+	if (err < 0)
+		return err;
+
+	return count;
+}
+
+static ssize_t get_fan_fault(struct device *dev,
+			     struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct max31790_data *data = max31790_update_device(dev);
+	int fault;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	fault = !!(data->fault_status & (1 << attr->index));
+
+	return sprintf(buf, "%d\n", fault);
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, get_fan, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, get_fan, NULL, 5);
+
+static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, get_fan_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, get_fan_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, get_fan_fault, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, get_fan_fault, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, get_fan_fault, NULL, 5);
+
+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, get_fan, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, get_fan, NULL, 7);
+static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, get_fan, NULL, 8);
+static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, get_fan, NULL, 9);
+static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, get_fan, NULL, 10);
+static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, get_fan, NULL, 11);
+
+static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, get_fan_fault, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, get_fan_fault, NULL, 7);
+static SENSOR_DEVICE_ATTR(fan9_fault, S_IRUGO, get_fan_fault, NULL, 8);
+static SENSOR_DEVICE_ATTR(fan10_fault, S_IRUGO, get_fan_fault, NULL, 9);
+static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, get_fan_fault, NULL, 10);
+static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, get_fan_fault, NULL, 11);
+
+static SENSOR_DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 0);
+static SENSOR_DEVICE_ATTR(fan2_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 1);
+static SENSOR_DEVICE_ATTR(fan3_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 2);
+static SENSOR_DEVICE_ATTR(fan4_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 3);
+static SENSOR_DEVICE_ATTR(fan5_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 4);
+static SENSOR_DEVICE_ATTR(fan6_target, S_IWUSR | S_IRUGO,
+		get_fan_target, set_fan_target, 5);
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 3);
+static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 4);
+static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR | S_IRUGO, get_pwm, set_pwm, 5);
+
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 2);
+static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 3);
+static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 4);
+static SENSOR_DEVICE_ATTR(pwm6_enable, S_IWUSR | S_IRUGO,
+		get_pwm_enable, set_pwm_enable, 5);
+
+static struct attribute *max31790_attrs[] = {
+	&sensor_dev_attr_fan1_input.dev_attr.attr,
+	&sensor_dev_attr_fan2_input.dev_attr.attr,
+	&sensor_dev_attr_fan3_input.dev_attr.attr,
+	&sensor_dev_attr_fan4_input.dev_attr.attr,
+	&sensor_dev_attr_fan5_input.dev_attr.attr,
+	&sensor_dev_attr_fan6_input.dev_attr.attr,
+
+	&sensor_dev_attr_fan1_fault.dev_attr.attr,
+	&sensor_dev_attr_fan2_fault.dev_attr.attr,
+	&sensor_dev_attr_fan3_fault.dev_attr.attr,
+	&sensor_dev_attr_fan4_fault.dev_attr.attr,
+	&sensor_dev_attr_fan5_fault.dev_attr.attr,
+	&sensor_dev_attr_fan6_fault.dev_attr.attr,
+
+	&sensor_dev_attr_fan7_input.dev_attr.attr,
+	&sensor_dev_attr_fan8_input.dev_attr.attr,
+	&sensor_dev_attr_fan9_input.dev_attr.attr,
+	&sensor_dev_attr_fan10_input.dev_attr.attr,
+	&sensor_dev_attr_fan11_input.dev_attr.attr,
+	&sensor_dev_attr_fan12_input.dev_attr.attr,
+
+	&sensor_dev_attr_fan7_fault.dev_attr.attr,
+	&sensor_dev_attr_fan8_fault.dev_attr.attr,
+	&sensor_dev_attr_fan9_fault.dev_attr.attr,
+	&sensor_dev_attr_fan10_fault.dev_attr.attr,
+	&sensor_dev_attr_fan11_fault.dev_attr.attr,
+	&sensor_dev_attr_fan12_fault.dev_attr.attr,
+
+	&sensor_dev_attr_fan1_target.dev_attr.attr,
+	&sensor_dev_attr_fan2_target.dev_attr.attr,
+	&sensor_dev_attr_fan3_target.dev_attr.attr,
+	&sensor_dev_attr_fan4_target.dev_attr.attr,
+	&sensor_dev_attr_fan5_target.dev_attr.attr,
+	&sensor_dev_attr_fan6_target.dev_attr.attr,
+
+	&sensor_dev_attr_pwm1.dev_attr.attr,
+	&sensor_dev_attr_pwm2.dev_attr.attr,
+	&sensor_dev_attr_pwm3.dev_attr.attr,
+	&sensor_dev_attr_pwm4.dev_attr.attr,
+	&sensor_dev_attr_pwm5.dev_attr.attr,
+	&sensor_dev_attr_pwm6.dev_attr.attr,
+
+	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm4_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm5_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm6_enable.dev_attr.attr,
+	NULL
+};
+
+static umode_t max31790_attrs_visible(struct kobject *kobj,
+				     struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct max31790_data *data = dev_get_drvdata(dev);
+	struct device_attribute *devattr =
+			container_of(a, struct device_attribute, attr);
+	int index = to_sensor_dev_attr(devattr)->index % NR_CHANNEL;
+	u8 fan_config;
+
+	fan_config = data->fan_config[index];
+
+	if (n >= NR_CHANNEL * 2 && n < NR_CHANNEL * 4 &&
+	    !(fan_config & MAX31790_FAN_CFG_TACH_INPUT))
+		return 0;
+	if (n >= NR_CHANNEL * 4 && (fan_config & MAX31790_FAN_CFG_TACH_INPUT))
+		return 0;
+
+	return a->mode;
+}
+
+static const struct attribute_group max31790_group = {
+	.attrs = max31790_attrs,
+	.is_visible = max31790_attrs_visible,
+};
+__ATTRIBUTE_GROUPS(max31790);
+
+static int max31790_init_client(struct i2c_client *client,
+				struct max31790_data *data)
+{
+	int i, rv;
+
+	for (i = 0; i < NR_CHANNEL; i++) {
+		rv = i2c_smbus_read_byte_data(client,
+				MAX31790_REG_FAN_CONFIG(i));
+		if (rv < 0)
+			return rv;
+		data->fan_config[i] = rv;
+
+		rv = i2c_smbus_read_byte_data(client,
+				MAX31790_REG_FAN_DYNAMICS(i));
+		if (rv < 0)
+			return rv;
+		data->fan_dynamics[i] = rv;
+	}
+
+	return 0;
+}
+
+static int max31790_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	struct device *dev = &client->dev;
+	struct max31790_data *data;
+	struct device *hwmon_dev;
+	int err;
+
+	if (!i2c_check_functionality(adapter,
+			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	data = devm_kzalloc(dev, sizeof(struct max31790_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->client = client;
+	mutex_init(&data->update_lock);
+
+	/*
+	 * Initialize the max31790 chip
+	 */
+	err = max31790_init_client(client, data);
+	if (err)
+		return err;
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+			client->name, data, max31790_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id max31790_id[] = {
+	{ "max31790", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max31790_id);
+
+static struct i2c_driver max31790_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.probe		= max31790_probe,
+	.driver = {
+		.name	= "max31790",
+	},
+	.id_table	= max31790_id,
+};
+
+module_i2c_driver(max31790_driver);
+
+MODULE_AUTHOR("Il Han <corone.il.han@gmail.com>");
+MODULE_DESCRIPTION("MAX31790 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index bd1c99deac71..8b4fa55e46c6 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -39,6 +39,7 @@
  * nct6779d    15      5       5       2+6    0xc560 0xc1    0x5ca3
  * nct6791d    15      6       6       2+6    0xc800 0xc1    0x5ca3
  * nct6792d    15      6       6       2+6    0xc910 0xc1    0x5ca3
+ * nct6793d    15      6       6       2+6    0xd120 0xc1    0x5ca3
  *
  * #temp lists the number of monitored temperature sources (first value) plus
  * the number of directly connectable temperature sensors (second value).
@@ -63,7 +64,7 @@
 
 #define USE_ALTERNATE
 
-enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792 };
+enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793 };
 
 /* used to set data->name = nct6775_device_names[data->sio_kind] */
 static const char * const nct6775_device_names[] = {
@@ -73,6 +74,17 @@ static const char * const nct6775_device_names[] = {
 	"nct6779",
 	"nct6791",
 	"nct6792",
+	"nct6793",
+};
+
+static const char * const nct6775_sio_names[] __initconst = {
+	"NCT6106D",
+	"NCT6775F",
+	"NCT6776D/F",
+	"NCT6779D",
+	"NCT6791D",
+	"NCT6792D",
+	"NCT6793D",
 };
 
 static unsigned short force_id;
@@ -104,6 +116,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
 #define SIO_NCT6779_ID		0xc560
 #define SIO_NCT6791_ID		0xc800
 #define SIO_NCT6792_ID		0xc910
+#define SIO_NCT6793_ID		0xd120
 #define SIO_ID_MASK		0xFFF0
 
 enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
@@ -354,6 +367,10 @@ static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1]
 
 /* NCT6776 specific data */
 
+/* STEP_UP_TIME and STEP_DOWN_TIME regs are swapped for all chips but NCT6775 */
+#define NCT6776_REG_FAN_STEP_UP_TIME NCT6775_REG_FAN_STEP_DOWN_TIME
+#define NCT6776_REG_FAN_STEP_DOWN_TIME NCT6775_REG_FAN_STEP_UP_TIME
+
 static const s8 NCT6776_ALARM_BITS[] = {
 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
 	17, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
@@ -533,7 +550,7 @@ static const s8 NCT6791_ALARM_BITS[] = {
 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
 	12, 9 };			/* intrusion0, intrusion1 */
 
-/* NCT6792 specific data */
+/* NCT6792/NCT6793 specific data */
 
 static const u16 NCT6792_REG_TEMP_MON[] = {
 	0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d };
@@ -1056,6 +1073,7 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
 	case nct6779:
 	case nct6791:
 	case nct6792:
+	case nct6793:
 		return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
 		  ((reg & 0xfff0) == 0x4b0 && (reg & 0x000f) < 0x0b) ||
 		  reg == 0x402 ||
@@ -1407,6 +1425,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
 		case nct6779:
 		case nct6791:
 		case nct6792:
+		case nct6793:
 			reg = nct6775_read_value(data,
 					data->REG_CRITICAL_PWM_ENABLE[i]);
 			if (reg & data->CRITICAL_PWM_ENABLE_MASK)
@@ -2822,6 +2841,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
 		case nct6779:
 		case nct6791:
 		case nct6792:
+		case nct6793:
 			nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
 					    val);
 			reg = nct6775_read_value(data,
@@ -3256,7 +3276,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 		pwm4pin = false;
 		pwm5pin = false;
 		pwm6pin = false;
-	} else {	/* NCT6779D, NCT6791D, or NCT6792D */
+	} else {	/* NCT6779D, NCT6791D, NCT6792D, or NCT6793D */
 		regval = superio_inb(sioreg, 0x1c);
 
 		fan3pin = !(regval & (1 << 5));
@@ -3269,7 +3289,8 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 
 		fan4min = fan4pin;
 
-		if (data->kind == nct6791 || data->kind == nct6792) {
+		if (data->kind == nct6791 || data->kind == nct6792 ||
+		    data->kind == nct6793) {
 			regval = superio_inb(sioreg, 0x2d);
 			fan6pin = (regval & (1 << 1));
 			pwm6pin = (regval & (1 << 0));
@@ -3528,8 +3549,8 @@ static int nct6775_probe(struct platform_device *pdev)
 		data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
-		data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
-		data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
+		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
+		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
 		data->REG_PWM[0] = NCT6775_REG_PWM;
 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
@@ -3600,8 +3621,8 @@ static int nct6775_probe(struct platform_device *pdev)
 		data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
-		data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
-		data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
+		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
+		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
 		data->REG_PWM[0] = NCT6775_REG_PWM;
 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
@@ -3643,6 +3664,7 @@ static int nct6775_probe(struct platform_device *pdev)
 		break;
 	case nct6791:
 	case nct6792:
+	case nct6793:
 		data->in_num = 15;
 		data->pwm_num = 6;
 		data->auto_pwm_num = 4;
@@ -3677,8 +3699,8 @@ static int nct6775_probe(struct platform_device *pdev)
 		data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
-		data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
-		data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
+		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
+		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
 		data->REG_PWM[0] = NCT6775_REG_PWM;
 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
@@ -3918,6 +3940,7 @@ static int nct6775_probe(struct platform_device *pdev)
 	case nct6779:
 	case nct6791:
 	case nct6792:
+	case nct6793:
 		break;
 	}
 
@@ -3950,6 +3973,7 @@ static int nct6775_probe(struct platform_device *pdev)
 			break;
 		case nct6791:
 		case nct6792:
+		case nct6793:
 			tmp |= 0x7e;
 			break;
 		}
@@ -4047,7 +4071,8 @@ static int __maybe_unused nct6775_resume(struct device *dev)
 	if (reg != data->sio_reg_enable)
 		superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable);
 
-	if (data->kind == nct6791 || data->kind == nct6792)
+	if (data->kind == nct6791 || data->kind == nct6792 ||
+	    data->kind == nct6793)
 		nct6791_enable_io_mapping(sioreg);
 
 	superio_exit(sioreg);
@@ -4106,15 +4131,6 @@ static struct platform_driver nct6775_driver = {
 	.probe		= nct6775_probe,
 };
 
-static const char * const nct6775_sio_names[] __initconst = {
-	"NCT6106D",
-	"NCT6775F",
-	"NCT6776D/F",
-	"NCT6779D",
-	"NCT6791D",
-	"NCT6792D",
-};
-
 /* nct6775_find() looks for a '627 in the Super-I/O config space */
 static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 {
@@ -4150,6 +4166,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 	case SIO_NCT6792_ID:
 		sio_data->kind = nct6792;
 		break;
+	case SIO_NCT6793_ID:
+		sio_data->kind = nct6793;
+		break;
 	default:
 		if (val != 0xffff)
 			pr_debug("unsupported chip ID: 0x%04x\n", val);
@@ -4175,7 +4194,8 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 		superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
 	}
 
-	if (sio_data->kind == nct6791 || sio_data->kind == nct6792)
+	if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
+	    sio_data->kind == nct6793)
 		nct6791_enable_io_mapping(sioaddr);
 
 	superio_exit(sioaddr);
@@ -4285,7 +4305,7 @@ static void __exit sensors_nct6775_exit(void)
 }
 
 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
-MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D/NCT6792D driver");
+MODULE_DESCRIPTION("Driver for NCT6775F and compatible chips");
 MODULE_LICENSE("GPL");
 
 module_init(sensors_nct6775_init);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 254a81a4e6f4..a6707642bb23 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -136,7 +136,9 @@ static void etm4_enable_hw(void *info)
 		writel_relaxed(drvdata->cntr_val[i],
 			       drvdata->base + TRCCNTVRn(i));
 	}
-	for (i = 0; i < drvdata->nr_resource; i++)
+
+	/* Resource selector pair 0 is always implemented and reserved */
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		writel_relaxed(drvdata->res_ctrl[i],
 			       drvdata->base + TRCRSCTLRn(i));
 
@@ -489,8 +491,9 @@ static ssize_t reset_store(struct device *dev,
 		drvdata->cntr_val[i] = 0x0;
 	}
 
-	drvdata->res_idx = 0x0;
-	for (i = 0; i < drvdata->nr_resource; i++)
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@@ -1732,7 +1735,7 @@ static ssize_t res_idx_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 	/* Resource selector pair 0 is always implemented and reserved */
-	if ((val == 0) || (val >= drvdata->nr_resource))
+	if (val < 2 || val >= drvdata->nr_resource * 2)
 		return -EINVAL;
 
 	/*
@@ -2416,8 +2419,13 @@ static void etm4_init_arch_data(void *info)
 	drvdata->nr_addr_cmp = BMVAL(etmidr4, 0, 3);
 	/* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
 	drvdata->nr_pe_cmp = BMVAL(etmidr4, 12, 15);
-	/* NUMRSPAIR, bits[19:16] the number of resource pairs for tracing */
-	drvdata->nr_resource = BMVAL(etmidr4, 16, 19);
+	/*
+	 * NUMRSPAIR, bits[19:16]
+	 * The number of resource pairs conveyed by the HW starts at 0, i.e a
+	 * value of 0x0 indicate 1 resource pair, 0x1 indicate two and so on.
+	 * As such add 1 to the value of NUMRSPAIR for a better representation.
+	 */
+	drvdata->nr_resource = BMVAL(etmidr4, 16, 19) + 1;
 	/*
 	 * NUMSSCC, bits[23:20] the number of single-shot
 	 * comparator control for tracing
@@ -2504,6 +2512,8 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
 		drvdata->cntr_val[i] = 0x0;
 	}
 
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
 	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 785aa674a4da..4960fc1b3ceb 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -53,6 +53,7 @@
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 /** Defines ********************************************************************
 *******************************************************************************/
@@ -118,6 +119,8 @@
 #define I2CR_IEN_OPCODE_0	0x0
 #define I2CR_IEN_OPCODE_1	I2CR_IEN
 
+#define I2C_PM_TIMEOUT		10 /* ms */
+
 /** Variables ******************************************************************
 *******************************************************************************/
 
@@ -520,9 +523,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
 	i2c_imx_set_clk(i2c_imx);
 
-	result = clk_prepare_enable(i2c_imx->clk);
-	if (result)
-		return result;
 	imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
 	/* Enable I2C controller */
 	imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
@@ -575,7 +575,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 	/* Disable I2C controller */
 	temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
 	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
-	clk_disable_unprepare(i2c_imx->clk);
 }
 
 static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
@@ -894,6 +893,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
+	result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
+	if (result < 0)
+		goto out;
+
 	/* Start I2C transfer */
 	result = i2c_imx_start(i2c_imx);
 	if (result)
@@ -950,6 +953,10 @@ fail0:
 	/* Stop I2C transfer */
 	i2c_imx_stop(i2c_imx);
 
+out:
+	pm_runtime_mark_last_busy(i2c_imx->adapter.dev.parent);
+	pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent);
+
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
 		(result < 0) ? "error" : "success msg",
 			(result < 0) ? result : num);
@@ -1020,9 +1027,10 @@ static int i2c_imx_probe(struct platform_device *pdev)
 
 	ret = clk_prepare_enable(i2c_imx->clk);
 	if (ret) {
-		dev_err(&pdev->dev, "can't enable I2C clock\n");
+		dev_err(&pdev->dev, "can't enable I2C clock, ret=%d\n", ret);
 		return ret;
 	}
+
 	/* Request IRQ */
 	ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
 				pdev->name, i2c_imx);
@@ -1037,6 +1045,13 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	/* Set up adapter data */
 	i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
 
+	/* Set up platform driver data */
+	platform_set_drvdata(pdev, i2c_imx);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
+	pm_runtime_use_autosuspend(&pdev->dev);
+
 	/* Set up clock divider */
 	i2c_imx->bitrate = IMX_I2C_BIT_RATE;
 	ret = of_property_read_u32(pdev->dev.of_node,
@@ -1056,9 +1071,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
 		goto clk_disable;
 	}
 
-	/* Set up platform driver data */
-	platform_set_drvdata(pdev, i2c_imx);
-	clk_disable_unprepare(i2c_imx->clk);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
 
 	dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", irq);
 	dev_dbg(&i2c_imx->adapter.dev, "device resources: %pR\n", res);
@@ -1079,6 +1093,11 @@ clk_disable:
 static int i2c_imx_remove(struct platform_device *pdev)
 {
 	struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0)
+		return ret;
 
 	/* remove adapter */
 	dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
@@ -1093,17 +1112,52 @@ static int i2c_imx_remove(struct platform_device *pdev)
 	imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);
 	imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
 
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int i2c_imx_runtime_suspend(struct device *dev)
+{
+	struct imx_i2c_struct *i2c_imx  = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(i2c_imx->clk);
+
+	return 0;
+}
+
+static int i2c_imx_runtime_resume(struct device *dev)
+{
+	struct imx_i2c_struct *i2c_imx  = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(i2c_imx->clk);
+	if (ret)
+		dev_err(dev, "can't enable I2C clock, ret=%d\n", ret);
+
+	return ret;
+}
+
+static const struct dev_pm_ops i2c_imx_pm_ops = {
+	SET_RUNTIME_PM_OPS(i2c_imx_runtime_suspend,
+			   i2c_imx_runtime_resume, NULL)
+};
+#define I2C_IMX_PM_OPS (&i2c_imx_pm_ops)
+#else
+#define I2C_IMX_PM_OPS NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver i2c_imx_driver = {
 	.probe = i2c_imx_probe,
 	.remove = i2c_imx_remove,
-	.driver	= {
-		.name	= DRIVER_NAME,
+	.driver = {
+		.name = DRIVER_NAME,
+		.pm = I2C_IMX_PM_OPS,
 		.of_match_table = i2c_imx_dt_ids,
 	},
-	.id_table	= imx_i2c_devtype,
+	.id_table = imx_i2c_devtype,
 };
 
 static int __init i2c_adap_imx_init(void)
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 4664c2a96c67..e3b2c2e62e32 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -43,7 +43,7 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST
 endmenu
 
 config IOMMU_IOVA
-	bool
+	tristate
 
 config OF_IOMMU
        def_bool y
@@ -135,6 +135,14 @@ config INTEL_IOMMU
 	  and include PCI device scope covered by these DMA
 	  remapping devices.
 
+config INTEL_IOMMU_SVM
+	bool "Support for Shared Virtual Memory with Intel IOMMU"
+	depends on INTEL_IOMMU && X86
+	help
+	  Shared Virtual Memory (SVM) provides a facility for devices
+	  to access DMA resources through process address space by
+	  means of a Process Address Space ID (PASID).
+
 config INTEL_IOMMU_DEFAULT_ON
 	def_bool y
 	prompt "Enable Intel DMA Remapping Devices by default"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6dcc513d711..dc6f511f45a3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o
+obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 2d7349a3ee14..8a74fcc9c495 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1667,6 +1667,10 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 
 	/* free context mapping */
 	free_context_table(iommu);
+
+#ifdef CONFIG_INTEL_IOMMU_SVM
+	intel_svm_free_pasid_tables(iommu);
+#endif
 }
 
 static struct dmar_domain *alloc_domain(int flags)
@@ -3095,6 +3099,9 @@ static int __init init_dmars(void)
 
 		if (!ecap_pass_through(iommu->ecap))
 			hw_pass_through = 0;
+#ifdef CONFIG_INTEL_IOMMU_SVM
+		intel_svm_alloc_pasid_tables(iommu);
+#endif
 	}
 
 	if (iommu_pass_through)
@@ -3215,6 +3222,8 @@ static struct iova *intel_alloc_iova(struct device *dev,
 
 	/* Restrict dma_mask to the width that the iommu can handle */
 	dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
+	/* Ensure we reserve the whole size-aligned region */
+	nrpages = __roundup_pow_of_two(nrpages);
 
 	if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
 		/*
@@ -3711,7 +3720,7 @@ static inline int iommu_devinfo_cache_init(void)
 static int __init iommu_init_mempool(void)
 {
 	int ret;
-	ret = iommu_iova_cache_init();
+	ret = iova_cache_get();
 	if (ret)
 		return ret;
 
@@ -3725,7 +3734,7 @@ static int __init iommu_init_mempool(void)
 
 	kmem_cache_destroy(iommu_domain_cache);
 domain_error:
-	iommu_iova_cache_destroy();
+	iova_cache_put();
 
 	return -ENOMEM;
 }
@@ -3734,7 +3743,7 @@ static void __init iommu_exit_mempool(void)
 {
 	kmem_cache_destroy(iommu_devinfo_cache);
 	kmem_cache_destroy(iommu_domain_cache);
-	iommu_iova_cache_destroy();
+	iova_cache_put();
 }
 
 static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
@@ -4108,6 +4117,10 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
 	if (ret)
 		goto out;
 
+#ifdef CONFIG_INTEL_IOMMU_SVM
+	intel_svm_alloc_pasid_tables(iommu);
+#endif
+
 	if (dmaru->ignored) {
 		/*
 		 * we always have to disable PMRs or DMA may fail on this device
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
new file mode 100644
index 000000000000..a0dc97895d54
--- /dev/null
+++ b/drivers/iommu/intel-svm.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2015 Intel Corporation.
+ *
+ * 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.
+ *
+ * Authors: David Woodhouse <dwmw2@infradead.org>
+ */
+
+#include <linux/intel-iommu.h>
+
+int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+{
+	struct page *pages;
+	int order;
+
+	if (!ecap_pasid(iommu->ecap))
+		return 0;
+
+	order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+	if (order < 0)
+		order = 0;
+
+	pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!pages) {
+		pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
+			iommu->name);
+		return -ENOMEM;
+	}
+	iommu->pasid_table = page_address(pages);
+	pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!pages) {
+		pr_warn("IOMMU: %s: Failed to allocate PASID state table\n",
+			iommu->name);
+		free_pages((unsigned long)iommu->pasid_table, order);
+		iommu->pasid_table = NULL;
+		return -ENOMEM;
+	}
+	iommu->pasid_state_table = page_address(pages);
+	printk("Allocated order %d PASID table at %p, state table at %p\n",order,
+	       iommu->pasid_table, iommu->pasid_state_table);
+	return 0;
+}
+
+int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
+{
+	int order;
+
+	if (!ecap_pasid(iommu->ecap))
+		return 0;
+
+	order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+	if (order < 0)
+		order = 0;
+
+	if (iommu->pasid_table) {
+		free_pages((unsigned long)iommu->pasid_table, order);
+		iommu->pasid_table = NULL;
+	}
+	if (iommu->pasid_state_table) {
+		free_pages((unsigned long)iommu->pasid_state_table, order);
+		iommu->pasid_state_table = NULL;
+	}
+	return 0;
+}
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index b7c3d923f3e1..fa0adef32bd6 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -18,42 +18,9 @@
  */
 
 #include <linux/iova.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
-static struct kmem_cache *iommu_iova_cache;
-
-int iommu_iova_cache_init(void)
-{
-	int ret = 0;
-
-	iommu_iova_cache = kmem_cache_create("iommu_iova",
-					 sizeof(struct iova),
-					 0,
-					 SLAB_HWCACHE_ALIGN,
-					 NULL);
-	if (!iommu_iova_cache) {
-		pr_err("Couldn't create iova cache\n");
-		ret = -ENOMEM;
-	}
-
-	return ret;
-}
-
-void iommu_iova_cache_destroy(void)
-{
-	kmem_cache_destroy(iommu_iova_cache);
-}
-
-struct iova *alloc_iova_mem(void)
-{
-	return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC);
-}
-
-void free_iova_mem(struct iova *iova)
-{
-	kmem_cache_free(iommu_iova_cache, iova);
-}
-
 void
 init_iova_domain(struct iova_domain *iovad, unsigned long granule,
 	unsigned long start_pfn, unsigned long pfn_32bit)
@@ -72,6 +39,7 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule,
 	iovad->start_pfn = start_pfn;
 	iovad->dma_32bit_pfn = pfn_32bit;
 }
+EXPORT_SYMBOL_GPL(init_iova_domain);
 
 static struct rb_node *
 __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
@@ -120,19 +88,14 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
 	}
 }
 
-/* Computes the padding size required, to make the
- * the start address naturally aligned on its size
+/*
+ * Computes the padding size required, to make the start address
+ * naturally aligned on the power-of-two order of its size
  */
-static int
-iova_get_pad_size(int size, unsigned int limit_pfn)
+static unsigned int
+iova_get_pad_size(unsigned int size, unsigned int limit_pfn)
 {
-	unsigned int pad_size = 0;
-	unsigned int order = ilog2(size);
-
-	if (order)
-		pad_size = (limit_pfn + 1) % (1 << order);
-
-	return pad_size;
+	return (limit_pfn + 1 - size) & (__roundup_pow_of_two(size) - 1);
 }
 
 static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
@@ -242,6 +205,57 @@ iova_insert_rbtree(struct rb_root *root, struct iova *iova)
 	rb_insert_color(&iova->node, root);
 }
 
+static struct kmem_cache *iova_cache;
+static unsigned int iova_cache_users;
+static DEFINE_MUTEX(iova_cache_mutex);
+
+struct iova *alloc_iova_mem(void)
+{
+	return kmem_cache_alloc(iova_cache, GFP_ATOMIC);
+}
+EXPORT_SYMBOL(alloc_iova_mem);
+
+void free_iova_mem(struct iova *iova)
+{
+	kmem_cache_free(iova_cache, iova);
+}
+EXPORT_SYMBOL(free_iova_mem);
+
+int iova_cache_get(void)
+{
+	mutex_lock(&iova_cache_mutex);
+	if (!iova_cache_users) {
+		iova_cache = kmem_cache_create(
+			"iommu_iova", sizeof(struct iova), 0,
+			SLAB_HWCACHE_ALIGN, NULL);
+		if (!iova_cache) {
+			mutex_unlock(&iova_cache_mutex);
+			printk(KERN_ERR "Couldn't create iova cache\n");
+			return -ENOMEM;
+		}
+	}
+
+	iova_cache_users++;
+	mutex_unlock(&iova_cache_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iova_cache_get);
+
+void iova_cache_put(void)
+{
+	mutex_lock(&iova_cache_mutex);
+	if (WARN_ON(!iova_cache_users)) {
+		mutex_unlock(&iova_cache_mutex);
+		return;
+	}
+	iova_cache_users--;
+	if (!iova_cache_users)
+		kmem_cache_destroy(iova_cache);
+	mutex_unlock(&iova_cache_mutex);
+}
+EXPORT_SYMBOL_GPL(iova_cache_put);
+
 /**
  * alloc_iova - allocates an iova
  * @iovad: - iova domain in question
@@ -265,12 +279,6 @@ alloc_iova(struct iova_domain *iovad, unsigned long size,
 	if (!new_iova)
 		return NULL;
 
-	/* If size aligned is set then round the size to
-	 * to next power of two.
-	 */
-	if (size_aligned)
-		size = __roundup_pow_of_two(size);
-
 	ret = __alloc_and_insert_iova_range(iovad, size, limit_pfn,
 			new_iova, size_aligned);
 
@@ -281,6 +289,7 @@ alloc_iova(struct iova_domain *iovad, unsigned long size,
 
 	return new_iova;
 }
+EXPORT_SYMBOL_GPL(alloc_iova);
 
 /**
  * find_iova - find's an iova for a given pfn
@@ -321,6 +330,7 @@ struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
 	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(find_iova);
 
 /**
  * __free_iova - frees the given iova
@@ -339,6 +349,7 @@ __free_iova(struct iova_domain *iovad, struct iova *iova)
 	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
 	free_iova_mem(iova);
 }
+EXPORT_SYMBOL_GPL(__free_iova);
 
 /**
  * free_iova - finds and frees the iova for a given pfn
@@ -356,6 +367,7 @@ free_iova(struct iova_domain *iovad, unsigned long pfn)
 		__free_iova(iovad, iova);
 
 }
+EXPORT_SYMBOL_GPL(free_iova);
 
 /**
  * put_iova_domain - destroys the iova doamin
@@ -378,6 +390,7 @@ void put_iova_domain(struct iova_domain *iovad)
 	}
 	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
 }
+EXPORT_SYMBOL_GPL(put_iova_domain);
 
 static int
 __is_range_overlap(struct rb_node *node,
@@ -467,6 +480,7 @@ finish:
 	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
 	return iova;
 }
+EXPORT_SYMBOL_GPL(reserve_iova);
 
 /**
  * copy_reserved_iova - copies the reserved between domains
@@ -493,6 +507,7 @@ copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
 	}
 	spin_unlock_irqrestore(&from->iova_rbtree_lock, flags);
 }
+EXPORT_SYMBOL_GPL(copy_reserved_iova);
 
 struct iova *
 split_and_remove_iova(struct iova_domain *iovad, struct iova *iova,
@@ -534,3 +549,6 @@ error:
 		free_iova_mem(prev);
 	return NULL;
 }
+
+MODULE_AUTHOR("Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 70f4255ff291..42990f2d0317 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -170,6 +170,7 @@ config LEDS_SUNFIRE
 
 config LEDS_IPAQ_MICRO
 	tristate "LED Support for the Compaq iPAQ h3xxx"
+	depends on LEDS_CLASS
 	depends on MFD_IPAQ_MICRO
 	help
 	  Choose this option if you want to use the notification LED on
@@ -229,7 +230,7 @@ config LEDS_LP55XX_COMMON
 	tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501"
 	depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501
 	select FW_LOADER
-	select FW_LOADER_USER_HELPER_FALLBACK
+	select FW_LOADER_USER_HELPER
 	help
 	  This option supports common operations for LP5521/5523/55231/5562/8501
 	  devices.
diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c
index fd7c25fd29c1..ac77d36b630c 100644
--- a/drivers/leds/leds-aat1290.c
+++ b/drivers/leds/leds-aat1290.c
@@ -331,7 +331,7 @@ static void aat1290_led_validate_mm_current(struct aat1290_led *led,
 	cfg->max_brightness = b + 1;
 }
 
-int init_mm_current_scale(struct aat1290_led *led,
+static int init_mm_current_scale(struct aat1290_led *led,
 			struct aat1290_led_config_data *cfg)
 {
 	int max_mm_current_percent[] = { 20, 22, 25, 28, 32, 36, 40, 45, 50, 56,
@@ -559,6 +559,7 @@ static const struct of_device_id aat1290_led_dt_match[] = {
 	{ .compatible = "skyworks,aat1290" },
 	{},
 };
+MODULE_DEVICE_TABLE(of, aat1290_led_dt_match);
 
 static struct platform_driver aat1290_led_driver = {
 	.probe		= aat1290_led_probe,
diff --git a/drivers/leds/leds-bcm6328.c b/drivers/leds/leds-bcm6328.c
index 986fe1e28f84..1793727bc9ae 100644
--- a/drivers/leds/leds-bcm6328.c
+++ b/drivers/leds/leds-bcm6328.c
@@ -395,6 +395,7 @@ static const struct of_device_id bcm6328_leds_of_match[] = {
 	{ .compatible = "brcm,bcm6328-leds", },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, bcm6328_leds_of_match);
 
 static struct platform_driver bcm6328_leds_driver = {
 	.probe = bcm6328_leds_probe,
diff --git a/drivers/leds/leds-bcm6358.c b/drivers/leds/leds-bcm6358.c
index 21f96930b3be..7ea3526702e0 100644
--- a/drivers/leds/leds-bcm6358.c
+++ b/drivers/leds/leds-bcm6358.c
@@ -226,6 +226,7 @@ static const struct of_device_id bcm6358_leds_of_match[] = {
 	{ .compatible = "brcm,bcm6358-leds", },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, bcm6358_leds_of_match);
 
 static struct platform_driver bcm6358_leds_driver = {
 	.probe = bcm6358_leds_probe,
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index d97522080491..9be195707b39 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -36,7 +36,6 @@ static struct led_classdev qube_front_led = {
 static int cobalt_qube_led_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	int retval;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
@@ -49,31 +48,11 @@ static int cobalt_qube_led_probe(struct platform_device *pdev)
 	led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
 	writeb(led_value, led_port);
 
-	retval = led_classdev_register(&pdev->dev, &qube_front_led);
-	if (retval)
-		goto err_null;
-
-	return 0;
-
-err_null:
-	led_port = NULL;
-
-	return retval;
-}
-
-static int cobalt_qube_led_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&qube_front_led);
-
-	if (led_port)
-		led_port = NULL;
-
-	return 0;
+	return devm_led_classdev_register(&pdev->dev, &qube_front_led);
 }
 
 static struct platform_driver cobalt_qube_led_driver = {
 	.probe	= cobalt_qube_led_probe,
-	.remove	= cobalt_qube_led_remove,
 	.driver	= {
 		.name	= "cobalt-qube-leds",
 	},
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index 0b84c0113126..a6b8db0e27f1 100644
--- a/drivers/leds/leds-hp6xx.c
+++ b/drivers/leds/leds-hp6xx.c
@@ -59,28 +59,15 @@ static int hp6xxled_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	ret = led_classdev_register(&pdev->dev, &hp6xx_red_led);
+	ret = devm_led_classdev_register(&pdev->dev, &hp6xx_red_led);
 	if (ret < 0)
 		return ret;
 
-	ret = led_classdev_register(&pdev->dev, &hp6xx_green_led);
-	if (ret < 0)
-		led_classdev_unregister(&hp6xx_red_led);
-
-	return ret;
-}
-
-static int hp6xxled_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&hp6xx_red_led);
-	led_classdev_unregister(&hp6xx_green_led);
-
-	return 0;
+	return devm_led_classdev_register(&pdev->dev, &hp6xx_green_led);
 }
 
 static struct platform_driver hp6xxled_driver = {
 	.probe		= hp6xxled_probe,
-	.remove		= hp6xxled_remove,
 	.driver		= {
 		.name		= "hp6xx-led",
 	},
diff --git a/drivers/leds/leds-ipaq-micro.c b/drivers/leds/leds-ipaq-micro.c
index 3776f516cd88..fa262b6b25eb 100644
--- a/drivers/leds/leds-ipaq-micro.c
+++ b/drivers/leds/leds-ipaq-micro.c
@@ -16,9 +16,9 @@
 #define LED_YELLOW	0x00
 #define LED_GREEN	0x01
 
-#define LED_EN          (1 << 4)        /* LED ON/OFF 0:off, 1:on                       */
-#define LED_AUTOSTOP    (1 << 5)        /* LED ON/OFF auto stop set 0:disable, 1:enable */
-#define LED_ALWAYS      (1 << 6)        /* LED Interrupt Mask 0:No mask, 1:mask         */
+#define LED_EN       (1 << 4) /* LED ON/OFF 0:off, 1:on                       */
+#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
+#define LED_ALWAYS   (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask         */
 
 static void micro_leds_brightness_set(struct led_classdev *led_cdev,
 				      enum led_brightness value)
@@ -79,14 +79,14 @@ static int micro_leds_blink_set(struct led_classdev *led_cdev,
 	};
 
 	msg.tx_data[0] = LED_GREEN;
-        if (*delay_on > IPAQ_LED_MAX_DUTY ||
+	if (*delay_on > IPAQ_LED_MAX_DUTY ||
 	    *delay_off > IPAQ_LED_MAX_DUTY)
-                return -EINVAL;
+		return -EINVAL;
 
-        if (*delay_on == 0 && *delay_off == 0) {
-                *delay_on = 100;
-                *delay_off = 100;
-        }
+	if (*delay_on == 0 && *delay_off == 0) {
+		*delay_on = 100;
+		*delay_off = 100;
+	}
 
 	msg.tx_data[1] = 0;
 	if (*delay_on >= IPAQ_LED_MAX_DUTY)
@@ -111,7 +111,7 @@ static int micro_leds_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	ret = led_classdev_register(&pdev->dev, &micro_led);
+	ret = devm_led_classdev_register(&pdev->dev, &micro_led);
 	if (ret) {
 		dev_err(&pdev->dev, "registering led failed: %d\n", ret);
 		return ret;
@@ -121,18 +121,11 @@ static int micro_leds_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int micro_leds_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&micro_led);
-	return 0;
-}
-
 static struct platform_driver micro_leds_device_driver = {
 	.driver = {
 		.name    = "ipaq-micro-leds",
 	},
 	.probe   = micro_leds_probe,
-	.remove  = micro_leds_remove,
 };
 module_platform_driver(micro_leds_device_driver);
 
diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c
index 2ae8c4d17ff8..feca07be85f5 100644
--- a/drivers/leds/leds-ktd2692.c
+++ b/drivers/leds/leds-ktd2692.c
@@ -426,6 +426,7 @@ static const struct of_device_id ktd2692_match[] = {
 	{ .compatible = "kinetic,ktd2692", },
 	{ /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, ktd2692_match);
 
 static struct platform_driver ktd2692_driver = {
 	.driver = {
diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c
index df348a06d8c7..afbb1409b2e2 100644
--- a/drivers/leds/leds-max77693.c
+++ b/drivers/leds/leds-max77693.c
@@ -1080,6 +1080,7 @@ static const struct of_device_id max77693_led_dt_match[] = {
 	{ .compatible = "maxim,max77693-led" },
 	{},
 };
+MODULE_DEVICE_TABLE(of, max77693_led_dt_match);
 
 static struct platform_driver max77693_led_driver = {
 	.probe		= max77693_led_probe,
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index b33514d9f427..a95a61220169 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -337,6 +337,7 @@ static const struct of_device_id of_ns2_leds_match[] = {
 	{ .compatible = "lacie,ns2-leds", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, of_ns2_leds_match);
 #endif /* CONFIG_OF_GPIO */
 
 struct ns2_led_priv {
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
index 39870de20a26..12af1127d9b7 100644
--- a/drivers/leds/leds-ot200.c
+++ b/drivers/leds/leds-ot200.c
@@ -124,9 +124,9 @@ static int ot200_led_probe(struct platform_device *pdev)
 		leds[i].cdev.name = leds[i].name;
 		leds[i].cdev.brightness_set = ot200_led_brightness_set;
 
-		ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
+		ret = devm_led_classdev_register(&pdev->dev, &leds[i].cdev);
 		if (ret < 0)
-			goto err;
+			return ret;
 	}
 
 	leds_front = 0;		/* turn off all front leds */
@@ -135,27 +135,10 @@ static int ot200_led_probe(struct platform_device *pdev)
 	outb(leds_back, 0x5a);
 
 	return 0;
-
-err:
-	for (i = i - 1; i >= 0; i--)
-		led_classdev_unregister(&leds[i].cdev);
-
-	return ret;
-}
-
-static int ot200_led_remove(struct platform_device *pdev)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(leds); i++)
-		led_classdev_unregister(&leds[i].cdev);
-
-	return 0;
 }
 
 static struct platform_driver ot200_led_driver = {
 	.probe		= ot200_led_probe,
-	.remove		= ot200_led_remove,
 	.driver		= {
 		.name	= "leds-ot200",
 	},
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 6578b7bc1fbb..6fcbfb063366 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -4249,6 +4249,10 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
 	struct thin_c *tc = ti->private;
 	struct pool *pool = tc->pool;
+	struct queue_limits *pool_limits = dm_get_queue_limits(pool->pool_md);
+
+	if (!pool_limits->discard_granularity)
+		return; /* pool's discard support is disabled */
 
 	limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
 	limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index c4b9374efd76..9afdda4b1f90 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -250,7 +250,7 @@ static const struct reg_sequence wm5110_revd_patch[] = {
 };
 
 /* Add extra headphone write sequence locations */
-static const struct reg_default wm5110_reve_patch[] = {
+static const struct reg_sequence wm5110_reve_patch[] = {
 	{ 0x80, 0x3 },
 	{ 0x80, 0x3 },
 	{ 0x4b, 0x138 },
diff --git a/drivers/mfd/wm8998-tables.c b/drivers/mfd/wm8998-tables.c
index e6de3cd8a9aa..607640c9c80f 100644
--- a/drivers/mfd/wm8998-tables.c
+++ b/drivers/mfd/wm8998-tables.c
@@ -21,7 +21,7 @@
 #define WM8998_NUM_AOD_ISR 2
 #define WM8998_NUM_ISR 5
 
-static const struct reg_default wm8998_rev_a_patch[] = {
+static const struct reg_sequence wm8998_rev_a_patch[] = {
 	{ 0x0212, 0x0000 },
 	{ 0x0211, 0x0014 },
 	{ 0x04E4, 0x0E0D },
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index 6dd16a6d153f..94b520896b18 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -48,6 +48,12 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
 
 	phb = pci_bus_to_host(dev->bus);
 	afu = (struct cxl_afu *)phb->private_data;
+
+	if (!cxl_adapter_link_ok(afu->adapter)) {
+		dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
+		return false;
+	}
+
 	set_dma_ops(&dev->dev, &dma_direct_ops);
 	set_dma_offset(&dev->dev, PAGE_OFFSET);
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index e3da2bddf143..89a174fa1300 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -3705,16 +3705,14 @@ out:
 
 void bnx2x_update_mfw_dump(struct bnx2x *bp)
 {
-	struct timeval epoc;
 	u32 drv_ver;
 	u32 valid_dump;
 
 	if (!SHMEM2_HAS(bp, drv_info))
 		return;
 
-	/* Update Driver load time */
-	do_gettimeofday(&epoc);
-	SHMEM2_WR(bp, drv_info.epoc, epoc.tv_sec);
+	/* Update Driver load time, possibly broken in y2038 */
+	SHMEM2_WR(bp, drv_info.epoc, (u32)ktime_get_real_seconds());
 
 	drv_ver = bnx2x_update_mng_version_utility(DRV_MODULE_VERSION, true);
 	SHMEM2_WR(bp, drv_info.drv_ver, drv_ver);
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 98d172b04f71..a9b9460de0d6 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -9,7 +9,7 @@
 
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
-#include <asm/cmpxchg.h>
+#include <linux/atomic.h>
 #include "net_driver.h"
 #include "nic.h"
 #include "io.h"
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index 1dd5ab8e5054..5a614b2d0767 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -32,6 +32,13 @@ config IEEE802154_AT86RF230
 	  This driver can also be built as a module. To do so, say M here.
 	  the module will be called 'at86rf230'.
 
+config IEEE802154_AT86RF230_DEBUGFS
+	depends on IEEE802154_AT86RF230
+	bool "AT86RF230 debugfs interface"
+	depends on DEBUG_FS
+	---help---
+	  This option compiles debugfs code for the at86rf230 driver.
+
 config IEEE802154_MRF24J40
 	tristate "Microchip MRF24J40 transceiver driver"
 	depends on IEEE802154_DRIVERS && MAC802154
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 6422caac8d40..9756e6451038 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -31,6 +31,7 @@
 #include <linux/skbuff.h>
 #include <linux/of_gpio.h>
 #include <linux/ieee802154.h>
+#include <linux/debugfs.h>
 
 #include <net/mac802154.h>
 #include <net/cfg802154.h>
@@ -83,6 +84,15 @@ struct at86rf230_state_change {
 	bool irq_enable;
 };
 
+struct at86rf230_trac {
+	u64 success;
+	u64 success_data_pending;
+	u64 success_wait_for_ack;
+	u64 channel_access_failure;
+	u64 no_ack;
+	u64 invalid;
+};
+
 struct at86rf230_local {
 	struct spi_device *spi;
 
@@ -103,6 +113,8 @@ struct at86rf230_local {
 	u8 tx_retry;
 	struct sk_buff *tx_skb;
 	struct at86rf230_state_change tx;
+
+	struct at86rf230_trac trac;
 };
 
 #define AT86RF2XX_NUMREGS 0x3F
@@ -377,14 +389,6 @@ at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
 	}
 }
 
-static inline u8 at86rf230_state_to_force(u8 state)
-{
-	if (state == STATE_TX_ON)
-		return STATE_FORCE_TX_ON;
-	else
-		return STATE_FORCE_TRX_OFF;
-}
-
 static void
 at86rf230_async_state_assert(void *context)
 {
@@ -426,7 +430,7 @@ at86rf230_async_state_assert(void *context)
 				u8 state = ctx->to_state;
 
 				if (lp->tx_retry >= AT86RF2XX_MAX_TX_RETRIES)
-					state = at86rf230_state_to_force(state);
+					state = STATE_FORCE_TRX_OFF;
 				lp->tx_retry++;
 
 				at86rf230_async_state_change(lp, ctx, state,
@@ -667,28 +671,34 @@ at86rf230_tx_trac_check(void *context)
 {
 	struct at86rf230_state_change *ctx = context;
 	struct at86rf230_local *lp = ctx->lp;
-	const u8 *buf = ctx->buf;
-	const u8 trac = (buf[1] & 0xe0) >> 5;
 
-	/* If trac status is different than zero we need to do a state change
-	 * to STATE_FORCE_TRX_OFF then STATE_RX_AACK_ON to recover the
-	 * transceiver.
-	 */
-	if (trac)
-		at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
-					     at86rf230_tx_on, true);
-	else
-		at86rf230_tx_on(context);
-}
+	if (IS_ENABLED(CONFIG_IEEE802154_AT86RF230_DEBUGFS)) {
+		u8 trac = TRAC_MASK(ctx->buf[1]);
 
-static void
-at86rf230_tx_trac_status(void *context)
-{
-	struct at86rf230_state_change *ctx = context;
-	struct at86rf230_local *lp = ctx->lp;
+		switch (trac) {
+		case TRAC_SUCCESS:
+			lp->trac.success++;
+			break;
+		case TRAC_SUCCESS_DATA_PENDING:
+			lp->trac.success_data_pending++;
+			break;
+		case TRAC_CHANNEL_ACCESS_FAILURE:
+			lp->trac.channel_access_failure++;
+			break;
+		case TRAC_NO_ACK:
+			lp->trac.no_ack++;
+			break;
+		case TRAC_INVALID:
+			lp->trac.invalid++;
+			break;
+		default:
+			WARN_ONCE(1, "received tx trac status %d\n", trac);
+			break;
+		}
+	}
 
-	at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx,
-				 at86rf230_tx_trac_check, true);
+	at86rf230_async_state_change(lp, &lp->irq, STATE_TX_ON,
+				     at86rf230_tx_on, true);
 }
 
 static void
@@ -723,13 +733,32 @@ at86rf230_rx_read_frame_complete(void *context)
 }
 
 static void
-at86rf230_rx_read_frame(void *context)
+at86rf230_rx_trac_check(void *context)
 {
 	struct at86rf230_state_change *ctx = context;
 	struct at86rf230_local *lp = ctx->lp;
 	u8 *buf = ctx->buf;
 	int rc;
 
+	if (IS_ENABLED(CONFIG_IEEE802154_AT86RF230_DEBUGFS)) {
+		u8 trac = TRAC_MASK(buf[1]);
+
+		switch (trac) {
+		case TRAC_SUCCESS:
+			lp->trac.success++;
+			break;
+		case TRAC_SUCCESS_WAIT_FOR_ACK:
+			lp->trac.success_wait_for_ack++;
+			break;
+		case TRAC_INVALID:
+			lp->trac.invalid++;
+			break;
+		default:
+			WARN_ONCE(1, "received rx trac status %d\n", trac);
+			break;
+		}
+	}
+
 	buf[0] = CMD_FB;
 	ctx->trx.len = AT86RF2XX_MAX_BUF;
 	ctx->msg.complete = at86rf230_rx_read_frame_complete;
@@ -742,26 +771,12 @@ at86rf230_rx_read_frame(void *context)
 }
 
 static void
-at86rf230_rx_trac_check(void *context)
-{
-	/* Possible check on trac status here. This could be useful to make
-	 * some stats why receive is failed. Not used at the moment, but it's
-	 * maybe timing relevant. Datasheet doesn't say anything about this.
-	 * The programming guide say do it so.
-	 */
-
-	at86rf230_rx_read_frame(context);
-}
-
-static void
 at86rf230_irq_trx_end(struct at86rf230_local *lp)
 {
 	if (lp->is_tx) {
 		lp->is_tx = 0;
-		at86rf230_async_state_change(lp, &lp->irq,
-					     STATE_FORCE_TX_ON,
-					     at86rf230_tx_trac_status,
-					     true);
+		at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq,
+					 at86rf230_tx_trac_check, true);
 	} else {
 		at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq,
 					 at86rf230_rx_trac_check, true);
@@ -920,6 +935,10 @@ at86rf230_start(struct ieee802154_hw *hw)
 {
 	struct at86rf230_local *lp = hw->priv;
 
+	/* reset trac stats on start */
+	if (IS_ENABLED(CONFIG_IEEE802154_AT86RF230_DEBUGFS))
+		memset(&lp->trac, 0, sizeof(struct at86rf230_trac));
+
 	at86rf230_awake(lp);
 	enable_irq(lp->spi->irq);
 
@@ -1357,7 +1376,7 @@ static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim)
 	if (irq_type == IRQ_TYPE_EDGE_RISING ||
 	    irq_type == IRQ_TYPE_EDGE_FALLING)
 		dev_warn(&lp->spi->dev,
-			 "Using edge triggered irq's are not recommended!\n");
+			 "Using edge triggered irq's are not recommended, because it can cause races and result in a non-functional driver!\n");
 	if (irq_type == IRQ_TYPE_EDGE_FALLING ||
 	    irq_type == IRQ_TYPE_LEVEL_LOW)
 		irq_pol = IRQ_ACTIVE_LOW;
@@ -1620,6 +1639,66 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp)
 	lp->tx.timer.function = at86rf230_async_state_timer;
 }
 
+#ifdef CONFIG_IEEE802154_AT86RF230_DEBUGFS
+static struct dentry *at86rf230_debugfs_root;
+
+static int at86rf230_stats_show(struct seq_file *file, void *offset)
+{
+	struct at86rf230_local *lp = file->private;
+
+	seq_printf(file, "SUCCESS:\t\t%8llu\n", lp->trac.success);
+	seq_printf(file, "SUCCESS_DATA_PENDING:\t%8llu\n",
+		   lp->trac.success_data_pending);
+	seq_printf(file, "SUCCESS_WAIT_FOR_ACK:\t%8llu\n",
+		   lp->trac.success_wait_for_ack);
+	seq_printf(file, "CHANNEL_ACCESS_FAILURE:\t%8llu\n",
+		   lp->trac.channel_access_failure);
+	seq_printf(file, "NO_ACK:\t\t\t%8llu\n", lp->trac.no_ack);
+	seq_printf(file, "INVALID:\t\t%8llu\n", lp->trac.invalid);
+	return 0;
+}
+
+static int at86rf230_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, at86rf230_stats_show, inode->i_private);
+}
+
+static const struct file_operations at86rf230_stats_fops = {
+	.open		= at86rf230_stats_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int at86rf230_debugfs_init(struct at86rf230_local *lp)
+{
+	char debugfs_dir_name[DNAME_INLINE_LEN + 1] = "at86rf230-";
+	struct dentry *stats;
+
+	strncat(debugfs_dir_name, dev_name(&lp->spi->dev), DNAME_INLINE_LEN);
+
+	at86rf230_debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
+	if (!at86rf230_debugfs_root)
+		return -ENOMEM;
+
+	stats = debugfs_create_file("trac_stats", S_IRUGO,
+				    at86rf230_debugfs_root, lp,
+				    &at86rf230_stats_fops);
+	if (!stats)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void at86rf230_debugfs_remove(void)
+{
+	debugfs_remove_recursive(at86rf230_debugfs_root);
+}
+#else
+static int at86rf230_debugfs_init(struct at86rf230_local *lp) { return 0; }
+static void at86rf230_debugfs_remove(void) { }
+#endif
+
 static int at86rf230_probe(struct spi_device *spi)
 {
 	struct ieee802154_hw *hw;
@@ -1715,12 +1794,18 @@ static int at86rf230_probe(struct spi_device *spi)
 	/* going into sleep by default */
 	at86rf230_sleep(lp);
 
-	rc = ieee802154_register_hw(lp->hw);
+	rc = at86rf230_debugfs_init(lp);
 	if (rc)
 		goto free_dev;
 
+	rc = ieee802154_register_hw(lp->hw);
+	if (rc)
+		goto free_debugfs;
+
 	return rc;
 
+free_debugfs:
+	at86rf230_debugfs_remove();
 free_dev:
 	ieee802154_free_hw(lp->hw);
 
@@ -1735,6 +1820,7 @@ static int at86rf230_remove(struct spi_device *spi)
 	at86rf230_write_subreg(lp, SR_IRQ_MASK, 0);
 	ieee802154_unregister_hw(lp->hw);
 	ieee802154_free_hw(lp->hw);
+	at86rf230_debugfs_remove();
 	dev_dbg(&spi->dev, "unregistered at86rf230\n");
 
 	return 0;
diff --git a/drivers/net/ieee802154/at86rf230.h b/drivers/net/ieee802154/at86rf230.h
index 1e6d1cc677f6..fd9c1f467f63 100644
--- a/drivers/net/ieee802154/at86rf230.h
+++ b/drivers/net/ieee802154/at86rf230.h
@@ -216,5 +216,13 @@
 #define STATE_TRANSITION_IN_PROGRESS 0x1F
 
 #define TRX_STATE_MASK		(0x1F)
+#define TRAC_MASK(x)		((x & 0xe0) >> 5)
+
+#define TRAC_SUCCESS			0
+#define TRAC_SUCCESS_DATA_PENDING	1
+#define TRAC_SUCCESS_WAIT_FOR_ACK	2
+#define TRAC_CHANNEL_ACCESS_FAILURE	3
+#define TRAC_NO_ACK			5
+#define TRAC_INVALID			7
 
 #endif /* !_AT86RF230_H */
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index 80dfc725b8dc..199a94a9c8bc 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -559,6 +559,7 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
 {
 	struct usb_device *usb_dev = atusb->usb_dev;
 	uint8_t man_id_0, man_id_1, part_num, version_num;
+	const char *chip;
 
 	man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
 	man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
@@ -574,14 +575,22 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
 			man_id_1, man_id_0);
 		goto fail;
 	}
-	if (part_num != 3 && part_num != 2) {
+
+	switch (part_num) {
+	case 2:
+		chip = "AT86RF230";
+		break;
+	case 3:
+		chip = "AT86RF231";
+		break;
+	default:
 		dev_err(&usb_dev->dev,
 			"unexpected transceiver, part 0x%02x version 0x%02x\n",
 			part_num, version_num);
 		goto fail;
 	}
 
-	dev_info(&usb_dev->dev, "ATUSB: AT86RF231 version %d\n", version_num);
+	dev_info(&usb_dev->dev, "ATUSB: %s version %d\n", chip, version_num);
 
 	return 0;
 
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 58ae11a14bb6..64bb44d5d867 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -1031,7 +1031,6 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud)
 static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed)
 {
 	struct ali_ircc_cb *self = priv;
-	unsigned long flags;
 	int iobase; 
 	int fcr;    /* FIFO control reg */
 	int lcr;    /* Line control reg */
@@ -1061,8 +1060,6 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed)
 	/* Update accounting for new speed */
 	self->io.speed = speed;
 
-	spin_lock_irqsave(&self->lock, flags);
-
 	divisor = 115200/speed;
 	
 	fcr = UART_FCR_ENABLE_FIFO;
@@ -1089,9 +1086,6 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed)
 	/* without this, the connection will be broken after come back from FIR speed,
 	   but with this, the SIR connection is harder to established */
 	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
-	
-	spin_unlock_irqrestore(&self->lock, flags);
-	
 }
 
 static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 6e0d9fa8e1d1..c7a05996d5c1 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -17,8 +17,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
-
-#include <asm/cmpxchg.h>
+#include <linux/atomic.h>
 
 #define USBHS_LPSTS			0x02
 #define USBHS_UGCTRL			0x80
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 69723e07036b..9638a00c67c2 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -349,6 +349,9 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio)
 	struct pinctrl_gpio_range *range = NULL;
 	struct gpio_chip *chip = gpio_to_chip(gpio);
 
+	if (WARN(!chip, "no gpio_chip for gpio%i?", gpio))
+		return false;
+
 	mutex_lock(&pinctrldev_list_mutex);
 
 	/* Loop over the pin controllers */
diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c
index 461fffc4c62a..11f8b835d3b6 100644
--- a/drivers/pinctrl/pinctrl-digicolor.c
+++ b/drivers/pinctrl/pinctrl-digicolor.c
@@ -337,9 +337,9 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
 	pmap->dev = &pdev->dev;
 
 	pmap->pctl = pinctrl_register(pctl_desc, &pdev->dev, pmap);
-	if (!pmap->pctl) {
+	if (IS_ERR(pmap->pctl)) {
 		dev_err(&pdev->dev, "pinctrl driver registration failed\n");
-		return -EINVAL;
+		return PTR_ERR(pmap->pctl);
 	}
 
 	ret = dc_gpiochip_add(pmap, pdev->dev.of_node);
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 67e08cb315c4..29984b36926a 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -313,8 +313,7 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
 
 	/* See if this pctldev has this function */
 	while (selector < nfuncs) {
-		const char *fname = ops->get_function_name(pctldev,
-							   selector);
+		const char *fname = ops->get_function_name(pctldev, selector);
 
 		if (!strcmp(function, fname))
 			return selector;
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
index c978b311031b..e1a3721bc8e5 100644
--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
@@ -723,9 +723,9 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev)
 #endif
 
 	pctrl->pctrl = pinctrl_register(&pctrl->desc, &pdev->dev, pctrl);
-	if (!pctrl->pctrl) {
+	if (IS_ERR(pctrl->pctrl)) {
 		dev_err(&pdev->dev, "couldn't register pm8xxx gpio driver\n");
-		return -ENODEV;
+		return PTR_ERR(pctrl->pctrl);
 	}
 
 	pctrl->chip = pm8xxx_gpio_template;
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c
index 2d1b69f171be..6652b8d7f707 100644
--- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c
+++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c
@@ -814,9 +814,9 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev)
 #endif
 
 	pctrl->pctrl = pinctrl_register(&pctrl->desc, &pdev->dev, pctrl);
-	if (!pctrl->pctrl) {
+	if (IS_ERR(pctrl->pctrl)) {
 		dev_err(&pdev->dev, "couldn't register pm8xxx mpp driver\n");
-		return -ENODEV;
+		return PTR_ERR(pctrl->pctrl);
 	}
 
 	pctrl->chip = pm8xxx_mpp_template;
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index 019844d479bb..d168b39dd7fd 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -361,7 +361,7 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc,
 				      u32 offset, u32 range)
 {
 	struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
-	struct irq_chip *chip = irq_desc_get_irq_chip(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct samsung_pinctrl_drv_data *d = data->drvdata;
 	unsigned int pend, mask;
 
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 3271cd1abe7c..d03df4a60d05 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -4,6 +4,7 @@
 
 menuconfig CHROME_PLATFORMS
 	bool "Platform support for Chrome hardware"
+	depends on X86 || ARM || ARM64 || COMPILE_TEST
 	---help---
 	  Say Y here to get to see options for platform support for
 	  various Chromebooks and Chromeboxes. This option alone does
@@ -39,7 +40,7 @@ config CHROMEOS_PSTORE
 
 config CROS_EC_CHARDEV
         tristate "Chrome OS Embedded Controller userspace device interface"
-        depends on CROS_EC_PROTO
+        depends on MFD_CROS_EC
         ---help---
           This driver adds support to talk with the ChromeOS EC from userspace.
 
@@ -48,7 +49,7 @@ config CROS_EC_CHARDEV
 
 config CROS_EC_LPC
         tristate "ChromeOS Embedded Controller (LPC)"
-        depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST)
+        depends on MFD_CROS_EC && (X86 || COMPILE_TEST)
         help
           If you say Y here, you get support for talking to the ChromeOS EC
           over an LPC bus. This uses a simple byte-level protocol with a
diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
index e8fcdc237029..2f4099820480 100644
--- a/drivers/platform/chrome/cros_ec_dev.c
+++ b/drivers/platform/chrome/cros_ec_dev.c
@@ -287,6 +287,12 @@ static int ec_device_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id cros_ec_id[] = {
+	{ "cros-ec-ctl", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, cros_ec_id);
+
 static struct platform_driver cros_ec_dev_driver = {
 	.driver = {
 		.name = "cros-ec-ctl",
diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c
index 144e09df9b84..ff7640575c75 100644
--- a/drivers/platform/chrome/cros_ec_lightbar.c
+++ b/drivers/platform/chrome/cros_ec_lightbar.c
@@ -252,7 +252,7 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
 
 		ret = sscanf(buf, "%i", &val[i++]);
 		if (ret == 0)
-			return -EINVAL;
+			goto exit;
 
 		if (i == 4) {
 			param = (struct ec_params_lightbar *)msg->data;
@@ -268,17 +268,15 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
 			if ((j++ % 4) == 0) {
 				ret = lb_throttle();
 				if (ret)
-					return ret;
+					goto exit;
 			}
 
 			ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
 			if (ret < 0)
 				goto exit;
 
-			if (msg->result != EC_RES_SUCCESS) {
-				ret = -EINVAL;
+			if (msg->result != EC_RES_SUCCESS)
 				goto exit;
-			}
 
 			i = 0;
 			ok = 1;
@@ -352,10 +350,6 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
 	struct cros_ec_dev *ec = container_of(dev,
 					      struct cros_ec_dev, class_dev);
 
-	msg = alloc_lightbar_cmd_msg(ec);
-	if (!msg)
-		return -ENOMEM;
-
 	for (len = 0; len < count; len++)
 		if (!isalnum(buf[len]))
 			break;
@@ -370,21 +364,30 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
 			return ret;
 	}
 
+	msg = alloc_lightbar_cmd_msg(ec);
+	if (!msg)
+		return -ENOMEM;
+
 	param = (struct ec_params_lightbar *)msg->data;
 	param->cmd = LIGHTBAR_CMD_SEQ;
 	param->seq.num = num;
 	ret = lb_throttle();
 	if (ret)
-		return ret;
+		goto exit;
 
 	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
 	if (ret < 0)
-		return ret;
+		goto exit;
 
-	if (msg->result != EC_RES_SUCCESS)
-		return -EINVAL;
+	if (msg->result != EC_RES_SUCCESS) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
-	return count;
+	ret = count;
+exit:
+	kfree(msg);
+	return ret;
 }
 
 /* Module initialization */
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index bdd77ce45f05..f9a245465fd0 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -166,19 +166,9 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
 
 	/* Check result */
 	msg->result = inb(EC_LPC_ADDR_HOST_DATA);
-
-	switch (msg->result) {
-	case EC_RES_SUCCESS:
-		break;
-	case EC_RES_IN_PROGRESS:
-		ret = -EAGAIN;
-		dev_dbg(ec->dev, "command 0x%02x in progress\n",
-			msg->command);
+	ret = cros_ec_check_result(ec, msg);
+	if (ret)
 		goto done;
-	default:
-		dev_dbg(ec->dev, "command 0x%02x returned %d\n",
-			msg->command, msg->result);
-	}
 
 	/* Read back args */
 	args.flags = inb(EC_LPC_ADDR_HOST_ARGS);
@@ -330,6 +320,13 @@ static struct dmi_system_id cros_ec_lpc_dmi_table[] __initdata = {
 		},
 	},
 	{
+		/* x86-samus, the Chromebook Pixel 2. */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Samus"),
+		},
+	},
+	{
 		/* x86-peppy, the Acer C720 Chromebook. */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index abdaed34c728..131fee2b093e 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -128,6 +128,24 @@ static const struct dmi_system_id asus_quirks[] = {
 	},
 	{
 		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X456UA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"),
+		},
+		.driver_data = &quirk_asus_wapf4,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X456UF",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"),
+		},
+		.driver_data = &quirk_asus_wapf4,
+	},
+	{
+		.callback = dmi_matched,
 		.ident = "ASUSTeK COMPUTER INC. X501U",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index aac47573f9ed..eb391a281833 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -194,34 +194,6 @@ static bool wmi_parse_guid(const u8 *src, u8 *dest)
 	return true;
 }
 
-/*
- * Convert a raw GUID to the ACII string representation
- */
-static int wmi_gtoa(const char *in, char *out)
-{
-	int i;
-
-	for (i = 3; i >= 0; i--)
-		out += sprintf(out, "%02X", in[i] & 0xFF);
-
-	out += sprintf(out, "-");
-	out += sprintf(out, "%02X", in[5] & 0xFF);
-	out += sprintf(out, "%02X", in[4] & 0xFF);
-	out += sprintf(out, "-");
-	out += sprintf(out, "%02X", in[7] & 0xFF);
-	out += sprintf(out, "%02X", in[6] & 0xFF);
-	out += sprintf(out, "-");
-	out += sprintf(out, "%02X", in[8] & 0xFF);
-	out += sprintf(out, "%02X", in[9] & 0xFF);
-	out += sprintf(out, "-");
-
-	for (i = 10; i <= 15; i++)
-		out += sprintf(out, "%02X", in[i] & 0xFF);
-
-	*out = '\0';
-	return 0;
-}
-
 static bool find_guid(const char *guid_string, struct wmi_block **out)
 {
 	char tmp[16], guid_input[16];
@@ -457,11 +429,7 @@ EXPORT_SYMBOL_GPL(wmi_set_block);
 
 static void wmi_dump_wdg(const struct guid_block *g)
 {
-	char guid_string[37];
-
-	wmi_gtoa(g->guid, guid_string);
-
-	pr_info("%s:\n", guid_string);
+	pr_info("%pUL:\n", g->guid);
 	pr_info("\tobject_id: %c%c\n", g->object_id[0], g->object_id[1]);
 	pr_info("\tnotify_id: %02X\n", g->notify_id);
 	pr_info("\treserved: %02X\n", g->reserved);
@@ -661,7 +629,6 @@ EXPORT_SYMBOL_GPL(wmi_has_guid);
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
-	char guid_string[37];
 	struct wmi_block *wblock;
 
 	wblock = dev_get_drvdata(dev);
@@ -670,9 +637,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 		return strlen(buf);
 	}
 
-	wmi_gtoa(wblock->gblock.guid, guid_string);
-
-	return sprintf(buf, "wmi:%s\n", guid_string);
+	return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid);
 }
 static DEVICE_ATTR_RO(modalias);
 
@@ -695,7 +660,7 @@ static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
 	if (!wblock)
 		return -ENOMEM;
 
-	wmi_gtoa(wblock->gblock.guid, guid_string);
+	sprintf(guid_string, "%pUL", wblock->gblock.guid);
 
 	strcpy(&env->buf[env->buflen - 1], "wmi:");
 	memcpy(&env->buf[env->buflen - 1 + 4], guid_string, 36);
@@ -721,12 +686,9 @@ static struct class wmi_class = {
 static int wmi_create_device(const struct guid_block *gblock,
 			     struct wmi_block *wblock, acpi_handle handle)
 {
-	char guid_string[37];
-
 	wblock->dev.class = &wmi_class;
 
-	wmi_gtoa(gblock->guid, guid_string);
-	dev_set_name(&wblock->dev, "%s", guid_string);
+	dev_set_name(&wblock->dev, "%pUL", gblock->guid);
 
 	dev_set_drvdata(&wblock->dev, wblock);
 
@@ -877,7 +839,6 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
 	struct guid_block *block;
 	struct wmi_block *wblock;
 	struct list_head *p;
-	char guid_string[37];
 
 	list_for_each(p, &wmi_block_list) {
 		wblock = list_entry(p, struct wmi_block, list);
@@ -888,8 +849,8 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
 			if (wblock->handler)
 				wblock->handler(event, wblock->handler_data);
 			if (debug_event) {
-				wmi_gtoa(wblock->gblock.guid, guid_string);
-				pr_info("DEBUG Event GUID: %s\n", guid_string);
+				pr_info("DEBUG Event GUID: %pUL\n",
+					wblock->gblock.guid);
 			}
 
 			acpi_bus_generate_netlink_event(
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index f4f2c1f76c32..74f2d3ff1d7c 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -91,7 +91,7 @@
 #define TWL4030_MSTATEC_COMPLETE1	0x0b
 #define TWL4030_MSTATEC_COMPLETE4	0x0e
 
-#if IS_ENABLED(CONFIG_TWL4030_MADC)
+#if IS_REACHABLE(CONFIG_TWL4030_MADC)
 /*
  * If AC (Accessory Charger) voltage exceeds 4.5V (MADC 11)
  * then AC is available.
@@ -1057,13 +1057,9 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 		phynode = of_find_compatible_node(bci->dev->of_node->parent,
 						  NULL, "ti,twl4030-usb");
-		if (phynode) {
+		if (phynode)
 			bci->transceiver = devm_usb_get_phy_by_node(
 				bci->dev, phynode, &bci->usb_nb);
-			if (IS_ERR(bci->transceiver) &&
-			    PTR_ERR(bci->transceiver) == -EPROBE_DEFER)
-				return -EPROBE_DEFER;
-		}
 	}
 
 	/* Enable interrupts now. */
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 7a85ac9e32c5..9283d9f7919b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1422,11 +1422,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 		return ret;
 
 	/* Cascade always-on state to supply */
-	if (_regulator_is_enabled(rdev)) {
+	if (_regulator_is_enabled(rdev) && rdev->supply) {
 		ret = regulator_enable(rdev->supply);
 		if (ret < 0) {
-			if (rdev->supply)
-				_regulator_put(rdev->supply);
+			_regulator_put(rdev->supply);
 			return ret;
 		}
 	}
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c
index 4fa7bcaf454e..f9d74d63be7c 100644
--- a/drivers/regulator/pbias-regulator.c
+++ b/drivers/regulator/pbias-regulator.c
@@ -45,6 +45,10 @@ struct pbias_regulator_data {
 	int voltage;
 };
 
+struct pbias_of_data {
+	unsigned int offset;
+};
+
 static const unsigned int pbias_volt_table[] = {
 	1800000,
 	3000000
@@ -102,8 +106,35 @@ static struct of_regulator_match pbias_matches[] = {
 };
 #define PBIAS_NUM_REGS	ARRAY_SIZE(pbias_matches)
 
+/* Offset from SCM general area (and syscon) base */
+
+static const struct pbias_of_data pbias_of_data_omap2 = {
+	.offset = 0x230,
+};
+
+static const struct pbias_of_data pbias_of_data_omap3 = {
+	.offset = 0x2b0,
+};
+
+static const struct pbias_of_data pbias_of_data_omap4 = {
+	.offset = 0x60,
+};
+
+static const struct pbias_of_data pbias_of_data_omap5 = {
+	.offset = 0x60,
+};
+
+static const struct pbias_of_data pbias_of_data_dra7 = {
+	.offset = 0xe00,
+};
+
 static const struct of_device_id pbias_of_match[] = {
 	{ .compatible = "ti,pbias-omap", },
+	{ .compatible = "ti,pbias-omap2", .data = &pbias_of_data_omap2, },
+	{ .compatible = "ti,pbias-omap3", .data = &pbias_of_data_omap3, },
+	{ .compatible = "ti,pbias-omap4", .data = &pbias_of_data_omap4, },
+	{ .compatible = "ti,pbias-omap5", .data = &pbias_of_data_omap5, },
+	{ .compatible = "ti,pbias-dra7", .data = &pbias_of_data_dra7, },
 	{},
 };
 MODULE_DEVICE_TABLE(of, pbias_of_match);
@@ -118,6 +149,9 @@ static int pbias_regulator_probe(struct platform_device *pdev)
 	const struct pbias_reg_info *info;
 	int ret = 0;
 	int count, idx, data_idx = 0;
+	const struct of_device_id *match;
+	const struct pbias_of_data *data;
+	unsigned int offset;
 
 	count = of_regulator_match(&pdev->dev, np, pbias_matches,
 						PBIAS_NUM_REGS);
@@ -133,6 +167,20 @@ static int pbias_regulator_probe(struct platform_device *pdev)
 	if (IS_ERR(syscon))
 		return PTR_ERR(syscon);
 
+	match = of_match_device(of_match_ptr(pbias_of_match), &pdev->dev);
+	if (match && match->data) {
+		data = match->data;
+		offset = data->offset;
+	} else {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res)
+			return -EINVAL;
+
+		offset = res->start;
+		dev_WARN(&pdev->dev,
+			 "using legacy dt data for pbias offset\n");
+	}
+
 	cfg.regmap = syscon;
 	cfg.dev = &pdev->dev;
 
@@ -145,10 +193,6 @@ static int pbias_regulator_probe(struct platform_device *pdev)
 		if (!info)
 			return -ENODEV;
 
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		if (!res)
-			return -EINVAL;
-
 		drvdata[data_idx].syscon = syscon;
 		drvdata[data_idx].info = info;
 		drvdata[data_idx].desc.name = info->name;
@@ -158,9 +202,9 @@ static int pbias_regulator_probe(struct platform_device *pdev)
 		drvdata[data_idx].desc.volt_table = pbias_volt_table;
 		drvdata[data_idx].desc.n_voltages = 2;
 		drvdata[data_idx].desc.enable_time = info->enable_time;
-		drvdata[data_idx].desc.vsel_reg = res->start;
+		drvdata[data_idx].desc.vsel_reg = offset;
 		drvdata[data_idx].desc.vsel_mask = info->vmode;
-		drvdata[data_idx].desc.enable_reg = res->start;
+		drvdata[data_idx].desc.enable_reg = offset;
 		drvdata[data_idx].desc.enable_mask = info->enable_mask;
 		drvdata[data_idx].desc.enable_val = info->enable;
 		drvdata[data_idx].desc.disable_val = info->disable_val;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index f73d2f579a7e..a263c10359e1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -3030,6 +3030,7 @@ static void dasd_setup_queue(struct dasd_block *block)
 	} else {
 		max = block->base->discipline->max_blocks << block->s2b_shift;
 	}
+	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, block->request_queue);
 	blk_queue_logical_block_size(block->request_queue,
 				     block->bp_block);
 	blk_queue_max_hw_sectors(block->request_queue, max);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4eb45546a3aa..a9603ebbc1f8 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -472,8 +472,7 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
 	unsigned long long z1, z2, z3;
 	int rc, copied;
 
-	if (crt->outputdatalength < crt->inputdatalength ||
-	    (crt->inputdatalength & 1))
+	if (crt->outputdatalength < crt->inputdatalength)
 		return -EINVAL;
 	/*
 	 * As long as outputdatalength is big enough, we can set the
diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h
index 1f42f103c761..ca0cdbe46368 100644
--- a/drivers/s390/crypto/zcrypt_cca_key.h
+++ b/drivers/s390/crypto/zcrypt_cca_key.h
@@ -291,7 +291,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt,
 
 	memset(key, 0, sizeof(*key));
 
-	short_len = crt->inputdatalength / 2;
+	short_len = (crt->inputdatalength + 1) / 2;
 	long_len = short_len + 8;
 	pad_len = -(3*long_len + 2*short_len) & 7;
 	key_len = 3*long_len + 2*short_len + pad_len + crt->inputdatalength;
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index 334e282f255b..6c9af1332967 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -248,7 +248,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
 	unsigned char *p, *q, *dp, *dq, *u, *inp;
 
 	mod_len = crt->inputdatalength;
-	short_len = mod_len / 2;
+	short_len = (mod_len + 1) / 2;
 
 	/*
 	 * CEX2A and CEX3A w/o FW update can handle requests up to
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 7a743f4c646c..2f220208da63 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -138,7 +138,7 @@ static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
 	int mod_len, short_len, long_len;
 
 	mod_len = crt->inputdatalength;
-	short_len = mod_len / 2;
+	short_len = (mod_len + 1) / 2;
 	long_len = mod_len / 2 + 8;
 
 	if (mod_len <= 128) {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index f0e462b0880d..9a73c8b66b96 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -248,6 +248,7 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
+ * @sdev: The sas_device associated with this target
  */
 struct MPT3SAS_TARGET {
 	struct scsi_target *starget;
@@ -257,6 +258,7 @@ struct MPT3SAS_TARGET {
 	u32	flags;
 	u8	deleted;
 	u8	tm_busy;
+	struct	_sas_device *sdev;
 };
 
 
@@ -335,6 +337,9 @@ struct _internal_cmd {
  * @pfa_led_on: flag for PFA LED status
  * @pend_sas_rphy_add: flag to check if device is in sas_rphy_add()
  *	addition routine.
+ * @enclosure_level: used for enclosure services
+ * @connector_name: ASCII value from pg0.ConnectorName
+ * @refcount: reference count for deletion
  */
 struct _sas_device {
 	struct list_head list;
@@ -358,8 +363,24 @@ struct _sas_device {
 	u8	pend_sas_rphy_add;
 	u8	enclosure_level;
 	u8	connector_name[4];
+	struct kref refcount;
 };
 
+static inline void sas_device_get(struct _sas_device *s)
+{
+	kref_get(&s->refcount);
+}
+
+static inline void sas_device_free(struct kref *r)
+{
+	kfree(container_of(r, struct _sas_device, refcount));
+}
+
+static inline void sas_device_put(struct _sas_device *s)
+{
+	kref_put(&s->refcount, sas_device_free);
+}
+
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -1090,7 +1111,9 @@ struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
 	struct MPT3SAS_ADAPTER *ioc, u16 handle);
 struct _sas_node *mpt3sas_scsih_expander_find_by_sas_address(
 	struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
-struct _sas_device *mpt3sas_scsih_sas_device_find_by_sas_address(
+struct _sas_device *mpt3sas_get_sdev_by_addr(
+	 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *__mpt3sas_get_sdev_by_addr(
 	struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8ccef38523fa..9e6843275fdf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -175,6 +175,7 @@ struct sense_info {
  * @VP_ID: virtual port id
  * @ignore: flag meaning this event has been marked to ignore
  * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
+ * @refcount: reference count for fw_event_work
  * @event_data: reply event data payload follows
  *
  * This object stored on ioc->fw_event_list.
@@ -191,9 +192,37 @@ struct fw_event_work {
 	u8			VP_ID;
 	u8			ignore;
 	u16			event;
+	struct kref		refcount;
 	char			event_data[0] __aligned(4);
 };
 
+static void fw_event_work_free(struct kref *r)
+{
+	kfree(container_of(r, struct fw_event_work, refcount));
+}
+
+static void fw_event_work_get(struct fw_event_work *fw_work)
+{
+	kref_get(&fw_work->refcount);
+}
+
+static void fw_event_work_put(struct fw_event_work *fw_work)
+{
+	kref_put(&fw_work->refcount, fw_event_work_free);
+}
+
+static struct fw_event_work *alloc_fw_event_work(int len)
+{
+	struct fw_event_work *fw_event;
+
+	fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC);
+	if (!fw_event)
+		return NULL;
+
+	kref_init(&fw_event->refcount);
+	return fw_event;
+}
+
 /* raid transport support */
 static struct raid_template *mpt3sas_raid_template;
 
@@ -518,8 +547,61 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
 	}
 }
 
+static struct _sas_device *
+__mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+	struct MPT3SAS_TARGET *tgt_priv)
+{
+	struct _sas_device *ret;
+
+	assert_spin_locked(&ioc->sas_device_lock);
+
+	ret = tgt_priv->sdev;
+	if (ret)
+		sas_device_get(ret);
+
+	return ret;
+}
+
+static struct _sas_device *
+mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+	struct MPT3SAS_TARGET *tgt_priv)
+{
+	struct _sas_device *ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	ret = __mpt3sas_get_sdev_from_target(ioc, tgt_priv);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	return ret;
+}
+
+struct _sas_device *
+__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
+	u64 sas_address)
+{
+	struct _sas_device *sas_device;
+
+	assert_spin_locked(&ioc->sas_device_lock);
+
+	list_for_each_entry(sas_device, &ioc->sas_device_list, list)
+		if (sas_device->sas_address == sas_address)
+			goto found_device;
+
+	list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
+		if (sas_device->sas_address == sas_address)
+			goto found_device;
+
+	return NULL;
+
+found_device:
+	sas_device_get(sas_device);
+	return sas_device;
+}
+
+
 /**
- * mpt3sas_scsih_sas_device_find_by_sas_address - sas device search
+ * mpt3sas_get_sdev_by_addr - sas device search
  * @ioc: per adapter object
  * @sas_address: sas address
  * Context: Calling function should acquire ioc->sas_device_lock
@@ -528,24 +610,44 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
  * object.
  */
 struct _sas_device *
-mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
+mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
 	u64 sas_address)
 {
 	struct _sas_device *sas_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
+			sas_address);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	return sas_device;
+}
+
+static struct _sas_device *
+__mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _sas_device *sas_device;
+
+	assert_spin_locked(&ioc->sas_device_lock);
 
 	list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-		if (sas_device->sas_address == sas_address)
-			return sas_device;
+		if (sas_device->handle == handle)
+			goto found_device;
 
 	list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-		if (sas_device->sas_address == sas_address)
-			return sas_device;
+		if (sas_device->handle == handle)
+			goto found_device;
 
 	return NULL;
+
+found_device:
+	sas_device_get(sas_device);
+	return sas_device;
 }
 
 /**
- * _scsih_sas_device_find_by_handle - sas device search
+ * mpt3sas_get_sdev_by_handle - sas device search
  * @ioc: per adapter object
  * @handle: sas device handle (assigned by firmware)
  * Context: Calling function should acquire ioc->sas_device_lock
@@ -554,19 +656,16 @@ mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
  * object.
  */
 static struct _sas_device *
-_scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
 	struct _sas_device *sas_device;
+	unsigned long flags;
 
-	list_for_each_entry(sas_device, &ioc->sas_device_list, list)
-		if (sas_device->handle == handle)
-			return sas_device;
-
-	list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
-		if (sas_device->handle == handle)
-			return sas_device;
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	return NULL;
+	return sas_device;
 }
 
 /**
@@ -575,7 +674,7 @@ _scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
  * @sas_device: the sas_device object
  * Context: This function will acquire ioc->sas_device_lock.
  *
- * Removing object and freeing associated memory from the ioc->sas_device_list.
+ * If sas_device is on the list, remove it and decrement its reference count.
  */
 static void
 _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
@@ -601,10 +700,15 @@ _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
 		   "removing enclosure level(0x%04x), connector name( %s)\n",
 		   ioc->name, sas_device->enclosure_level,
 		   sas_device->connector_name);
-
+	/*
+	 * The lock serializes access to the list, but we still need to verify
+	 * that nobody removed the entry while we were waiting on the lock.
+	 */
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	list_del(&sas_device->list);
-	kfree(sas_device);
+	if (!list_empty(&sas_device->list)) {
+		list_del_init(&sas_device->list);
+		sas_device_put(sas_device);
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 }
 
@@ -625,12 +729,17 @@ _scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 		return;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (sas_device)
-		list_del(&sas_device->list);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
+	if (sas_device) {
+		list_del_init(&sas_device->list);
+		sas_device_put(sas_device);
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-	if (sas_device)
+
+	if (sas_device) {
 		_scsih_remove_device(ioc, sas_device);
+		sas_device_put(sas_device);
+	}
 }
 
 /**
@@ -651,13 +760,17 @@ mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
 		return;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-	    sas_address);
-	if (sas_device)
-		list_del(&sas_device->list);
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address);
+	if (sas_device) {
+		list_del_init(&sas_device->list);
+		sas_device_put(sas_device);
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-	if (sas_device)
+
+	if (sas_device) {
 		_scsih_remove_device(ioc, sas_device);
+		sas_device_put(sas_device);
+	}
 }
 
 /**
@@ -692,6 +805,7 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
 		    sas_device->enclosure_level, sas_device->connector_name));
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device_get(sas_device);
 	list_add_tail(&sas_device->list, &ioc->sas_device_list);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
@@ -745,6 +859,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
 		    sas_device->connector_name));
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device_get(sas_device);
 	list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
 	_scsih_determine_boot_device(ioc, sas_device, 0);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
@@ -1123,12 +1238,15 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 		goto not_sata;
 	if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
 		goto not_sata;
+
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-	   sas_device_priv_data->sas_target->sas_address);
-	if (sas_device && sas_device->device_info &
-	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
-		max_depth = MPT3SAS_SATA_QUEUE_DEPTH;
+	sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
+	if (sas_device) {
+		if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
+			max_depth = MPT3SAS_SATA_QUEUE_DEPTH;
+
+		sas_device_put(sas_device);
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
  not_sata:
@@ -1185,12 +1303,13 @@ _scsih_target_alloc(struct scsi_target *starget)
 	/* sas/sata devices */
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	rphy = dev_to_rphy(starget->dev.parent);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	   rphy->identify.sas_address);
 
 	if (sas_device) {
 		sas_target_priv_data->handle = sas_device->handle;
 		sas_target_priv_data->sas_address = sas_device->sas_address;
+		sas_target_priv_data->sdev = sas_device;
 		sas_device->starget = starget;
 		sas_device->id = starget->id;
 		sas_device->channel = starget->channel;
@@ -1240,13 +1359,21 @@ _scsih_target_destroy(struct scsi_target *starget)
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	rphy = dev_to_rphy(starget->dev.parent);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-	   rphy->identify.sas_address);
+	sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
 	if (sas_device && (sas_device->starget == starget) &&
 	    (sas_device->id == starget->id) &&
 	    (sas_device->channel == starget->channel))
 		sas_device->starget = NULL;
 
+	if (sas_device) {
+		/*
+		 * Corresponding get() is in _scsih_target_alloc()
+		 */
+		sas_target_priv_data->sdev = NULL;
+		sas_device_put(sas_device);
+
+		sas_device_put(sas_device);
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
  out:
@@ -1302,7 +1429,7 @@ _scsih_slave_alloc(struct scsi_device *sdev)
 
 	if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+		sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 					sas_target_priv_data->sas_address);
 		if (sas_device && (sas_device->starget == NULL)) {
 			sdev_printk(KERN_INFO, sdev,
@@ -1310,6 +1437,10 @@ _scsih_slave_alloc(struct scsi_device *sdev)
 				__func__, __LINE__);
 			sas_device->starget = starget;
 		}
+
+		if (sas_device)
+			sas_device_put(sas_device);
+
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	}
 
@@ -1344,10 +1475,14 @@ _scsih_slave_destroy(struct scsi_device *sdev)
 
 	if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-		   sas_target_priv_data->sas_address);
+		sas_device = __mpt3sas_get_sdev_from_target(ioc,
+				sas_target_priv_data);
 		if (sas_device && !sas_target_priv_data->num_luns)
 			sas_device->starget = NULL;
+
+		if (sas_device)
+			sas_device_put(sas_device);
+
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	}
 
@@ -1783,7 +1918,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
 	}
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	   sas_device_priv_data->sas_target->sas_address);
 	if (!sas_device) {
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
@@ -1823,12 +1958,12 @@ _scsih_slave_configure(struct scsi_device *sdev)
 		     ds, sas_device->enclosure_level,
 		     sas_device->connector_name);
 
+	sas_device_put(sas_device);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
 	if (!ssp_target)
 		_scsih_display_sata_capabilities(ioc, handle, sdev);
 
-
 	_scsih_change_queue_depth(sdev, qdepth);
 
 	if (ssp_target) {
@@ -2219,8 +2354,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
 		    device_str, (unsigned long long)priv_target->sas_address);
 	} else {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-		    priv_target->sas_address);
+		sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
 		if (sas_device) {
 			if (priv_target->flags &
 			    MPT_TARGET_FLAGS_RAID_COMPONENT) {
@@ -2246,8 +2380,9 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
 				"enclosure level(0x%04x),connector name(%s)\n",
 				 sas_device->enclosure_level,
 				 sas_device->connector_name);
+
+			sas_device_put(sas_device);
 		}
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	}
 }
 
@@ -2321,10 +2456,11 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
 {
 	struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
-	struct _sas_device *sas_device;
-	unsigned long flags;
+	struct _sas_device *sas_device = NULL;
 	u16	handle;
 	int r;
+	struct scsi_target *starget = scmd->device->sdev_target;
+	struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
 
 	sdev_printk(KERN_INFO, scmd->device,
 		"attempting device reset! scmd(%p)\n", scmd);
@@ -2344,12 +2480,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
 	handle = 0;
 	if (sas_device_priv_data->sas_target->flags &
 	    MPT_TARGET_FLAGS_RAID_COMPONENT) {
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = _scsih_sas_device_find_by_handle(ioc,
-		   sas_device_priv_data->sas_target->handle);
+		sas_device = mpt3sas_get_sdev_from_target(ioc,
+				target_priv_data);
 		if (sas_device)
 			handle = sas_device->volume_handle;
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	} else
 		handle = sas_device_priv_data->sas_target->handle;
 
@@ -2366,6 +2500,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
  out:
 	sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
 	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+
+	if (sas_device)
+		sas_device_put(sas_device);
+
 	return r;
 }
 
@@ -2380,11 +2518,11 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
 {
 	struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
-	struct _sas_device *sas_device;
-	unsigned long flags;
+	struct _sas_device *sas_device = NULL;
 	u16	handle;
 	int r;
 	struct scsi_target *starget = scmd->device->sdev_target;
+	struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
 
 	starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n",
 		scmd);
@@ -2404,12 +2542,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
 	handle = 0;
 	if (sas_device_priv_data->sas_target->flags &
 	    MPT_TARGET_FLAGS_RAID_COMPONENT) {
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = _scsih_sas_device_find_by_handle(ioc,
-		   sas_device_priv_data->sas_target->handle);
+		sas_device = mpt3sas_get_sdev_from_target(ioc,
+				target_priv_data);
 		if (sas_device)
 			handle = sas_device->volume_handle;
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	} else
 		handle = sas_device_priv_data->sas_target->handle;
 
@@ -2426,6 +2562,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
  out:
 	starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
 	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+
+	if (sas_device)
+		sas_device_put(sas_device);
+
 	return r;
 }
 
@@ -2483,32 +2623,36 @@ _scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 		return;
 
 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
+	fw_event_work_get(fw_event);
 	INIT_LIST_HEAD(&fw_event->list);
 	list_add_tail(&fw_event->list, &ioc->fw_event_list);
 	INIT_WORK(&fw_event->work, _firmware_event_work);
+	fw_event_work_get(fw_event);
 	queue_work(ioc->firmware_event_thread, &fw_event->work);
 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 }
 
 /**
- * _scsih_fw_event_free - delete fw_event
+ * _scsih_fw_event_del_from_list - delete fw_event from the list
  * @ioc: per adapter object
  * @fw_event: object describing the event
  * Context: This function will acquire ioc->fw_event_lock.
  *
- * This removes firmware event object from link list, frees associated memory.
+ * If the fw_event is on the fw_event_list, remove it and do a put.
  *
  * Return nothing.
  */
 static void
-_scsih_fw_event_free(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
+_scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
 	*fw_event)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
-	list_del(&fw_event->list);
-	kfree(fw_event);
+	if (!list_empty(&fw_event->list)) {
+		list_del_init(&fw_event->list);
+		fw_event_work_put(fw_event);
+	}
 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 }
 
@@ -2528,14 +2672,14 @@ mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc,
 
 	if (ioc->is_driver_loading)
 		return;
-	fw_event = kzalloc(sizeof(*fw_event) + sizeof(*event_data),
-			   GFP_ATOMIC);
+	fw_event = alloc_fw_event_work(sizeof(*event_data));
 	if (!fw_event)
 		return;
 	fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG;
 	fw_event->ioc = ioc;
 	memcpy(fw_event->event_data, event_data, sizeof(*event_data));
 	_scsih_fw_event_add(ioc, fw_event);
+	fw_event_work_put(fw_event);
 }
 
 /**
@@ -2551,12 +2695,13 @@ _scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc)
 
 	if (ioc->is_driver_loading)
 		return;
-	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+	fw_event = alloc_fw_event_work(0);
 	if (!fw_event)
 		return;
 	fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES;
 	fw_event->ioc = ioc;
 	_scsih_fw_event_add(ioc, fw_event);
+	fw_event_work_put(fw_event);
 }
 
 /**
@@ -2570,12 +2715,29 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc)
 {
 	struct fw_event_work *fw_event;
 
-	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+	fw_event = alloc_fw_event_work(0);
 	if (!fw_event)
 		return;
 	fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE;
 	fw_event->ioc = ioc;
 	_scsih_fw_event_add(ioc, fw_event);
+	fw_event_work_put(fw_event);
+}
+
+static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc)
+{
+	unsigned long flags;
+	struct fw_event_work *fw_event = NULL;
+
+	spin_lock_irqsave(&ioc->fw_event_lock, flags);
+	if (!list_empty(&ioc->fw_event_list)) {
+		fw_event = list_first_entry(&ioc->fw_event_list,
+				struct fw_event_work, list);
+		list_del_init(&fw_event->list);
+	}
+	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
+
+	return fw_event;
 }
 
 /**
@@ -2590,17 +2752,25 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc)
 static void
 _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc)
 {
-	struct fw_event_work *fw_event, *next;
+	struct fw_event_work *fw_event;
 
 	if (list_empty(&ioc->fw_event_list) ||
 	     !ioc->firmware_event_thread || in_interrupt())
 		return;
 
-	list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
-		if (cancel_delayed_work_sync(&fw_event->delayed_work)) {
-			_scsih_fw_event_free(ioc, fw_event);
-			continue;
-		}
+	while ((fw_event = dequeue_next_fw_event(ioc))) {
+		/*
+		 * Wait on the fw_event to complete. If this returns 1, then
+		 * the event was never executed, and we need a put for the
+		 * reference the delayed_work had on the fw_event.
+		 *
+		 * If it did execute, we wait for it to finish, and the put will
+		 * happen from _firmware_event_work()
+		 */
+		if (cancel_work_sync(&fw_event->work))
+			fw_event_work_put(fw_event);
+
+		fw_event_work_put(fw_event);
 	}
 }
 
@@ -2763,7 +2933,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	struct scsi_device *sdev;
 	struct _sas_device *sas_device;
 
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (!sas_device)
 		return;
 
@@ -2779,6 +2949,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 			continue;
 		_scsih_internal_device_block(sdev, sas_device_priv_data);
 	}
+
+	sas_device_put(sas_device);
 }
 
 /**
@@ -2804,15 +2976,15 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc,
 
 	list_for_each_entry(mpt3sas_port,
 	   &sas_expander->sas_port_list, port_list) {
-		if (mpt3sas_port->remote_identify.device_type ==
-		    SAS_END_DEVICE) {
+		if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
 			spin_lock_irqsave(&ioc->sas_device_lock, flags);
-			sas_device =
-			    mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-			   mpt3sas_port->remote_identify.sas_address);
-			if (sas_device)
+			sas_device = __mpt3sas_get_sdev_by_addr(ioc,
+					mpt3sas_port->remote_identify.sas_address);
+			if (sas_device) {
 				set_bit(sas_device->handle,
-				    ioc->blocking_handles);
+					ioc->blocking_handles);
+				sas_device_put(sas_device);
+			}
 			spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 		}
 	}
@@ -2880,7 +3052,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
 	Mpi2SCSITaskManagementRequest_t *mpi_request;
 	u16 smid;
-	struct _sas_device *sas_device;
+	struct _sas_device *sas_device = NULL;
 	struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
 	u64 sas_address = 0;
 	unsigned long flags;
@@ -2913,7 +3085,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 		return;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (sas_device && sas_device->starget &&
 	    sas_device->starget->hostdata) {
 		sas_target_priv_data = sas_device->starget->hostdata;
@@ -2947,14 +3119,14 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	if (!smid) {
 		delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
 		if (!delayed_tr)
-			return;
+			goto out;
 		INIT_LIST_HEAD(&delayed_tr->list);
 		delayed_tr->handle = handle;
 		list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
 		dewtprintk(ioc, pr_info(MPT3SAS_FMT
 		    "DELAYED:tr:handle(0x%04x), (open)\n",
 		    ioc->name, handle));
-		return;
+		goto out;
 	}
 
 	dewtprintk(ioc, pr_info(MPT3SAS_FMT
@@ -2968,6 +3140,9 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
 	mpt3sas_base_put_smid_hi_priority(ioc, smid);
 	mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
+out:
+	if (sas_device)
+		sas_device_put(sas_device);
 }
 
 /**
@@ -3818,7 +3993,6 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	char *desc_scsi_state = ioc->tmp_string;
 	u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
 	struct _sas_device *sas_device = NULL;
-	unsigned long flags;
 	struct scsi_target *starget = scmd->device->sdev_target;
 	struct MPT3SAS_TARGET *priv_target = starget->hostdata;
 	char *device_str = NULL;
@@ -3946,9 +4120,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 		pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
 		    device_str, (unsigned long long)priv_target->sas_address);
 	} else {
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-		    priv_target->sas_address);
+		sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
 		if (sas_device) {
 			pr_warn(MPT3SAS_FMT
 				"\tsas_address(0x%016llx), phy(%d)\n",
@@ -3967,8 +4139,9 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 				  " connector name( %s)\n", ioc->name,
 				  sas_device->enclosure_level,
 				  sas_device->connector_name);
+
+			sas_device_put(sas_device);
 		}
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	}
 
 	pr_warn(MPT3SAS_FMT
@@ -4020,7 +4193,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	Mpi2SepRequest_t mpi_request;
 	struct _sas_device *sas_device;
 
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (!sas_device)
 		return;
 
@@ -4035,7 +4208,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	    &mpi_request)) != 0) {
 		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
 		__FILE__, __LINE__, __func__);
-		return;
+		goto out;
 	}
 	sas_device->pfa_led_on = 1;
 
@@ -4044,8 +4217,10 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 			"enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
 			ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
 		    le32_to_cpu(mpi_reply.IOCLogInfo)));
-		return;
+		goto out;
 	}
+out:
+	sas_device_put(sas_device);
 }
 /**
  * _scsih_turn_off_pfa_led - turn off Fault LED
@@ -4098,13 +4273,14 @@ _scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
 	struct fw_event_work *fw_event;
 
-	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+	fw_event = alloc_fw_event_work(0);
 	if (!fw_event)
 		return;
 	fw_event->event = MPT3SAS_TURN_ON_PFA_LED;
 	fw_event->device_handle = handle;
 	fw_event->ioc = ioc;
 	_scsih_fw_event_add(ioc, fw_event);
+	fw_event_work_put(fw_event);
 }
 
 /**
@@ -4128,19 +4304,17 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 
 	/* only handle non-raid devices */
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
+		goto out_unlock;
 	}
 	starget = sas_device->starget;
 	sas_target_priv_data = starget->hostdata;
 
 	if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
-	   ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
-	}
+	   ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)))
+		goto out_unlock;
+
 	if (sas_device->enclosure_handle != 0)
 		starget_printk(KERN_INFO, starget, "predicted fault, "
 			"enclosure logical id(0x%016llx), slot(%d)\n",
@@ -4163,7 +4337,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	if (!event_reply) {
 		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
-		return;
+		goto out;
 	}
 
 	event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
@@ -4180,6 +4354,14 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
 	mpt3sas_ctl_add_to_event_log(ioc, event_reply);
 	kfree(event_reply);
+out:
+	if (sas_device)
+		sas_device_put(sas_device);
+	return;
+
+out_unlock:
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	goto out;
 }
 
 /**
@@ -4933,13 +5115,11 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	    sas_address);
 
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
-	}
+	if (!sas_device)
+		goto out_unlock;
 
 	if (unlikely(sas_device->handle != handle)) {
 		starget = sas_device->starget;
@@ -4967,20 +5147,24 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
 		pr_err(MPT3SAS_FMT
 			"device is not present handle(0x%04x), flags!!!\n",
 			ioc->name, handle);
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
+		goto out_unlock;
 	}
 
 	/* check if there were any issues with discovery */
 	if (_scsih_check_access_status(ioc, sas_address, handle,
-	    sas_device_pg0.AccessStatus)) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
-	}
+	    sas_device_pg0.AccessStatus))
+		goto out_unlock;
 
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	_scsih_ublock_io_device(ioc, sas_address);
+	if (sas_device)
+		sas_device_put(sas_device);
+	return;
 
+out_unlock:
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	if (sas_device)
+		sas_device_put(sas_device);
 }
 
 /**
@@ -5005,7 +5189,6 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
 	u32 ioc_status;
 	u64 sas_address;
 	u32 device_info;
-	unsigned long flags;
 
 	if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
 	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
@@ -5041,13 +5224,11 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
 	    sas_device_pg0.AccessStatus))
 		return -1;
 
-	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-	    sas_address);
-	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
-	if (sas_device)
+	sas_device = mpt3sas_get_sdev_by_addr(ioc, sas_address);
+	if (sas_device) {
+		sas_device_put(sas_device);
 		return -1;
+	}
 
 	sas_device = kzalloc(sizeof(struct _sas_device),
 	    GFP_KERNEL);
@@ -5057,6 +5238,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
 		return 0;
 	}
 
+	kref_init(&sas_device->refcount);
 	sas_device->handle = handle;
 	if (_scsih_get_sas_address(ioc,
 	    le16_to_cpu(sas_device_pg0.ParentDevHandle),
@@ -5098,6 +5280,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
 	else
 		_scsih_sas_device_add(ioc, sas_device);
 
+	sas_device_put(sas_device);
 	return 0;
 }
 
@@ -5506,25 +5689,25 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_address = le64_to_cpu(event_data->SASAddress);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
-	    sas_address);
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address);
 
-	if (!sas_device || !sas_device->starget) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
-	}
+	if (!sas_device || !sas_device->starget)
+		goto out;
 
 	target_priv_data = sas_device->starget->hostdata;
-	if (!target_priv_data) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		return;
-	}
+	if (!target_priv_data)
+		goto out;
 
 	if (event_data->ReasonCode ==
 	    MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
 		target_priv_data->tm_busy = 1;
 	else
 		target_priv_data->tm_busy = 0;
+
+out:
+	if (sas_device)
+		sas_device_put(sas_device);
+
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 }
 
@@ -6008,7 +6191,7 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc,
 	u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (sas_device) {
 		sas_device->volume_handle = 0;
 		sas_device->volume_wwid = 0;
@@ -6027,6 +6210,8 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc,
 	/* exposing raid component */
 	if (starget)
 		starget_for_each_device(starget, NULL, _scsih_reprobe_lun);
+
+	sas_device_put(sas_device);
 }
 
 /**
@@ -6055,7 +6240,7 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
 		    &volume_wwid);
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+	sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (sas_device) {
 		set_bit(handle, ioc->pd_handles);
 		if (sas_device->starget && sas_device->starget->hostdata) {
@@ -6075,6 +6260,8 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc,
 	_scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
 	if (starget)
 		starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun);
+
+	sas_device_put(sas_device);
 }
 
 /**
@@ -6107,7 +6294,6 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
 	Mpi2EventIrConfigElement_t *element)
 {
 	struct _sas_device *sas_device;
-	unsigned long flags;
 	u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasDevicePage0_t sas_device_pg0;
@@ -6117,11 +6303,10 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc,
 
 	set_bit(handle, ioc->pd_handles);
 
-	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
 	if (sas_device) {
 		_scsih_ir_fastpath(ioc, handle, element->PhysDiskNum);
+		sas_device_put(sas_device);
 		return;
 	}
 
@@ -6398,7 +6583,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
 	u16 handle, parent_handle;
 	u32 state;
 	struct _sas_device *sas_device;
-	unsigned long flags;
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasDevicePage0_t sas_device_pg0;
 	u32 ioc_status;
@@ -6427,12 +6611,12 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
 	case MPI2_RAID_PD_STATE_HOT_SPARE:
 
 		set_bit(handle, ioc->pd_handles);
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-		if (sas_device)
+		sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
+		if (sas_device) {
+			sas_device_put(sas_device);
 			return;
+		}
 
 		if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
 		    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
@@ -6906,6 +7090,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
 	struct _raid_device *raid_device, *raid_device_next;
 	struct list_head tmp_list;
 	unsigned long flags;
+	LIST_HEAD(head);
 
 	pr_info(MPT3SAS_FMT "removing unresponding devices: start\n",
 	    ioc->name);
@@ -6913,14 +7098,29 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
 	/* removing unresponding end devices */
 	pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n",
 	    ioc->name);
+
+	/*
+	 * Iterate, pulling off devices marked as non-responding. We become the
+	 * owner for the reference the list had on any object we prune.
+	 */
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	list_for_each_entry_safe(sas_device, sas_device_next,
-	    &ioc->sas_device_list, list) {
+				 &ioc->sas_device_list, list) {
 		if (!sas_device->responding)
-			mpt3sas_device_remove_by_sas_address(ioc,
-			    sas_device->sas_address);
+			list_move_tail(&sas_device->list, &head);
 		else
 			sas_device->responding = 0;
 	}
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	/*
+	 * Now, uninitialize and remove the unresponding devices we pruned.
+	 */
+	list_for_each_entry_safe(sas_device, sas_device_next, &head, list) {
+		_scsih_remove_device(ioc, sas_device);
+		list_del_init(&sas_device->list);
+		sas_device_put(sas_device);
+	}
 
 	/* removing unresponding volumes */
 	if (ioc->ir_firmware) {
@@ -7074,11 +7274,11 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
 		}
 		phys_disk_num = pd_pg0.PhysDiskNum;
 		handle = le16_to_cpu(pd_pg0.DevHandle);
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		if (sas_device)
+		sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
+		if (sas_device) {
+			sas_device_put(sas_device);
 			continue;
+		}
 		if (mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply,
 		    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
 		    handle) != 0)
@@ -7199,12 +7399,12 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
 		if (!(_scsih_is_end_device(
 		    le32_to_cpu(sas_device_pg0.DeviceInfo))))
 			continue;
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+		sas_device = mpt3sas_get_sdev_by_addr(ioc,
 		    le64_to_cpu(sas_device_pg0.SASAddress));
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		if (sas_device)
+		if (sas_device) {
+			sas_device_put(sas_device);
 			continue;
+		}
 		parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
 		if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
 			pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \
@@ -7296,10 +7496,11 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
 static void
 _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 {
+	_scsih_fw_event_del_from_list(ioc, fw_event);
+
 	/* the queue is being flushed so ignore this event */
-	if (ioc->remove_host ||
-	    ioc->pci_error_recovery) {
-		_scsih_fw_event_free(ioc, fw_event);
+	if (ioc->remove_host || ioc->pci_error_recovery) {
+		fw_event_work_put(fw_event);
 		return;
 	}
 
@@ -7310,8 +7511,17 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 			fw_event->event_data);
 		break;
 	case MPT3SAS_REMOVE_UNRESPONDING_DEVICES:
-		while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery)
+		while (scsi_host_in_recovery(ioc->shost) ||
+				ioc->shost_recovery) {
+			/*
+			 * If we're unloading, bail. Otherwise, this can become
+			 * an infinite loop.
+			 */
+			if (ioc->remove_host)
+				goto out;
+
 			ssleep(1);
+		}
 		_scsih_remove_unresponding_sas_devices(ioc);
 		_scsih_scan_for_devices_after_reset(ioc);
 		break;
@@ -7356,7 +7566,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 		_scsih_sas_ir_operation_status_event(ioc, fw_event);
 		break;
 	}
-	_scsih_fw_event_free(ioc, fw_event);
+out:
+	fw_event_work_put(fw_event);
 }
 
 /**
@@ -7472,7 +7683,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
 	}
 
 	sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
-	fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC);
+	fw_event = alloc_fw_event_work(sz);
 	if (!fw_event) {
 		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
@@ -7485,6 +7696,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
 	fw_event->VP_ID = mpi_reply->VP_ID;
 	fw_event->event = event;
 	_scsih_fw_event_add(ioc, fw_event);
+	fw_event_work_put(fw_event);
 	return 1;
 }
 
@@ -7831,6 +8043,48 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc)
 	}
 }
 
+static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc)
+{
+	struct _sas_device *sas_device = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	if (!list_empty(&ioc->sas_device_init_list)) {
+		sas_device = list_first_entry(&ioc->sas_device_init_list,
+				struct _sas_device, list);
+		sas_device_get(sas_device);
+	}
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	return sas_device;
+}
+
+static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc,
+		struct _sas_device *sas_device)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+
+	/*
+	 * Since we dropped the lock during the call to port_add(), we need to
+	 * be careful here that somebody else didn't move or delete this item
+	 * while we were busy with other things.
+	 *
+	 * If it was on the list, we need a put() for the reference the list
+	 * had. Either way, we need a get() for the destination list.
+	 */
+	if (!list_empty(&sas_device->list)) {
+		list_del_init(&sas_device->list);
+		sas_device_put(sas_device);
+	}
+
+	sas_device_get(sas_device);
+	list_add_tail(&sas_device->list, &ioc->sas_device_list);
+
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+}
+
 /**
  * _scsih_probe_sas - reporting sas devices to sas transport
  * @ioc: per adapter object
@@ -7840,17 +8094,13 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc)
 static void
 _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
 {
-	struct _sas_device *sas_device, *next;
-	unsigned long flags;
-
-	/* SAS Device List */
-	list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
-	    list) {
+	struct _sas_device *sas_device;
 
+	while ((sas_device = get_next_sas_device(ioc))) {
 		if (!mpt3sas_transport_port_add(ioc, sas_device->handle,
-		    sas_device->sas_address_parent)) {
-			list_del(&sas_device->list);
-			kfree(sas_device);
+				sas_device->sas_address_parent)) {
+			_scsih_sas_device_remove(ioc, sas_device);
+			sas_device_put(sas_device);
 			continue;
 		} else if (!sas_device->starget) {
 			/*
@@ -7861,17 +8111,16 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
 			 */
 			if (!ioc->is_driver_loading) {
 				mpt3sas_transport_port_remove(ioc,
-				    sas_device->sas_address,
-				    sas_device->sas_address_parent);
-				list_del(&sas_device->list);
-				kfree(sas_device);
+						sas_device->sas_address,
+						sas_device->sas_address_parent);
+				_scsih_sas_device_remove(ioc, sas_device);
+				sas_device_put(sas_device);
 				continue;
 			}
 		}
 
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		list_move_tail(&sas_device->list, &ioc->sas_device_list);
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+		sas_device_make_active(ioc, sas_device);
+		sas_device_put(sas_device);
 	}
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 70fd019e7ee5..ca36d7ea0964 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -734,7 +734,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 	rphy->identify = mpt3sas_port->remote_identify;
 
 	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
-		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+		sas_device = mpt3sas_get_sdev_by_addr(ioc,
 				    mpt3sas_port->remote_identify.sas_address);
 		if (!sas_device) {
 			dfailprintk(ioc, printk(MPT3SAS_FMT
@@ -750,8 +750,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 		    ioc->name, __FILE__, __LINE__, __func__);
 	}
 
-	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE)
+	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
 		sas_device->pend_sas_rphy_add = 0;
+		sas_device_put(sas_device);
+	}
 
 	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
 		dev_printk(KERN_INFO, &rphy->dev,
@@ -1324,15 +1326,17 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
 	int rc;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	    rphy->identify.sas_address);
 	if (sas_device) {
 		*identifier = sas_device->enclosure_logical_id;
 		rc = 0;
+		sas_device_put(sas_device);
 	} else {
 		*identifier = 0;
 		rc = -ENXIO;
 	}
+
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	return rc;
 }
@@ -1352,12 +1356,14 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
 	int rc;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	    rphy->identify.sas_address);
-	if (sas_device)
+	if (sas_device) {
 		rc = sas_device->slot;
-	else
+		sas_device_put(sas_device);
+	} else {
 		rc = -ENXIO;
+	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	return rc;
 }
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index 7dff08e2a071..6ce7f0d26dcf 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -99,15 +99,7 @@ static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
  */
 static inline void activate_irq(int irq)
 {
-#ifdef CONFIG_ARM
-	/* ARM requires an extra step to clear IRQ_NOREQUEST, which it
-	 * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
-	 */
-	set_irq_flags(irq, IRQF_VALID);
-#else
-	/* same effect on other architectures */
-	irq_set_noprobe(irq);
-#endif
+	irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE);
 }
 
 static inline int intc_handle_int_cmp(const void *a, const void *b)
diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
index d3d1891cda3c..25abd4eb7d10 100644
--- a/drivers/sh/pm_runtime.c
+++ b/drivers/sh/pm_runtime.c
@@ -35,20 +35,11 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
 static int __init sh_pm_runtime_init(void)
 {
 	if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) {
-		if (!of_machine_is_compatible("renesas,emev2") &&
-		    !of_machine_is_compatible("renesas,r7s72100") &&
-#ifndef CONFIG_PM_GENERIC_DOMAINS_OF
-		    !of_machine_is_compatible("renesas,r8a73a4") &&
-		    !of_machine_is_compatible("renesas,r8a7740") &&
-		    !of_machine_is_compatible("renesas,sh73a0") &&
-#endif
-		    !of_machine_is_compatible("renesas,r8a7778") &&
-		    !of_machine_is_compatible("renesas,r8a7779") &&
-		    !of_machine_is_compatible("renesas,r8a7790") &&
-		    !of_machine_is_compatible("renesas,r8a7791") &&
-		    !of_machine_is_compatible("renesas,r8a7792") &&
-		    !of_machine_is_compatible("renesas,r8a7793") &&
-		    !of_machine_is_compatible("renesas,r8a7794"))
+		if (!of_find_compatible_node(NULL, NULL,
+					     "renesas,cpg-mstp-clocks"))
+			return 0;
+		if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS_OF) &&
+		    of_find_node_with_property(NULL, "#power-domain-cells"))
 			return 0;
 	}
 
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index bf9ed380bb1c..63318e2afba1 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1720,6 +1720,7 @@ static int atmel_spi_runtime_resume(struct device *dev)
 	return clk_prepare_enable(as->clk);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int atmel_spi_suspend(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
@@ -1756,6 +1757,7 @@ static int atmel_spi_resume(struct device *dev)
 
 	return ret;
 }
+#endif
 
 static const struct dev_pm_ops atmel_spi_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(atmel_spi_suspend, atmel_spi_resume)
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index e7874a6171ec..3e8eeb23d4e9 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master,
 	/* otherwise we only allow transfers within the same page
 	 * to avoid wasting time on dma_mapping when it is not practical
 	 */
-	if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) {
+	if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
 		dev_warn_once(&spi->dev,
 			      "Unaligned spi tx-transfer bridging page\n");
 		return false;
 	}
-	if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) {
+	if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
 		dev_warn_once(&spi->dev,
-			      "Unaligned spi tx-transfer bridging page\n");
+			      "Unaligned spi rx-transfer bridging page\n");
 		return false;
 	}
 
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 5f6315c47920..26ec09b803c0 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -85,7 +85,7 @@ struct mtk_spi {
 	void __iomem *base;
 	u32 state;
 	u32 pad_sel;
-	struct clk *spi_clk, *parent_clk;
+	struct clk *parent_clk, *sel_clk, *spi_clk;
 	struct spi_transfer *cur_transfer;
 	u32 xfer_len;
 	struct scatterlist *tx_sgl, *rx_sgl;
@@ -173,22 +173,6 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 		writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG);
 }
 
-static int mtk_spi_prepare_hardware(struct spi_master *master)
-{
-	struct spi_transfer *trans;
-	struct mtk_spi *mdata = spi_master_get_devdata(master);
-	struct spi_message *msg = master->cur_msg;
-
-	trans = list_first_entry(&msg->transfers, struct spi_transfer,
-				 transfer_list);
-	if (!trans->cs_change) {
-		mdata->state = MTK_SPI_IDLE;
-		mtk_spi_reset(mdata);
-	}
-
-	return 0;
-}
-
 static int mtk_spi_prepare_message(struct spi_master *master,
 				   struct spi_message *msg)
 {
@@ -228,11 +212,15 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
 
 	reg_val = readl(mdata->base + SPI_CMD_REG);
-	if (!enable)
+	if (!enable) {
 		reg_val |= SPI_CMD_PAUSE_EN;
-	else
+		writel(reg_val, mdata->base + SPI_CMD_REG);
+	} else {
 		reg_val &= ~SPI_CMD_PAUSE_EN;
-	writel(reg_val, mdata->base + SPI_CMD_REG);
+		writel(reg_val, mdata->base + SPI_CMD_REG);
+		mdata->state = MTK_SPI_IDLE;
+		mtk_spi_reset(mdata);
+	}
 }
 
 static void mtk_spi_prepare_transfer(struct spi_master *master,
@@ -509,7 +497,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 
 	master->set_cs = mtk_spi_set_cs;
-	master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
 	master->prepare_message = mtk_spi_prepare_message;
 	master->transfer_one = mtk_spi_transfer_one;
 	master->can_dma = mtk_spi_can_dma;
@@ -576,17 +563,24 @@ static int mtk_spi_probe(struct platform_device *pdev)
 		goto err_put_master;
 	}
 
-	mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
-	if (IS_ERR(mdata->spi_clk)) {
+	mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
+	if (IS_ERR(mdata->parent_clk)) {
+		ret = PTR_ERR(mdata->parent_clk);
+		dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
+		goto err_put_master;
+	}
+
+	mdata->sel_clk = devm_clk_get(&pdev->dev, "sel-clk");
+	if (IS_ERR(mdata->sel_clk)) {
 		ret = PTR_ERR(mdata->spi_clk);
-		dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
+		dev_err(&pdev->dev, "failed to get sel-clk: %d\n", ret);
 		goto err_put_master;
 	}
 
-	mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
-	if (IS_ERR(mdata->parent_clk)) {
+	mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
+	if (IS_ERR(mdata->spi_clk)) {
 		ret = PTR_ERR(mdata->parent_clk);
-		dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
+		dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
 		goto err_put_master;
 	}
 
@@ -596,7 +590,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
 		goto err_put_master;
 	}
 
-	ret = clk_set_parent(mdata->spi_clk, mdata->parent_clk);
+	ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
 		goto err_disable_clk;
@@ -630,7 +624,6 @@ static int mtk_spi_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	mtk_spi_reset(mdata);
-	clk_disable_unprepare(mdata->spi_clk);
 	spi_master_put(master);
 
 	return 0;
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index fdd791977041..a8ef38ebb9c9 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -654,6 +654,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
 	if (!(sccr1_reg & SSCR1_TIE))
 		mask &= ~SSSR_TFS;
 
+	/* Ignore RX timeout interrupt if it is disabled */
+	if (!(sccr1_reg & SSCR1_TINTE))
+		mask &= ~SSSR_TINT;
+
 	if (!(status & mask))
 		return IRQ_NONE;
 
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 3abb3903f2ad..a5f53de813d3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1610,8 +1610,7 @@ static struct class spi_master_class = {
  *
  * The caller is responsible for assigning the bus number and initializing
  * the master's methods before calling spi_register_master(); and (after errors
- * adding the device) calling spi_master_put() and kfree() to prevent a memory
- * leak.
+ * adding the device) calling spi_master_put() to prevent a memory leak.
  */
 struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
 {
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index fba92a526531..ef008e52f953 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -651,7 +651,8 @@ static int spidev_release(struct inode *inode, struct file *filp)
 		kfree(spidev->rx_buffer);
 		spidev->rx_buffer = NULL;
 
-		spidev->speed_hz = spidev->spi->max_speed_hz;
+		if (spidev->spi)
+			spidev->speed_hz = spidev->spi->max_speed_hz;
 
 		/* ... after we unbound from the underlying device? */
 		spin_lock_irq(&spidev->spi_lock);
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 68307121c9c1..42b15126aa06 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -54,7 +54,7 @@ config SW_SYNC
 	depends on SYNC
 	---help---
 	  A sync object driver that uses a 32bit counter to coordinate
-	  syncrhronization.  Useful when there is no hardware primitive backing
+	  synchronization.  Useful when there is no hardware primitive backing
 	  the synchronization.
 
 config SW_SYNC_USER
diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO
index 20288fc53946..8f3ac37bfe12 100644
--- a/drivers/staging/android/TODO
+++ b/drivers/staging/android/TODO
@@ -5,5 +5,25 @@ TODO:
 	- add proper arch dependencies as needed
 	- audit userspace interfaces to make sure they are sane
 
+
+ion/
+ - Remove ION_IOC_SYNC: Flushing for devices should be purely a kernel internal
+   interface on top of dma-buf. flush_for_device needs to be added to dma-buf
+   first.
+ - Remove ION_IOC_CUSTOM: Atm used for cache flushing for cpu access in some
+   vendor trees. Should be replaced with an ioctl on the dma-buf to expose the
+   begin/end_cpu_access hooks to userspace.
+ - Clarify the tricks ion plays with explicitly managing coherency behind the
+   dma api's back (this is absolutely needed for high-perf gpu drivers): Add an
+   explicit coherency management mode to flush_for_device to be used by drivers
+   which want to manage caches themselves and which indicates whether cpu caches
+   need flushing.
+ - With those removed there's probably no use for ION_IOC_IMPORT anymore either
+   since ion would just be the central allocator for shared buffers.
+ - Add dt-binding to expose cma regions as ion heaps, with the rule that any
+   such cma regions must already be used by some device for dma. I.e. ion only
+   exposes existing cma regions and doesn't reserve unecessarily memory when
+   booting a system which doesn't use ion.
+
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
 Arve Hjønnevåg <arve@android.com> and Riley Andrews <riandrews@android.com>
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 60200a3da821..f9318003bd0b 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -311,10 +311,9 @@ static ssize_t ashmem_read(struct file *file, char __user *buf,
 	 * ashmem_release is called.
 	 */
 	ret = __vfs_read(asma->file, buf, len, pos);
-	if (ret >= 0) {
+	if (ret >= 0)
 		/** Update backing file pos, since f_ops->read() doesn't */
 		asma->file->f_pos = *pos;
-	}
 	return ret;
 
 out_unlock:
@@ -618,7 +617,8 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend)
 
 			/* Case #3: We overlap from the rear, so adjust it */
 			if (range->pgend <= pgend) {
-				range_shrink(range, range->pgstart, pgstart-1);
+				range_shrink(range, range->pgstart,
+					     pgstart - 1);
 				continue;
 			}
 
@@ -715,7 +715,7 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
 	if (unlikely((pin.offset | pin.len) & ~PAGE_MASK))
 		return -EINVAL;
 
-	if (unlikely(((__u32) -1) - pin.offset < pin.len))
+	if (unlikely(((__u32)-1) - pin.offset < pin.len))
 		return -EINVAL;
 
 	if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len))
@@ -759,7 +759,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		ret = -EINVAL;
 		if (!asma->file) {
 			ret = 0;
-			asma->size = (size_t) arg;
+			asma->size = (size_t)arg;
 		}
 		break;
 	case ASHMEM_GET_SIZE:
@@ -833,16 +833,16 @@ static int __init ashmem_init(void)
 	int ret;
 
 	ashmem_area_cachep = kmem_cache_create("ashmem_area_cache",
-					  sizeof(struct ashmem_area),
-					  0, 0, NULL);
+					       sizeof(struct ashmem_area),
+					       0, 0, NULL);
 	if (unlikely(!ashmem_area_cachep)) {
 		pr_err("failed to create slab cache\n");
 		return -ENOMEM;
 	}
 
 	ashmem_range_cachep = kmem_cache_create("ashmem_range_cache",
-					  sizeof(struct ashmem_range),
-					  0, 0, NULL);
+						sizeof(struct ashmem_range),
+						0, 0, NULL);
 	if (unlikely(!ashmem_range_cachep)) {
 		pr_err("failed to create slab cache\n");
 		return -ENOMEM;
diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c
index c90838d36953..29b5c3567180 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -145,7 +145,7 @@ static int sw_sync_open(struct inode *inode, struct file *file)
 	get_task_comm(task_comm, current);
 
 	obj = sw_sync_timeline_create(task_comm);
-	if (obj == NULL)
+	if (!obj)
 		return -ENOMEM;
 
 	file->private_data = obj;
@@ -179,14 +179,14 @@ static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj,
 	}
 
 	pt = sw_sync_pt_create(obj, data.value);
-	if (pt == NULL) {
+	if (!pt) {
 		err = -ENOMEM;
 		goto err;
 	}
 
 	data.name[sizeof(data.name) - 1] = '\0';
 	fence = sync_fence_create(data.name, pt);
-	if (fence == NULL) {
+	if (!fence) {
 		sync_pt_free(pt);
 		err = -ENOMEM;
 		goto err;
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 57e71f9f14a2..682987eaf6e4 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -400,14 +400,6 @@ config COMEDI_DMM32AT
 	  To compile this driver as a module, choose M here: the module will be
 	  called dmm32at.
 
-config COMEDI_UNIOXX5
-	tristate "Fastwel UNIOxx-5 analog and digital io board support"
-	---help---
-	  Enable support for Fastwel UNIOxx-5 (analog and digital i/o) boards
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called unioxx5.
-
 config COMEDI_FL512
 	tristate "FL512 ISA card support"
 	---help---
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 5764dc9a6893..c3b8f2d7611b 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -90,7 +90,6 @@ obj-$(CONFIG_COMEDI_CONTEC_PCI_DIO)	+= contec_pci_dio.o
 obj-$(CONFIG_COMEDI_DAS08_PCI)		+= das08_pci.o
 obj-$(CONFIG_COMEDI_DT3000)		+= dt3000.o
 obj-$(CONFIG_COMEDI_DYNA_PCI10XX)	+= dyna_pci10xx.o
-obj-$(CONFIG_COMEDI_UNIOXX5)		+= unioxx5.o
 obj-$(CONFIG_COMEDI_GSC_HPDI)		+= gsc_hpdi.o
 obj-$(CONFIG_COMEDI_ICP_MULTI)		+= icp_multi.o
 obj-$(CONFIG_COMEDI_DAQBOARD2000)	+= daqboard2000.o
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 5bfd43d5c889..651b39319a3f 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -502,11 +502,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d)
 	if (int_amcc & TARGET_ABORT_INT)
 		dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
 
-	if ((status & APCI3120_STATUS_EOC_INT) == 0 &&
-	    (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) {
-		/* nothing to do... EOC mode is not currently used */
-	}
-
 	if ((status & APCI3120_STATUS_EOS_INT) &&
 	    (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
 		unsigned short val;
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index 0207b8edfcb4..8e9204150eb7 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -66,24 +66,24 @@ Configuration Options:
 #define MPC624_IRQ_MASK         6 /* IRQ masking enable/disable */
 
 /* Register bits' names */
-#define MPC624_ADBUSY           (1<<5)
-#define MPC624_ADSDO            (1<<4)
-#define MPC624_ADFO             (1<<3)
-#define MPC624_ADCS             (1<<2)
-#define MPC624_ADSCK            (1<<1)
-#define MPC624_ADSDI            (1<<0)
+#define MPC624_ADBUSY           BIT(5)
+#define MPC624_ADSDO            BIT(4)
+#define MPC624_ADFO             BIT(3)
+#define MPC624_ADCS             BIT(2)
+#define MPC624_ADSCK            BIT(1)
+#define MPC624_ADSDI            BIT(0)
 
 /* SDI Speed/Resolution Programming bits */
-#define MPC624_OSR4             (1<<31)
-#define MPC624_OSR3             (1<<30)
-#define MPC624_OSR2             (1<<29)
-#define MPC624_OSR1             (1<<28)
-#define MPC624_OSR0             (1<<27)
+#define MPC624_OSR4             BIT(31)
+#define MPC624_OSR3             BIT(30)
+#define MPC624_OSR2             BIT(29)
+#define MPC624_OSR1             BIT(28)
+#define MPC624_OSR0             BIT(27)
 
 /* 32-bit output value bits' names */
-#define MPC624_EOC_BIT          (1<<31)
-#define MPC624_DMY_BIT          (1<<30)
-#define MPC624_SGN_BIT          (1<<29)
+#define MPC624_EOC_BIT          BIT(31)
+#define MPC624_DMY_BIT          BIT(30)
+#define MPC624_SGN_BIT          BIT(29)
 
 /* Conversion speeds */
 /* OSR4 OSR3 OSR2 OSR1 OSR0  Conversion rate  RMS noise  ENOB^
@@ -189,7 +189,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
 			outb(0, dev->iobase + MPC624_ADC);
 			udelay(1);
 
-			if (data_out & (1 << 31)) { /*  the next bit is a 1 */
+			if (data_out & BIT(31)) { /*  the next bit is a 1 */
 				/*  Set the ADSDI line (send to MPC624) */
 				outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
 				udelay(1);
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index 6f3e8a08e75c..d70c97947627 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -1,79 +1,96 @@
 /*
-    comedi/drivers/s526.c
-    Sensoray s526 Comedi driver
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.
-*/
-/*
-Driver: s526
-Description: Sensoray 526 driver
-Devices: [Sensoray] 526 (s526)
-Author: Richie
-	Everett Wang <everett.wang@everteq.com>
-Updated: Thu, 14 Sep. 2006
-Status: experimental
-
-Encoder works
-Analog input works
-Analog output works
-PWM output works
-Commands are not supported yet.
-
-Configuration Options:
+ * s526.c
+ * Sensoray s526 Comedi driver
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
 
-comedi_config /dev/comedi0 s526 0x2C0,0x3
-
-*/
+/*
+ * Driver: s526
+ * Description: Sensoray 526 driver
+ * Devices: [Sensoray] 526 (s526)
+ * Author: Richie
+ *	   Everett Wang <everett.wang@everteq.com>
+ * Updated: Thu, 14 Sep. 2006
+ * Status: experimental
+ *
+ * Encoder works
+ * Analog input works
+ * Analog output works
+ * PWM output works
+ * Commands are not supported yet.
+ *
+ * Configuration Options:
+ *   [0] - I/O port base address
+ */
 
 #include <linux/module.h>
 #include "../comedidev.h"
 #include <asm/byteorder.h>
 
-#define S526_START_AI_CONV	0
-#define S526_AI_READ		0
-
-/* Ports */
-#define S526_NUM_PORTS 27
-
-/* registers */
-#define REG_TCR 0x00
-#define REG_WDC 0x02
-#define REG_DAC 0x04
-#define REG_ADC 0x06
-#define REG_ADD 0x08
-#define REG_DIO 0x0A
-#define REG_IER 0x0C
-#define REG_ISR 0x0E
-#define REG_MSC 0x10
-#define REG_C0L 0x12
-#define REG_C0H 0x14
-#define REG_C0M 0x16
-#define REG_C0C 0x18
-#define REG_C1L 0x1A
-#define REG_C1H 0x1C
-#define REG_C1M 0x1E
-#define REG_C1C 0x20
-#define REG_C2L 0x22
-#define REG_C2H 0x24
-#define REG_C2M 0x26
-#define REG_C2C 0x28
-#define REG_C3L 0x2A
-#define REG_C3H 0x2C
-#define REG_C3M 0x2E
-#define REG_C3C 0x30
-#define REG_EED 0x32
-#define REG_EEC 0x34
+/*
+ * Register I/O map
+ */
+#define S526_TIMER_REG		0x00
+#define S526_TIMER_LOAD(x)	(((x) & 0xff) << 8)
+#define S526_TIMER_MODE		((x) << 1)
+#define S526_TIMER_MANUAL	S526_TIMER_MODE(0)
+#define S526_TIMER_AUTO		S526_TIMER_MODE(1)
+#define S526_TIMER_RESTART	BIT(0)
+#define S526_WDOG_REG		0x02
+#define S526_WDOG_INVERTED	BIT(4)
+#define S526_WDOG_ENA		BIT(3)
+#define S526_WDOG_INTERVAL(x)	(((x) & 0x7) << 0)
+#define S526_AO_CTRL_REG	0x04
+#define S526_AO_CTRL_RESET	BIT(3)
+#define S526_AO_CTRL_CHAN(x)	(((x) & 0x3) << 1)
+#define S526_AO_CTRL_START	BIT(0)
+#define S526_AI_CTRL_REG	0x06
+#define S526_AI_CTRL_DELAY	BIT(15)
+#define S526_AI_CTRL_CONV(x)	(1 << (5 + ((x) & 0x9)))
+#define S526_AI_CTRL_READ(x)	(((x) & 0xf) << 1)
+#define S526_AI_CTRL_START	BIT(0)
+#define S526_AO_REG		0x08
+#define S526_AI_REG		0x08
+#define S526_DIO_CTRL_REG	0x0a
+#define S526_DIO_CTRL_DIO3_NEG	BIT(15)	/* irq on DIO3 neg/pos edge */
+#define S526_DIO_CTRL_DIO2_NEG	BIT(14)	/* irq on DIO2 neg/pos edge */
+#define S526_DIO_CTRL_DIO1_NEG	BIT(13)	/* irq on DIO1 neg/pos edge */
+#define S526_DIO_CTRL_DIO0_NEG	BIT(12)	/* irq on DIO0 neg/pos edge */
+#define S526_DIO_CTRL_GRP2_OUT	BIT(11)
+#define S526_DIO_CTRL_GRP1_OUT	BIT(10)
+#define S526_DIO_CTRL_GRP2_NEG	BIT(8)	/* irq on DIO[4-7] neg/pos edge */
+#define S526_INT_ENA_REG	0x0c
+#define S526_INT_STATUS_REG	0x0e
+#define S526_INT_DIO(x)		BIT(8 + ((x) & 0x7))
+#define S526_INT_EEPROM		BIT(7)	/* status only */
+#define S526_INT_CNTR(x)	BIT(3 + (3 - ((x) & 0x3)))
+#define S526_INT_AI		BIT(2)
+#define S526_INT_AO		BIT(1)
+#define S526_INT_TIMER		BIT(0)
+#define S526_MISC_REG		0x10
+#define S526_MISC_LED_OFF	BIT(0)
+#define S526_GPCT_LSB_REG(x)	(0x12 + ((x) * 8))
+#define S526_GPCT_MSB_REG(x)	(0x14 + ((x) * 8))
+#define S526_GPCT_MODE_REG(x)	(0x16 + ((x) * 8))
+#define S526_GPCT_CTRL_REG(x)	(0x18 + ((x) * 8))
+#define S526_EEPROM_DATA_REG	0x32
+#define S526_EEPROM_CTRL_REG	0x34
+#define S526_EEPROM_CTRL_ADDR(x) (((x) & 0x3f) << 3)
+#define S526_EEPROM_CTRL(x)	(((x) & 0x3) << 1)
+#define S526_EEPROM_CTRL_READ	S526_EEPROM_CTRL(2)
+#define S526_EEPROM_CTRL_START	BIT(0)
 
 struct counter_mode_register_t {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
@@ -112,27 +129,39 @@ union cmReg {
 
 struct s526_private {
 	unsigned int gpct_config[4];
-	unsigned short ai_config;
+	unsigned short ai_ctrl;
 };
 
+static void s526_gpct_write(struct comedi_device *dev,
+			    unsigned int chan, unsigned int val)
+{
+	/* write high word then low word */
+	outw((val >> 16) & 0xffff, dev->iobase + S526_GPCT_MSB_REG(chan));
+	outw(val & 0xffff, dev->iobase + S526_GPCT_LSB_REG(chan));
+}
+
+static unsigned int s526_gpct_read(struct comedi_device *dev,
+				   unsigned int chan)
+{
+	unsigned int val;
+
+	/* read the low word then high word */
+	val = inw(dev->iobase + S526_GPCT_LSB_REG(chan)) & 0xffff;
+	val |= (inw(dev->iobase + S526_GPCT_MSB_REG(chan)) & 0xff) << 16;
+
+	return val;
+}
+
 static int s526_gpct_rinsn(struct comedi_device *dev,
 			   struct comedi_subdevice *s,
 			   struct comedi_insn *insn,
 			   unsigned int *data)
 {
 	unsigned int chan = CR_CHAN(insn->chanspec);
-	unsigned long chan_iobase = dev->iobase + chan * 8;
-	unsigned int lo;
-	unsigned int hi;
 	int i;
 
-	for (i = 0; i < insn->n; i++) {
-		/* Read the low word first */
-		lo = inw(chan_iobase + REG_C0L) & 0xffff;
-		hi = inw(chan_iobase + REG_C0H) & 0xff;
-
-		data[i] = (hi << 16) | lo;
-	}
+	for (i = 0; i < insn->n; i++)
+		data[i] = s526_gpct_read(dev, chan);
 
 	return insn->n;
 }
@@ -144,63 +173,34 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
 {
 	struct s526_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
-	unsigned long chan_iobase = dev->iobase + chan * 8;
 	unsigned int val;
 	union cmReg cmReg;
 
-	/*  Check what type of Counter the user requested, data[0] contains */
-	/*  the Application type */
+	/*
+	 * Check what type of Counter the user requested
+	 * data[0] contains the Application type
+	 */
 	switch (data[0]) {
 	case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
 		/*
-		   data[0]: Application Type
-		   data[1]: Counter Mode Register Value
-		   data[2]: Pre-load Register Value
-		   data[3]: Conter Control Register
+		 * data[0]: Application Type
+		 * data[1]: Counter Mode Register Value
+		 * data[2]: Pre-load Register Value
+		 * data[3]: Conter Control Register
 		 */
 		devpriv->gpct_config[chan] = data[0];
 
-#if 0
-		/*  Example of Counter Application */
-		/* One-shot (software trigger) */
-		cmReg.reg.coutSource = 0;	/*  out RCAP */
-		cmReg.reg.coutPolarity = 1;	/*  Polarity inverted */
-		cmReg.reg.autoLoadResetRcap = 0;/*  Auto load disabled */
-		cmReg.reg.hwCtEnableSource = 3;	/*  NOT RCAP */
-		cmReg.reg.ctEnableCtrl = 2;	/*  Hardware */
-		cmReg.reg.clockSource = 2;	/*  Internal */
-		cmReg.reg.countDir = 1;	/*  Down */
-		cmReg.reg.countDirCtrl = 1;	/*  Software */
-		cmReg.reg.outputRegLatchCtrl = 0;	/*  latch on read */
-		cmReg.reg.preloadRegSel = 0;	/*  PR0 */
-		cmReg.reg.reserved = 0;
-
-		outw(cmReg.value, chan_iobase + REG_C0M);
-
-		outw(0x0001, chan_iobase + REG_C0H);
-		outw(0x3C68, chan_iobase + REG_C0L);
-
-		/*  Reset the counter */
-		outw(0x8000, chan_iobase + REG_C0C);
-		/*  Load the counter from PR0 */
-		outw(0x4000, chan_iobase + REG_C0C);
-
-		/*  Reset RCAP (fires one-shot) */
-		outw(0x0008, chan_iobase + REG_C0C);
-
-#endif
-
 #if 1
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
-		outw(cmReg.value, chan_iobase + REG_C0M);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
 		/*  Reset the counter if it is software preload */
 		if (cmReg.reg.autoLoadResetRcap == 0) {
 			/*  Reset the counter */
-			outw(0x8000, chan_iobase + REG_C0C);
+			outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan));
 			/* Load the counter from PR0
-			 * outw(0x4000, chan_iobase + REG_C0C);
+			 * outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan));
 			 */
 		}
 #else
@@ -216,11 +216,13 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
 			cmReg.reg.clockSource = 0;
 
 		/*  When to take into account the indexpulse: */
-		/*if (data[2] == GPCT_IndexPhaseLowLow) {
-		} else if (data[2] == GPCT_IndexPhaseLowHigh) {
-		} else if (data[2] == GPCT_IndexPhaseHighLow) {
-		} else if (data[2] == GPCT_IndexPhaseHighHigh) {
-		}*/
+		/*
+		 * if (data[2] == GPCT_IndexPhaseLowLow) {
+		 * } else if (data[2] == GPCT_IndexPhaseLowHigh) {
+		 * } else if (data[2] == GPCT_IndexPhaseHighLow) {
+		 * } else if (data[2] == GPCT_IndexPhaseHighHigh) {
+		 * }
+		 */
 		/*  Take into account the index pulse? */
 		if (data[3] == GPCT_RESET_COUNTER_ON_INDEX)
 			/*  Auto load with INDEX^ */
@@ -228,114 +230,89 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
 
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
-		outw(cmReg.value, chan_iobase + REG_C0M);
-
-		/*  Load the pre-load register high word */
-		val = (data[2] >> 16) & 0xffff;
-		outw(val, chan_iobase + REG_C0H);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
-		/*  Load the pre-load register low word */
-		val = data[2] & 0xffff;
-		outw(val, chan_iobase + REG_C0L);
+		/*  Load the pre-load register */
+		s526_gpct_write(dev, chan, data[2]);
 
 		/*  Write the Counter Control Register */
-		if (data[3]) {
-			val = data[3] & 0xffff;
-			outw(val, chan_iobase + REG_C0C);
-		}
+		if (data[3])
+			outw(data[3] & 0xffff,
+			     dev->iobase + S526_GPCT_CTRL_REG(chan));
+
 		/*  Reset the counter if it is software preload */
 		if (cmReg.reg.autoLoadResetRcap == 0) {
 			/*  Reset the counter */
-			outw(0x8000, chan_iobase + REG_C0C);
+			outw(0x8000, dev->iobase + S526_GPCT_CTRL_REG(chan));
 			/*  Load the counter from PR0 */
-			outw(0x4000, chan_iobase + REG_C0C);
+			outw(0x4000, dev->iobase + S526_GPCT_CTRL_REG(chan));
 		}
 #endif
 		break;
 
 	case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
 		/*
-		   data[0]: Application Type
-		   data[1]: Counter Mode Register Value
-		   data[2]: Pre-load Register 0 Value
-		   data[3]: Pre-load Register 1 Value
-		   data[4]: Conter Control Register
+		 * data[0]: Application Type
+		 * data[1]: Counter Mode Register Value
+		 * data[2]: Pre-load Register 0 Value
+		 * data[3]: Pre-load Register 1 Value
+		 * data[4]: Conter Control Register
 		 */
 		devpriv->gpct_config[chan] = data[0];
 
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
 		cmReg.reg.preloadRegSel = 0;	/*  PR0 */
-		outw(cmReg.value, chan_iobase + REG_C0M);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
-		/*  Load the pre-load register 0 high word */
-		val = (data[2] >> 16) & 0xffff;
-		outw(val, chan_iobase + REG_C0H);
-
-		/*  Load the pre-load register 0 low word */
-		val = data[2] & 0xffff;
-		outw(val, chan_iobase + REG_C0L);
+		/* Load the pre-load register 0 */
+		s526_gpct_write(dev, chan, data[2]);
 
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
 		cmReg.reg.preloadRegSel = 1;	/*  PR1 */
-		outw(cmReg.value, chan_iobase + REG_C0M);
-
-		/*  Load the pre-load register 1 high word */
-		val = (data[3] >> 16) & 0xffff;
-		outw(val, chan_iobase + REG_C0H);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
-		/*  Load the pre-load register 1 low word */
-		val = data[3] & 0xffff;
-		outw(val, chan_iobase + REG_C0L);
+		/* Load the pre-load register 1 */
+		s526_gpct_write(dev, chan, data[3]);
 
 		/*  Write the Counter Control Register */
 		if (data[4]) {
 			val = data[4] & 0xffff;
-			outw(val, chan_iobase + REG_C0C);
+			outw(val, dev->iobase + S526_GPCT_CTRL_REG(chan));
 		}
 		break;
 
 	case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
 		/*
-		   data[0]: Application Type
-		   data[1]: Counter Mode Register Value
-		   data[2]: Pre-load Register 0 Value
-		   data[3]: Pre-load Register 1 Value
-		   data[4]: Conter Control Register
+		 * data[0]: Application Type
+		 * data[1]: Counter Mode Register Value
+		 * data[2]: Pre-load Register 0 Value
+		 * data[3]: Pre-load Register 1 Value
+		 * data[4]: Conter Control Register
 		 */
 		devpriv->gpct_config[chan] = data[0];
 
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
 		cmReg.reg.preloadRegSel = 0;	/*  PR0 */
-		outw(cmReg.value, chan_iobase + REG_C0M);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
-		/*  Load the pre-load register 0 high word */
-		val = (data[2] >> 16) & 0xffff;
-		outw(val, chan_iobase + REG_C0H);
-
-		/*  Load the pre-load register 0 low word */
-		val = data[2] & 0xffff;
-		outw(val, chan_iobase + REG_C0L);
+		/* Load the pre-load register 0 */
+		s526_gpct_write(dev, chan, data[2]);
 
 		/*  Set Counter Mode Register */
 		cmReg.value = data[1] & 0xffff;
 		cmReg.reg.preloadRegSel = 1;	/*  PR1 */
-		outw(cmReg.value, chan_iobase + REG_C0M);
-
-		/*  Load the pre-load register 1 high word */
-		val = (data[3] >> 16) & 0xffff;
-		outw(val, chan_iobase + REG_C0H);
+		outw(cmReg.value, dev->iobase + S526_GPCT_MODE_REG(chan));
 
-		/*  Load the pre-load register 1 low word */
-		val = data[3] & 0xffff;
-		outw(val, chan_iobase + REG_C0L);
+		/* Load the pre-load register 1 */
+		s526_gpct_write(dev, chan, data[3]);
 
 		/*  Write the Counter Control Register */
 		if (data[4]) {
 			val = data[4] & 0xffff;
-			outw(val, chan_iobase + REG_C0C);
+			outw(val, dev->iobase + S526_GPCT_CTRL_REG(chan));
 		}
 		break;
 
@@ -353,18 +330,18 @@ static int s526_gpct_winsn(struct comedi_device *dev,
 {
 	struct s526_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
-	unsigned long chan_iobase = dev->iobase + chan * 8;
 
-	inw(chan_iobase + REG_C0M);	/* Is this read required? */
+	inw(dev->iobase + S526_GPCT_MODE_REG(chan));	/* Is this required? */
 
 	/*  Check what Application of Counter this channel is configured for */
 	switch (devpriv->gpct_config[chan]) {
 	case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
-		/* data[0] contains the PULSE_WIDTH
-		   data[1] contains the PULSE_PERIOD
-		   @pre PULSE_PERIOD > PULSE_WIDTH > 0
-		   The above periods must be expressed as a multiple of the
-		   pulse frequency on the selected source
+		/*
+		 * data[0] contains the PULSE_WIDTH
+		 * data[1] contains the PULSE_PERIOD
+		 * @pre PULSE_PERIOD > PULSE_WIDTH > 0
+		 * The above periods must be expressed as a multiple of the
+		 * pulse frequency on the selected source
 		 */
 		if ((data[1] <= data[0]) || !data[0])
 			return -EINVAL;
@@ -373,8 +350,7 @@ static int s526_gpct_winsn(struct comedi_device *dev,
 
 	case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
 	case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
-		outw((data[0] >> 16) & 0xffff, chan_iobase + REG_C0H);
-		outw(data[0] & 0xffff, chan_iobase + REG_C0L);
+		s526_gpct_write(dev, chan, data[0]);
 		break;
 
 	default:
@@ -384,86 +360,60 @@ static int s526_gpct_winsn(struct comedi_device *dev,
 	return insn->n;
 }
 
-#define ISR_ADC_DONE 0x4
-static int s526_ai_insn_config(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       struct comedi_insn *insn, unsigned int *data)
-{
-	struct s526_private *devpriv = dev->private;
-	int result = -EINVAL;
-
-	if (insn->n < 1)
-		return result;
-
-	result = insn->n;
-
-	/* data[0] : channels was set in relevant bits.
-	   data[1] : delay
-	 */
-	/* COMMENT: abbotti 2008-07-24: I don't know why you'd want to
-	 * enable channels here.  The channel should be enabled in the
-	 * INSN_READ handler. */
-
-	/*  Enable ADC interrupt */
-	outw(ISR_ADC_DONE, dev->iobase + REG_IER);
-	devpriv->ai_config = (data[0] & 0x3ff) << 5;
-	if (data[1] > 0)
-		devpriv->ai_config |= 0x8000;	/* set the delay */
-
-	devpriv->ai_config |= 0x0001;		/* ADC start bit */
-
-	return result;
-}
-
-static int s526_ai_eoc(struct comedi_device *dev,
-		       struct comedi_subdevice *s,
-		       struct comedi_insn *insn,
-		       unsigned long context)
+static int s526_eoc(struct comedi_device *dev,
+		    struct comedi_subdevice *s,
+		    struct comedi_insn *insn,
+		    unsigned long context)
 {
 	unsigned int status;
 
-	status = inw(dev->iobase + REG_ISR);
-	if (status & ISR_ADC_DONE)
+	status = inw(dev->iobase + S526_INT_STATUS_REG);
+	if (status & context) {
+		/* we got our eoc event, clear it */
+		outw(context, dev->iobase + S526_INT_STATUS_REG);
 		return 0;
+	}
 	return -EBUSY;
 }
 
-static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			 struct comedi_insn *insn, unsigned int *data)
+static int s526_ai_insn_read(struct comedi_device *dev,
+			     struct comedi_subdevice *s,
+			     struct comedi_insn *insn,
+			     unsigned int *data)
 {
 	struct s526_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
-	int n;
-	unsigned short value;
-	unsigned int d;
+	unsigned int ctrl;
+	unsigned int val;
 	int ret;
+	int i;
 
-	/* Set configured delay, enable channel for this channel only,
-	 * select "ADC read" channel, set "ADC start" bit. */
-	value = (devpriv->ai_config & 0x8000) |
-		((1 << 5) << chan) | (chan << 1) | 0x0001;
+	ctrl = S526_AI_CTRL_CONV(chan) | S526_AI_CTRL_READ(chan) |
+	       S526_AI_CTRL_START;
+	if (ctrl != devpriv->ai_ctrl) {
+		/*
+		 * The multiplexor needs to change, enable the 15us
+		 * delay for the first sample.
+		 */
+		devpriv->ai_ctrl = ctrl;
+		ctrl |= S526_AI_CTRL_DELAY;
+	}
 
-	/* convert n samples */
-	for (n = 0; n < insn->n; n++) {
+	for (i = 0; i < insn->n; i++) {
 		/* trigger conversion */
-		outw(value, dev->iobase + REG_ADC);
+		outw(ctrl, dev->iobase + S526_AI_CTRL_REG);
+		ctrl &= ~S526_AI_CTRL_DELAY;
 
 		/* wait for conversion to end */
-		ret = comedi_timeout(dev, s, insn, s526_ai_eoc, 0);
+		ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AI);
 		if (ret)
 			return ret;
 
-		outw(ISR_ADC_DONE, dev->iobase + REG_ISR);
-
-		/* read data */
-		d = inw(dev->iobase + REG_ADD);
-
-		/* munge data */
-		data[n] = d ^ 0x8000;
+		val = inw(dev->iobase + S526_AI_REG);
+		data[i] = comedi_offset_munge(s, val);
 	}
 
-	/* return the number of samples read/written */
-	return n;
+	return insn->n;
 }
 
 static int s526_ao_insn_write(struct comedi_device *dev,
@@ -472,16 +422,23 @@ static int s526_ao_insn_write(struct comedi_device *dev,
 			      unsigned int *data)
 {
 	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int ctrl = S526_AO_CTRL_CHAN(chan);
 	unsigned int val = s->readback[chan];
+	int ret;
 	int i;
 
-	outw(chan << 1, dev->iobase + REG_DAC);
+	outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
+	ctrl |= S526_AO_CTRL_START;
 
 	for (i = 0; i < insn->n; i++) {
 		val = data[i];
-		outw(val, dev->iobase + REG_ADD);
-		/* starts the D/A conversion */
-		outw((chan << 1) | 1, dev->iobase + REG_DAC);
+		outw(val, dev->iobase + S526_AO_REG);
+		outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
+
+		/* wait for conversion to end */
+		ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AO);
+		if (ret)
+			return ret;
 	}
 	s->readback[chan] = val;
 
@@ -494,9 +451,9 @@ static int s526_dio_insn_bits(struct comedi_device *dev,
 			      unsigned int *data)
 {
 	if (comedi_dio_update_state(s, data))
-		outw(s->state, dev->iobase + REG_DIO);
+		outw(s->state, dev->iobase + S526_DIO_CTRL_REG);
 
-	data[1] = inw(dev->iobase + REG_DIO) & 0xff;
+	data[1] = inw(dev->iobase + S526_DIO_CTRL_REG) & 0xff;
 
 	return insn->n;
 }
@@ -510,6 +467,10 @@ static int s526_dio_insn_config(struct comedi_device *dev,
 	unsigned int mask;
 	int ret;
 
+	/*
+	 * Digital I/O can be configured as inputs or outputs in
+	 * groups of 4; DIO group 1 (DIO0-3) and DIO group 2 (DIO4-7).
+	 */
 	if (chan < 4)
 		mask = 0x0f;
 	else
@@ -519,17 +480,16 @@ static int s526_dio_insn_config(struct comedi_device *dev,
 	if (ret)
 		return ret;
 
-	/* bit 10/11 set the group 1/2's mode */
 	if (s->io_bits & 0x0f)
-		s->state |= (1 << 10);
+		s->state |= S526_DIO_CTRL_GRP1_OUT;
 	else
-		s->state &= ~(1 << 10);
+		s->state &= ~S526_DIO_CTRL_GRP1_OUT;
 	if (s->io_bits & 0xf0)
-		s->state |= (1 << 11);
+		s->state |= S526_DIO_CTRL_GRP2_OUT;
 	else
-		s->state &= ~(1 << 11);
+		s->state &= ~S526_DIO_CTRL_GRP2_OUT;
 
-	outw(s->state, dev->iobase + REG_DIO);
+	outw(s->state, dev->iobase + S526_DIO_CTRL_REG);
 
 	return insn->n;
 }
@@ -552,51 +512,53 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (ret)
 		return ret;
 
+	/* General-Purpose Counter/Timer (GPCT) */
 	s = &dev->subdevices[0];
-	/* GENERAL-PURPOSE COUNTER/TIME (GPCT) */
-	s->type = COMEDI_SUBD_COUNTER;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
-	s->n_chan = 4;
-	s->maxdata = 0x00ffffff;	/* 24 bit counter */
-	s->insn_read = s526_gpct_rinsn;
-	s->insn_config = s526_gpct_insn_config;
-	s->insn_write = s526_gpct_winsn;
-
+	s->type		= COMEDI_SUBD_COUNTER;
+	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+	s->n_chan	= 4;
+	s->maxdata	= 0x00ffffff;
+	s->insn_read	= s526_gpct_rinsn;
+	s->insn_config	= s526_gpct_insn_config;
+	s->insn_write	= s526_gpct_winsn;
+
+	/*
+	 * Analog Input subdevice
+	 * channels 0 to 7 are the regular differential inputs
+	 * channel 8 is "reference 0" (+10V)
+	 * channel 9 is "reference 1" (0V)
+	 */
 	s = &dev->subdevices[1];
-	/* analog input subdevice */
-	s->type = COMEDI_SUBD_AI;
-	s->subdev_flags = SDF_READABLE | SDF_DIFF;
-	/* channels 0 to 7 are the regular differential inputs */
-	/* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */
-	s->n_chan = 10;
-	s->maxdata = 0xffff;
-	s->range_table = &range_bipolar10;
-	s->len_chanlist = 16;
-	s->insn_read = s526_ai_rinsn;
-	s->insn_config = s526_ai_insn_config;
-
+	s->type		= COMEDI_SUBD_AI;
+	s->subdev_flags	= SDF_READABLE | SDF_DIFF;
+	s->n_chan	= 10;
+	s->maxdata	= 0xffff;
+	s->range_table	= &range_bipolar10;
+	s->len_chanlist	= 16;
+	s->insn_read	= s526_ai_insn_read;
+
+	/* Analog Output subdevice */
 	s = &dev->subdevices[2];
-	/* analog output subdevice */
-	s->type = COMEDI_SUBD_AO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->n_chan = 4;
-	s->maxdata = 0xffff;
-	s->range_table = &range_bipolar10;
-	s->insn_write = s526_ao_insn_write;
+	s->type		= COMEDI_SUBD_AO;
+	s->subdev_flags	= SDF_WRITABLE;
+	s->n_chan	= 4;
+	s->maxdata	= 0xffff;
+	s->range_table	= &range_bipolar10;
+	s->insn_write	= s526_ao_insn_write;
 
 	ret = comedi_alloc_subdev_readback(s);
 	if (ret)
 		return ret;
 
+	/* Digital I/O subdevice */
 	s = &dev->subdevices[3];
-	/* digital i/o subdevice */
-	s->type = COMEDI_SUBD_DIO;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	s->n_chan = 8;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_bits = s526_dio_insn_bits;
-	s->insn_config = s526_dio_insn_config;
+	s->type		= COMEDI_SUBD_DIO;
+	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= s526_dio_insn_bits;
+	s->insn_config	= s526_dio_insn_config;
 
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index 5f19374c460d..7a1defcf2102 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -1,30 +1,29 @@
 /*
-    comedi/drivers/serial2002.c
-    Skeleton code for a Comedi driver
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
-
-    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.
-*/
+ * serial2002.c
+ * Comedi driver for serial connected hardware
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
+ *
+ * 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.
+ */
 
 /*
-Driver: serial2002
-Description: Driver for serial connected hardware
-Devices:
-Author: Anders Blomdell
-Updated: Fri,  7 Jun 2002 12:56:45 -0700
-Status: in development
-
-*/
+ * Driver: serial2002
+ * Description: Driver for serial connected hardware
+ * Devices:
+ * Author: Anders Blomdell
+ * Updated: Fri,  7 Jun 2002 12:56:45 -0700
+ * Status: in development
+ */
 
 #include <linux/module.h>
 #include "../comedidev.h"
@@ -102,7 +101,7 @@ static long serial2002_tty_ioctl(struct file *f, unsigned op,
 	if (f->f_op->unlocked_ioctl)
 		return f->f_op->unlocked_ioctl(f, op, param);
 
-	return -ENOSYS;
+	return -ENOTTY;
 }
 
 static int serial2002_tty_write(struct file *f, unsigned char *buf, int count)
@@ -176,7 +175,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
 					result = ch;
 					break;
 				}
-				udelay(100);
+				usleep_range(100, 1000);
 			}
 		}
 		set_fs(oldfs);
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index acc7f3445c58..f9f634fd53cf 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -1,28 +1,29 @@
 /*
-    comedi/drivers/ssv_dnp.c
-    generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
-    Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.
-*/
+ * ssv_dnp.c
+ * generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
+ * Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
 /*
-Driver: ssv_dnp
-Description: SSV Embedded Systems DIL/Net-PC
-Author: Robert Schwebel <robert@schwebel.de>
-Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
-Status: unknown
-*/
+ * Driver: ssv_dnp
+ * Description: SSV Embedded Systems DIL/Net-PC
+ * Author: Robert Schwebel <robert@schwebel.de>
+ * Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
+ * Status: unknown
+ */
 
 /* include files ----------------------------------------------------------- */
 
@@ -134,6 +135,12 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	struct comedi_subdevice *s;
 	int ret;
 
+	/*
+	 * We use I/O ports 0x22, 0x23 and 0xa3-0xa9, which are always
+	 * allocated for the primary 8259, so we don't need to allocate
+	 * them ourselves.
+	 */
+
 	ret = comedi_alloc_subdevices(dev, 1);
 	if (ret)
 		return ret;
@@ -148,10 +155,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->insn_bits = dnp_dio_insn_bits;
 	s->insn_config = dnp_dio_insn_config;
 
-	/* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always
-	 * allocated for the primary 8259, so we don't need to allocate them
-	 * ourselves. */
-
 	/* configure all ports as input (default)                            */
 	outb(PAMR, CSCIR);
 	outb(0x00, CSCDR);
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
deleted file mode 100644
index 51498b889c6c..000000000000
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *  comedi/drivers/unioxx5.c                                               *
- *  Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.           *
- *                                                                         *
- *  Copyright (C) 2006 Kruchinin Daniil (asgard) [asgard@etersoft.ru]      *
- *                                                                         *
- *  COMEDI - Linux Control and Measurement Device Interface                *
- *  Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>              *
- *                                                                         *
- *  This program is free software; you can redistribute it and/or modify   *
- *  it under the terms of the GNU General Public License as published by   *
- *  the Free Software Foundation; either version 2 of the License, or      *
- *  (at your option) any later version.                                    *
- *                                                                         *
- *  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.                           *
- *                                                                         *
- ***************************************************************************/
-/*
-
-Driver: unioxx5
-Description: Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.
-Author: Kruchinin Daniil (asgard) <asgard@etersoft.ru>
-Status: unknown
-Updated: 2006-10-09
-Devices: [Fastwel] UNIOxx-5 (unioxx5),
-
- This card supports digital and analog I/O. It written for g01
- subdevices only.
- channels range: 0 .. 23 dio channels
- and 0 .. 11 analog modules range
- During attaching unioxx5 module displays modules identifiers
- (see dmesg after comedi_config) in format:
- | [module_number] module_id |
-
-*/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include "../comedidev.h"
-
-#define UNIOXX5_SIZE 0x10
-#define UNIOXX5_SUBDEV_BASE 0xA000	/* base addr of first subdev */
-#define UNIOXX5_SUBDEV_ODDS 0x400
-
-/* modules types */
-#define MODULE_DIGITAL 0
-#define MODULE_OUTPUT_MASK 0x80	/* analog input/output */
-
-/* constants for digital i/o */
-#define UNIOXX5_NUM_OF_CHANS 24
-
-/* constants for analog i/o */
-#define TxBE  0x10		/* transmit buffer enable */
-#define RxCA  0x20		/* 1 receive character available */
-#define Rx2CA 0x40		/* 2 receive character available */
-#define Rx4CA 0x80		/* 4 receive character available */
-
-/* bytes mask errors */
-#define Rx2CA_ERR_MASK 0x04	/* 2 bytes receiving error */
-#define Rx4CA_ERR_MASK 0x08	/* 4 bytes receiving error */
-
-/* channel modes */
-#define ALL_2_INPUT  0		/* config all digital channels to input */
-#define ALL_2_OUTPUT 1		/* config all digital channels to output */
-
-/* 'private' structure for each subdevice */
-struct unioxx5_subd_priv {
-	int usp_iobase;
-	/* 12 modules. each can be 70L or 73L */
-	unsigned char usp_module_type[12];
-	/* for saving previous written value for analog modules */
-	unsigned char usp_extra_data[12][4];
-	unsigned char usp_prev_wr_val[3];	/* previous written value */
-	unsigned char usp_prev_cn_val[3];	/* previous channel value */
-};
-
-static int __unioxx5_define_chan_offset(int chan_num)
-{
-	if (chan_num < 0 || chan_num > 23)
-		return -1;
-
-	return (chan_num >> 3) + 1;
-}
-
-#if 0				/* not used? */
-static void __unioxx5_digital_config(struct comedi_subdevice *s, int mode)
-{
-	struct unioxx5_subd_priv *usp = s->private;
-	struct device *csdev = s->device->class_dev;
-	int i, mask;
-
-	mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00;
-	dev_dbg(csdev, "mode = %d\n", mask);
-
-	outb(1, usp->usp_iobase + 0);
-
-	for (i = 0; i < 3; i++)
-		outb(mask, usp->usp_iobase + i);
-
-	outb(0, usp->usp_iobase + 0);
-}
-#endif
-
-/* configure channels for analog i/o (even to output, odd to input) */
-static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel)
-{
-	int chan_a, chan_b, conf, channel_offset;
-
-	channel_offset = __unioxx5_define_chan_offset(channel);
-	conf = usp->usp_prev_cn_val[channel_offset - 1];
-	chan_a = chan_b = 1;
-
-	/* setting channel A and channel B mask */
-	if (channel % 2 == 0) {
-		chan_a <<= channel & 0x07;
-		chan_b <<= (channel + 1) & 0x07;
-	} else {
-		chan_a <<= (channel - 1) & 0x07;
-		chan_b <<= channel & 0x07;
-	}
-
-	conf |= chan_a;		/* even channel ot output */
-	conf &= ~chan_b;	/* odd channel to input */
-
-	outb(1, usp->usp_iobase + 0);
-	outb(conf, usp->usp_iobase + channel_offset);
-	outb(0, usp->usp_iobase + 0);
-
-	usp->usp_prev_cn_val[channel_offset - 1] = conf;
-}
-
-static int __unioxx5_digital_read(struct comedi_subdevice *s,
-				  unsigned int *data, int channel, int minor)
-{
-	struct unioxx5_subd_priv *usp = s->private;
-	struct device *csdev = s->device->class_dev;
-	int channel_offset, mask = 1 << (channel & 0x07);
-
-	channel_offset = __unioxx5_define_chan_offset(channel);
-	if (channel_offset < 0) {
-		dev_err(csdev,
-			"undefined channel %d. channel range is 0 .. 23\n",
-			channel);
-		return 0;
-	}
-
-	*data = inb(usp->usp_iobase + channel_offset);
-	*data &= mask;
-
-	/* correct the read value to 0 or 1 */
-	if (channel_offset > 1)
-		channel -= 2 << channel_offset;
-	*data >>= channel;
-	return 1;
-}
-
-static int __unioxx5_analog_read(struct comedi_subdevice *s,
-				 unsigned int *data, int channel, int minor)
-{
-	struct unioxx5_subd_priv *usp = s->private;
-	struct device *csdev = s->device->class_dev;
-	int module_no, read_ch;
-	char control;
-
-	module_no = channel / 2;
-	read_ch = channel % 2;	/* depend on type of channel (A or B) */
-
-	/* defining if given module can work on input */
-	if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
-		dev_err(csdev,
-			"module in position %d with id 0x%02x is for output only",
-			module_no, usp->usp_module_type[module_no]);
-		return 0;
-	}
-
-	__unioxx5_analog_config(usp, channel);
-	/* sends module number to card(1 .. 12) */
-	outb(module_no + 1, usp->usp_iobase + 5);
-	outb('V', usp->usp_iobase + 6);	/* sends to module (V)erify command */
-	control = inb(usp->usp_iobase);	/* get control register byte */
-
-	/* waits while reading four bytes will be allowed */
-	while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA))
-		;
-
-	/* if four bytes readding error occurs - return 0(false) */
-	if ((control & Rx4CA_ERR_MASK)) {
-		dev_err(csdev, "4 bytes error\n");
-		return 0;
-	}
-
-	if (read_ch)
-		*data = inw(usp->usp_iobase + 6);	/* channel B */
-	else
-		*data = inw(usp->usp_iobase + 4);	/* channel A */
-
-	return 1;
-}
-
-static int __unioxx5_digital_write(struct comedi_subdevice *s,
-				   unsigned int *data, int channel, int minor)
-{
-	struct unioxx5_subd_priv *usp = s->private;
-	struct device *csdev = s->device->class_dev;
-	int channel_offset, val;
-	int mask = 1 << (channel & 0x07);
-
-	channel_offset = __unioxx5_define_chan_offset(channel);
-	if (channel_offset < 0) {
-		dev_err(csdev,
-			"undefined channel %d. channel range is 0 .. 23\n",
-			channel);
-		return 0;
-	}
-
-	/* getting previous written value */
-	val = usp->usp_prev_wr_val[channel_offset - 1];
-
-	if (*data)
-		val |= mask;
-	else
-		val &= ~mask;
-
-	outb(val, usp->usp_iobase + channel_offset);
-	/* saving new written value */
-	usp->usp_prev_wr_val[channel_offset - 1] = val;
-
-	return 1;
-}
-
-static int __unioxx5_analog_write(struct comedi_subdevice *s,
-				  unsigned int *data, int channel, int minor)
-{
-	struct unioxx5_subd_priv *usp = s->private;
-	struct device *csdev = s->device->class_dev;
-	int module, i;
-
-	module = channel / 2;	/* definig module number(0 .. 11) */
-	i = (channel % 2) << 1;	/* depends on type of channel (A or B) */
-
-	/* defining if given module can work on output */
-	if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
-		dev_err(csdev,
-			"module in position %d with id 0x%0x is for input only!\n",
-			module, usp->usp_module_type[module]);
-		return 0;
-	}
-
-	__unioxx5_analog_config(usp, channel);
-	/* saving minor byte */
-	usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF);
-	/* saving major byte */
-	usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8);
-
-	/* while(!((inb(usp->usp_iobase + 0)) & TxBE)); */
-	/* sending module number to card(1 .. 12) */
-	outb(module + 1, usp->usp_iobase + 5);
-	outb('W', usp->usp_iobase + 6);	/* sends (W)rite command to module */
-
-	/* sending for bytes to module(one byte per cycle iteration) */
-	for (i = 0; i < 4; i++) {
-		while (!((inb(usp->usp_iobase + 0)) & TxBE))
-			;	/* waits while writing will be allowed */
-		outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6);
-	}
-
-	return 1;
-}
-
-static int unioxx5_subdev_read(struct comedi_device *dev,
-			       struct comedi_subdevice *subdev,
-			       struct comedi_insn *insn, unsigned int *data)
-{
-	struct unioxx5_subd_priv *usp = subdev->private;
-	int channel, type;
-
-	channel = CR_CHAN(insn->chanspec);
-	/* defining module type(analog or digital) */
-	type = usp->usp_module_type[channel / 2];
-
-	if (type == MODULE_DIGITAL) {
-		if (!__unioxx5_digital_read(subdev, data, channel, dev->minor))
-			return -1;
-	} else {
-		if (!__unioxx5_analog_read(subdev, data, channel, dev->minor))
-			return -1;
-	}
-
-	return 1;
-}
-
-static int unioxx5_subdev_write(struct comedi_device *dev,
-				struct comedi_subdevice *subdev,
-				struct comedi_insn *insn, unsigned int *data)
-{
-	struct unioxx5_subd_priv *usp = subdev->private;
-	int channel, type;
-
-	channel = CR_CHAN(insn->chanspec);
-	/* defining module type(analog or digital) */
-	type = usp->usp_module_type[channel / 2];
-
-	if (type == MODULE_DIGITAL) {
-		if (!__unioxx5_digital_write(subdev, data, channel, dev->minor))
-			return -1;
-	} else {
-		if (!__unioxx5_analog_write(subdev, data, channel, dev->minor))
-			return -1;
-	}
-
-	return 1;
-}
-
-/* for digital modules only */
-static int unioxx5_insn_config(struct comedi_device *dev,
-			       struct comedi_subdevice *subdev,
-			       struct comedi_insn *insn, unsigned int *data)
-{
-	int channel_offset, flags, channel = CR_CHAN(insn->chanspec), type;
-	struct unioxx5_subd_priv *usp = subdev->private;
-	int mask = 1 << (channel & 0x07);
-
-	type = usp->usp_module_type[channel / 2];
-
-	if (type != MODULE_DIGITAL) {
-		dev_err(dev->class_dev,
-			"channel configuration accessible only for digital modules\n");
-		return -1;
-	}
-
-	channel_offset = __unioxx5_define_chan_offset(channel);
-	if (channel_offset < 0) {
-		dev_err(dev->class_dev,
-			"undefined channel %d. channel range is 0 .. 23\n",
-			channel);
-		return -1;
-	}
-
-	/* gets previously written value */
-	flags = usp->usp_prev_cn_val[channel_offset - 1];
-
-	switch (*data) {
-	case COMEDI_INPUT:
-		flags &= ~mask;
-		break;
-	case COMEDI_OUTPUT:
-		flags |= mask;
-		break;
-	default:
-		dev_err(dev->class_dev, "unknown flag\n");
-		return -1;
-	}
-
-	/*                                                        *\
-	 * sets channels buffer to 1(after this we are allowed to *
-	 * change channel type on input or output)                *
-	 \*                                                        */
-	outb(1, usp->usp_iobase + 0);
-	/* changes type of _one_ channel */
-	outb(flags, usp->usp_iobase + channel_offset);
-	/* sets channels bank to 0(allows directly input/output) */
-	outb(0, usp->usp_iobase + 0);
-	/* saves written value */
-	usp->usp_prev_cn_val[channel_offset - 1] = flags;
-
-	return 0;
-}
-
-/* initializing subdevice with given address */
-static int __unioxx5_subdev_init(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 int iobase)
-{
-	struct unioxx5_subd_priv *usp;
-	int i, to, ndef_flag = 0;
-	int ret;
-
-	usp = comedi_alloc_spriv(s, sizeof(*usp));
-	if (!usp)
-		return -ENOMEM;
-
-	ret = __comedi_request_region(dev, iobase, UNIOXX5_SIZE);
-	if (ret)
-		return ret;
-	usp->usp_iobase = iobase;
-
-	/* defining modules types */
-	for (i = 0; i < 12; i++) {
-		to = 10000;
-
-		__unioxx5_analog_config(usp, i * 2);
-		/* sends channel number to card */
-		outb(i + 1, iobase + 5);
-		outb('H', iobase + 6);	/* requests EEPROM world */
-		while (!(inb(iobase + 0) & TxBE))
-			;	/* waits while writing will be allowed */
-		outb(0, iobase + 6);
-
-		/* waits while reading of two bytes will be allowed */
-		while (!(inb(iobase + 0) & Rx2CA)) {
-			if (--to <= 0) {
-				ndef_flag = 1;
-				break;
-			}
-		}
-
-		if (ndef_flag) {
-			usp->usp_module_type[i] = 0;
-			ndef_flag = 0;
-		} else {
-			usp->usp_module_type[i] = inb(iobase + 6);
-		}
-
-		udelay(1);
-	}
-
-	/* initial subdevice for digital or analog i/o */
-	s->type = COMEDI_SUBD_DIO;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	s->n_chan = UNIOXX5_NUM_OF_CHANS;
-	s->maxdata = 0xFFF;
-	s->range_table = &range_digital;
-	s->insn_read = unioxx5_subdev_read;
-	s->insn_write = unioxx5_subdev_write;
-	/* for digital modules only!!! */
-	s->insn_config = unioxx5_insn_config;
-
-	return 0;
-}
-
-static int unioxx5_attach(struct comedi_device *dev,
-			  struct comedi_devconfig *it)
-{
-	struct comedi_subdevice *s;
-	int iobase, i, n_subd;
-	int id, num, ba;
-	int ret;
-
-	iobase = it->options[0];
-
-	dev->iobase = iobase;
-	iobase += UNIOXX5_SUBDEV_BASE;
-	n_subd = 0;
-
-	/* getting number of subdevices with types 'g01' */
-	for (i = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
-		id = inb(ba + 0xE);
-		num = inb(ba + 0xF);
-
-		if (id != 'g' || num != 1)
-			continue;
-
-		n_subd++;
-	}
-
-	/* unioxx5 can has from two to four subdevices */
-	if (n_subd < 2) {
-		dev_err(dev->class_dev,
-			"your card must has at least 2 'g01' subdevices\n");
-		return -1;
-	}
-
-	ret = comedi_alloc_subdevices(dev, n_subd);
-	if (ret)
-		return ret;
-
-	/* initializing each of for same subdevices */
-	for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) {
-		s = &dev->subdevices[i];
-		ret = __unioxx5_subdev_init(dev, s, iobase);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static void unioxx5_detach(struct comedi_device *dev)
-{
-	struct comedi_subdevice *s;
-	struct unioxx5_subd_priv *spriv;
-	int i;
-
-	for (i = 0; i < dev->n_subdevices; i++) {
-		s = &dev->subdevices[i];
-		spriv = s->private;
-		if (spriv && spriv->usp_iobase)
-			release_region(spriv->usp_iobase, UNIOXX5_SIZE);
-	}
-}
-
-static struct comedi_driver unioxx5_driver = {
-	.driver_name	= "unioxx5",
-	.module		= THIS_MODULE,
-	.attach		= unioxx5_attach,
-	.detach		= unioxx5_detach,
-};
-module_comedi_driver(unioxx5_driver);
-
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index ced05e581620..39710f2297a6 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -108,55 +108,55 @@
 #define BULK_TIMEOUT		1000
 
 /* 300Hz max frequ under PWM */
-#define MIN_PWM_PERIOD  ((long)(1E9/300))
+#define MIN_PWM_PERIOD		((long)(1E9 / 300))
 
 /* Default PWM frequency */
-#define PWM_DEFAULT_PERIOD ((long)(1E9/100))
+#define PWM_DEFAULT_PERIOD	((long)(1E9 / 100))
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(uint16_t)))
+#define SIZEADIN		((sizeof(u16)))
 
 /*
  * Size of the input-buffer IN BYTES
  * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
  */
-#define SIZEINBUF         ((8*SIZEADIN))
+#define SIZEINBUF		(8 * SIZEADIN)
 
 /* 16 bytes. */
-#define SIZEINSNBUF       16
+#define SIZEINSNBUF		16
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
+#define SIZEDAOUT		((sizeof(u8) + sizeof(u16)))
 
 /*
  * Size of the output-buffer in bytes
  * Actually only the first 4 triplets are used but for the
  * high speed mode we need to pad it to 8 (microframes).
  */
-#define SIZEOUTBUF         ((8*SIZEDAOUT))
+#define SIZEOUTBUF		(8 * SIZEDAOUT)
 
 /*
  * Size of the buffer for the dux commands: just now max size is determined
  * by the analogue out + command byte + panic bytes...
  */
-#define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
+#define SIZEOFDUXBUFFER		(8 * SIZEDAOUT + 2)
 
 /* Number of in-URBs which receive the data: min=2 */
-#define NUMOFINBUFFERSFULL     5
+#define NUMOFINBUFFERSFULL	5
 
 /* Number of out-URBs which send the data: min=2 */
-#define NUMOFOUTBUFFERSFULL    5
+#define NUMOFOUTBUFFERSFULL	5
 
 /* Number of in-URBs which receive the data: min=5 */
 /* must have more buffers due to buggy USB ctr */
-#define NUMOFINBUFFERSHIGH     10
+#define NUMOFINBUFFERSHIGH	10
 
 /* Number of out-URBs which send the data: min=5 */
 /* must have more buffers due to buggy USB ctr */
-#define NUMOFOUTBUFFERSHIGH    10
+#define NUMOFOUTBUFFERSHIGH	10
 
 /* number of retries to get the right dux command */
-#define RETRIES 10
+#define RETRIES			10
 
 static const struct comedi_lrange range_usbdux_ai_range = {
 	4, {
@@ -187,7 +187,7 @@ struct usbdux_private {
 	/* PWM period */
 	unsigned int pwm_period;
 	/* PWM internal delay for the GPIF in the FX2 */
-	uint8_t pwm_delay;
+	u8 pwm_delay;
 	/* size of the PWM buffer which holds the bit pattern */
 	int pwm_buf_sz;
 	/* input buffer for the ISO-transfer */
@@ -209,7 +209,7 @@ struct usbdux_private {
 	/* interval in frames/uframes */
 	unsigned int ai_interval;
 	/* commands */
-	uint8_t *dux_commands;
+	u8 *dux_commands;
 	struct semaphore sem;
 };
 
@@ -262,11 +262,11 @@ static void usbduxsub_ai_handle_urb(struct comedi_device *dev,
 		/* get the data from the USB bus and hand it over to comedi */
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			unsigned int range = CR_RANGE(cmd->chanlist[i]);
-			uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
+			u16 val = le16_to_cpu(devpriv->in_buf[i]);
 
 			/* bipolar data is two's-complement */
 			if (comedi_range_is_bipolar(s, range))
-				val ^= ((s->maxdata + 1) >> 1);
+				val = comedi_offset_munge(s, val);
 
 			/* transfer data */
 			if (!comedi_buf_write_samples(s, &val, 1))
@@ -380,7 +380,7 @@ static void usbduxsub_ao_handle_urb(struct comedi_device *dev,
 	struct usbdux_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	uint8_t *datap;
+	u8 *datap;
 	int ret;
 	int i;
 
@@ -516,9 +516,8 @@ static int usbdux_submit_urbs(struct comedi_device *dev,
 static int usbdux_ai_cmdtest(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
-	struct usbdux_private *this_usbduxsub = dev->private;
-	int err = 0, i;
-	unsigned int tmp_timer;
+	struct usbdux_private *devpriv = dev->private;
+	int err = 0;
 
 	/* Step 1 : check if triggers are trivially valid */
 
@@ -549,40 +548,31 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
-		if (this_usbduxsub->high_speed) {
+		/* full speed does 1kHz scans every USB frame */
+		unsigned int arg = 1000000;
+		unsigned int min_arg = arg;
+
+		if (devpriv->high_speed) {
 			/*
 			 * In high speed mode microframes are possible.
 			 * However, during one microframe we can roughly
 			 * sample one channel. Thus, the more channels
 			 * are in the channel list the more time we need.
 			 */
-			i = 1;
+			int i = 1;
+
 			/* find a power of 2 for the number of channels */
-			while (i < (cmd->chanlist_len))
+			while (i < cmd->chanlist_len)
 				i = i * 2;
 
-			err |= comedi_check_trigger_arg_min(&cmd->
-							    scan_begin_arg,
-							    1000000 / 8 * i);
-			/* now calc the real sampling rate with all the
-			 * rounding errors */
-			tmp_timer =
-			    ((unsigned int)(cmd->scan_begin_arg / 125000)) *
-			    125000;
-		} else {
-			/* full speed */
-			/* 1kHz scans every USB frame */
-			err |= comedi_check_trigger_arg_min(&cmd->
-							    scan_begin_arg,
-							    1000000);
-			/*
-			 * calc the real sampling rate with the rounding errors
-			 */
-			tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
-						   1000000)) * 1000000;
+			arg /= 8;
+			min_arg = arg * i;
 		}
-		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg,
-						   tmp_timer);
+		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
+						    min_arg);
+		/* calc the real sampling rate with the rounding errors */
+		arg = (cmd->scan_begin_arg / arg) * arg;
+		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 	}
 
 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
@@ -603,10 +593,10 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
  * creates the ADC command for the MAX1271
  * range is the range value from comedi
  */
-static uint8_t create_adc_command(unsigned int chan, unsigned int range)
+static u8 create_adc_command(unsigned int chan, unsigned int range)
 {
-	uint8_t p = (range <= 1);
-	uint8_t r = ((range % 2) == 0);
+	u8 p = (range <= 1);
+	u8 r = ((range % 2) == 0);
 
 	return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
 }
@@ -786,7 +776,7 @@ static int usbdux_ai_insn_read(struct comedi_device *dev,
 
 		/* bipolar data is two's-complement */
 		if (comedi_range_is_bipolar(s, range))
-			val ^= ((s->maxdata + 1) >> 1);
+			val = comedi_offset_munge(s, val);
 
 		data[i] = val;
 	}
@@ -887,18 +877,14 @@ ao_trig_exit:
 static int usbdux_ao_cmdtest(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
-	struct usbdux_private *this_usbduxsub = dev->private;
 	int err = 0;
 	unsigned int flags;
 
-	if (!this_usbduxsub)
-		return -EFAULT;
-
 	/* Step 1 : check if triggers are trivially valid */
 
 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
 
-	if (0) {		/* (this_usbduxsub->high_speed) */
+	if (0) {		/* (devpriv->high_speed) */
 		/* the sampling rate is set by the coversion rate */
 		flags = TRIG_FOLLOW;
 	} else {
@@ -907,7 +893,7 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
 	}
 	err |= comedi_check_trigger_src(&cmd->scan_begin_src, flags);
 
-	if (0) {		/* (this_usbduxsub->high_speed) */
+	if (0) {		/* (devpriv->high_speed) */
 		/*
 		 * in usb-2.0 only one conversion it transmitted
 		 * but with 8kHz/n
@@ -1391,8 +1377,8 @@ static int usbdux_firmware_upload(struct comedi_device *dev,
 				  unsigned long context)
 {
 	struct usb_device *usb = comedi_to_usb_dev(dev);
-	uint8_t *buf;
-	uint8_t *tmp;
+	u8 *buf;
+	u8 *tmp;
 	int ret;
 
 	if (!data)
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index d90dc59982be..c6b2a6582127 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -97,7 +97,7 @@
 /*
  * size of one A/D value
  */
-#define SIZEADIN	(sizeof(int16_t))
+#define SIZEADIN	(sizeof(s16))
 
 /*
  * size of the input-buffer IN BYTES
@@ -156,11 +156,10 @@ static const struct comedi_lrange range_usbduxfast_ai_range = {
  */
 struct usbduxfast_private {
 	struct urb *urb;	/* BULK-transfer handling: urb */
-	uint8_t *duxbuf;
-	int8_t *inbuf;
+	u8 *duxbuf;
+	s8 *inbuf;
 	short int ai_cmd_running;	/* asynchronous command is running */
-	int ignore;		/* counter which ignores the first
-				   buffers */
+	int ignore;		/* counter which ignores the first buffers */
 	struct semaphore sem;
 };
 
@@ -190,8 +189,7 @@ static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
 }
 
 static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
-				uint8_t len, uint8_t op, uint8_t out,
-				uint8_t log)
+				u8 len, u8 op, u8 out, u8 log)
 {
 	struct usbduxfast_private *devpriv = dev->private;
 
@@ -223,9 +221,6 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev,
 	struct usbduxfast_private *devpriv = dev->private;
 	int ret;
 
-	if (!devpriv)
-		return -EFAULT;
-
 	down(&devpriv->sem);
 	ret = usbduxfast_ai_stop(dev, 1);
 	up(&devpriv->sem);
@@ -317,9 +312,6 @@ static int usbduxfast_submit_urb(struct comedi_device *dev)
 	struct usbduxfast_private *devpriv = dev->private;
 	int ret;
 
-	if (!devpriv)
-		return -EFAULT;
-
 	usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
 			  devpriv->inbuf, SIZEINBUF,
 			  usbduxfast_ai_interrupt, dev);
@@ -332,22 +324,50 @@ static int usbduxfast_submit_urb(struct comedi_device *dev)
 	return 0;
 }
 
+static int usbduxfast_ai_check_chanlist(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_cmd *cmd)
+{
+	unsigned int gain0 = CR_RANGE(cmd->chanlist[0]);
+	int i;
+
+	if (cmd->chanlist_len > 3 && cmd->chanlist_len != 16) {
+		dev_err(dev->class_dev, "unsupported combination of channels\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cmd->chanlist_len; ++i) {
+		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+		unsigned int gain = CR_RANGE(cmd->chanlist[i]);
+
+		if (chan != i) {
+			dev_err(dev->class_dev,
+				"channels are not consecutive\n");
+			return -EINVAL;
+		}
+		if (gain != gain0 && cmd->chanlist_len > 3) {
+			dev_err(dev->class_dev,
+				"gain must be the same for all channels\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
 				 struct comedi_subdevice *s,
 				 struct comedi_cmd *cmd)
 {
 	int err = 0;
-	long int steps, tmp;
-	int min_sample_period;
+	unsigned int steps;
+	unsigned int arg;
 
 	/* Step 1 : check if triggers are trivially valid */
 
 	err |= comedi_check_trigger_src(&cmd->start_src,
 					TRIG_NOW | TRIG_EXT | TRIG_INT);
-	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
-					TRIG_FOLLOW | TRIG_EXT);
-	err |= comedi_check_trigger_src(&cmd->convert_src,
-					TRIG_TIMER | TRIG_EXT);
+	err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
+	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 
@@ -357,16 +377,10 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
 	/* Step 2a : make sure trigger sources are unique */
 
 	err |= comedi_check_trigger_is_unique(cmd->start_src);
-	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
-	err |= comedi_check_trigger_is_unique(cmd->convert_src);
 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
 
 	/* Step 2b : and mutually compatible */
 
-	/* can't have external stop and start triggers at once */
-	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
-		err |= -EINVAL;
-
 	if (err)
 		return 2;
 
@@ -377,47 +391,44 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
 	if (!cmd->chanlist_len)
 		err |= -EINVAL;
 
+	/* external start trigger is only valid for 1 or 16 channels */
+	if (cmd->start_src == TRIG_EXT &&
+	    cmd->chanlist_len != 1 && cmd->chanlist_len != 16)
+		err |= -EINVAL;
+
 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 					   cmd->chanlist_len);
 
-	if (cmd->chanlist_len == 1)
-		min_sample_period = 1;
-	else
-		min_sample_period = MIN_SAMPLING_PERIOD;
-
-	if (cmd->convert_src == TRIG_TIMER) {
-		steps = cmd->convert_arg * 30;
-		if (steps < (min_sample_period * 1000))
-			steps = min_sample_period * 1000;
-
-		if (steps > (MAX_SAMPLING_PERIOD * 1000))
-			steps = MAX_SAMPLING_PERIOD * 1000;
-
-		/* calc arg again */
-		tmp = steps / 30;
-		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, tmp);
-	}
-
-	/* stop source */
-	switch (cmd->stop_src) {
-	case TRIG_COUNT:
+	/*
+	 * Validate the conversion timing:
+	 * for 1 channel the timing in 30MHz "steps" is:
+	 *	steps <= MAX_SAMPLING_PERIOD
+	 * for all other chanlist_len it is:
+	 *	MIN_SAMPLING_PERIOD <= steps <= MAX_SAMPLING_PERIOD
+	 */
+	steps = (cmd->convert_arg * 30) / 1000;
+	if (cmd->chanlist_len !=  1)
+		err |= comedi_check_trigger_arg_min(&steps,
+						    MIN_SAMPLING_PERIOD);
+	err |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD);
+	arg = (steps * 1000) / 30;
+	err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
+
+	if (cmd->stop_src == TRIG_COUNT)
 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
-		break;
-	case TRIG_NONE:
+	else	/* TRIG_NONE */
 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-		break;
-		/*
-		 * TRIG_EXT doesn't care since it doesn't trigger
-		 * off a numbered channel
-		 */
-	default:
-		break;
-	}
 
 	if (err)
 		return 3;
 
-	/* step 4: fix up any arguments */
+	/* Step 4: fix up any arguments */
+
+	/* Step 5: check channel list if it exists */
+	if (cmd->chanlist && cmd->chanlist_len > 0)
+		err |= usbduxfast_ai_check_chanlist(dev, s, cmd);
+	if (err)
+		return 5;
 
 	return 0;
 }
@@ -430,9 +441,6 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev,
 	struct comedi_cmd *cmd = &s->async->cmd;
 	int ret;
 
-	if (!devpriv)
-		return -EFAULT;
-
 	if (trig_num != cmd->start_arg)
 		return -EINVAL;
 
@@ -460,19 +468,14 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 {
 	struct usbduxfast_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int chan, gain, rngmask = 0xff;
-	int i, j, ret;
-	int result;
+	unsigned int rngmask = 0xff;
+	int j, ret;
 	long steps, steps_tmp;
 
-	if (!devpriv)
-		return -EFAULT;
-
 	down(&devpriv->sem);
 	if (devpriv->ai_cmd_running) {
-		dev_err(dev->class_dev, "ai_cmd not possible\n");
-		up(&devpriv->sem);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto cmd_exit;
 	}
 
 	/*
@@ -481,50 +484,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 	 */
 	devpriv->ignore = PACKETS_TO_IGNORE;
 
-	gain = CR_RANGE(cmd->chanlist[0]);
-	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		if (chan != i) {
-			dev_err(dev->class_dev,
-				"channels are not consecutive\n");
-			up(&devpriv->sem);
-			return -EINVAL;
-		}
-		if ((gain != CR_RANGE(cmd->chanlist[i]))
-			&& (cmd->chanlist_len > 3)) {
-			dev_err(dev->class_dev,
-				"gain must be the same for all channels\n");
-			up(&devpriv->sem);
-			return -EINVAL;
-		}
-		if (i >= NUMCHANNELS) {
-			dev_err(dev->class_dev, "chanlist too long\n");
-			break;
-		}
-	}
-	steps = 0;
-	if (cmd->convert_src == TRIG_TIMER)
-		steps = (cmd->convert_arg * 30) / 1000;
-
-	if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
-		dev_err(dev->class_dev,
-			"steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
-			steps, cmd->scan_begin_arg);
-		up(&devpriv->sem);
-		return -EINVAL;
-	}
-	if (steps > MAX_SAMPLING_PERIOD) {
-		dev_err(dev->class_dev, "sampling rate too low\n");
-		up(&devpriv->sem);
-		return -EINVAL;
-	}
-	if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
-	    && (cmd->chanlist_len != 16)) {
-		dev_err(dev->class_dev,
-			"TRIG_EXT only with 1 or 16 channels possible\n");
-		up(&devpriv->sem);
-		return -EINVAL;
-	}
+	steps = (cmd->convert_arg * 30) / 1000;
 
 	switch (cmd->chanlist_len) {
 	case 1:
@@ -769,19 +729,12 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
 
 		break;
-
-	default:
-		dev_err(dev->class_dev, "unsupported combination of channels\n");
-		up(&devpriv->sem);
-		return -EFAULT;
 	}
 
 	/* 0 means that the AD commands are sent */
-	result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
-	if (result < 0) {
-		up(&devpriv->sem);
-		return result;
-	}
+	ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
+	if (ret < 0)
+		goto cmd_exit;
 
 	if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
 		/* enable this acquisition operation */
@@ -790,16 +743,17 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		if (ret < 0) {
 			devpriv->ai_cmd_running = 0;
 			/* fixme: unlink here?? */
-			up(&devpriv->sem);
-			return ret;
+			goto cmd_exit;
 		}
 		s->async->inttrig = NULL;
 	} else {	/* TRIG_INT */
 		s->async->inttrig = usbduxfast_ai_inttrig;
 	}
+
+cmd_exit:
 	up(&devpriv->sem);
 
-	return 0;
+	return ret;
 }
 
 /*
@@ -814,7 +768,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 	struct usbduxfast_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
 	unsigned int range = CR_RANGE(insn->chanspec);
-	uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
+	u8 rngmask = range ? (0xff - 0x04) : 0xff;
 	int i, j, n, actual_length;
 	int ret;
 
@@ -869,14 +823,14 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 			up(&devpriv->sem);
 			return ret;
 		}
-		n = actual_length / sizeof(uint16_t);
+		n = actual_length / sizeof(u16);
 		if ((n % 16) != 0) {
 			dev_err(dev->class_dev, "insn data packet corrupted\n");
 			up(&devpriv->sem);
 			return -EINVAL;
 		}
 		for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
-			data[i] = ((uint16_t *) (devpriv->inbuf))[j];
+			data[i] = ((u16 *)(devpriv->inbuf))[j];
 			i++;
 		}
 	}
@@ -886,45 +840,12 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 	return insn->n;
 }
 
-static int usbduxfast_attach_common(struct comedi_device *dev)
-{
-	struct usbduxfast_private *devpriv = dev->private;
-	struct comedi_subdevice *s;
-	int ret;
-
-	down(&devpriv->sem);
-
-	ret = comedi_alloc_subdevices(dev, 1);
-	if (ret) {
-		up(&devpriv->sem);
-		return ret;
-	}
-
-	/* Analog Input subdevice */
-	s = &dev->subdevices[0];
-	dev->read_subdev = s;
-	s->type		= COMEDI_SUBD_AI;
-	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
-	s->n_chan	= 16;
-	s->len_chanlist	= 16;
-	s->insn_read	= usbduxfast_ai_insn_read;
-	s->do_cmdtest	= usbduxfast_ai_cmdtest;
-	s->do_cmd	= usbduxfast_ai_cmd;
-	s->cancel	= usbduxfast_ai_cancel;
-	s->maxdata	= 0x1000;
-	s->range_table	= &range_usbduxfast_ai_range;
-
-	up(&devpriv->sem);
-
-	return 0;
-}
-
 static int usbduxfast_upload_firmware(struct comedi_device *dev,
 				      const u8 *data, size_t size,
 				      unsigned long context)
 {
 	struct usb_device *usb = comedi_to_usb_dev(dev);
-	uint8_t *buf;
+	u8 *buf;
 	unsigned char *tmp;
 	int ret;
 
@@ -996,6 +917,7 @@ static int usbduxfast_auto_attach(struct comedi_device *dev,
 	struct usb_interface *intf = comedi_to_usb_interface(dev);
 	struct usb_device *usb = comedi_to_usb_dev(dev);
 	struct usbduxfast_private *devpriv;
+	struct comedi_subdevice *s;
 	int ret;
 
 	if (usb->speed != USB_SPEED_HIGH) {
@@ -1038,7 +960,25 @@ static int usbduxfast_auto_attach(struct comedi_device *dev,
 	if (ret)
 		return ret;
 
-	return usbduxfast_attach_common(dev);
+	ret = comedi_alloc_subdevices(dev, 1);
+	if (ret)
+		return ret;
+
+	/* Analog Input subdevice */
+	s = &dev->subdevices[0];
+	dev->read_subdev = s;
+	s->type		= COMEDI_SUBD_AI;
+	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+	s->n_chan	= 16;
+	s->maxdata	= 0x1000;	/* 12-bit + 1 overflow bit */
+	s->range_table	= &range_usbduxfast_ai_range;
+	s->insn_read	= usbduxfast_ai_insn_read;
+	s->len_chanlist	= s->n_chan;
+	s->do_cmdtest	= usbduxfast_ai_cmdtest;
+	s->do_cmd	= usbduxfast_ai_cmd;
+	s->cancel	= usbduxfast_ai_cancel;
+
+	return 0;
 }
 
 static void usbduxfast_detach(struct comedi_device *dev)
@@ -1058,16 +998,10 @@ static void usbduxfast_detach(struct comedi_device *dev)
 		usb_kill_urb(devpriv->urb);
 
 		kfree(devpriv->inbuf);
-		devpriv->inbuf = NULL;
-
 		usb_free_urb(devpriv->urb);
-		devpriv->urb = NULL;
 	}
 
 	kfree(devpriv->duxbuf);
-	devpriv->duxbuf = NULL;
-
-	devpriv->ai_cmd_running = 0;
 
 	up(&devpriv->sem);
 }
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index 649cf47184a4..d49147bc2786 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -66,22 +66,22 @@
 #define USBDUXSUB_CPUCS 0xE600
 
 /* 300Hz max frequ under PWM */
-#define MIN_PWM_PERIOD  ((long)(1E9/300))
+#define MIN_PWM_PERIOD  ((long)(1E9 / 300))
 
 /* Default PWM frequency */
-#define PWM_DEFAULT_PERIOD ((long)(1E9/100))
+#define PWM_DEFAULT_PERIOD ((long)(1E9 / 100))
 
 /* Number of channels (16 AD and offset)*/
 #define NUMCHANNELS 16
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(uint32_t)))
+#define SIZEADIN          ((sizeof(u32)))
 
 /*
  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
  * as the first byte.
  */
-#define SIZEINBUF         (((NUMCHANNELS+1)*SIZEADIN))
+#define SIZEINBUF         (((NUMCHANNELS + 1) * SIZEADIN))
 
 /* 16 bytes. */
 #define SIZEINSNBUF       16
@@ -90,20 +90,20 @@
 #define NUMOUTCHANNELS    8
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
+#define SIZEDAOUT          ((sizeof(u8) + sizeof(uint16_t)))
 
 /*
  * Size of the output-buffer in bytes
  * Actually only the first 4 triplets are used but for the
  * high speed mode we need to pad it to 8 (microframes).
  */
-#define SIZEOUTBUF         ((8*SIZEDAOUT))
+#define SIZEOUTBUF         ((8 * SIZEDAOUT))
 
 /*
  * Size of the buffer for the dux commands: just now max size is determined
  * by the analogue out + command byte + panic bytes...
  */
-#define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
+#define SIZEOFDUXBUFFER    ((8 * SIZEDAOUT + 2))
 
 /* Number of in-URBs which receive the data: min=2 */
 #define NUMOFINBUFFERSFULL     5
@@ -150,13 +150,13 @@ struct usbduxsigma_private {
 	/* PWM period */
 	unsigned int pwm_period;
 	/* PWM internal delay for the GPIF in the FX2 */
-	uint8_t pwm_delay;
+	u8 pwm_delay;
 	/* size of the PWM buffer which holds the bit pattern */
 	int pwm_buf_sz;
 	/* input buffer for the ISO-transfer */
 	__be32 *in_buf;
 	/* input buffer for single insn */
-	uint8_t *insn_buf;
+	u8 *insn_buf;
 
 	unsigned high_speed:1;
 	unsigned ai_cmd_running:1;
@@ -172,7 +172,7 @@ struct usbduxsigma_private {
 	/* interval in frames/uframes */
 	unsigned int ai_interval;
 	/* commands */
-	uint8_t *dux_commands;
+	u8 *dux_commands;
 	struct semaphore sem;
 };
 
@@ -214,7 +214,7 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
 	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	uint32_t val;
+	u32 val;
 	int ret;
 	int i;
 
@@ -223,15 +223,14 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
 		if (devpriv->ai_counter == 0) {
 			devpriv->ai_counter = devpriv->ai_timer;
 
-			/* get the data from the USB bus
-			   and hand it over to comedi */
+			/*
+			 * Get the data from the USB bus and hand it over
+			 * to comedi. Note, first byte is the DIO state.
+			 */
 			for (i = 0; i < cmd->chanlist_len; i++) {
-				/* transfer data,
-				   note first byte is the DIO state */
-				val = be32_to_cpu(devpriv->in_buf[i+1]);
+				val = be32_to_cpu(devpriv->in_buf[i + 1]);
 				val &= 0x00ffffff; /* strip status byte */
-				val ^= 0x00800000; /* convert to unsigned */
-
+				val = comedi_offset_munge(s, val);
 				if (!comedi_buf_write_samples(s, &val, 1))
 					return;
 			}
@@ -341,7 +340,7 @@ static void usbduxsigma_ao_handle_urb(struct comedi_device *dev,
 	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	uint8_t *datap;
+	u8 *datap;
 	int ret;
 	int i;
 
@@ -553,13 +552,12 @@ static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
  * range is the range value from comedi
  */
 static void create_adc_command(unsigned int chan,
-			       uint8_t *muxsg0,
-			       uint8_t *muxsg1)
+			       u8 *muxsg0, u8 *muxsg1)
 {
 	if (chan < 8)
 		(*muxsg0) = (*muxsg0) | (1 << chan);
 	else if (chan < 16)
-		(*muxsg1) = (*muxsg1) | (1 << (chan-8));
+		(*muxsg1) = (*muxsg1) | (1 << (chan - 8));
 }
 
 static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
@@ -634,9 +632,9 @@ static int usbduxsigma_ai_cmd(struct comedi_device *dev,
 	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int len = cmd->chanlist_len;
-	uint8_t muxsg0 = 0;
-	uint8_t muxsg1 = 0;
-	uint8_t sysred = 0;
+	u8 muxsg0 = 0;
+	u8 muxsg1 = 0;
+	u8 sysred = 0;
 	int ret;
 	int i;
 
@@ -708,9 +706,9 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
 {
 	struct usbduxsigma_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
-	uint8_t muxsg0 = 0;
-	uint8_t muxsg1 = 0;
-	uint8_t sysred = 0;
+	u8 muxsg0 = 0;
+	u8 muxsg1 = 0;
+	u8 sysred = 0;
 	int ret;
 	int i;
 
@@ -738,7 +736,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
 	}
 
 	for (i = 0; i < insn->n; i++) {
-		uint32_t val;
+		u32 val;
 
 		ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
 		if (ret < 0) {
@@ -750,9 +748,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
 		val = be32_to_cpu(get_unaligned((__be32
 						 *)(devpriv->insn_buf + 1)));
 		val &= 0x00ffffff;	/* strip status byte */
-		val ^= 0x00800000;	/* convert to unsigned */
-
-		data[i] = val;
+		data[i] = comedi_offset_munge(s, val);
 	}
 	up(&devpriv->sem);
 
@@ -1220,9 +1216,10 @@ static int usbduxsigma_pwm_config(struct comedi_device *dev,
 
 static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
 {
+	struct comedi_subdevice *s = dev->read_subdev;
 	struct usbduxsigma_private *devpriv = dev->private;
-	uint8_t sysred;
-	uint32_t val;
+	u8 sysred;
+	u32 val;
 	int ret;
 
 	switch (chan) {
@@ -1264,9 +1261,8 @@ static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
 	/* 32 bits big endian from the A/D converter */
 	val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1)));
 	val &= 0x00ffffff;	/* strip status byte */
-	val ^= 0x00800000;	/* convert to unsigned */
 
-	return (int)val;
+	return (int)comedi_offset_munge(s, val);
 }
 
 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
@@ -1274,8 +1270,8 @@ static int usbduxsigma_firmware_upload(struct comedi_device *dev,
 				       unsigned long context)
 {
 	struct usb_device *usb = comedi_to_usb_dev(dev);
-	uint8_t *buf;
-	uint8_t *tmp;
+	u8 *buf;
+	u8 *tmp;
 	int ret;
 
 	if (!data)
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 3af075aa3946..8c7393ef762d 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -1,22 +1,23 @@
 /*
-    comedi/drivers/vmk80xx.c
-    Velleman USB Board Low-Level Driver
-
-    Copyright (C) 2009 Manuel Gebele <forensixs@gmx.de>, Germany
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
+ * vmk80xx.c
+ * Velleman USB Board Low-Level Driver
+ *
+ * Copyright (C) 2009 Manuel Gebele <forensixs@gmx.de>, Germany
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
 
-    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.
-*/
 /*
  * Driver: vmk80xx
  * Description: Velleman USB Board Low-Level Driver
@@ -51,52 +52,52 @@ enum {
 	DEVICE_VMK8061
 };
 
-#define VMK8055_DI_REG          0x00
-#define VMK8055_DO_REG          0x01
-#define VMK8055_AO1_REG         0x02
-#define VMK8055_AO2_REG         0x03
-#define VMK8055_AI1_REG         0x02
-#define VMK8055_AI2_REG         0x03
-#define VMK8055_CNT1_REG        0x04
-#define VMK8055_CNT2_REG        0x06
-
-#define VMK8061_CH_REG          0x01
-#define VMK8061_DI_REG          0x01
-#define VMK8061_DO_REG          0x01
-#define VMK8061_PWM_REG1        0x01
-#define VMK8061_PWM_REG2        0x02
-#define VMK8061_CNT_REG         0x02
-#define VMK8061_AO_REG          0x02
-#define VMK8061_AI_REG1         0x02
-#define VMK8061_AI_REG2         0x03
-
-#define VMK8055_CMD_RST         0x00
-#define VMK8055_CMD_DEB1_TIME   0x01
-#define VMK8055_CMD_DEB2_TIME   0x02
-#define VMK8055_CMD_RST_CNT1    0x03
-#define VMK8055_CMD_RST_CNT2    0x04
-#define VMK8055_CMD_WRT_AD      0x05
-
-#define VMK8061_CMD_RD_AI       0x00
-#define VMK8061_CMR_RD_ALL_AI   0x01	/* !non-active! */
-#define VMK8061_CMD_SET_AO      0x02
-#define VMK8061_CMD_SET_ALL_AO  0x03	/* !non-active! */
-#define VMK8061_CMD_OUT_PWM     0x04
-#define VMK8061_CMD_RD_DI       0x05
-#define VMK8061_CMD_DO          0x06	/* !non-active! */
-#define VMK8061_CMD_CLR_DO      0x07
-#define VMK8061_CMD_SET_DO      0x08
-#define VMK8061_CMD_RD_CNT      0x09	/* TODO: completely pointless? */
-#define VMK8061_CMD_RST_CNT     0x0a	/* TODO: completely pointless? */
-#define VMK8061_CMD_RD_VERSION  0x0b	/* internal usage */
-#define VMK8061_CMD_RD_JMP_STAT 0x0c	/* TODO: not implemented yet */
-#define VMK8061_CMD_RD_PWR_STAT 0x0d	/* internal usage */
-#define VMK8061_CMD_RD_DO       0x0e
-#define VMK8061_CMD_RD_AO       0x0f
-#define VMK8061_CMD_RD_PWM      0x10
-
-#define IC3_VERSION             (1 << 0)
-#define IC6_VERSION             (1 << 1)
+#define VMK8055_DI_REG		0x00
+#define VMK8055_DO_REG		0x01
+#define VMK8055_AO1_REG		0x02
+#define VMK8055_AO2_REG		0x03
+#define VMK8055_AI1_REG		0x02
+#define VMK8055_AI2_REG		0x03
+#define VMK8055_CNT1_REG	0x04
+#define VMK8055_CNT2_REG	0x06
+
+#define VMK8061_CH_REG		0x01
+#define VMK8061_DI_REG		0x01
+#define VMK8061_DO_REG		0x01
+#define VMK8061_PWM_REG1	0x01
+#define VMK8061_PWM_REG2	0x02
+#define VMK8061_CNT_REG		0x02
+#define VMK8061_AO_REG		0x02
+#define VMK8061_AI_REG1		0x02
+#define VMK8061_AI_REG2		0x03
+
+#define VMK8055_CMD_RST		0x00
+#define VMK8055_CMD_DEB1_TIME	0x01
+#define VMK8055_CMD_DEB2_TIME	0x02
+#define VMK8055_CMD_RST_CNT1	0x03
+#define VMK8055_CMD_RST_CNT2	0x04
+#define VMK8055_CMD_WRT_AD	0x05
+
+#define VMK8061_CMD_RD_AI	0x00
+#define VMK8061_CMR_RD_ALL_AI	0x01	/* !non-active! */
+#define VMK8061_CMD_SET_AO	0x02
+#define VMK8061_CMD_SET_ALL_AO	0x03	/* !non-active! */
+#define VMK8061_CMD_OUT_PWM	0x04
+#define VMK8061_CMD_RD_DI	0x05
+#define VMK8061_CMD_DO		0x06	/* !non-active! */
+#define VMK8061_CMD_CLR_DO	0x07
+#define VMK8061_CMD_SET_DO	0x08
+#define VMK8061_CMD_RD_CNT	0x09	/* TODO: completely pointless? */
+#define VMK8061_CMD_RST_CNT	0x0a	/* TODO: completely pointless? */
+#define VMK8061_CMD_RD_VERSION	0x0b	/* internal usage */
+#define VMK8061_CMD_RD_JMP_STAT	0x0c	/* TODO: not implemented yet */
+#define VMK8061_CMD_RD_PWR_STAT	0x0d	/* internal usage */
+#define VMK8061_CMD_RD_DO	0x0e
+#define VMK8061_CMD_RD_AO	0x0f
+#define VMK8061_CMD_RD_PWM	0x10
+
+#define IC3_VERSION		BIT(0)
+#define IC6_VERSION		BIT(1)
 
 enum vmk80xx_model {
 	VMK8055_MODEL,
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 76bf5619fdd5..d0a8a28edd36 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -1,20 +1,20 @@
 /*
-    kcomedilib/kcomedilib.c
-    a comedlib interface for kernel modules
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.
-*/
+ * kcomedilib/kcomedilib.c
+ * a comedlib interface for kernel modules
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/module.h>
 
diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c
index 9112dd2bf4d7..303d97023ccb 100644
--- a/drivers/staging/dgap/dgap.c
+++ b/drivers/staging/dgap/dgap.c
@@ -287,28 +287,6 @@ static struct toklist dgap_tlist[] = {
 	{ 0,		NULL }
 };
 
-
-/*
- * dgap_sindex: much like index(), but it looks for a match of any character in
- * the group, and returns that position.
- */
-static char *dgap_sindex(char *string, char *group)
-{
-	char *ptr;
-
-	if (!string || !group)
-		return NULL;
-
-	for (; *string; string++) {
-		for (ptr = group; *ptr; ptr++) {
-			if (*ptr == *string)
-				return string;
-		}
-	}
-
-	return NULL;
-}
-
 /*
  * get a word from the input stream, also keep track of current line number.
  * words are separated by whitespace.
@@ -317,7 +295,7 @@ static char *dgap_getword(char **in)
 {
 	char *ret_ptr = *in;
 
-	char *ptr = dgap_sindex(*in, " \t\n");
+	char *ptr = strpbrk(*in, " \t\n");
 
 	/* If no word found, return null */
 	if (!ptr)
@@ -349,6 +327,8 @@ static int dgap_gettok(char **in)
 
 	if (strstr(dgap_cword, "board")) {
 		w = dgap_getword(in);
+		if (!w)
+			return 0;
 		snprintf(dgap_cword, MAXCWORD, "%s", w);
 		for (t = dgap_brdtype; t->token != 0; t++) {
 			if (!strcmp(w, t->string))
@@ -1864,7 +1844,6 @@ static int dgap_event(struct board_t *bd)
 	int port;
 	int reason;
 	int modem;
-	int b1;
 
 	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
 		return -EIO;
@@ -1909,7 +1888,7 @@ static int dgap_event(struct board_t *bd)
 		port   = ioread8(event);
 		reason = ioread8(event + 1);
 		modem  = ioread8(event + 2);
-		b1     = ioread8(event + 3);
+		ioread8(event + 3);
 
 		/*
 		 * Make sure the interrupt is valid.
@@ -4568,7 +4547,6 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
  */
 static void dgap_tty_close(struct tty_struct *tty, struct file *file)
 {
-	struct ktermios *ts;
 	struct board_t *bd;
 	struct channel_t *ch;
 	struct un_t *un;
@@ -4589,8 +4567,6 @@ static void dgap_tty_close(struct tty_struct *tty, struct file *file)
 	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
 		return;
 
-	ts = &tty->termios;
-
 	spin_lock_irqsave(&ch->ch_lock, lock_flags);
 
 	/*
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
index b6b76ff09657..597b78df7c1a 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -12,10 +12,6 @@
  *  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, Suite 500, Boston, MA 02110-1335, USA.
  */
 
 #include <linux/kernel.h>
@@ -67,12 +63,10 @@ static void _nbu2ss_fifo_flush(struct nbu2ss_udc *, struct nbu2ss_ep *);
 #define	_nbu2ss_zero_len_pkt(udc, epnum)	\
 	_nbu2ss_ep_in_end(udc, epnum, 0, 0)
 
-
 /*===========================================================================*/
 /* Global */
 struct nbu2ss_udc udc_controller;
 
-
 /*-------------------------------------------------------------------------*/
 /* Read */
 static inline u32 _nbu2ss_readl(void *address)
@@ -114,7 +108,7 @@ static void _nbu2ss_dump_register(struct nbu2ss_udc *udc)
 
 	pr_info("=== %s()\n", __func__);
 
-	if (udc == NULL) {
+	if (!udc) {
 		pr_err("%s udc == NULL\n", __func__);
 		return;
 	}
@@ -155,7 +149,7 @@ static void _nbu2ss_ep0_complete(struct usb_ep *_ep, struct usb_request *_req)
 	struct usb_ctrlrequest	*p_ctrl;
 	struct nbu2ss_udc *udc;
 
-	if ((_ep == NULL) || (_req == NULL))
+	if ((!_ep) || (!_req))
 		return;
 
 	udc = (struct nbu2ss_udc *)_req->context;
@@ -691,7 +685,6 @@ static int EP0_receive_NULL(struct nbu2ss_udc *udc, bool pid_flag)
 /*-------------------------------------------------------------------------*/
 static int _nbu2ss_ep0_in_transfer(
 	struct nbu2ss_udc *udc,
-	struct nbu2ss_ep *ep,
 	struct nbu2ss_req *req
 )
 {
@@ -749,7 +742,6 @@ static int _nbu2ss_ep0_in_transfer(
 /*-------------------------------------------------------------------------*/
 static int _nbu2ss_ep0_out_transfer(
 	struct nbu2ss_udc *udc,
-	struct nbu2ss_ep *ep,
 	struct nbu2ss_req *req
 )
 {
@@ -1258,11 +1250,11 @@ static int _nbu2ss_start_transfer(
 		/* EP0 */
 		switch (udc->ep0state) {
 		case EP0_IN_DATA_PHASE:
-			nret = _nbu2ss_ep0_in_transfer(udc, ep, req);
+			nret = _nbu2ss_ep0_in_transfer(udc, req);
 			break;
 
 		case EP0_OUT_DATA_PHASE:
-			nret = _nbu2ss_ep0_out_transfer(udc, ep, req);
+			nret = _nbu2ss_ep0_out_transfer(udc, req);
 			break;
 
 		case EP0_IN_STATUS_PHASE:
@@ -1300,7 +1292,7 @@ static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep)
 	else
 		req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
 
-	if (req == NULL)
+	if (!req)
 		return;
 
 	if (ep->epnum > 0) {
@@ -1398,7 +1390,6 @@ static void _nbu2ss_set_endpoint_stall(
 	}
 }
 
-
 /*-------------------------------------------------------------------------*/
 /* Device Descriptor */
 static struct usb_device_descriptor device_desc = {
@@ -1635,7 +1626,7 @@ static int std_req_get_status(struct nbu2ss_udc *udc)
 	if (result >= 0) {
 		memcpy(udc->ep0_buf, &status_data, length);
 		_nbu2ss_create_ep0_packet(udc, udc->ep0_buf, length);
-		_nbu2ss_ep0_in_transfer(udc, &udc->ep[0], &udc->ep0_req);
+		_nbu2ss_ep0_in_transfer(udc, &udc->ep0_req);
 
 	} else {
 		dev_err(udc->dev, " Error GET_STATUS\n");
@@ -1707,7 +1698,7 @@ static int std_req_set_configuration(struct nbu2ss_udc *udc)
 /*-------------------------------------------------------------------------*/
 static inline void _nbu2ss_read_request_data(struct nbu2ss_udc *udc, u32 *pdata)
 {
-	if ((udc == NULL) && (pdata == NULL))
+	if ((!udc) && (!pdata))
 		return;
 
 	*pdata = _nbu2ss_readl(&udc->p_regs->SETUP_DATA0);
@@ -1800,13 +1791,13 @@ static inline int _nbu2ss_ep0_in_data_stage(struct nbu2ss_udc *udc)
 	else
 		req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
 
-	if (req == NULL)
+	if (!req)
 		req = &udc->ep0_req;
 
 	req->req.actual += req->div_len;
 	req->div_len = 0;
 
-	nret = _nbu2ss_ep0_in_transfer(udc, ep, req);
+	nret = _nbu2ss_ep0_in_transfer(udc, req);
 	if (nret == 0) {
 		udc->ep0state = EP0_OUT_STATUS_PAHSE;
 		EP0_receive_NULL(udc, TRUE);
@@ -1827,10 +1818,10 @@ static inline int _nbu2ss_ep0_out_data_stage(struct nbu2ss_udc *udc)
 	else
 		req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
 
-	if (req == NULL)
+	if (!req)
 		req = &udc->ep0_req;
 
-	nret = _nbu2ss_ep0_out_transfer(udc, ep, req);
+	nret = _nbu2ss_ep0_out_transfer(udc, req);
 	if (nret == 0) {
 		udc->ep0state = EP0_IN_STATUS_PHASE;
 		EP0_send_NULL(udc, TRUE);
@@ -1854,7 +1845,7 @@ static inline int _nbu2ss_ep0_status_stage(struct nbu2ss_udc *udc)
 	else
 		req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
 
-	if (req == NULL) {
+	if (!req) {
 		req = &udc->ep0_req;
 		if (req->req.complete)
 			req->req.complete(&ep->ep, &req->req);
@@ -2161,7 +2152,7 @@ static inline void _nbu2ss_epn_int(struct nbu2ss_udc *udc, u32 epnum)
 	else
 		req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
 
-	if (req == NULL) {
+	if (!req) {
 		/* pr_warn("=== %s(%d) req == NULL\n", __func__, epnum); */
 		return;
 	}
@@ -2199,7 +2190,6 @@ static void _nbu2ss_ep0_enable(struct nbu2ss_udc *udc)
 	_nbu2ss_writel(&udc->p_regs->EP0_INT_ENA, EP0_INT_EN_BIT);
 }
 
-
 /*-------------------------------------------------------------------------*/
 static int _nbu2ss_nuke(struct nbu2ss_udc *udc,
 			struct nbu2ss_ep *ep,
@@ -2335,7 +2325,6 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc)
 	return 0;
 }
 
-
 /*-------------------------------------------------------------------------*/
 static void _nbu2ss_reset_controller(struct nbu2ss_udc *udc)
 {
@@ -2568,13 +2557,13 @@ static int nbu2ss_ep_enable(
 	struct nbu2ss_ep	*ep;
 	struct nbu2ss_udc	*udc;
 
-	if ((_ep == NULL) || (desc == NULL)) {
+	if ((!_ep) || (!desc)) {
 		pr_err(" *** %s, bad param\n", __func__);
 		return -EINVAL;
 	}
 
 	ep = container_of(_ep, struct nbu2ss_ep, ep);
-	if ((ep == NULL) || (ep->udc == NULL)) {
+	if ((!ep) || (!ep->udc)) {
 		pr_err(" *** %s, ep == NULL !!\n", __func__);
 		return -EINVAL;
 	}
@@ -2591,7 +2580,7 @@ static int nbu2ss_ep_enable(
 	if (udc->vbus_active == 0)
 		return -ESHUTDOWN;
 
-	if ((udc->driver == NULL)
+	if ((!udc->driver)
 		|| (udc->gadget.speed == USB_SPEED_UNKNOWN)) {
 
 		dev_err(ep->udc->dev, " *** %s, udc !!\n", __func__);
@@ -2628,13 +2617,13 @@ static int nbu2ss_ep_disable(struct usb_ep *_ep)
 	struct nbu2ss_udc	*udc;
 	unsigned long		flags;
 
-	if (_ep == NULL) {
+	if (!_ep) {
 		pr_err(" *** %s, bad param\n", __func__);
 		return -EINVAL;
 	}
 
 	ep = container_of(_ep, struct nbu2ss_ep, ep);
-	if ((ep == NULL) || (ep->udc == NULL)) {
+	if ((!ep) || (!ep->udc)) {
 		pr_err("udc: *** %s, ep == NULL !!\n", __func__);
 		return -EINVAL;
 	}
@@ -2676,7 +2665,7 @@ static void nbu2ss_ep_free_request(
 {
 	struct nbu2ss_req *req;
 
-	if (_req != NULL) {
+	if (_req) {
 		req = container_of(_req, struct nbu2ss_req, req);
 
 		kfree(req);
@@ -2697,11 +2686,11 @@ static int nbu2ss_ep_queue(
 	int			result = -EINVAL;
 
 	/* catch various bogus parameters */
-	if ((_ep == NULL) || (_req == NULL)) {
-		if (_ep == NULL)
+	if ((!_ep) || (!_req)) {
+		if (!_ep)
 			pr_err("udc: %s --- _ep == NULL\n", __func__);
 
-		if (_req == NULL)
+		if (!_req)
 			pr_err("udc: %s --- _req == NULL\n", __func__);
 
 		return -EINVAL;
@@ -2747,7 +2736,7 @@ static int nbu2ss_ep_queue(
 		req->unaligned = FALSE;
 
 	if (req->unaligned) {
-		if (ep->virt_buf == NULL)
+		if (!ep->virt_buf)
 			ep->virt_buf = (u8 *)dma_alloc_coherent(
 				NULL, PAGE_SIZE,
 				&ep->phys_buf, GFP_ATOMIC | GFP_DMA);
@@ -2803,7 +2792,7 @@ static int nbu2ss_ep_dequeue(
 	unsigned long flags;
 
 	/* catch various bogus parameters */
-	if ((_ep == NULL) || (_req == NULL)) {
+	if ((!_ep) || (!_req)) {
 		/* pr_err("%s, bad param(1)\n", __func__); */
 		return -EINVAL;
 	}
@@ -2815,7 +2804,7 @@ static int nbu2ss_ep_dequeue(
 	}
 
 	udc = ep->udc;
-	if (udc == NULL)
+	if (!udc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&udc->lock, flags);
@@ -2989,7 +2978,6 @@ static struct usb_ep_ops nbu2ss_ep_ops = {
 	.fifo_flush	= nbu2ss_ep_fifo_flush,
 };
 
-
 /*-------------------------------------------------------------------------*/
 /* usb_gadget_ops */
 
@@ -2999,13 +2987,13 @@ static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget)
 	u32			data;
 	struct nbu2ss_udc	*udc;
 
-	if (pgadget == NULL) {
+	if (!pgadget) {
 		pr_err("udc: %s, bad param\n", __func__);
 		return -EINVAL;
 	}
 
 	udc = container_of(pgadget, struct nbu2ss_udc, gadget);
-	if (udc == NULL) {
+	if (!udc) {
 		dev_err(&pgadget->dev, "%s, udc == NULL\n", __func__);
 		return -EINVAL;
 	}
@@ -3027,13 +3015,13 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget)
 
 	struct nbu2ss_udc	*udc;
 
-	if (pgadget == NULL) {
+	if (!pgadget) {
 		pr_err("%s, bad param\n", __func__);
 		return -EINVAL;
 	}
 
 	udc = container_of(pgadget, struct nbu2ss_udc, gadget);
-	if (udc == NULL) {
+	if (!udc) {
 		dev_err(&pgadget->dev, "%s, udc == NULL\n", __func__);
 		return -EINVAL;
 	}
@@ -3065,7 +3053,7 @@ static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget,
 	struct nbu2ss_udc       *udc;
 	unsigned long		flags;
 
-	if (pgadget == NULL) {
+	if (!pgadget) {
 		pr_err("%s, bad param\n", __func__);
 		return -EINVAL;
 	}
@@ -3091,7 +3079,7 @@ static int nbu2ss_gad_vbus_draw(struct usb_gadget *pgadget, unsigned mA)
 	struct nbu2ss_udc	*udc;
 	unsigned long		flags;
 
-	if (pgadget == NULL) {
+	if (!pgadget) {
 		pr_err("%s, bad param\n", __func__);
 		return -EINVAL;
 	}
@@ -3111,14 +3099,14 @@ static int nbu2ss_gad_pullup(struct usb_gadget *pgadget, int is_on)
 	struct nbu2ss_udc	*udc;
 	unsigned long		flags;
 
-	if (pgadget == NULL) {
+	if (!pgadget) {
 		pr_err("%s, bad param\n", __func__);
 		return -EINVAL;
 	}
 
 	udc = container_of(pgadget, struct nbu2ss_udc, gadget);
 
-	if (udc->driver == NULL) {
+	if (!udc->driver) {
 		pr_warn("%s, Not Regist Driver\n", __func__);
 		return -EINVAL;
 	}
@@ -3142,7 +3130,6 @@ static int nbu2ss_gad_ioctl(
 	return 0;
 }
 
-
 static const struct usb_gadget_ops nbu2ss_gadget_ops = {
 	.get_frame		= nbu2ss_gad_get_frame,
 	.wakeup			= nbu2ss_gad_wakeup,
@@ -3295,14 +3282,14 @@ static int nbu2ss_drv_probe(struct platform_device *pdev)
 	/* USB Function Controller Interrupt */
 	if (status != 0) {
 		dev_err(udc->dev, "request_irq(USB_UDC_IRQ_1) failed\n");
-		goto cleanup1;
+		return status;
 	}
 
 	/* Driver Initialization */
 	status = nbu2ss_drv_contest_init(pdev, udc);
 	if (status < 0) {
 		/* Error */
-		goto cleanup1;
+		return status;
 	}
 
 	/* VBUS Interrupt */
@@ -3315,13 +3302,10 @@ static int nbu2ss_drv_probe(struct platform_device *pdev)
 
 	if (status != 0) {
 		dev_err(udc->dev, "request_irq(INT_VBUS) failed\n");
-		goto cleanup1;
+		return status;
 	}
 
 	return status;
-
-cleanup1:
-	return status;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -3330,7 +3314,7 @@ static void nbu2ss_drv_shutdown(struct platform_device *pdev)
 	struct nbu2ss_udc	*udc;
 
 	udc = platform_get_drvdata(pdev);
-	if (udc == NULL)
+	if (!udc)
 		return;
 
 	_nbu2ss_disable_controller(udc);
@@ -3364,7 +3348,7 @@ static int nbu2ss_drv_suspend(struct platform_device *pdev, pm_message_t state)
 	struct nbu2ss_udc	*udc;
 
 	udc = platform_get_drvdata(pdev);
-	if (udc == NULL)
+	if (!udc)
 		return 0;
 
 	if (udc->vbus_active) {
@@ -3391,7 +3375,7 @@ static int nbu2ss_drv_resume(struct platform_device *pdev)
 	struct nbu2ss_udc	*udc;
 
 	udc = platform_get_drvdata(pdev);
-	if (udc == NULL)
+	if (!udc)
 		return 0;
 
 	data = gpio_get_value(VBUS_VALUE);
@@ -3407,7 +3391,6 @@ static int nbu2ss_drv_resume(struct platform_device *pdev)
 	return 0;
 }
 
-
 static struct platform_driver udc_driver = {
 	.probe		= nbu2ss_drv_probe,
 	.shutdown	= nbu2ss_drv_shutdown,
@@ -3425,4 +3408,3 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Renesas Electronics Corporation");
 MODULE_LICENSE("GPL");
 
-
diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h
index 0db6b41333ea..4a2cc38de7b3 100644
--- a/drivers/staging/emxx_udc/emxx_udc.h
+++ b/drivers/staging/emxx_udc/emxx_udc.h
@@ -11,20 +11,11 @@
  *  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, Suite 500, Boston, MA 02110-1335, USA.
  */
 
-
-
-
 #ifndef _LINUX_EMXX_H
 #define _LINUX_EMXX_H
 
-
-
 /*---------------------------------------------------------------------------*/
 /*----------------- Default undef */
 #if 0
@@ -36,14 +27,11 @@
 #define	USE_DMA	1
 #define USE_SUSPEND_WAIT	1
 
-
-
 #ifndef TRUE
 #define TRUE	1
 #define FALSE	0
 #endif
 
-
 /*------------ Board dependence(Resource) */
 #define	VBUS_VALUE		GPIO_VBUS
 
@@ -58,15 +46,11 @@
 /* DMA Abort wait time ms */
 #define DMA_DISABLE_TIME		10
 
-
-
 /*------------ Controller dependence */
 #define NUM_ENDPOINTS		14		/* Endpoint */
 #define REG_EP_NUM		15		/* Endpoint Register */
 #define DMA_MAX_COUNT		256		/* DMA Block */
 
-
-
 #define EPC_RST_DISABLE_TIME		1	/* 1 usec */
 #define EPC_DIRPD_DISABLE_TIME		1	/* 1 msec */
 #define EPC_PLL_LOCK_COUNT		1000	/* 1000 */
@@ -75,12 +59,10 @@
 #define CHATGER_TIME			700	/* 700msec */
 #define USB_SUSPEND_TIME		2000	/* 2 sec */
 
-
 /* U2F FLAG */
 #define U2F_ENABLE		1
 #define U2F_DISABLE		0
 
-
 /*------- BIT */
 #define BIT00		0x00000001
 #define BIT01		0x00000002
@@ -460,8 +442,6 @@
 /*------- (0x1118:) EPnTADR Register */
 #define EPn_TADR			0xFFFFFFFF	/* RW */
 
-
-
 /*===========================================================================*/
 /* Struct */
 /*------- ep_regs */
@@ -526,13 +506,6 @@ struct fc_regs {
 	u8 Reserved1200[0x1000-0x200];	/* Reserved */
 } __aligned(32);
 
-
-
-
-
-
-
-
 #define EP0_PACKETSIZE			64
 #define EP_PACKETSIZE			1024
 
@@ -543,10 +516,8 @@ struct fc_regs {
 #define D_FS_RAM_SIZE_BULK		64
 #define D_HS_RAM_SIZE_BULK		512
 
-
 struct nbu2ss_udc;
 
-
 enum ep0_state {
 	EP0_IDLE,
 	EP0_IN_DATA_PHASE,
@@ -591,7 +562,6 @@ struct nbu2ss_ep {
 	dma_addr_t	phys_buf;
 };
 
-
 struct nbu2ss_udc {
 	struct usb_gadget gadget;
 	struct usb_gadget_driver *driver;
diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
index 94dd49ce18de..8eb5e696fa9a 100644
--- a/drivers/staging/fbtft/fb_agm1264k-fl.c
+++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
@@ -41,8 +41,7 @@
 #define CS0			gpio.aux[0]
 #define CS1			gpio.aux[1]
 
-
-/* diffusing error (�Floyd-Steinberg�) */
+/* diffusing error (Floyd-Steinberg) */
 #define DIFFUSING_MATRIX_WIDTH	2
 #define DIFFUSING_MATRIX_HEIGHT	2
 
@@ -245,10 +244,6 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 	addr_win.ys_page = ys / 8;
 	addr_win.xe = xe;
 	addr_win.ye_page = ye / 8;
-
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys_page=%d, xe=%d, ye_page=%d)\n", __func__,
-		addr_win.xs, addr_win.ys_page, addr_win.xe, addr_win.ye_page);
 }
 
 static void
@@ -420,7 +415,6 @@ static int write(struct fbtft_par *par, void *buf, size_t len)
 
 	gpio_set_value(par->RW, 0); /* set write mode */
 
-
 	while (len--) {
 		u8 i, data;
 
@@ -456,6 +450,7 @@ static struct fbtft_display display = {
 		.write_vmem = write_vmem,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", &display);
 
 MODULE_ALIAS("platform:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c
index 17a2162a7e5b..ea013e9d45e6 100644
--- a/drivers/staging/fbtft/fb_bd663474.c
+++ b/drivers/staging/fbtft/fb_bd663474.c
@@ -16,10 +16,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -122,8 +118,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
 	switch (par->info->var.rotate) {
 	/* R200h = Horizontal GRAM Start Address */
 	/* R201h = Vertical GRAM Start Address */
@@ -181,6 +175,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "hitachi,bd663474", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c
index 54528aa0c0ef..e1ed177f9184 100644
--- a/drivers/staging/fbtft/fb_hx8340bn.c
+++ b/drivers/staging/fbtft/fb_hx8340bn.c
@@ -17,10 +17,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -39,12 +35,10 @@
 #define DEFAULT_GAMMA	"1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
 			"3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
 
-
 static bool emulate;
 module_param(emulate, bool, 0);
 MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
 
-
 static int init_display(struct fbtft_par *par)
 {
 	par->fbtftops.reset(par);
@@ -117,9 +111,9 @@ static int set_var(struct fbtft_par *par)
 {
 	/* MADCTL - Memory data access control */
 	/* RGB/BGR can be set with H/W pin SRGB and MADCTL BGR bit */
-#define MY (1 << 7)
-#define MX (1 << 6)
-#define MV (1 << 5)
+#define MY BIT(7)
+#define MX BIT(6)
+#define MV BIT(5)
 	switch (par->info->var.rotate) {
 	case 0:
 		write_reg(par, 0x36, par->bgr << 3);
@@ -145,7 +139,7 @@ static int set_var(struct fbtft_par *par)
     OP0 OP1 CP0 CP1 CP2 CP3 CP4 MP0 MP1 MP2 MP3 MP4 MP5 CGM0 CGM1
     ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX  GC
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -192,7 +186,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -208,6 +201,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c
index 03ae95b4f79e..8b3ee2460b8c 100644
--- a/drivers/staging/fbtft/fb_hx8347d.c
+++ b/drivers/staging/fbtft/fb_hx8347d.c
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -33,7 +29,6 @@
 #define DEFAULT_GAMMA	"0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" \
 			"0 0 0 0 0 0 0 0 0 0 0 0 0 0"
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -92,9 +87,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	write_reg(par, 0x02, (xs >> 8) & 0xFF);
 	write_reg(par, 0x03, xs & 0xFF);
 	write_reg(par, 0x04, (xe >> 8) & 0xFF);
@@ -111,7 +103,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
     VRP0 VRP1 VRP2 VRP3 VRP4 VRP5 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 CGM
     VRN0 VRN1 VRN2 VRN3 VRN4 VRN5 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 CGM
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -154,7 +146,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -168,6 +159,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8347d", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_hx8353d.c b/drivers/staging/fbtft/fb_hx8353d.c
index d7f4308e1249..b36f6e1f6fbe 100644
--- a/drivers/staging/fbtft/fb_hx8353d.c
+++ b/drivers/staging/fbtft/fb_hx8353d.c
@@ -13,10 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -78,9 +74,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* column address */
 	write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
 
@@ -91,9 +84,9 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 	write_reg(par, 0x2c);
 }
 
-#define my (1 << 7)
-#define mx (1 << 6)
-#define mv (1 << 5)
+#define my BIT(7)
+#define mx BIT(6)
+#define mv BIT(5)
 static int set_var(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -139,7 +132,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = 128,
@@ -154,6 +146,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8353d", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_hx8357d.c b/drivers/staging/fbtft/fb_hx8357d.c
index 8c7bb3ac8030..3a28a36904bc 100644
--- a/drivers/staging/fbtft/fb_hx8357d.c
+++ b/drivers/staging/fbtft/fb_hx8357d.c
@@ -16,9 +16,6 @@
  * 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/module.h>
@@ -33,7 +30,6 @@
 #define WIDTH		320
 #define HEIGHT		480
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -145,9 +141,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column addr set */
 	write_reg(par, HX8357_CASET,
 		xs >> 8, xs & 0xff,  /* XSTART */
@@ -210,6 +203,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8357d", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c
index ed92a64306ff..d166ca905d97 100644
--- a/drivers/staging/fbtft/fb_ili9163.c
+++ b/drivers/staging/fbtft/fb_ili9163.c
@@ -149,9 +149,6 @@ static int init_display(struct fbtft_par *par)
 static void set_addr_win(struct fbtft_par *par, int xs, int ys,
 				int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	switch (par->info->var.rotate) {
 	case 0:
 		write_reg(par, CMD_CLMADRS, xs >> 8, xs & 0xff, xe >> 8,
@@ -230,7 +227,7 @@ static int set_var(struct fbtft_par *par)
 }
 
 #ifdef GAMMA_ADJ
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int gamma_adj(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -243,7 +240,7 @@ static int gamma_adj(struct fbtft_par *par, unsigned long *curves)
 
 	for (i = 0; i < GAMMA_NUM; i++)
 		for (j = 0; j < GAMMA_LEN; j++)
-			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
 
 	write_reg(par, CMD_PGAMMAC,
 				CURVE(0, 0),
diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c
index ef4fa6b72c79..30bed2c674c9 100644
--- a/drivers/staging/fbtft/fb_ili9320.c
+++ b/drivers/staging/fbtft/fb_ili9320.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -33,7 +29,6 @@
 #define DEFAULT_GAMMA	"07 07 6 0 0 0 5 5 4 0\n" \
 			"07 08 4 7 5 1 2 0 7 7"
 
-
 static unsigned read_devicecode(struct fbtft_par *par)
 {
 	int ret;
@@ -96,7 +91,6 @@ static int init_display(struct fbtft_par *par)
 	/* RGB interface polarity */
 	write_reg(par, 0x000F, 0x0000);
 
-
 	/* ***********Power On sequence *************** */
 	/* SAP, BT[3:0], AP, DSTB, SLP, STB */
 	write_reg(par, 0x0010, 0x0000);
@@ -181,9 +175,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	switch (par->info->var.rotate) {
 	/* R20h = Horizontal GRAM Start Address */
 	/* R21h = Vertical GRAM Start Address */
@@ -233,7 +224,7 @@ static int set_var(struct fbtft_par *par)
     VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
     VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -247,7 +238,7 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	/* apply mask */
 	for (i = 0; i < 2; i++)
 		for (j = 0; j < 10; j++)
-			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
 
 	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
 	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
@@ -265,7 +256,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 16,
 	.width = WIDTH,
@@ -280,6 +270,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9320", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c
index 19d254e9a420..25e5a11d451e 100644
--- a/drivers/staging/fbtft/fb_ili9325.c
+++ b/drivers/staging/fbtft/fb_ili9325.c
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -36,7 +32,6 @@
 #define DEFAULT_GAMMA	"0F 00 7 2 0 0 6 5 4 1\n" \
 			"04 16 2 7 6 3 2 1 7 7"
 
-
 static unsigned bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
 module_param(bt, uint, 0);
 MODULE_PARM_DESC(bt, "Sets the factor used in the step-up circuits");
@@ -60,7 +55,6 @@ static unsigned vcm = 0x0a; /* VCOMH=VREG1OUT*0.735 */
 module_param(vcm, uint, 0);
 MODULE_PARM_DESC(vcm, "Set the internal VcomH voltage");
 
-
 /*
 Verify that this configuration is within the Voltage limits
 
@@ -176,8 +170,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
 	switch (par->info->var.rotate) {
 	/* R20h = Horizontal GRAM Start Address */
 	/* R21h = Vertical GRAM Start Address */
@@ -229,7 +221,7 @@ static int set_var(struct fbtft_par *par)
     VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
     VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -243,7 +235,7 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	/* apply mask */
 	for (i = 0; i < 2; i++)
 		for (j = 0; j < 10; j++)
-			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
 
 	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
 	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
@@ -261,7 +253,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 16,
 	.width = WIDTH,
@@ -278,6 +269,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9325", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c
index 0f4a42f89e5e..7efd8bc1201b 100644
--- a/drivers/staging/fbtft/fb_ili9340.c
+++ b/drivers/staging/fbtft/fb_ili9340.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -30,7 +26,6 @@
 #define WIDTH		240
 #define HEIGHT		320
 
-
 /* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */
 static int init_display(struct fbtft_par *par)
 {
@@ -98,9 +93,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address */
 	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
 
@@ -140,7 +132,6 @@ static int set_var(struct fbtft_par *par)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -151,6 +142,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9340", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c
index 709492e560b6..d07a312ad293 100644
--- a/drivers/staging/fbtft/fb_ili9341.c
+++ b/drivers/staging/fbtft/fb_ili9341.c
@@ -18,10 +18,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -38,7 +34,6 @@
 #define DEFAULT_GAMMA	"1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
 			"00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -82,9 +77,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address set */
 	write_reg(par, 0x2A,
 		(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
@@ -113,7 +105,7 @@ static int set_var(struct fbtft_par *par)
 		break;
 	case 270:
 		write_reg(par, 0x36,
-			(1<<MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
+			(1 << MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
 		break;
 	case 180:
 		write_reg(par, 0x36, (1 << MEM_Y) | (par->bgr << MEM_BGR));
@@ -132,7 +124,7 @@ static int set_var(struct fbtft_par *par)
     Positive: Par1 Par2 [...] Par15
     Negative: Par1 Par2 [...] Par15
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	int i;
@@ -151,7 +143,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -167,6 +158,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9481.c b/drivers/staging/fbtft/fb_ili9481.c
index 8bae09c2d5ce..85387f01d254 100644
--- a/drivers/staging/fbtft/fb_ili9481.c
+++ b/drivers/staging/fbtft/fb_ili9481.c
@@ -13,10 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -57,9 +53,6 @@ static int default_init_sequence[] = {
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* column address */
 	write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
 
@@ -105,6 +98,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9481", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ili9486.c b/drivers/staging/fbtft/fb_ili9486.c
index dd4ddca384ad..10068b0d1de9 100644
--- a/drivers/staging/fbtft/fb_ili9486.c
+++ b/drivers/staging/fbtft/fb_ili9486.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -28,7 +24,6 @@
 #define WIDTH		320
 #define HEIGHT		480
 
-
 /* this init sequence matches PiScreen */
 static int default_init_sequence[] = {
 	/* Interface Mode Control */
@@ -61,9 +56,6 @@ static int default_init_sequence[] = {
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address */
 	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
 
@@ -98,7 +90,6 @@ static int set_var(struct fbtft_par *par)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -109,6 +100,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9486", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c
index 15da0ec77513..7ba220f07d01 100644
--- a/drivers/staging/fbtft/fb_pcd8544.c
+++ b/drivers/staging/fbtft/fb_pcd8544.c
@@ -15,10 +15,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -33,7 +29,7 @@
 #define DRVNAME	       "fb_pcd8544"
 #define WIDTH          84
 #define HEIGHT         48
-#define TXBUFLEN       (84*6)
+#define TXBUFLEN       (84 * 6)
 #define DEFAULT_GAMMA  "40" /* gamma controls the contrast in this driver */
 
 static unsigned tc;
@@ -44,7 +40,6 @@ static unsigned bs = 4;
 module_param(bs, uint, 0);
 MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -101,9 +96,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n",
-		      __func__, xs, ys, xe, ye);
-
 	/* H=0 Set X address of RAM
 	 *
 	 * 7:1  1
@@ -133,14 +125,15 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 		for (y = 0; y < 6; y++) {
 			*buf = 0x00;
 			for (i = 0; i < 8; i++)
-				*buf |= (vmem16[(y*8+i)*84+x] ? 1 : 0) << i;
+				*buf |= (vmem16[(y * 8 + i) * 84 + x] ?
+					 1 : 0) << i;
 			buf++;
 		}
 	}
 
 	/* Write data */
 	gpio_set_value(par->gpio.dc, 1);
-	ret = par->fbtftops.write(par, par->txbuf.buf, 6*84);
+	ret = par->fbtftops.write(par, par->txbuf.buf, 6 * 84);
 	if (ret < 0)
 		dev_err(par->info->device, "write failed and returned: %d\n",
 			ret);
@@ -162,7 +155,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -179,6 +171,7 @@ static struct fbtft_display display = {
 	},
 	.backlight = 1,
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "philips,pdc8544", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c
index 54bc566b09fd..5c1d93d425d0 100644
--- a/drivers/staging/fbtft/fb_ra8875.c
+++ b/drivers/staging/fbtft/fb_ra8875.c
@@ -1,19 +1,7 @@
-/******************************************************************************
-
-  ProjectName: FBTFT driver                       ***** *****
-	       for the RA8875 LCD Controller     *     *      ************
-						*   **   **   *           *
-  Copyright � by Pf@nne & NOTRO                *   *   *   *   *   ****	   *
-						*   *       *   *   *   *   *
-  Last modification by:                        *   *       *   *   ****    *
-  - Pf@nne (pf@nne-mail.de)                     *   *     *****           *
-						 *   *        *   *******
-						  *****      *   *
-  Date    : 10.06.2014                                      *   *
-  Version : V1.13                                          *****
-  Revision : 5
-
-*******************************************************************************
+/*
+ * FBTFT driver for the RA8875 LCD Controller
+ * Copyright by Pf@nne & NOTRO
+ *
  * 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
@@ -23,10 +11,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -197,18 +181,15 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Set_Active_Window */
 	write_reg(par, 0x30, xs & 0x00FF);
 	write_reg(par, 0x31, (xs & 0xFF00) >> 8);
 	write_reg(par, 0x32, ys & 0x00FF);
 	write_reg(par, 0x33, (ys & 0xFF00) >> 8);
-	write_reg(par, 0x34, (xs+xe) & 0x00FF);
-	write_reg(par, 0x35, ((xs+xe) & 0xFF00) >> 8);
-	write_reg(par, 0x36, (ys+ye) & 0x00FF);
-	write_reg(par, 0x37, ((ys+ye) & 0xFF00) >> 8);
+	write_reg(par, 0x34, (xs + xe) & 0x00FF);
+	write_reg(par, 0x35, ((xs + xe) & 0xFF00) >> 8);
+	write_reg(par, 0x36, (ys + ye) & 0x00FF);
+	write_reg(par, 0x37, ((ys + ye) & 0xFF00) >> 8);
 
 	/* Set_Memory_Write_Cursor */
 	write_reg(par, 0x46,  xs & 0xff);
@@ -324,6 +305,7 @@ static struct fbtft_display display = {
 		.write = write_spi,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "raio,ra8875", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_s6d02a1.c b/drivers/staging/fbtft/fb_s6d02a1.c
index f3302525ec00..0ae5bc6c53a6 100644
--- a/drivers/staging/fbtft/fb_s6d02a1.c
+++ b/drivers/staging/fbtft/fb_s6d02a1.c
@@ -13,10 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -102,9 +98,6 @@ static int default_init_sequence[] = {
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address */
 	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
 
@@ -115,9 +108,9 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 	write_reg(par, 0x2C);
 }
 
-#define MY (1 << 7)
-#define MX (1 << 6)
-#define MV (1 << 5)
+#define MY BIT(7)
+#define MX BIT(6)
+#define MV BIT(5)
 static int set_var(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -156,6 +149,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d02a1", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c
index 2e1b72ad54aa..9ee8d56cd569 100644
--- a/drivers/staging/fbtft/fb_s6d1121.c
+++ b/drivers/staging/fbtft/fb_s6d1121.c
@@ -16,10 +16,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -86,8 +82,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
 	switch (par->info->var.rotate) {
 	/* R20h = Horizontal GRAM Start Address */
 	/* R21h = Vertical GRAM Start Address */
@@ -139,7 +133,7 @@ static int set_var(struct fbtft_par *par)
     PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
     PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -154,7 +148,7 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	/* apply mask */
 	for (i = 0; i < 2; i++)
 		for (j = 0; j < 14; j++)
-			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
 
 	write_reg(par, 0x0030, CURVE(0, 1) << 8 | CURVE(0, 0));
 	write_reg(par, 0x0031, CURVE(0, 3) << 8 | CURVE(0, 2));
@@ -177,7 +171,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 16,
 	.width = WIDTH,
@@ -194,6 +187,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d1121", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
index 17a77e061498..e6804524a47b 100644
--- a/drivers/staging/fbtft/fb_ssd1289.c
+++ b/drivers/staging/fbtft/fb_ssd1289.c
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -37,7 +33,6 @@ static unsigned reg11 = 0x6040;
 module_param(reg11, uint, 0);
 MODULE_PARM_DESC(reg11, "Register 11h value");
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -84,9 +79,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	switch (par->info->var.rotate) {
 	/* R4Eh - Set GDDRAM X address counter */
 	/* R4Fh - Set GDDRAM Y address counter */
@@ -147,7 +139,7 @@ static int set_var(struct fbtft_par *par)
     VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
     VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	unsigned long mask[] = {
@@ -161,7 +153,7 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	/* apply mask */
 	for (i = 0; i < 2; i++)
 		for (j = 0; j < 10; j++)
-			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
 
 	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
 	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
@@ -178,7 +170,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 16,
 	.width = WIDTH,
@@ -193,6 +184,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1289", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c
index 15ee44dd130b..4fe899ba68cf 100644
--- a/drivers/staging/fbtft/fb_ssd1306.c
+++ b/drivers/staging/fbtft/fb_ssd1306.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -30,7 +26,6 @@
 #define WIDTH		128
 #define HEIGHT		64
 
-
 /*
   write_reg() caveat:
 
@@ -132,9 +127,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Set Lower Column Start Address for Page Addressing Mode */
 	write_reg(par, 0x00 | 0x0);
 	/* Set Higher Column Start Address for Page Addressing Mode */
@@ -183,7 +175,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 		for (y = 0; y < par->info->var.yres/8; y++) {
 			*buf = 0x00;
 			for (i = 0; i < 8; i++)
-				*buf |= (vmem16[(y*8+i)*par->info->var.xres+x] ? 1 : 0) << i;
+				*buf |= (vmem16[(y * 8 + i) *
+						par->info->var.xres + x] ?
+					 1 : 0) << i;
 			buf++;
 		}
 	}
@@ -191,7 +185,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 	/* Write data */
 	gpio_set_value(par->gpio.dc, 1);
 	ret = par->fbtftops.write(par, par->txbuf.buf,
-				par->info->var.xres*par->info->var.yres/8);
+				  par->info->var.xres * par->info->var.yres /
+				  8);
 	if (ret < 0)
 		dev_err(par->info->device, "write failed and returned: %d\n",
 			ret);
@@ -199,7 +194,6 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 	return ret;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -216,7 +210,6 @@ static struct fbtft_display display = {
 	},
 };
 
-
 FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1306", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c
index 5bb741046c85..9ac75f6822a9 100644
--- a/drivers/staging/fbtft/fb_ssd1331.c
+++ b/drivers/staging/fbtft/fb_ssd1331.c
@@ -54,9 +54,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	write_reg(par, 0x15, xs, xe);
 	write_reg(par, 0x75, ys, ye);
 }
@@ -126,7 +123,6 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
 			:
 			Setting of GS63 has to be > Setting of GS62 +1
 
-
 */
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
@@ -176,7 +172,6 @@ static int blank(struct fbtft_par *par, bool on)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
index 9bcd7a0aeed4..7e3762d5aa2a 100644
--- a/drivers/staging/fbtft/fb_ssd1351.c
+++ b/drivers/staging/fbtft/fb_ssd1351.c
@@ -61,9 +61,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	write_reg(par, 0x15, xs, xe);
 	write_reg(par, 0x75, ys, ye);
 	write_reg(par, 0x5c);
@@ -123,7 +120,6 @@ static int set_var(struct fbtft_par *par)
 			:
 			Setting of GS63 has to be > Setting of GS62 +1
 
-
 */
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
@@ -173,7 +169,6 @@ static int blank(struct fbtft_par *par, bool on)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -208,25 +203,22 @@ static int update_onboard_backlight(struct backlight_device *bd)
 	return 0;
 }
 
+static const struct backlight_ops bl_ops = {
+	.update_status = update_onboard_backlight,
+};
+
 static void register_onboard_backlight(struct fbtft_par *par)
 {
 	struct backlight_device *bd;
 	struct backlight_properties bl_props = { 0, };
-	struct backlight_ops *bl_ops;
 
 	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
 
-	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
-				GFP_KERNEL);
-	if (!bl_ops)
-		return;
-
-	bl_ops->update_status = update_onboard_backlight;
 	bl_props.type = BACKLIGHT_RAW;
 	bl_props.power = FB_BLANK_POWERDOWN;
 
 	bd = backlight_device_register(dev_driver_string(par->info->device),
-				par->info->device, par, bl_ops, &bl_props);
+				par->info->device, par, &bl_ops, &bl_props);
 	if (IS_ERR(bd)) {
 		dev_err(par->info->device,
 			"cannot register backlight device (%ld)\n",
@@ -242,7 +234,6 @@ static void register_onboard_backlight(struct fbtft_par *par)
 static void register_onboard_backlight(struct fbtft_par *par) { };
 #endif
 
-
 FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1351", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c
index f65224318610..e249bbfe5e89 100644
--- a/drivers/staging/fbtft/fb_st7735r.c
+++ b/drivers/staging/fbtft/fb_st7735r.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -28,7 +24,6 @@
 #define DEFAULT_GAMMA   "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
 			"0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
 
-
 static int default_init_sequence[] = {
 	/* SWRESET - Software reset */
 	-1, 0x01,
@@ -96,9 +91,6 @@ static int default_init_sequence[] = {
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address */
 	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
 
@@ -109,9 +101,9 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 	write_reg(par, 0x2C);
 }
 
-#define MY (1 << 7)
-#define MX (1 << 6)
-#define MV (1 << 5)
+#define MY BIT(7)
+#define MX BIT(6)
+#define MV BIT(5)
 static int set_var(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -145,7 +137,7 @@ static int set_var(struct fbtft_par *par)
     VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
     VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
 */
-#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+#define CURVE(num, idx)  curves[num * par->gamma.num_values + idx]
 static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 {
 	int i, j;
@@ -168,7 +160,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 }
 #undef CURVE
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = 128,
@@ -183,6 +174,7 @@ static struct fbtft_display display = {
 		.set_gamma = set_gamma,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c
index 4c740b7e9f53..04d1e344a3a0 100644
--- a/drivers/staging/fbtft/fb_tinylcd.c
+++ b/drivers/staging/fbtft/fb_tinylcd.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -29,7 +25,6 @@
 #define WIDTH		320
 #define HEIGHT		480
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -64,9 +59,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address */
 	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
 
@@ -103,7 +95,6 @@ static int set_var(struct fbtft_par *par)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -114,6 +105,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "neosec,tinylcd", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c
index 3253a25e9184..1225ba9f8b1b 100644
--- a/drivers/staging/fbtft/fb_tls8204.c
+++ b/drivers/staging/fbtft/fb_tls8204.c
@@ -16,10 +16,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -86,10 +82,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		      "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n",
-		      __func__, xs, ys, xe, ye);
-
 	/* H=0 Set X address of RAM */
 	write_reg(par, 0x80); /* 7:1  1
 				 6-0: X[6:0] - 0x00
@@ -110,7 +102,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 
 	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
 
-	for (y = 0; y < HEIGHT/8; y++) {
+	for (y = 0; y < HEIGHT / 8; y++) {
 		u8 *buf = par->txbuf.buf;
 		/* The display is 102x68 but the LCD is 84x48.  Set
 		   the write pointer at the start of each row. */
@@ -121,9 +113,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 		for (x = 0; x < WIDTH; x++) {
 			u8 ch = 0;
 
-			for (i = 0; i < 8*WIDTH; i += WIDTH) {
+			for (i = 0; i < 8 * WIDTH; i += WIDTH) {
 				ch >>= 1;
-				if (vmem16[(y*8*WIDTH)+i+x])
+				if (vmem16[(y * 8 * WIDTH) + i + x])
 					ch |= 0x80;
 			}
 			*buf++ = ch;
@@ -155,7 +147,6 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
 	return 0;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -172,6 +163,7 @@ static struct fbtft_display display = {
 	},
 	.backlight = 1,
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "teralane,tls8204", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c
index 32f3a9d921d6..2f5d6f9a60f0 100644
--- a/drivers/staging/fbtft/fb_uc1611.c
+++ b/drivers/staging/fbtft/fb_uc1611.c
@@ -76,7 +76,7 @@ static int init_display(struct fbtft_par *par)
 
 	/* Set CS active high */
 	par->spi->mode |= SPI_CS_HIGH;
-	ret = par->spi->master->setup(par->spi);
+	ret = spi_setup(par->spi);
 	if (ret) {
 		dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
 		return ret;
@@ -115,10 +115,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		      "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n",
-		      __func__, xs, ys, xe, ye);
-
 	switch (par->info->var.rotate) {
 	case 90:
 	case 270:
diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c
index 26d669b57916..e0d4d36047cc 100644
--- a/drivers/staging/fbtft/fb_uc1701.c
+++ b/drivers/staging/fbtft/fb_uc1701.c
@@ -15,10 +15,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -33,7 +29,7 @@
 #define DRVNAME	"fb_uc1701"
 #define WIDTH	  102
 #define HEIGHT	 64
-#define PAGES	  (HEIGHT/8)
+#define PAGES	  (HEIGHT / 8)
 
 /* 1: Display on/off */
 #define LCD_DISPLAY_ENABLE    0xAE
@@ -73,7 +69,6 @@
 /* column offset for bottom view orientation */
 #define SHIFT_ADDR_TOPVIEW    30
 
-
 static int init_display(struct fbtft_par *par)
 {
 	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
@@ -121,7 +116,7 @@ static int init_display(struct fbtft_par *par)
 
 	/* advanced program control */
 	write_reg(par, LCD_ADV_PROG_CTRL);
-	write_reg(par, LCD_ADV_PROG_CTRL2|LCD_TEMPCOMP_HIGH);
+	write_reg(par, LCD_ADV_PROG_CTRL2 | LCD_TEMPCOMP_HIGH);
 
 	/* enable display */
 	write_reg(par, LCD_DISPLAY_ENABLE | 1);
@@ -131,8 +126,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* goto address */
 	/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
 	 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
@@ -162,13 +155,15 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 		for (x = 0; x < WIDTH; x++) {
 			*buf = 0x00;
 			for (i = 0; i < 8; i++)
-				*buf |= (vmem16[((y*8*WIDTH)+(i*WIDTH))+x] ? 1 : 0) << i;
+				*buf |= (vmem16[((y * 8 * WIDTH) +
+						 (i * WIDTH)) + x] ?
+					 1 : 0) << i;
 			buf++;
 		}
 		/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
 		 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
 		  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
-		write_reg(par, LCD_PAGE_ADDRESS|(u8)y);
+		write_reg(par, LCD_PAGE_ADDRESS | (u8)y);
 		/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
 		 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
 		  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
@@ -189,7 +184,6 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
 	return ret;
 }
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.width = WIDTH,
@@ -201,6 +195,7 @@ static struct fbtft_display display = {
 	},
 	.backlight = 1,
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "UltraChip,uc1701", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c
index 176c2106d724..f0011ee9868b 100644
--- a/drivers/staging/fbtft/fb_upd161704.c
+++ b/drivers/staging/fbtft/fb_upd161704.c
@@ -16,10 +16,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -131,8 +127,6 @@ static int init_display(struct fbtft_par *par)
 
 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
 	switch (par->info->var.rotate) {
 	/* R20h = Horizontal GRAM Start Address */
 	/* R21h = Vertical GRAM Start Address */
@@ -194,6 +188,7 @@ static struct fbtft_display display = {
 		.set_var = set_var,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "nec,upd161704", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
index 88fb2c0132d5..30249e3dd5c8 100644
--- a/drivers/staging/fbtft/fb_watterott.c
+++ b/drivers/staging/fbtft/fb_watterott.c
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -43,7 +39,6 @@
 #define COLOR_RGB233		10
 #define COLOR_RGB565		16
 
-
 static short mode = 565;
 module_param(mode, short, 0);
 MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)");
@@ -169,7 +164,7 @@ static int init_display(struct fbtft_par *par)
 	/* enable SPI interface by having CS and MOSI low during reset */
 	save_mode = par->spi->mode;
 	par->spi->mode |= SPI_CS_HIGH;
-	ret = par->spi->master->setup(par->spi); /* set CS inactive low */
+	ret = spi_setup(par->spi); /* set CS inactive low */
 	if (ret) {
 		dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
 		return ret;
@@ -180,7 +175,7 @@ static int init_display(struct fbtft_par *par)
 	par->fbtftops.reset(par);
 	mdelay(1000);
 	par->spi->mode = save_mode;
-	ret = par->spi->master->setup(par->spi);
+	ret = spi_setup(par->spi);
 	if (ret) {
 		dev_err(par->info->device, "Could not restore SPI mode\n");
 		return ret;
@@ -257,31 +252,24 @@ static int backlight_chip_update_status(struct backlight_device *bd)
 	return 0;
 }
 
+static const struct backlight_ops bl_ops = {
+	.update_status = backlight_chip_update_status,
+};
+
 static void register_chip_backlight(struct fbtft_par *par)
 {
 	struct backlight_device *bd;
 	struct backlight_properties bl_props = { 0, };
-	struct backlight_ops *bl_ops;
 
 	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
 
-	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
-				GFP_KERNEL);
-	if (!bl_ops) {
-		dev_err(par->info->device,
-			"%s: could not allocate memory for backlight operations.\n",
-			__func__);
-		return;
-	}
-
-	bl_ops->update_status = backlight_chip_update_status;
 	bl_props.type = BACKLIGHT_RAW;
 	bl_props.power = FB_BLANK_POWERDOWN;
 	bl_props.max_brightness = 100;
 	bl_props.brightness = DEFAULT_BRIGHTNESS;
 
 	bd = backlight_device_register(dev_driver_string(par->info->device),
-				par->info->device, par, bl_ops, &bl_props);
+				par->info->device, par, &bl_ops, &bl_props);
 	if (IS_ERR(bd)) {
 		dev_err(par->info->device,
 			"cannot register backlight device (%ld)\n",
@@ -297,7 +285,6 @@ static void register_chip_backlight(struct fbtft_par *par)
 #define register_chip_backlight NULL
 #endif
 
-
 static struct fbtft_display display = {
 	.regwidth = 8,
 	.buswidth = 8,
@@ -315,6 +302,7 @@ static struct fbtft_display display = {
 		.register_backlight = register_chip_backlight,
 	},
 };
+
 FBTFT_REGISTER_DRIVER(DRVNAME, "watterott,openlcd", &display);
 
 MODULE_ALIAS("spi:" DRVNAME);
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
index 912c6328fb87..97129241cab9 100644
--- a/drivers/staging/fbtft/fbtft-bus.c
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -4,9 +4,6 @@
 #include <linux/spi/spi.h>
 #include "fbtft.h"
 
-
-
-
 /*****************************************************************************
  *
  *   void (*write_reg)(struct fbtft_par *par, int len, ...);
@@ -41,7 +38,7 @@ void func(struct fbtft_par *par, int len, ...)                                \
 	*buf = modifier((type)va_arg(args, unsigned int));                    \
 	if (par->gpio.dc != -1)                                               \
 		gpio_set_value(par->gpio.dc, 0);                              \
-	ret = par->fbtftops.write(par, par->buf, sizeof(type)+offset);        \
+	ret = par->fbtftops.write(par, par->buf, sizeof(type) + offset);      \
 	if (ret < 0) {                                                        \
 		va_end(args);                                                 \
 		dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
@@ -59,7 +56,8 @@ void func(struct fbtft_par *par, int len, ...)                                \
 		}                                                             \
 		if (par->gpio.dc != -1)                                       \
 			gpio_set_value(par->gpio.dc, 1);                      \
-		ret = par->fbtftops.write(par, par->buf, len * (sizeof(type)+offset)); \
+		ret = par->fbtftops.write(par, par->buf,		      \
+					  len * (sizeof(type) + offset));     \
 		if (ret < 0) {                                                \
 			va_end(args);                                         \
 			dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
@@ -117,9 +115,6 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
 }
 EXPORT_SYMBOL(fbtft_write_reg8_bus9);
 
-
-
-
 /*****************************************************************************
  *
  *   int (*write_vmem)(struct fbtft_par *par);
@@ -220,7 +215,7 @@ int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len)
 			txbuf16[i]   = 0x0100 | ioread8(vmem8 + i);
 #endif
 		vmem8 = vmem8 + to_copy;
-		ret = par->fbtftops.write(par, par->txbuf.buf, to_copy*2);
+		ret = par->fbtftops.write(par, par->txbuf.buf, to_copy * 2);
 		if (ret < 0)
 			return ret;
 		remain -= to_copy;
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index 23392eb6799e..f2b0a20f7f8b 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -53,7 +49,6 @@ module_param(dma, bool, 0);
 MODULE_PARM_DESC(dma, "Use DMA buffer");
 #endif
 
-
 void fbtft_dbg_hex(const struct device *dev, int groupsize,
 			void *buf, size_t len, const char *fmt, ...)
 {
@@ -127,33 +122,34 @@ static int fbtft_request_gpios(struct fbtft_par *par)
 	unsigned long flags;
 	int ret;
 
-	if (pdata && pdata->gpios) {
-		gpio = pdata->gpios;
-		while (gpio->name[0]) {
-			flags = FBTFT_GPIO_NO_MATCH;
-			/* if driver provides match function, try it first,
-			   if no match use our own */
-			if (par->fbtftops.request_gpios_match)
-				flags = par->fbtftops.request_gpios_match(par, gpio);
-			if (flags == FBTFT_GPIO_NO_MATCH)
-				flags = fbtft_request_gpios_match(par, gpio);
-			if (flags != FBTFT_GPIO_NO_MATCH) {
-				ret = devm_gpio_request_one(par->info->device,
-						gpio->gpio, flags,
-						par->info->device->driver->name);
-				if (ret < 0) {
-					dev_err(par->info->device,
-						"%s: gpio_request_one('%s'=%d) failed with %d\n",
-						__func__, gpio->name,
-						gpio->gpio, ret);
-					return ret;
-				}
-				fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par,
-					"%s: '%s' = GPIO%d\n",
-					__func__, gpio->name, gpio->gpio);
+	if (!(pdata && pdata->gpios))
+		return 0;
+
+	gpio = pdata->gpios;
+	while (gpio->name[0]) {
+		flags = FBTFT_GPIO_NO_MATCH;
+		/* if driver provides match function, try it first,
+		   if no match use our own */
+		if (par->fbtftops.request_gpios_match)
+			flags = par->fbtftops.request_gpios_match(par, gpio);
+		if (flags == FBTFT_GPIO_NO_MATCH)
+			flags = fbtft_request_gpios_match(par, gpio);
+		if (flags != FBTFT_GPIO_NO_MATCH) {
+			ret = devm_gpio_request_one(par->info->device,
+					gpio->gpio, flags,
+					par->info->device->driver->name);
+			if (ret < 0) {
+				dev_err(par->info->device,
+					"%s: gpio_request_one('%s'=%d) failed with %d\n",
+					__func__, gpio->name,
+					gpio->gpio, ret);
+				return ret;
 			}
-			gpio++;
+			fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par,
+				"%s: '%s' = GPIO%d\n",
+				__func__, gpio->name, gpio->gpio);
 		}
+		gpio++;
 	}
 
 	return 0;
@@ -270,24 +266,25 @@ static int fbtft_backlight_get_brightness(struct backlight_device *bd)
 
 void fbtft_unregister_backlight(struct fbtft_par *par)
 {
-	const struct backlight_ops *bl_ops;
-
 	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
 
 	if (par->info->bl_dev) {
 		par->info->bl_dev->props.power = FB_BLANK_POWERDOWN;
 		backlight_update_status(par->info->bl_dev);
-		bl_ops = par->info->bl_dev->ops;
 		backlight_device_unregister(par->info->bl_dev);
 		par->info->bl_dev = NULL;
 	}
 }
 
+static const struct backlight_ops fbtft_bl_ops = {
+	.get_brightness	= fbtft_backlight_get_brightness,
+	.update_status	= fbtft_backlight_update_status,
+};
+
 void fbtft_register_backlight(struct fbtft_par *par)
 {
 	struct backlight_device *bd;
 	struct backlight_properties bl_props = { 0, };
-	struct backlight_ops *bl_ops;
 
 	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
 
@@ -297,13 +294,6 @@ void fbtft_register_backlight(struct fbtft_par *par)
 		return;
 	}
 
-	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
-				GFP_KERNEL);
-	if (!bl_ops)
-		return;
-
-	bl_ops->get_brightness = fbtft_backlight_get_brightness;
-	bl_ops->update_status = fbtft_backlight_update_status;
 	bl_props.type = BACKLIGHT_RAW;
 	/* Assume backlight is off, get polarity from current state of pin */
 	bl_props.power = FB_BLANK_POWERDOWN;
@@ -311,7 +301,7 @@ void fbtft_register_backlight(struct fbtft_par *par)
 		bl_props.state |= BL_CORE_DRIVER1;
 
 	bd = backlight_device_register(dev_driver_string(par->info->device),
-				par->info->device, par, bl_ops, &bl_props);
+				par->info->device, par, &fbtft_bl_ops, &bl_props);
 	if (IS_ERR(bd)) {
 		dev_err(par->info->device,
 			"cannot register backlight device (%ld)\n",
@@ -333,9 +323,6 @@ EXPORT_SYMBOL(fbtft_unregister_backlight);
 static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
 			       int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
-
 	/* Column address set */
 	write_reg(par, 0x2A,
 		(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
@@ -348,7 +335,6 @@ static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
 	write_reg(par, 0x2C);
 }
 
-
 static void fbtft_reset(struct fbtft_par *par)
 {
 	if (par->gpio.reset == -1)
@@ -360,7 +346,6 @@ static void fbtft_reset(struct fbtft_par *par)
 	mdelay(120);
 }
 
-
 static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
 				 unsigned end_line)
 {
@@ -400,7 +385,7 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
 
 	if (par->fbtftops.set_addr_win)
 		par->fbtftops.set_addr_win(par, 0, start_line,
-				par->info->var.xres-1, end_line);
+				par->info->var.xres - 1, end_line);
 
 	offset = start_line * par->info->fix.line_length;
 	len = (end_line - start_line + 1) * par->info->fix.line_length;
@@ -439,7 +424,6 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
 	}
 }
 
-
 static void fbtft_mkdirty(struct fb_info *info, int y, int height)
 {
 	struct fbtft_par *par = info->par;
@@ -501,7 +485,6 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
 					dirty_lines_start, dirty_lines_end);
 }
 
-
 static void fbtft_fb_fillrect(struct fb_info *info,
 			      const struct fb_fillrect *rect)
 {
@@ -802,7 +785,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
 	info->fix.xpanstep =	   0;
 	info->fix.ypanstep =	   0;
 	info->fix.ywrapstep =	   0;
-	info->fix.line_length =    width*bpp/8;
+	info->fix.line_length =    width * bpp / 8;
 	info->fix.accel =          FB_ACCEL_NONE;
 	info->fix.smem_len =       vmem_size;
 
@@ -998,12 +981,12 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
 			par->txbuf.len >> 10, par->txbuf.dma ? "DMA " : "");
 	if (spi)
 		sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
-				spi->chip_select, spi->max_speed_hz/1000000);
+			spi->chip_select, spi->max_speed_hz / 1000000);
 	dev_info(fb_info->dev,
 		"%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
 		fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
 		fb_info->fix.smem_len >> 10, text1,
-		HZ/fb_info->fbdefio->delay, text2);
+		HZ / fb_info->fbdefio->delay, text2);
 
 #ifdef CONFIG_FB_BACKLIGHT
 	/* Turn on backlight if available */
@@ -1185,7 +1168,7 @@ int fbtft_init_display(struct fbtft_par *par)
 				"missing delimiter at position %d\n", i);
 			return -EINVAL;
 		}
-		if (par->init_sequence[i+1] < 0) {
+		if (par->init_sequence[i + 1] < 0) {
 			dev_err(par->info->device,
 				"missing value after delimiter %d at position %d\n",
 				par->init_sequence[i], i);
@@ -1436,15 +1419,11 @@ int fbtft_probe_common(struct fbtft_display *display,
 
 	/* 9-bit SPI setup */
 	if (par->spi && display->buswidth == 9) {
-		par->spi->bits_per_word = 9;
-		ret = par->spi->master->setup(par->spi);
-		if (ret) {
+		if (par->spi->master->bits_per_word_mask & SPI_BPW_MASK(9)) {
+			par->spi->bits_per_word = 9;
+		} else {
 			dev_warn(&par->spi->dev,
 				"9-bit SPI not available, emulating using 8-bit.\n");
-			par->spi->bits_per_word = 8;
-			ret = par->spi->master->setup(par->spi);
-			if (ret)
-				goto out_release;
 			/* allocate buffer with room for dc bits */
 			par->extra = devm_kzalloc(par->info->device,
 				par->txbuf.len + (par->txbuf.len / 8) + 8,
diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c
index c4cc452f9f2b..8d8bd12b90a1 100644
--- a/drivers/staging/fbtft/fbtft-sysfs.c
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -103,8 +103,8 @@ sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf)
 	for (i = 0; i < par->gamma.num_curves; i++) {
 		for (j = 0; j < par->gamma.num_values; j++)
 			len += scnprintf(&buf[len], PAGE_SIZE,
-				"%04lx ", curves[i*par->gamma.num_values + j]);
-		buf[len-1] = '\n';
+			     "%04lx ", curves[i * par->gamma.num_values + j]);
+		buf[len - 1] = '\n';
 	}
 	mutex_unlock(&par->gamma.lock);
 
@@ -149,7 +149,6 @@ static struct device_attribute gamma_device_attrs[] = {
 	__ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve),
 };
 
-
 void fbtft_expand_debug_value(unsigned long *debug)
 {
 	switch (*debug & 0x7) {
@@ -205,7 +204,6 @@ static ssize_t show_debug(struct device *device,
 static struct device_attribute debug_device_attr = \
 	__ATTR(debug, 0660, show_debug, store_debug);
 
-
 void fbtft_sysfs_init(struct fbtft_par *par)
 {
 	device_create_file(par->info->dev, &debug_device_attr);
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
index 7e9a506d65f9..6dd42b28d594 100644
--- a/drivers/staging/fbtft/fbtft.h
+++ b/drivers/staging/fbtft/fbtft.h
@@ -10,10 +10,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __LINUX_FBTFT_H
@@ -24,7 +20,6 @@
 #include <linux/spi/spi.h>
 #include <linux/platform_device.h>
 
-
 #define FBTFT_NOP		0x00
 #define FBTFT_SWRESET	0x01
 #define FBTFT_RDDID		0x04
@@ -295,7 +290,6 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
 void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
 void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
 
-
 #define FBTFT_REGISTER_DRIVER(_name, _compatible, _display)                \
 									   \
 static int fbtft_driver_probe_spi(struct spi_device *spi)                  \
@@ -369,7 +363,6 @@ static void __exit fbtft_driver_module_exit(void)                          \
 module_init(fbtft_driver_module_init);                                     \
 module_exit(fbtft_driver_module_exit);
 
-
 /* Debug macros */
 
 /* shorthand debug levels */
@@ -415,7 +408,6 @@ module_exit(fbtft_driver_module_exit);
 #define DEBUG_REQUEST_GPIOS_MATCH   (1<<30)
 #define DEBUG_VERIFY_GPIOS          (1<<31)
 
-
 #define fbtft_init_dbg(dev, format, arg...)                  \
 do {                                                         \
 	if (unlikely((dev)->platform_data &&                 \
@@ -429,7 +421,6 @@ do {                                                         \
 		dev_info(par->info->device, format, ##arg);  \
 } while (0)
 
-
 #define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \
 do {                                                                       \
 	if (unlikely(par->debug & level))                                  \
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
index fa916e88d549..a60f389122b0 100644
--- a/drivers/staging/fbtft/fbtft_device.c
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -11,12 +11,9 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define pr_fmt(fmt) "fbtft_device: " fmt
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -25,8 +22,6 @@
 
 #include "fbtft.h"
 
-#define DRVNAME "fbtft_device"
-
 #define MAX_GPIOS 32
 
 static struct spi_device *spi_device;
@@ -115,7 +110,6 @@ module_param(verbose, uint, 0);
 MODULE_PARM_DESC(verbose,
 "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
 
-
 struct fbtft_device_display {
 	char *name;
 	struct spi_board_info *spi;
@@ -1201,15 +1195,13 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
 						int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
 	write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
 	write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
 	write_reg(par, 0x2C);
 }
 
 /* used if gpios parameter is present */
-static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
+static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { };
 
 static void fbtft_device_pdev_release(struct device *dev)
 {
@@ -1222,16 +1214,16 @@ static int spi_device_found(struct device *dev, void *data)
 {
 	struct spi_device *spi = container_of(dev, struct spi_device, dev);
 
-	pr_info(DRVNAME":      %s %s %dkHz %d bits mode=0x%02X\n",
-		spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
-		spi->bits_per_word, spi->mode);
+	dev_info(dev, "%s %s %dkHz %d bits mode=0x%02X\n", spi->modalias,
+		 dev_name(dev), spi->max_speed_hz / 1000, spi->bits_per_word,
+		 spi->mode);
 
 	return 0;
 }
 
 static void pr_spi_devices(void)
 {
-	pr_info(DRVNAME":  SPI devices registered:\n");
+	pr_debug("SPI devices registered:\n");
 	bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
 }
 
@@ -1241,16 +1233,15 @@ static int p_device_found(struct device *dev, void *data)
 	*pdev = container_of(dev, struct platform_device, dev);
 
 	if (strstr(pdev->name, "fb"))
-		pr_info(DRVNAME":      %s id=%d pdata? %s\n",
-				pdev->name, pdev->id,
-				pdev->dev.platform_data ? "yes" : "no");
+		dev_info(dev, "%s id=%d pdata? %s\n", pdev->name, pdev->id,
+			 pdev->dev.platform_data ? "yes" : "no");
 
 	return 0;
 }
 
 static void pr_p_devices(void)
 {
-	pr_info(DRVNAME":  'fb' Platform devices registered:\n");
+	pr_debug("'fb' Platform devices registered:\n");
 	bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
 }
 
@@ -1265,7 +1256,7 @@ static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
 	dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
 	if (dev) {
 		if (verbose)
-			pr_info(DRVNAME": Deleting %s\n", str);
+			dev_info(dev, "Deleting %s\n", str);
 		device_del(dev);
 	}
 }
@@ -1276,8 +1267,8 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
 
 	master = spi_busnum_to_master(spi->bus_num);
 	if (!master) {
-		pr_err(DRVNAME ":  spi_busnum_to_master(%d) returned NULL\n",
-								spi->bus_num);
+		pr_err("spi_busnum_to_master(%d) returned NULL\n",
+		       spi->bus_num);
 		return -EINVAL;
 	}
 	/* make sure it's available */
@@ -1285,7 +1276,7 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
 	spi_device = spi_new_device(master, spi);
 	put_device(&master->dev);
 	if (!spi_device) {
-		pr_err(DRVNAME ":    spi_new_device() returned NULL\n");
+		dev_err(&master->dev, "spi_new_device() returned NULL\n");
 		return -EPERM;
 	}
 	return 0;
@@ -1308,11 +1299,9 @@ static int __init fbtft_device_init(void)
 	long val;
 	int ret = 0;
 
-	pr_debug("\n\n"DRVNAME": init\n");
-
 	if (name == NULL) {
 #ifdef MODULE
-		pr_err(DRVNAME":  missing module parameter: 'name'\n");
+		pr_err("missing module parameter: 'name'\n");
 		return -EINVAL;
 #else
 		return 0;
@@ -1320,41 +1309,37 @@ static int __init fbtft_device_init(void)
 	}
 
 	if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
-		pr_err(DRVNAME
-			":  init parameter: exceeded max array size: %d\n",
-			FBTFT_MAX_INIT_SEQUENCE);
+		pr_err("init parameter: exceeded max array size: %d\n",
+		       FBTFT_MAX_INIT_SEQUENCE);
 		return -EINVAL;
 	}
 
 	/* parse module parameter: gpios */
 	while ((p_gpio = strsep(&gpios, ","))) {
 		if (strchr(p_gpio, ':') == NULL) {
-			pr_err(DRVNAME
-				":  error: missing ':' in gpios parameter: %s\n",
-				p_gpio);
+			pr_err("error: missing ':' in gpios parameter: %s\n",
+			       p_gpio);
 			return -EINVAL;
 		}
 		p_num = p_gpio;
 		p_name = strsep(&p_num, ":");
 		if (p_name == NULL || p_num == NULL) {
-			pr_err(DRVNAME
-				":  something bad happened parsing gpios parameter: %s\n",
-				p_gpio);
+			pr_err("something bad happened parsing gpios parameter: %s\n",
+			       p_gpio);
 			return -EINVAL;
 		}
 		ret = kstrtol(p_num, 10, &val);
 		if (ret) {
-			pr_err(DRVNAME
-				":  could not parse number in gpios parameter: %s:%s\n",
-				p_name, p_num);
+			pr_err("could not parse number in gpios parameter: %s:%s\n",
+			       p_name, p_num);
 			return -EINVAL;
 		}
-		strcpy(fbtft_device_param_gpios[i].name, p_name);
+		strncpy(fbtft_device_param_gpios[i].name, p_name,
+			FBTFT_GPIO_NAME_SIZE - 1);
 		fbtft_device_param_gpios[i++].gpio = (int) val;
 		if (i == MAX_GPIOS) {
-			pr_err(DRVNAME
-				":  gpios parameter: exceeded max array size: %d\n",
-				MAX_GPIOS);
+			pr_err("gpios parameter: exceeded max array size: %d\n",
+			       MAX_GPIOS);
 			return -EINVAL;
 		}
 	}
@@ -1367,7 +1352,7 @@ static int __init fbtft_device_init(void)
 	if (verbose > 2)
 		pr_p_devices(); /* print list of 'fb' platform devices */
 
-	pr_debug(DRVNAME":  name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
+	pr_debug("name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
 
 	if (rotate > 0 && rotate < 4) {
 		rotate = (4 - rotate) * 90;
@@ -1381,11 +1366,11 @@ static int __init fbtft_device_init(void)
 	}
 
 	/* name=list lists all supported displays */
-	if (strncmp(name, "list", 32) == 0) {
-		pr_info(DRVNAME":  Supported displays:\n");
+	if (strncmp(name, "list", FBTFT_GPIO_NAME_SIZE) == 0) {
+		pr_info("Supported displays:\n");
 
 		for (i = 0; i < ARRAY_SIZE(displays); i++)
-			pr_info(DRVNAME":      %s\n", displays[i].name);
+			pr_info("%s\n", displays[i].name);
 		return -ECANCELED;
 	}
 
@@ -1416,7 +1401,7 @@ static int __init fbtft_device_init(void)
 				p_device = displays[i].pdev;
 				pdata = p_device->dev.platform_data;
 			} else {
-				pr_err(DRVNAME": broken displays array\n");
+				pr_err("broken displays array\n");
 				return -EINVAL;
 			}
 
@@ -1448,16 +1433,14 @@ static int __init fbtft_device_init(void)
 			if (displays[i].spi) {
 				ret = fbtft_device_spi_device_register(spi);
 				if (ret) {
-					pr_err(DRVNAME
-						": failed to register SPI device\n");
+					pr_err("failed to register SPI device\n");
 					return ret;
 				}
 			} else {
 				ret = platform_device_register(p_device);
 				if (ret < 0) {
-					pr_err(DRVNAME
-						":    platform_device_register() returned %d\n",
-						ret);
+					pr_err("platform_device_register() returned %d\n",
+					       ret);
 					return ret;
 				}
 			}
@@ -1467,22 +1450,21 @@ static int __init fbtft_device_init(void)
 	}
 
 	if (!found) {
-		pr_err(DRVNAME":  display not supported: '%s'\n", name);
+		pr_err("display not supported: '%s'\n", name);
 		return -EINVAL;
 	}
 
 	if (verbose && pdata && pdata->gpios) {
 		gpio = pdata->gpios;
-		pr_info(DRVNAME":  GPIOS used by '%s':\n", name);
+		pr_info("GPIOS used by '%s':\n", name);
 		found = false;
 		while (verbose && gpio->name[0]) {
-			pr_info(DRVNAME":    '%s' = GPIO%d\n",
-				gpio->name, gpio->gpio);
+			pr_info("'%s' = GPIO%d\n", gpio->name, gpio->gpio);
 			gpio++;
 			found = true;
 		}
 		if (!found)
-			pr_info(DRVNAME":    (none)\n");
+			pr_info("(none)\n");
 	}
 
 	if (spi_device && (verbose > 1))
@@ -1495,8 +1477,6 @@ static int __init fbtft_device_init(void)
 
 static void __exit fbtft_device_exit(void)
 {
-	pr_debug(DRVNAME" - exit\n");
-
 	if (spi_device) {
 		device_del(&spi_device->dev);
 		kfree(spi_device);
diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c
index c763efc5de7d..704b78c78f13 100644
--- a/drivers/staging/fbtft/flexfb.c
+++ b/drivers/staging/fbtft/flexfb.c
@@ -233,8 +233,6 @@ static const struct flexfb_lcd_controller flexfb_chip_table[] = {
 static void flexfb_set_addr_win_1(struct fbtft_par *par,
 				  int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n",
-		      __func__, xs, ys, xe, ye);
 	switch (par->info->var.rotate) {
 	/* R20h = Horizontal GRAM Start Address */
 	/* R21h = Vertical GRAM Start Address */
@@ -262,10 +260,6 @@ static void flexfb_set_addr_win_1(struct fbtft_par *par,
 static void flexfb_set_addr_win_2(struct fbtft_par *par,
 				  int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		      "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n",
-		      __func__, xs, ys, xe, ye);
-
 	switch (par->info->var.rotate) {
 	/* R4Eh - Set GDDRAM X address counter */
 	/* R4Fh - Set GDDRAM Y address counter */
@@ -295,10 +289,6 @@ static void flexfb_set_addr_win_2(struct fbtft_par *par,
 static void set_addr_win_3(struct fbtft_par *par,
 			   int xs, int ys, int xe, int ye)
 {
-	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-		      "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__,
-		      xs, ys, xe, ye);
-
 	write_reg(par, 0x15, xs, xe);
 	write_reg(par, 0x75, ys, ye);
 	write_reg(par, 0x5C);
@@ -463,15 +453,12 @@ static int flexfb_probe_common(struct spi_device *sdev,
 			}
 			par->fbtftops.write_register = fbtft_write_reg8_bus9;
 			par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
-			sdev->bits_per_word = 9;
-			ret = sdev->master->setup(sdev);
-			if (ret) {
+			if (par->spi->master->bits_per_word_mask
+			    & SPI_BPW_MASK(9)) {
+				par->spi->bits_per_word = 9;
+			} else {
 				dev_warn(dev,
 					"9-bit SPI not available, emulating using 8-bit.\n");
-				sdev->bits_per_word = 8;
-				ret = sdev->master->setup(sdev);
-				if (ret)
-					goto out_release;
 				/* allocate buffer with room for dc bits */
 				par->extra = devm_kzalloc(par->info->device,
 						par->txbuf.len + (par->txbuf.len / 8) + 8,
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c
index 766a65959b01..b3a60a032a17 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -209,7 +209,7 @@ EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
 static int get_dprc_icid(struct fsl_mc_io *mc_io,
 			 int container_id, uint16_t *icid)
 {
-	uint16_t dprc_handle;
+	u16 dprc_handle;
 	struct dprc_attributes attr;
 	int error;
 
@@ -234,7 +234,7 @@ common_cleanup:
 	return error;
 }
 
-static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr)
+static int translate_mc_addr(u64 mc_addr, phys_addr_t *phys_addr)
 {
 	int i;
 	struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
@@ -600,7 +600,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 	struct fsl_mc_io *mc_io = NULL;
 	int container_id;
 	phys_addr_t mc_portal_phys_addr;
-	uint32_t mc_portal_size;
+	u32 mc_portal_size;
 	struct mc_version mc_version;
 	struct resource res;
 
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
index 83683e9a1451..612ac0bd3756 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
@@ -82,13 +82,6 @@
 #define  STATE_DONE_PROV         0x06
 #define  STATE_DONE_FILE         0x07
 
-u16 get_handshake(struct net_device *dev, u16 expected_value);
-void put_handshake(struct net_device *dev, u16 handshake_value);
-u16 get_request_type(struct net_device *dev);
-long get_request_value(struct net_device *dev);
-void put_request_value(struct net_device *dev, long lvalue);
-u16 hdr_checksum(struct pseudo_hdr *pHdr);
-
 struct dsp_file_hdr {
 	u32  version_id;	/* Version ID of this image format. */
 	u32  package_id;	/* Package ID of code release. */
@@ -146,7 +139,7 @@ void card_bootload(struct net_device *dev)
 	spin_unlock_irqrestore(&info->dpram_lock, flags);
 }
 
-u16 get_handshake(struct net_device *dev, u16 expected_value)
+static u16 get_handshake(struct net_device *dev, u16 expected_value)
 {
 	struct ft1000_info *info = netdev_priv(dev);
 	u16 handshake;
@@ -180,7 +173,7 @@ u16 get_handshake(struct net_device *dev, u16 expected_value)
 
 }
 
-void put_handshake(struct net_device *dev, u16 handshake_value)
+static void put_handshake(struct net_device *dev, u16 handshake_value)
 {
 	struct ft1000_info *info = netdev_priv(dev);
 	u32 tempx;
@@ -196,7 +189,7 @@ void put_handshake(struct net_device *dev, u16 handshake_value)
 	}
 }
 
-u16 get_request_type(struct net_device *dev)
+static u16 get_request_type(struct net_device *dev)
 {
 	struct ft1000_info *info = netdev_priv(dev);
 	u16 request_type;
@@ -215,7 +208,7 @@ u16 get_request_type(struct net_device *dev)
 
 }
 
-long get_request_value(struct net_device *dev)
+static long get_request_value(struct net_device *dev)
 {
 	struct ft1000_info *info = netdev_priv(dev);
 	long value;
@@ -244,7 +237,7 @@ long get_request_value(struct net_device *dev)
 
 }
 
-void put_request_value(struct net_device *dev, long lvalue)
+static void put_request_value(struct net_device *dev, long lvalue)
 {
 	struct ft1000_info *info = netdev_priv(dev);
 	u16 size;
@@ -271,7 +264,7 @@ void put_request_value(struct net_device *dev, long lvalue)
 
 }
 
-u16 hdr_checksum(struct pseudo_hdr *pHdr)
+static u16 hdr_checksum(struct pseudo_hdr *pHdr)
 {
 	u16 *usPtr = (u16 *)pHdr;
 	u16 chksum;
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
index eecfa377054d..545f49845384 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
@@ -906,7 +906,6 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 	struct prov_record *ptr;
 	struct pseudo_hdr *ppseudo_hdr;
 	u16 *pmsg;
-	struct timeval tv;
 	union {
 		u8 byte[2];
 		u16 wrd;
@@ -983,8 +982,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 						netif_carrier_on(dev);
 						netif_wake_queue(dev);
 						info->mediastate = 1;
-						do_gettimeofday(&tv);
-						info->ConTm = tv.tv_sec;
+						info->ConTm = ktime_get_seconds();
 					}
 				} else {
 					pr_debug("Media is down\n");
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
index f241a3a5a684..be5ddb4817fe 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
@@ -413,7 +413,6 @@ static long ft1000_ioctl(struct file *file, unsigned int command,
 	int i;
 	u16 tempword;
 	unsigned long flags;
-	struct timeval tv;
 	struct IOCTL_GET_VER get_ver_data;
 	struct IOCTL_GET_DSP_STAT get_stat_data;
 	u8 ConnectionMsg[] = {
@@ -520,8 +519,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command,
 		get_stat_data.nRxPkts = info->stats.rx_packets;
 		get_stat_data.nTxBytes = info->stats.tx_bytes;
 		get_stat_data.nRxBytes = info->stats.rx_bytes;
-		do_gettimeofday(&tv);
-		get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm);
+		get_stat_data.ConTm = ktime_get_seconds() - info->ConTm;
 		pr_debug("Connection Time = %d\n", (int)get_stat_data.ConTm);
 		if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) {
 			pr_debug("copy fault occurred\n");
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
index 96209703ba25..5f4794bd8e1c 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
@@ -619,7 +619,6 @@ static int ft1000_open(struct net_device *dev)
 {
 	struct ft1000_info *pInfo = netdev_priv(dev);
 	struct ft1000_usb *pFt1000Dev = pInfo->priv;
-	struct timeval tv;
 
 	pr_debug("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber);
 
@@ -627,8 +626,7 @@ static int ft1000_open(struct net_device *dev)
 	pInfo->stats.tx_bytes = 0;
 	pInfo->stats.rx_packets = 0;
 	pInfo->stats.tx_packets = 0;
-	do_gettimeofday(&tv);
-	pInfo->ConTm = tv.tv_sec;
+	pInfo->ConTm = ktime_get_seconds();
 	pInfo->ProgConStat = 0;
 
 	netif_start_queue(dev);
diff --git a/drivers/staging/ft1000/ft1000.h b/drivers/staging/ft1000/ft1000.h
index 8a2e4caa532d..12fea0ffc7e4 100644
--- a/drivers/staging/ft1000/ft1000.h
+++ b/drivers/staging/ft1000/ft1000.h
@@ -6,6 +6,8 @@
  *
  */
 
+#include <linux/time64.h>
+
 #define DSPVERSZ	4
 #define HWSERNUMSZ	16
 #define SKUSZ		20
@@ -347,7 +349,7 @@ struct ft1000_info {
 	u8 HwSerNum[HWSERNUMSZ];	/* Hardware Serial Number */
 	u8 Sku[SKUSZ];			/* SKU */
 	u8 eui64[EUISZ];		/* EUI64 */
-	time_t ConTm;			/* Connection Time */
+	time64_t ConTm;			/* Connection Time */
 	u8 ProductMode[MODESZ];
 	u8 RfCalVer[CALVERSZ];
 	u8 RfCalDate[CALDATESZ];
diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c
index 96bf2bf87ff4..72c0f7ef8f2b 100644
--- a/drivers/staging/gdm72xx/gdm_qos.c
+++ b/drivers/staging/gdm72xx/gdm_qos.c
@@ -190,7 +190,7 @@ static int get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph)
 	int ip_ver, i;
 	struct qos_cb_s *qcb = &nic->qos;
 
-	if (iph == NULL || tcpudph == NULL)
+	if (!iph || !tcpudph)
 		return -1;
 
 	ip_ver = (iph[0]>>4)&0xf;
diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c
index a5fd0794842e..1f5a087723ba 100644
--- a/drivers/staging/gdm72xx/gdm_sdio.c
+++ b/drivers/staging/gdm72xx/gdm_sdio.c
@@ -36,7 +36,7 @@
 #define RX_BUF_SIZE	(25*1024)
 
 #define TX_HZ		2000
-#define TX_INTERVAL	(1000000/TX_HZ)
+#define TX_INTERVAL	(NSEC_PER_SEC/TX_HZ)
 
 static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx)
 {
@@ -173,12 +173,12 @@ static int init_sdio(struct sdiowm_dev *sdev)
 	spin_lock_init(&tx->lock);
 
 	tx->sdu_buf = kmalloc(SDU_TX_BUF_SIZE, GFP_KERNEL);
-	if (tx->sdu_buf == NULL)
+	if (!tx->sdu_buf)
 		goto fail;
 
 	for (i = 0; i < MAX_NR_SDU_BUF; i++) {
 		t = alloc_tx_struct(tx);
-		if (t == NULL) {
+		if (!t) {
 			ret = -ENOMEM;
 			goto fail;
 		}
@@ -192,7 +192,7 @@ static int init_sdio(struct sdiowm_dev *sdev)
 
 	for (i = 0; i < MAX_NR_RX_BUF; i++) {
 		r = alloc_rx_struct(rx);
-		if (r == NULL) {
+		if (!r) {
 			ret = -ENOMEM;
 			goto fail;
 		}
@@ -200,7 +200,7 @@ static int init_sdio(struct sdiowm_dev *sdev)
 	}
 
 	rx->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
-	if (rx->rx_buf == NULL)
+	if (!rx->rx_buf)
 		goto fail;
 
 	return 0;
@@ -303,7 +303,7 @@ static void send_sdu(struct sdio_func *func, struct tx_cxt *tx)
 		put_tx_struct(t->tx_cxt, t);
 	}
 
-	do_gettimeofday(&tx->sdu_stamp);
+	tx->sdu_stamp = ktime_get();
 	spin_unlock_irqrestore(&tx->lock, flags);
 }
 
@@ -330,7 +330,7 @@ static void do_tx(struct work_struct *work)
 	struct sdio_func *func = sdev->func;
 	struct tx_cxt *tx = &sdev->tx;
 	struct sdio_tx *t = NULL;
-	struct timeval now, *before;
+	ktime_t now, before;
 	int is_sdu = 0;
 	long diff;
 	unsigned long flags;
@@ -346,11 +346,10 @@ static void do_tx(struct work_struct *work)
 		list_del(&t->list);
 		is_sdu = 0;
 	} else if (!tx->stop_sdu_tx && !list_empty(&tx->sdu_list)) {
-		do_gettimeofday(&now);
-		before = &tx->sdu_stamp;
+		now = ktime_get();
+		before = tx->sdu_stamp;
 
-		diff = (now.tv_sec - before->tv_sec) * 1000000 +
-			(now.tv_usec - before->tv_usec);
+		diff = ktime_to_ns(ktime_sub(now, before));
 		if (diff >= 0 && diff < TX_INTERVAL) {
 			schedule_work(&sdev->ws);
 			spin_unlock_irqrestore(&tx->lock, flags);
@@ -359,7 +358,7 @@ static void do_tx(struct work_struct *work)
 		is_sdu = 1;
 	}
 
-	if (!is_sdu && t == NULL) {
+	if (!is_sdu && !t) {
 		spin_unlock_irqrestore(&tx->lock, flags);
 		return;
 	}
@@ -393,7 +392,7 @@ static int gdm_sdio_send(void *priv_dev, void *data, int len,
 	cmd_evt = (pkt[0] << 8) | pkt[1];
 	if (cmd_evt == WIMAX_TX_SDU) {
 		t = get_tx_struct(tx, &no_spc);
-		if (t == NULL) {
+		if (!t) {
 			/* This case must not happen. */
 			spin_unlock_irqrestore(&tx->lock, flags);
 			return -ENOSPC;
@@ -407,7 +406,7 @@ static int gdm_sdio_send(void *priv_dev, void *data, int len,
 		t->cb_data = cb_data;
 	} else {
 		t = alloc_tx_struct(tx);
-		if (t == NULL) {
+		if (!t) {
 			spin_unlock_irqrestore(&tx->lock, flags);
 			return -ENOMEM;
 		}
@@ -581,7 +580,7 @@ static int gdm_sdio_receive(void *priv_dev,
 
 	spin_lock_irqsave(&rx->lock, flags);
 	r = get_rx_struct(rx);
-	if (r == NULL) {
+	if (!r) {
 		spin_unlock_irqrestore(&rx->lock, flags);
 		return -ENOMEM;
 	}
@@ -615,12 +614,12 @@ static int sdio_wimax_probe(struct sdio_func *func,
 		return ret;
 
 	phy_dev = kzalloc(sizeof(*phy_dev), GFP_KERNEL);
-	if (phy_dev == NULL) {
+	if (!phy_dev) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
-	if (sdev == NULL) {
+	if (!sdev) {
 		ret = -ENOMEM;
 		goto out;
 	}
diff --git a/drivers/staging/gdm72xx/gdm_sdio.h b/drivers/staging/gdm72xx/gdm_sdio.h
index 77ad9d686f8e..aa7dad22a219 100644
--- a/drivers/staging/gdm72xx/gdm_sdio.h
+++ b/drivers/staging/gdm72xx/gdm_sdio.h
@@ -15,7 +15,7 @@
 #define __GDM72XX_GDM_SDIO_H__
 
 #include <linux/types.h>
-#include <linux/time.h>
+#include <linux/ktime.h>
 
 #define MAX_NR_SDU_BUF  64
 
@@ -32,7 +32,7 @@ struct tx_cxt {
 	struct list_head	free_list;
 	struct list_head	sdu_list;
 	struct list_head	hci_list;
-	struct timeval		sdu_stamp;
+	ktime_t			sdu_stamp;
 	u8			*sdu_buf;
 	spinlock_t		lock;
 	int			can_send;
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c
index eac2f3478bb9..16e497d9d0cf 100644
--- a/drivers/staging/gdm72xx/gdm_usb.c
+++ b/drivers/staging/gdm72xx/gdm_usb.c
@@ -139,7 +139,7 @@ static struct usb_rx *get_rx_struct(struct rx_cxt *rx)
 
 	if (list_empty(&rx->free_list)) {
 		r = alloc_rx_struct(rx);
-		if (r == NULL)
+		if (!r)
 			return NULL;
 
 		list_add(&r->list, &rx->free_list);
@@ -224,7 +224,7 @@ static int init_usb(struct usbwm_dev *udev)
 	spin_lock_irqsave(&tx->lock, flags);
 	for (i = 0; i < MAX_NR_SDU_BUF; i++) {
 		t = alloc_tx_struct(tx);
-		if (t == NULL) {
+		if (!t) {
 			spin_unlock_irqrestore(&tx->lock, flags);
 			ret = -ENOMEM;
 			goto fail;
@@ -234,7 +234,7 @@ static int init_usb(struct usbwm_dev *udev)
 	spin_unlock_irqrestore(&tx->lock, flags);
 
 	r = alloc_rx_struct(rx);
-	if (r == NULL) {
+	if (!r) {
 		ret = -ENOMEM;
 		goto fail;
 	}
@@ -313,7 +313,7 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
 	cmd_evt = (pkt[0] << 8) | pkt[1];
 	if (cmd_evt == WIMAX_TX_SDU) {
 		t = get_tx_struct(tx, &no_spc);
-		if (t == NULL) {
+		if (!t) {
 			/* This case must not happen. */
 			spin_unlock_irqrestore(&tx->lock, flags);
 			return -ENOSPC;
@@ -321,7 +321,7 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
 		list_add_tail(&t->list, &tx->sdu_list);
 	} else {
 		t = alloc_tx_struct(tx);
-		if (t == NULL) {
+		if (!t) {
 			spin_unlock_irqrestore(&tx->lock, flags);
 			return -ENOMEM;
 		}
@@ -478,7 +478,7 @@ static int gdm_usb_receive(void *priv_dev,
 	r = get_rx_struct(rx);
 	spin_unlock_irqrestore(&rx->lock, flags);
 
-	if (r == NULL)
+	if (!r)
 		return -ENOMEM;
 
 	r->callback = cb;
@@ -558,12 +558,12 @@ static int gdm_usb_probe(struct usb_interface *intf,
 	}
 
 	phy_dev = kzalloc(sizeof(*phy_dev), GFP_KERNEL);
-	if (phy_dev == NULL) {
+	if (!phy_dev) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	udev = kzalloc(sizeof(*udev), GFP_KERNEL);
-	if (udev == NULL) {
+	if (!udev) {
 		ret = -ENOMEM;
 		goto out;
 	}
diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c
index 08290d901b0c..6e8dbaf35445 100644
--- a/drivers/staging/gdm72xx/gdm_wimax.c
+++ b/drivers/staging/gdm72xx/gdm_wimax.c
@@ -62,7 +62,7 @@ static inline int gdm_wimax_header(struct sk_buff **pskb)
 		struct sk_buff *skb2;
 
 		skb2 = skb_realloc_headroom(skb, HCI_HEADER_SIZE);
-		if (skb2 == NULL)
+		if (!skb2)
 			return -ENOMEM;
 		if (skb->sk)
 			skb_set_owner_w(skb2, skb->sk);
@@ -397,7 +397,7 @@ static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src)
 	if (!(dst->buf && dst->size == src->size)) {
 		kdelete(&dst->buf);
 		dst->buf = kmalloc(src->size, GFP_KERNEL);
-		if (dst->buf == NULL)
+		if (!dst->buf)
 			return -ENOMEM;
 	}
 
diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c
index 2c02842ac5da..ba94b5f13bb2 100644
--- a/drivers/staging/gdm72xx/sdio_boot.c
+++ b/drivers/staging/gdm72xx/sdio_boot.c
@@ -72,7 +72,7 @@ static int download_image(struct sdio_func *func, const char *img_name)
 	}
 
 	buf = kmalloc(DOWNLOAD_SIZE + TYPE_A_HEADER_SIZE, GFP_KERNEL);
-	if (buf == NULL)
+	if (!buf)
 		return -ENOMEM;
 
 	img_len = firm->size;
@@ -139,7 +139,7 @@ int sdio_boot(struct sdio_func *func)
 	const char *rfs_name = FW_DIR FW_RFS;
 
 	tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL);
-	if (tx_buf == NULL)
+	if (!tx_buf)
 		return -ENOMEM;
 
 	ret = download_image(func, krn_name);
diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c
index 3ccc447730e8..39ca34031a6b 100644
--- a/drivers/staging/gdm72xx/usb_boot.c
+++ b/drivers/staging/gdm72xx/usb_boot.c
@@ -159,8 +159,10 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
 	}
 
 	tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
-	if (tx_buf == NULL)
+	if (!tx_buf) {
+		release_firmware(firm);
 		return -ENOMEM;
+	}
 
 	if (firm->size < sizeof(hdr)) {
 		dev_err(&usbdev->dev, "Cannot read the image info.\n");
@@ -285,8 +287,10 @@ static int em_download_image(struct usb_device *usbdev, const char *img_name,
 	}
 
 	buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
-	if (buf == NULL)
+	if (!buf) {
+		release_firmware(firm);
 		return -ENOMEM;
+	}
 
 	strcpy(buf+pad_size, type_string);
 	ret = gdm_wibro_send(usbdev, buf, strlen(type_string)+pad_size);
diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c
index 66ae48fcc2b2..623353db5a08 100644
--- a/drivers/staging/goldfish/goldfish_nand.c
+++ b/drivers/staging/goldfish/goldfish_nand.c
@@ -48,7 +48,7 @@ static u32 goldfish_nand_cmd_with_params(struct mtd_info *mtd,
 	struct cmd_params *cps = nand->cmd_params;
 	unsigned char __iomem  *base = nand->base;
 
-	if (cps == NULL)
+	if (!cps)
 		return -1;
 
 	switch (cmd) {
@@ -379,7 +379,7 @@ static int goldfish_nand_probe(struct platform_device *pdev)
 	unsigned char __iomem  *base;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (r == NULL)
+	if (!r)
 		return -ENODEV;
 
 	base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
diff --git a/drivers/staging/goldfish/goldfish_nand_reg.h b/drivers/staging/goldfish/goldfish_nand_reg.h
index fe7f47c7a5c8..43aeba3a4c8f 100644
--- a/drivers/staging/goldfish/goldfish_nand_reg.h
+++ b/drivers/staging/goldfish/goldfish_nand_reg.h
@@ -66,11 +66,11 @@ enum nand_reg {
 };
 
 struct cmd_params {
-	uint32_t dev;
-	uint32_t addr_low;
-	uint32_t addr_high;
-	uint32_t transfer_size;
+	u32 dev;
+	u32 addr_low;
+	u32 addr_high;
+	u32 transfer_size;
 	unsigned long data;
-	uint32_t result;
+	u32 result;
 };
 #endif
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 5b11b42c0254..a1dd74525c10 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -1756,43 +1756,43 @@ static irqreturn_t adt7316_event_handler(int irq, void *private)
 			stat1 &= 0x1F;
 
 		time = iio_get_time_ns();
-		if (stat1 & (1 << 0))
+		if (stat1 & BIT(0))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_RISING),
 				       time);
-		if (stat1 & (1 << 1))
+		if (stat1 & BIT(1))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_FALLING),
 				       time);
-		if (stat1 & (1 << 2))
+		if (stat1 & BIT(2))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_RISING),
 				       time);
-		if (stat1 & (1 << 3))
+		if (stat1 & BIT(3))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_FALLING),
 				       time);
-		if (stat1 & (1 << 5))
+		if (stat1 & BIT(5))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_EITHER),
 				       time);
-		if (stat1 & (1 << 6))
+		if (stat1 & BIT(6))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2,
 							    IIO_EV_TYPE_THRESH,
 							    IIO_EV_DIR_EITHER),
 				       time);
-		if (stat1 & (1 << 7))
+		if (stat1 & BIT(7))
 			iio_push_event(indio_dev,
 				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3,
 							    IIO_EV_TYPE_THRESH,
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index e6e9eaa9eab5..10fa372a4182 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -46,10 +46,10 @@
 #define AD7746_REG_VOLT_GAINL		18
 
 /* Status Register Bit Designations (AD7746_REG_STATUS) */
-#define AD7746_STATUS_EXCERR		(1 << 3)
-#define AD7746_STATUS_RDY		(1 << 2)
-#define AD7746_STATUS_RDYVT		(1 << 1)
-#define AD7746_STATUS_RDYCAP		(1 << 0)
+#define AD7746_STATUS_EXCERR		BIT(3)
+#define AD7746_STATUS_RDY		BIT(2)
+#define AD7746_STATUS_RDYVT		BIT(1)
+#define AD7746_STATUS_RDYCAP		BIT(0)
 
 /* Capacitive Channel Setup Register Bit Designations (AD7746_REG_CAP_SETUP) */
 #define AD7746_CAPSETUP_CAPEN		(1 << 7)
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index ffc7f0ddff14..3d2e50cfe9a3 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -219,7 +219,7 @@ static int ade7753_reset(struct device *dev)
 	u16 val;
 
 	ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val);
-	val |= 1 << 6; /* Software Chip Reset */
+	val |= BIT(6); /* Software Chip Reset */
 
 	return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
 }
@@ -328,10 +328,10 @@ static int ade7753_set_irq(struct device *dev, bool enable)
 		goto error_ret;
 
 	if (enable)
-		irqen |= 1 << 3; /* Enables an interrupt when a data is
+		irqen |= BIT(3); /* Enables an interrupt when a data is
 				    present in the waveform register */
 	else
-		irqen &= ~(1 << 3);
+		irqen &= ~BIT(3);
 
 	ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen);
 
@@ -345,7 +345,7 @@ static int ade7753_stop_device(struct device *dev)
 	u16 val;
 
 	ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val);
-	val |= 1 << 4;  /* AD converters can be turned off */
+	val |= BIT(4);  /* AD converters can be turned off */
 
 	return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
 }
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index f12b2e50329b..8552c76cbbe7 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -223,7 +223,7 @@ static int ade7754_reset(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	val |= 1 << 6; /* Software Chip Reset */
+	val |= BIT(6); /* Software Chip Reset */
 	return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
 }
 
@@ -350,10 +350,10 @@ static int ade7754_set_irq(struct device *dev, bool enable)
 		goto error_ret;
 
 	if (enable)
-		irqen |= 1 << 14; /* Enables an interrupt when a data is
+		irqen |= BIT(14); /* Enables an interrupt when a data is
 				     present in the waveform register */
 	else
-		irqen &= ~(1 << 14);
+		irqen &= ~BIT(14);
 
 	ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
 	if (ret)
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 77141ae1349d..38838085824f 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -308,7 +308,7 @@ static int ade7758_reset(struct device *dev)
 		dev_err(dev, "Failed to read opmode reg\n");
 		return ret;
 	}
-	val |= 1 << 6; /* Software Chip Reset */
+	val |= BIT(6); /* Software Chip Reset */
 	ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val);
 	if (ret < 0)
 		dev_err(dev, "Failed to write opmode reg\n");
@@ -426,10 +426,10 @@ int ade7758_set_irq(struct device *dev, bool enable)
 		goto error_ret;
 
 	if (enable)
-		irqen |= 1 << 16; /* Enables an interrupt when a data is
+		irqen |= BIT(16); /* Enables an interrupt when a data is
 				     present in the waveform register */
 	else
-		irqen &= ~(1 << 16);
+		irqen &= ~BIT(16);
 
 	ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen);
 	if (ret)
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index dbceda1e67ea..23e739207027 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -224,7 +224,7 @@ static int ade7759_reset(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	val |= 1 << 6; /* Software Chip Reset */
+	val |= BIT(6); /* Software Chip Reset */
 	return ade7759_spi_write_reg_16(dev,
 			ADE7759_MODE,
 			val);
@@ -288,10 +288,10 @@ static int ade7759_set_irq(struct device *dev, bool enable)
 		goto error_ret;
 
 	if (enable)
-		irqen |= 1 << 3; /* Enables an interrupt when a data is
+		irqen |= BIT(3); /* Enables an interrupt when a data is
 				    present in the waveform register */
 	else
-		irqen &= ~(1 << 3);
+		irqen &= ~BIT(3);
 
 	ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen);
 
@@ -314,7 +314,7 @@ static int ade7759_stop_device(struct device *dev)
 		return ret;
 	}
 
-	val |= 1 << 4;  /* AD converters can be turned off */
+	val |= BIT(4);  /* AD converters can be turned off */
 
 	return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val);
 }
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index d620bbd603a3..a83883596dbc 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -181,7 +181,7 @@ static int ade7854_reset(struct device *dev)
 	u16 val;
 
 	st->read_reg_16(dev, ADE7854_CONFIG, &val);
-	val |= 1 << 7; /* Software Chip Reset */
+	val |= BIT(7); /* Software Chip Reset */
 
 	return st->write_reg_16(dev, ADE7854_CONFIG, val);
 }
@@ -420,10 +420,10 @@ static int ade7854_set_irq(struct device *dev, bool enable)
 		goto error_ret;
 
 	if (enable)
-		irqen |= 1 << 17; /* 1: interrupt enabled when all periodical
+		irqen |= BIT(17); /* 1: interrupt enabled when all periodical
 				     (at 8 kHz rate) DSP computations finish. */
 	else
-		irqen &= ~(1 << 17);
+		irqen &= ~BIT(17);
 
 	ret = st->write_reg_32(dev, ADE7854_MASK0, irqen);
 	if (ret)
diff --git a/drivers/staging/lustre/README.txt b/drivers/staging/lustre/README.txt
index cf0ca50ff83b..0676243eea9e 100644
--- a/drivers/staging/lustre/README.txt
+++ b/drivers/staging/lustre/README.txt
@@ -14,10 +14,8 @@ Unlike shared disk storage cluster filesystems (e.g. OCFS2, GFS, GPFS),
 Lustre has independent Metadata and Data servers that clients can access
 in parallel to maximize performance.
 
-In order to use Lustre client you will need to download lustre client
-tools from
-https://downloads.hpdd.intel.com/public/lustre/latest-feature-release/
-the package name is lustre-client.
+In order to use Lustre client you will need to download the "lustre-client"
+package that contains the userspace tools from http://lustre.org/download/
 
 You will need to install and configure your Lustre servers separately.
 
@@ -76,12 +74,10 @@ Mount Options
 
 More Information
 ================
-You can get more information at
-OpenSFS website: http://lustre.opensfs.org/about/
-Intel HPDD wiki: https://wiki.hpdd.intel.com
+You can get more information at the Lustre website: http://wiki.lustre.org/
 
-Out of tree Lustre client and server code is available at:
-http://git.whamcloud.com/fs/lustre-release.git
+Source for the userspace tools and out-of-tree client and server code
+is available at: http://git.hpdd.intel.com/fs/lustre-release.git
 
 Latest binary packages:
-http://lustre.opensfs.org/download-lustre/
+http://lustre.org/download/
diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h
index 940f73f266d1..11630180c5e7 100644
--- a/drivers/staging/lustre/include/linux/lnet/types.h
+++ b/drivers/staging/lustre/include/linux/lnet/types.h
@@ -303,7 +303,7 @@ static inline int LNetHandleIsEqual(lnet_handle_any_t h1, lnet_handle_any_t h2)
  */
 static inline int LNetHandleIsInvalid(lnet_handle_any_t h)
 {
-	return LNET_WIRE_HANDLE_COOKIE_NONE == h.cookie;
+	return h.cookie == LNET_WIRE_HANDLE_COOKIE_NONE;
 }
 
 /**
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index f4b6c33ac318..07e81cb4a12e 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -79,38 +79,33 @@
 #define IBLND_N_SCHED_HIGH		4
 
 typedef struct {
-	int          *kib_dev_failover;      /* HCA failover */
-	unsigned int *kib_service;           /* IB service number */
-	int          *kib_min_reconnect_interval; /* first failed connection
-						   * retry... */
-	int          *kib_max_reconnect_interval; /* ...exponentially increasing
-						   * to this */
-	int          *kib_cksum;             /* checksum kib_msg_t? */
-	int          *kib_timeout;           /* comms timeout (seconds) */
-	int          *kib_keepalive;         /* keepalive timeout (seconds) */
-	int          *kib_ntx;               /* # tx descs */
-	int          *kib_credits;           /* # concurrent sends */
-	int          *kib_peertxcredits;     /* # concurrent sends to 1 peer */
-	int          *kib_peerrtrcredits;    /* # per-peer router buffer
-					      * credits */
-	int          *kib_peercredits_hiw;   /* # when eagerly to return
-					      * credits */
-	int          *kib_peertimeout;       /* seconds to consider peer dead */
-	char         **kib_default_ipif;     /* default IPoIB interface */
-	int          *kib_retry_count;
-	int          *kib_rnr_retry_count;
-	int          *kib_concurrent_sends;  /* send work queue sizing */
-	int          *kib_ib_mtu;            /* IB MTU */
-	int          *kib_map_on_demand;     /* map-on-demand if RD has more
-					      * fragments than this value, 0
-					      * disable map-on-demand */
-	int          *kib_fmr_pool_size;     /* # FMRs in pool */
-	int          *kib_fmr_flush_trigger; /* When to trigger FMR flush */
-	int          *kib_fmr_cache;         /* enable FMR pool cache? */
-	int          *kib_require_priv_port; /* accept only privileged ports */
-	int          *kib_use_priv_port;     /* use privileged port for active
-					      * connect */
-	int          *kib_nscheds;           /* # threads on each CPT */
+	int *kib_dev_failover;           /* HCA failover */
+	unsigned int *kib_service;       /* IB service number */
+	int *kib_min_reconnect_interval; /* first failed connection retry... */
+	int *kib_max_reconnect_interval; /* exponentially increasing to this */
+	int *kib_cksum;                  /* checksum kib_msg_t? */
+	int *kib_timeout;                /* comms timeout (seconds) */
+	int *kib_keepalive;              /* keepalive timeout (seconds) */
+	int *kib_ntx;                    /* # tx descs */
+	int *kib_credits;                /* # concurrent sends */
+	int *kib_peertxcredits;          /* # concurrent sends to 1 peer */
+	int *kib_peerrtrcredits;         /* # per-peer router buffer credits */
+	int *kib_peercredits_hiw;        /* # when eagerly to return credits */
+	int *kib_peertimeout;            /* seconds to consider peer dead */
+	char **kib_default_ipif;         /* default IPoIB interface */
+	int *kib_retry_count;
+	int *kib_rnr_retry_count;
+	int *kib_concurrent_sends;       /* send work queue sizing */
+	int *kib_ib_mtu;                 /* IB MTU */
+	int *kib_map_on_demand;          /* map-on-demand if RD has more */
+					 /* fragments than this value, 0 */
+					 /* disable map-on-demand */
+	int *kib_fmr_pool_size;          /* # FMRs in pool */
+	int *kib_fmr_flush_trigger;      /* When to trigger FMR flush */
+	int *kib_fmr_cache;              /* enable FMR pool cache? */
+	int *kib_require_priv_port;      /* accept only privileged ports */
+	int *kib_use_priv_port; /* use privileged port for active connect */
+	int *kib_nscheds;                /* # threads on each CPT */
 } kib_tunables_t;
 
 extern kib_tunables_t  kiblnd_tunables;
@@ -199,8 +194,7 @@ typedef struct {
 	unsigned long      ibd_next_failover;
 	int                ibd_failed_failover; /* # failover failures */
 	unsigned int       ibd_failover;        /* failover in progress */
-	unsigned int       ibd_can_failover;    /* IPoIB interface is a bonding
-						 * master */
+	unsigned int ibd_can_failover; /* IPoIB interface is a bonding master */
 	struct list_head   ibd_nets;
 	struct kib_hca_dev *ibd_hdev;
 } kib_dev_t;
@@ -249,28 +243,26 @@ typedef struct kib_poolset {
 	char                  ps_name[IBLND_POOL_NAME_LEN]; /* pool set name */
 	struct list_head      ps_pool_list;       /* list of pools */
 	struct list_head      ps_failed_pool_list;/* failed pool list */
-	unsigned long         ps_next_retry;      /* time stamp for retry if
-						   * failed to allocate */
+	unsigned long         ps_next_retry;      /* time stamp for retry if */
+						  /* failed to allocate */
 	int                   ps_increasing;      /* is allocating new pool */
 	int                   ps_pool_size;       /* new pool size */
 	int                   ps_cpt;             /* CPT id */
 
 	kib_ps_pool_create_t  ps_pool_create;     /* create a new pool */
 	kib_ps_pool_destroy_t ps_pool_destroy;    /* destroy a pool */
-	kib_ps_node_init_t    ps_node_init;       /* initialize new allocated
-						   * node */
+	kib_ps_node_init_t    ps_node_init; /* initialize new allocated node */
 	kib_ps_node_fini_t    ps_node_fini;       /* finalize node */
 } kib_poolset_t;
 
 typedef struct kib_pool {
-	struct list_head      po_list;         /* chain on pool list */
-	struct list_head      po_free_list;    /* pre-allocated node */
-	kib_poolset_t         *po_owner;       /* pool_set of this pool */
-	unsigned long         po_deadline;     /* deadline of this pool */
-	int                   po_allocated;    /* # of elements in use */
-	int                   po_failed;       /* pool is created on failed
-						* HCA */
-	int                   po_size;         /* # of pre-allocated elements */
+	struct list_head      po_list;       /* chain on pool list */
+	struct list_head      po_free_list;  /* pre-allocated node */
+	kib_poolset_t         *po_owner;     /* pool_set of this pool */
+	unsigned long         po_deadline;   /* deadline of this pool */
+	int                   po_allocated;  /* # of elements in use */
+	int                   po_failed;     /* pool is created on failed HCA */
+	int                   po_size;       /* # of pre-allocated elements */
 } kib_pool_t;
 
 typedef struct {
@@ -295,8 +287,8 @@ typedef struct {
 	int                   fps_pool_size;
 	int                   fps_flush_trigger;
 	int                   fps_increasing;      /* is allocating new pool */
-	unsigned long         fps_next_retry;      /* time stamp for retry if
-						    * failed to allocate */
+	unsigned long         fps_next_retry;      /* time stamp for retry if*/
+						   /* failed to allocate */
 } kib_fmr_poolset_t;
 
 typedef struct {
@@ -344,31 +336,22 @@ struct kib_sched_info {
 };
 
 typedef struct {
-	int                   kib_init;           /* initialisation state */
-	int                   kib_shutdown;       /* shut down? */
-	struct list_head      kib_devs;           /* IB devices extant */
-	struct list_head      kib_failed_devs;    /* list head of failed
-						   * devices */
-	wait_queue_head_t     kib_failover_waitq; /* schedulers sleep here */
-	atomic_t              kib_nthreads;       /* # live threads */
-	rwlock_t              kib_global_lock;    /* stabilize net/dev/peer/conn
-						   * ops */
-	struct list_head      *kib_peers;         /* hash table of all my known
-						   * peers */
-	int                   kib_peer_hash_size; /* size of kib_peers */
-	void                  *kib_connd;         /* the connd task
-						   * (serialisation assertions)
-						   */
-	struct list_head      kib_connd_conns;    /* connections to
-						   * setup/teardown */
-	struct list_head      kib_connd_zombies;  /* connections with zero
-						   * refcount */
-	wait_queue_head_t     kib_connd_waitq;    /* connection daemon sleeps
-						   * here */
-	spinlock_t            kib_connd_lock;     /* serialise */
-	struct ib_qp_attr     kib_error_qpa;      /* QP->ERROR */
-	struct kib_sched_info **kib_scheds;       /* percpt data for schedulers
-						   */
+	int               kib_init;           /* initialisation state */
+	int               kib_shutdown;       /* shut down? */
+	struct list_head  kib_devs;           /* IB devices extant */
+	struct list_head  kib_failed_devs;    /* list head of failed devices */
+	wait_queue_head_t kib_failover_waitq; /* schedulers sleep here */
+	atomic_t kib_nthreads;                /* # live threads */
+	rwlock_t kib_global_lock;    /* stabilize net/dev/peer/conn ops */
+	struct list_head *kib_peers; /* hash table of all my known peers */
+	int  kib_peer_hash_size;     /* size of kib_peers */
+	void *kib_connd; /* the connd task (serialisation assertions) */
+	struct list_head kib_connd_conns;   /* connections to setup/teardown */
+	struct list_head kib_connd_zombies; /* connections with zero refcount */
+	wait_queue_head_t kib_connd_waitq;  /* connection daemon sleeps here */
+	spinlock_t kib_connd_lock;          /* serialise */
+	struct ib_qp_attr kib_error_qpa;    /* QP->ERROR */
+	struct kib_sched_info **kib_scheds; /* percpt data for schedulers */
 } kib_data_t;
 
 #define IBLND_INIT_NOTHING 0
@@ -480,10 +463,10 @@ typedef struct {
 #define IBLND_REJECT_FATAL          3 /* Anything else */
 #define IBLND_REJECT_CONN_UNCOMPAT  4 /* incompatible version peer */
 #define IBLND_REJECT_CONN_STALE     5 /* stale peer */
-#define IBLND_REJECT_RDMA_FRAGS     6 /* Fatal: peer's rdma frags can't match
-				       * mine */
-#define IBLND_REJECT_MSG_QUEUE_SIZE 7 /* Fatal: peer's msg queue size can't
-				       * match mine */
+#define IBLND_REJECT_RDMA_FRAGS     6 /* Fatal: peer's rdma frags can't match */
+				      /* mine */
+#define IBLND_REJECT_MSG_QUEUE_SIZE 7 /* Fatal: peer's msg queue size can't */
+				      /* match mine */
 
 /***********************************************************************/
 
@@ -491,8 +474,7 @@ typedef struct kib_rx                         /* receive message */
 {
 	struct list_head       rx_list;       /* queue for attention */
 	struct kib_conn        *rx_conn;      /* owning conn */
-	int                    rx_nob;        /* # bytes received (-1 while
-					       * posted) */
+	int                    rx_nob; /* # bytes received (-1 while posted) */
 	enum ib_wc_status      rx_status;     /* completion status */
 	kib_msg_t              *rx_msg;       /* message buffer (host vaddr) */
 	__u64                  rx_msgaddr;    /* message buffer (I/O addr) */
@@ -501,38 +483,35 @@ typedef struct kib_rx                         /* receive message */
 	struct ib_sge          rx_sge;        /* ...and its memory */
 } kib_rx_t;
 
-#define IBLND_POSTRX_DONT_POST    0   /* don't post */
-#define IBLND_POSTRX_NO_CREDIT    1   /* post: no credits */
-#define IBLND_POSTRX_PEER_CREDIT  2   /* post: give peer back 1 credit */
-#define IBLND_POSTRX_RSRVD_CREDIT 3   /* post: give myself back 1 reserved
-				       * credit */
+#define IBLND_POSTRX_DONT_POST    0 /* don't post */
+#define IBLND_POSTRX_NO_CREDIT    1 /* post: no credits */
+#define IBLND_POSTRX_PEER_CREDIT  2 /* post: give peer back 1 credit */
+#define IBLND_POSTRX_RSRVD_CREDIT 3 /* post: give self back 1 reserved credit */
 
 typedef struct kib_tx                         /* transmit message */
 {
-	struct list_head       tx_list;       /* queue on idle_txs ibc_tx_queue
-					       * etc. */
-	kib_tx_pool_t          *tx_pool;      /* pool I'm from */
-	struct kib_conn        *tx_conn;      /* owning conn */
-	short                  tx_sending;    /* # tx callbacks outstanding */
-	short                  tx_queued;     /* queued for sending */
-	short                  tx_waiting;    /* waiting for peer */
-	int                    tx_status;     /* LNET completion status */
-	unsigned long          tx_deadline;   /* completion deadline */
-	__u64                  tx_cookie;     /* completion cookie */
-	lnet_msg_t             *tx_lntmsg[2]; /* lnet msgs to finalize on
-					       * completion */
-	kib_msg_t              *tx_msg;       /* message buffer (host vaddr) */
-	__u64                  tx_msgaddr;    /* message buffer (I/O addr) */
+	struct list_head      tx_list; /* queue on idle_txs ibc_tx_queue etc. */
+	kib_tx_pool_t         *tx_pool;       /* pool I'm from */
+	struct kib_conn       *tx_conn;       /* owning conn */
+	short                 tx_sending;     /* # tx callbacks outstanding */
+	short                 tx_queued;      /* queued for sending */
+	short                 tx_waiting;     /* waiting for peer */
+	int                   tx_status;      /* LNET completion status */
+	unsigned long         tx_deadline;    /* completion deadline */
+	__u64                 tx_cookie;      /* completion cookie */
+	lnet_msg_t *tx_lntmsg[2]; /* lnet msgs to finalize on completion */
+	kib_msg_t             *tx_msg;        /* message buffer (host vaddr) */
+	__u64                 tx_msgaddr;     /* message buffer (I/O addr) */
 	DECLARE_PCI_UNMAP_ADDR(tx_msgunmap);  /* for dma_unmap_single() */
-	int                    tx_nwrq;       /* # send work items */
-	struct ib_send_wr      *tx_wrq;       /* send work items... */
-	struct ib_sge          *tx_sge;       /* ...and their memory */
-	kib_rdma_desc_t        *tx_rd;        /* rdma descriptor */
-	int                    tx_nfrags;     /* # entries in... */
-	struct scatterlist     *tx_frags;     /* dma_map_sg descriptor */
-	__u64                  *tx_pages;     /* rdma phys page addrs */
-	kib_fmr_t		fmr;	      /* FMR */
-	int                    tx_dmadir;     /* dma direction */
+	int                   tx_nwrq;        /* # send work items */
+	struct ib_send_wr     *tx_wrq;        /* send work items... */
+	struct ib_sge         *tx_sge;        /* ...and their memory */
+	kib_rdma_desc_t       *tx_rd;         /* rdma descriptor */
+	int                   tx_nfrags;      /* # entries in... */
+	struct scatterlist    *tx_frags;      /* dma_map_sg descriptor */
+	__u64                 *tx_pages;      /* rdma phys page addrs */
+	kib_fmr_t             fmr;	      /* FMR */
+	int                   tx_dmadir;      /* dma direction */
 } kib_tx_t;
 
 typedef struct kib_connvars {
@@ -540,53 +519,44 @@ typedef struct kib_connvars {
 } kib_connvars_t;
 
 typedef struct kib_conn {
-	struct kib_sched_info *ibc_sched;           /* scheduler information */
-	struct kib_peer       *ibc_peer;            /* owning peer */
-	kib_hca_dev_t         *ibc_hdev;            /* HCA bound on */
-	struct list_head      ibc_list;             /* stash on peer's conn
-						     * list */
-	struct list_head      ibc_sched_list;       /* schedule for attention */
-	__u16                 ibc_version;          /* version of connection */
-	__u64                 ibc_incarnation;      /* which instance of the
-						     * peer */
-	atomic_t              ibc_refcount;         /* # users */
-	int                   ibc_state;            /* what's happening */
-	int                   ibc_nsends_posted;    /* # uncompleted sends */
-	int                   ibc_noops_posted;     /* # uncompleted NOOPs */
-	int                   ibc_credits;          /* # credits I have */
+	struct kib_sched_info *ibc_sched;      /* scheduler information */
+	struct kib_peer       *ibc_peer;       /* owning peer */
+	kib_hca_dev_t         *ibc_hdev;       /* HCA bound on */
+	struct list_head ibc_list;             /* stash on peer's conn list */
+	struct list_head      ibc_sched_list;  /* schedule for attention */
+	__u16                 ibc_version;     /* version of connection */
+	__u64                 ibc_incarnation; /* which instance of the peer */
+	atomic_t              ibc_refcount;    /* # users */
+	int                   ibc_state;       /* what's happening */
+	int                   ibc_nsends_posted; /* # uncompleted sends */
+	int                   ibc_noops_posted;  /* # uncompleted NOOPs */
+	int                   ibc_credits;     /* # credits I have */
 	int                   ibc_outstanding_credits; /* # credits to return */
 	int                   ibc_reserved_credits; /* # ACK/DONE msg credits */
-	int                   ibc_comms_error;      /* set on comms error */
-	unsigned int          ibc_nrx:16;           /* receive buffers owned */
-	unsigned int          ibc_scheduled:1;      /* scheduled for attention
-						     */
-	unsigned int          ibc_ready:1;          /* CQ callback fired */
-	unsigned long         ibc_last_send;        /* time of last send */
-	struct list_head      ibc_connd_list;       /* link chain for
-						     * kiblnd_check_conns only
-						     */
-	struct list_head      ibc_early_rxs;        /* rxs completed before
-						     * ESTABLISHED */
-	struct list_head      ibc_tx_noops;         /* IBLND_MSG_NOOPs for
-						     * IBLND_MSG_VERSION_1 */
-	struct list_head      ibc_tx_queue;         /* sends that need a credit
-						     */
-	struct list_head      ibc_tx_queue_nocred;  /* sends that don't need a
-						     * credit */
-	struct list_head      ibc_tx_queue_rsrvd;   /* sends that need to
-						     * reserve an ACK/DONE msg
-						     */
-	struct list_head      ibc_active_txs;       /* active tx awaiting
-						     * completion */
-	spinlock_t            ibc_lock;             /* serialise */
-	kib_rx_t              *ibc_rxs;             /* the rx descs */
-	kib_pages_t           *ibc_rx_pages;        /* premapped rx msg pages */
-
-	struct rdma_cm_id     *ibc_cmid;            /* CM id */
-	struct ib_cq          *ibc_cq;              /* completion queue */
-
-	kib_connvars_t        *ibc_connvars;        /* in-progress connection
-						     * state */
+	int                   ibc_comms_error; /* set on comms error */
+	unsigned int          ibc_nrx:16;      /* receive buffers owned */
+	unsigned int          ibc_scheduled:1; /* scheduled for attention */
+	unsigned int          ibc_ready:1;     /* CQ callback fired */
+	unsigned long         ibc_last_send;   /* time of last send */
+	struct list_head      ibc_connd_list;  /* link chain for */
+					       /* kiblnd_check_conns only */
+	struct list_head ibc_early_rxs; /* rxs completed before ESTABLISHED */
+	struct list_head ibc_tx_noops;         /* IBLND_MSG_NOOPs for */
+					       /* IBLND_MSG_VERSION_1 */
+	struct list_head ibc_tx_queue;         /* sends that need a credit */
+	struct list_head ibc_tx_queue_nocred;  /* sends that don't need a */
+					       /* credit */
+	struct list_head ibc_tx_queue_rsrvd;   /* sends that need to */
+					       /* reserve an ACK/DONE msg */
+	struct list_head ibc_active_txs; /* active tx awaiting completion */
+	spinlock_t            ibc_lock;        /* serialise */
+	kib_rx_t              *ibc_rxs;        /* the rx descs */
+	kib_pages_t           *ibc_rx_pages;   /* premapped rx msg pages */
+
+	struct rdma_cm_id     *ibc_cmid;       /* CM id */
+	struct ib_cq          *ibc_cq;         /* completion queue */
+
+	kib_connvars_t        *ibc_connvars; /* in-progress connection state */
 } kib_conn_t;
 
 #define IBLND_CONN_INIT           0	 /* being initialised */
@@ -780,8 +750,8 @@ kiblnd_queue2str(kib_conn_t *conn, struct list_head *q)
 	return NULL;
 }
 
-/* CAVEAT EMPTOR: We rely on descriptor alignment to allow us to use the
- * lowest bits of the work request id to stash the work item type. */
+/* CAVEAT EMPTOR: We rely on descriptor alignment to allow us to use the */
+/* lowest bits of the work request id to stash the work item type. */
 
 #define IBLND_WID_TX    0
 #define IBLND_WID_RDMA  1
@@ -928,9 +898,9 @@ static inline unsigned int kiblnd_sg_dma_len(struct ib_device *dev,
 	return ib_sg_dma_len(dev, sg);
 }
 
-/* XXX We use KIBLND_CONN_PARAM(e) as writable buffer, it's not strictly
- * right because OFED1.2 defines it as const, to use it we have to add
- * (void *) cast to overcome "const" */
+/* XXX We use KIBLND_CONN_PARAM(e) as writable buffer, it's not strictly */
+/* right because OFED1.2 defines it as const, to use it we have to add */
+/* (void *) cast to overcome "const" */
 
 #define KIBLND_CONN_PARAM(e)     ((e)->param.conn.private_data)
 #define KIBLND_CONN_PARAM_LEN(e) ((e)->param.conn.private_data_len)
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index a23a6d956a4d..345ed4d27cc6 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -253,11 +253,10 @@ kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie)
 	}
 
 	if (tx->tx_status == 0) {	       /* success so far */
-		if (status < 0) {	       /* failed? */
+		if (status < 0) /* failed? */
 			tx->tx_status = status;
-		} else if (txtype == IBLND_MSG_GET_REQ) {
+		else if (txtype == IBLND_MSG_GET_REQ)
 			lnet_set_reply_msg_len(ni, tx->tx_lntmsg[1], status);
-		}
 	}
 
 	tx->tx_waiting = 0;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 0d5aac6a2bb3..6d87731c539d 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -626,7 +626,7 @@ ksocknal_find_conn_locked(ksock_peer_t *peer, ksock_tx_t *tx, int nonblk)
 	list_for_each (tmp, &peer->ksnp_conns) {
 		ksock_conn_t *c  = list_entry(tmp, ksock_conn_t, ksnc_list);
 		int nob = atomic_read(&c->ksnc_tx_nob) +
-                                      c->ksnc_sock->sk->sk_wmem_queued;
+			c->ksnc_sock->sk->sk_wmem_queued;
 		int rc;
 
 		LASSERT(!c->ksnc_closing);
@@ -714,7 +714,7 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
 	LASSERT(tx->tx_resid == tx->tx_nob);
 
 	CDEBUG (D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n",
-		tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type:
+		tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type :
 					       KSOCK_MSG_NOOP,
 		tx->tx_nob, tx->tx_niov, tx->tx_nkiov);
 
@@ -1092,7 +1092,7 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 		conn->ksnc_rx_iov[niov].iov_len  = nob;
 		niov++;
 		skipped += nob;
-		nob_to_skip -=nob;
+		nob_to_skip -= nob;
 
 	} while (nob_to_skip != 0 &&    /* mustn't overflow conn's rx iov */
 		 niov < sizeof(conn->ksnc_rx_iov_space) / sizeof (struct iovec));
@@ -1313,7 +1313,7 @@ ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
 	       unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
 	       unsigned int offset, unsigned int mlen, unsigned int rlen)
 {
-	ksock_conn_t *conn = (ksock_conn_t *)private;
+	ksock_conn_t *conn = private;
 	ksock_sched_t *sched = conn->ksnc_scheduler;
 
 	LASSERT(mlen <= rlen);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
index 340706110c21..679785b0209c 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
@@ -355,9 +355,9 @@ ksocknal_lib_recv_kiov(ksock_conn_t *conn)
 			LASSERT(i < niov);
 
 			/* Dang! have to kmap again because I have nowhere to
-                         * stash the mapped address.  But by doing it while the
-                         * page is still mapped, the kernel just bumps the map
-                         * count and returns me the address it stashed. */
+			 * stash the mapped address.  But by doing it while the
+			 * page is still mapped, the kernel just bumps the map
+			 * count and returns me the address it stashed. */
 			base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
 			fragnob = kiov[i].kiov_len;
 			if (fragnob > sum)
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 84707c5cb464..b4f573ab62cc 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -420,9 +420,9 @@ lnet_mt_match_md(struct lnet_match_table *mtable,
 
 	if (info->mi_opc == LNET_MD_OP_GET ||
 	    !lnet_ptl_is_lazy(the_lnet.ln_portals[info->mi_portal]))
-		return LNET_MATCHMD_DROP | exhausted;
+		return exhausted | LNET_MATCHMD_DROP;
 
-	return LNET_MATCHMD_NONE | exhausted;
+	return exhausted | LNET_MATCHMD_NONE;
 }
 
 static int
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index 7d33cf9e9d99..ae7ed75573b9 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -105,8 +105,8 @@ typedef struct lstcon_rpc_trans {
 
 #define LST_TRANS_STATQRY       0x21
 
-typedef int (* lstcon_rpc_cond_func_t)(int, struct lstcon_node *, void *);
-typedef int (* lstcon_rpc_readent_func_t)(int, srpc_msg_t *, lstcon_rpc_ent_t *);
+typedef int (*lstcon_rpc_cond_func_t)(int, struct lstcon_node *, void *);
+typedef int (*lstcon_rpc_readent_func_t)(int, srpc_msg_t *, lstcon_rpc_ent_t *);
 
 int  lstcon_sesrpc_prep(struct lstcon_node *nd, int transop,
 			unsigned version, lstcon_rpc_t **crpc);
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index f47c8f27f975..5c624e19eaa1 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -308,7 +308,7 @@ lstcon_group_ndlink_release(lstcon_group_t *grp, lstcon_ndlink_t *ndl)
 {
 	list_del_init(&ndl->ndl_link);
 	lstcon_ndlink_release(ndl);
-	grp->grp_nnode --;
+	grp->grp_nnode--;
 }
 
 static void
@@ -320,7 +320,7 @@ lstcon_group_ndlink_move(lstcon_group_t *old,
 
 	list_del(&ndl->ndl_hlink);
 	list_del(&ndl->ndl_link);
-	old->grp_nnode --;
+	old->grp_nnode--;
 
 	list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);
 	list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);
@@ -527,7 +527,7 @@ lstcon_group_add(char *name)
 	lstcon_group_t *grp;
 	int rc;
 
-	rc = (lstcon_group_find(name, &grp) == 0)? -EEXIST: 0;
+	rc = (lstcon_group_find(name, &grp) == 0) ? -EEXIST : 0;
 	if (rc != 0) {
 		/* find a group with same name */
 		lstcon_group_put(grp);
@@ -816,7 +816,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
 		LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp);
 
 	rc = copy_to_user(gents_p, gentp,
-			      sizeof(lstcon_ndlist_ent_t)) ? -EFAULT: 0;
+			      sizeof(lstcon_ndlist_ent_t)) ? -EFAULT : 0;
 
 	LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t));
 
@@ -847,7 +847,7 @@ lstcon_batch_add(char *name)
 	int i;
 	int rc;
 
-	rc = (lstcon_batch_find(name, &bat) == 0)? -EEXIST: 0;
+	rc = (lstcon_batch_find(name, &bat) == 0) ? -EEXIST : 0;
 	if (rc != 0) {
 		CDEBUG(D_NET, "Batch %s already exists\n", name);
 		return rc;
@@ -911,7 +911,7 @@ lstcon_batch_list(int index, int len, char *name_up)
 	list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) {
 		if (index-- == 0) {
 			return copy_to_user(name_up, bat->bat_name, len) ?
-			       -EFAULT: 0;
+			       -EFAULT : 0;
 		}
 	}
 
@@ -956,7 +956,7 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t *ent_up, int server,
 				  &test->tes_dst_grp->grp_ndl_list;
 
 	if (dents_up != NULL) {
-		rc = lstcon_nodes_getent((server ? srvlst: clilst),
+		rc = lstcon_nodes_getent((server ? srvlst : clilst),
 					 index_p, ndent_p, dents_up);
 		return rc;
 	}
@@ -1683,7 +1683,7 @@ int
 lstcon_session_match(lst_sid_t sid)
 {
 	return (console_session.ses_id.ses_nid   == sid.ses_nid &&
-		console_session.ses_id.ses_stamp == sid.ses_stamp) ?  1: 0;
+		console_session.ses_id.ses_stamp == sid.ses_stamp) ?  1 : 0;
 }
 
 static void
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index 7939e4e04d90..dfe3342750e9 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -562,7 +562,7 @@ static inline const char *
 swi_state2str (int state)
 {
 #define STATE2STR(x) case x: return #x
-	switch(state) {
+	switch (state) {
 		default:
 			LBUG();
 		STATE2STR(SWI_STATE_NEWBORN);
diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index d56c8bea89c4..04dcb5111756 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -1095,7 +1095,7 @@ do {								    \
 									\
 	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
 		cl_page_print(env, &msgdata, lu_cdebug_printer, page);  \
-		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+		CDEBUG(mask, format, ## __VA_ARGS__);		  \
 	}							       \
 } while (0)
 
@@ -1108,7 +1108,7 @@ do {									  \
 									      \
 	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {			 \
 		cl_page_header_print(env, &msgdata, lu_cdebug_printer, page); \
-		CDEBUG(mask, format , ## __VA_ARGS__);			\
+		CDEBUG(mask, format, ## __VA_ARGS__);			\
 	}								     \
 } while (0)
 
@@ -1475,13 +1475,13 @@ enum cl_lock_flags {
 	 * lock has been cancelled. This flag is never cleared once set (by
 	 * cl_lock_cancel0()).
 	 */
-	CLF_CANCELLED  = 1 << 0,
+	CLF_CANCELLED	= 1 << 0,
 	/** cancellation is pending for this lock. */
-	CLF_CANCELPEND = 1 << 1,
+	CLF_CANCELPEND	= 1 << 1,
 	/** destruction is pending for this lock. */
-	CLF_DOOMED     = 1 << 2,
+	CLF_DOOMED	= 1 << 2,
 	/** from enqueue RPC reply upcall. */
-	CLF_FROM_UPCALL= 1 << 3,
+	CLF_FROM_UPCALL	= 1 << 3,
 };
 
 /**
@@ -1833,7 +1833,7 @@ do {								    \
 									\
 	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
 		cl_lock_print(env, &msgdata, lu_cdebug_printer, lock);  \
-		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+		CDEBUG(mask, format, ## __VA_ARGS__);		  \
 	}							       \
 } while (0)
 
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
index 45651caf42cc..f5d83ebe2fdd 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
@@ -40,7 +40,7 @@
 #endif
 
 
-#include <asm/statfs.h>
+#include <linux/statfs.h>
 
 #include <linux/fs.h>
 #include <linux/dcache.h>
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index fd3c4df319c2..213666b03f7c 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -206,7 +206,8 @@ struct lprocfs_stats {
 #define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC)
 
 /* Pack all opcodes down into a single monotonically increasing index */
-static inline int opcode_offset(__u32 opc) {
+static inline int opcode_offset(__u32 opc)
+{
 	if (opc < OST_LAST_OPC) {
 		 /* OST opcode */
 		return (opc - OST_FIRST_OPC);
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index e1d72a7a5c2d..a16c9ea98373 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -790,7 +790,7 @@ do {								      \
 									  \
 	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		     \
 		lu_object_print(env, &msgdata, lu_cdebug_printer, object);\
-		CDEBUG(mask, format , ## __VA_ARGS__);		    \
+		CDEBUG(mask, format, ## __VA_ARGS__);		    \
 	}								 \
 } while (0)
 
@@ -805,7 +805,7 @@ do {								    \
 		lu_object_header_print(env, &msgdata, lu_cdebug_printer,\
 				       (object)->lo_header);	    \
 		lu_cdebug_printer(env, &msgdata, "\n");		 \
-		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+		CDEBUG(mask, format, ## __VA_ARGS__);		  \
 	}							       \
 } while (0)
 
@@ -1131,7 +1131,7 @@ struct lu_context_key {
 								  \
 		return value;				     \
 	}							 \
-	struct __##mod##__dummy_init {;} /* semicolon catcher */
+	struct __##mod##__dummy_init {; } /* semicolon catcher */
 
 #define LU_KEY_FINI(mod, type)					      \
 	static void mod##_key_fini(const struct lu_context *ctx,	    \
@@ -1141,7 +1141,7 @@ struct lu_context_key {
 									    \
 		OBD_FREE_PTR(info);					 \
 	}								   \
-	struct __##mod##__dummy_fini {;} /* semicolon catcher */
+	struct __##mod##__dummy_fini {; } /* semicolon catcher */
 
 #define LU_KEY_INIT_FINI(mod, type)   \
 	LU_KEY_INIT(mod, type);	\
@@ -1193,28 +1193,28 @@ void  lu_context_key_revive  (struct lu_context_key *key);
 		mod##_key_init_generic(__VA_ARGS__, NULL);	      \
 		return lu_context_key_register_many(__VA_ARGS__, NULL); \
 	}							       \
-	struct __##mod##_dummy_type_init {;}
+	struct __##mod##_dummy_type_init {; }
 
 #define LU_TYPE_FINI(mod, ...)					  \
 	static void mod##_type_fini(struct lu_device_type *t)	   \
 	{							       \
 		lu_context_key_degister_many(__VA_ARGS__, NULL);	\
 	}							       \
-	struct __##mod##_dummy_type_fini {;}
+	struct __##mod##_dummy_type_fini {; }
 
 #define LU_TYPE_START(mod, ...)				 \
 	static void mod##_type_start(struct lu_device_type *t)  \
 	{						       \
 		lu_context_key_revive_many(__VA_ARGS__, NULL);  \
 	}						       \
-	struct __##mod##_dummy_type_start {;}
+	struct __##mod##_dummy_type_start {; }
 
 #define LU_TYPE_STOP(mod, ...)				  \
 	static void mod##_type_stop(struct lu_device_type *t)   \
 	{						       \
 		lu_context_key_quiesce_many(__VA_ARGS__, NULL); \
 	}						       \
-	struct __##mod##_dummy_type_stop {;}
+	struct __##mod##_dummy_type_stop {; }
 
 
 
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index ac78dbc38b9f..e79af19ce853 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -827,7 +827,7 @@ static inline int lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
 	typeof(val0) __val0 = (val0);			   \
 	typeof(val1) __val1 = (val1);			   \
 								\
-	(__val0 == __val1 ? 0 : __val0 > __val1 ? +1 : -1);     \
+	(__val0 == __val1 ? 0 : __val0 > __val1 ? 1 : -1);     \
 })
 
 static inline int lu_fid_cmp(const struct lu_fid *f0,
@@ -1404,9 +1404,9 @@ void lustre_swab_connect(struct obd_connect_data *ocd);
  * algorithm and also the OBD_FL_CKSUM* flags.
  */
 typedef enum {
-	OBD_CKSUM_CRC32 = 0x00000001,
-	OBD_CKSUM_ADLER = 0x00000002,
-	OBD_CKSUM_CRC32C= 0x00000004,
+	OBD_CKSUM_CRC32  = 0x00000001,
+	OBD_CKSUM_ADLER  = 0x00000002,
+	OBD_CKSUM_CRC32C = 0x00000004,
 } cksum_type_t;
 
 /*
@@ -1444,7 +1444,7 @@ enum obdo_flags {
 	OBD_FL_DELORPHAN    = 0x00000004, /* if set in o_flags delete orphans */
 	OBD_FL_NORPC	= 0x00000008, /* set in o_flags do in OSC not OST */
 	OBD_FL_IDONLY       = 0x00000010, /* set in o_flags only adjust obj id*/
-	OBD_FL_RECREATE_OBJS= 0x00000020, /* recreate missing obj */
+	OBD_FL_RECREATE_OBJS = 0x00000020, /* recreate missing obj */
 	OBD_FL_DEBUG_CHECK  = 0x00000040, /* echo client/server debug check */
 	OBD_FL_NO_USRQUOTA  = 0x00000100, /* the object's owner is over quota */
 	OBD_FL_NO_GRPQUOTA  = 0x00000200, /* the object's group is over quota */
@@ -3574,7 +3574,7 @@ struct link_ea_entry {
 	unsigned char      lee_reclen[2];
 	unsigned char      lee_parent_fid[sizeof(struct lu_fid)];
 	char	       lee_name[0];
-}__attribute__((packed));
+} __attribute__((packed));
 
 /** fid2path request/reply structure */
 struct getinfo_fid2path {
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
index 9b1bb23c4d3c..e9925ef1dbee 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
@@ -658,7 +658,8 @@ enum changelog_rec_type {
 	CL_LAST
 };
 
-static inline const char *changelog_type2str(int type) {
+static inline const char *changelog_type2str(int type)
+{
 	static const char *changelog_str[] = {
 		"MARK",  "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
 		"RMDIR", "RENME", "RNMTO", "OPEN",  "CLOSE", "LYOUT", "TRUNC",
@@ -798,14 +799,14 @@ struct changelog_ext_rec {
 
 static inline int changelog_rec_size(struct changelog_rec *rec)
 {
-	return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec):
+	return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec) :
 					     sizeof(*rec);
 }
 
 static inline char *changelog_rec_name(struct changelog_rec *rec)
 {
 	return CHANGELOG_REC_EXTENDED(rec) ?
-		((struct changelog_ext_rec *)rec)->cr_name: rec->cr_name;
+		((struct changelog_ext_rec *)rec)->cr_name : rec->cr_name;
 }
 
 static inline int changelog_rec_snamelen(struct changelog_ext_rec *rec)
diff --git a/drivers/staging/lustre/lustre/include/lustre_capa.h b/drivers/staging/lustre/lustre/include/lustre_capa.h
index fe19534ebd8f..11bcdb935443 100644
--- a/drivers/staging/lustre/lustre/include/lustre_capa.h
+++ b/drivers/staging/lustre/lustre/include/lustre_capa.h
@@ -171,7 +171,7 @@ CDEBUG(level, fmt " capability key@%p seq %llu keyid %u\n",		 \
        ##args, k, capa_key_seq(k), capa_key_keyid(k));			 \
 } while (0)
 
-typedef int (* renew_capa_cb_t)(struct obd_capa *, struct lustre_capa *);
+typedef int (*renew_capa_cb_t)(struct obd_capa *, struct lustre_capa *);
 
 /* obdclass/capa.c */
 extern struct list_head capa_list[];
diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h
index 9b2833131744..131985d3081a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_disk.h
+++ b/drivers/staging/lustre/lustre/include/lustre_disk.h
@@ -365,7 +365,7 @@ static inline void check_lcd(char *obd_name, int index,
 			     struct lsd_client_data *lcd)
 {
 	int length = sizeof(lcd->lcd_uuid);
-	if (strnlen((char*)lcd->lcd_uuid, length) == length) {
+	if (strnlen((char *)lcd->lcd_uuid, length) == length) {
 		lcd->lcd_uuid[length - 1] = '\0';
 
 		LCONSOLE_ERROR("the client UUID (%s) on %s for exports stored in last_rcvd(index = %d) is bad!\n",
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index 355254689dee..92b24be7c21e 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -1025,7 +1025,7 @@ char *ldlm_it2str(int it);
  * with a debugging message that is ldlm-related
  */
 #define LDLM_DEBUG_NOLOCK(format, a...)			\
-	CDEBUG(D_DLMTRACE, "### " format "\n" , ##a)
+	CDEBUG(D_DLMTRACE, "### " format "\n", ##a)
 
 /**
  * Support function for lock information printing into debug logs.
@@ -1051,7 +1051,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 #define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) do {			 \
 	static struct cfs_debug_limit_state _ldlm_cdls;			   \
 	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_ldlm_cdls);	      \
-	ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt , ##a);\
+	ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt, ##a);\
 } while (0)
 
 #define LDLM_ERROR(lock, fmt, a...) LDLM_DEBUG_LIMIT(D_ERROR, lock, fmt, ## a)
@@ -1062,7 +1062,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 	if (likely(lock != NULL)) {					    \
 		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_DLMTRACE, NULL);      \
 		ldlm_lock_debug(&msgdata, D_DLMTRACE, NULL, lock,	    \
-				"### " fmt , ##a);			    \
+				"### " fmt, ##a);			    \
 	} else {							    \
 		LDLM_DEBUG_NOLOCK("no dlm lock: " fmt, ##a);		    \
 	}								    \
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
index d4cc09635271..d27bdae0b373 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
@@ -51,58 +51,58 @@
 
 /** extent, mode, or resource changed */
 #define LDLM_FL_LOCK_CHANGED            0x0000000000000001ULL // bit   0
-#define ldlm_is_lock_changed(_l)        LDLM_TEST_FLAG(( _l), 1ULL <<  0)
-#define ldlm_set_lock_changed(_l)       LDLM_SET_FLAG((  _l), 1ULL <<  0)
+#define ldlm_is_lock_changed(_l)        LDLM_TEST_FLAG((_l), 1ULL <<  0)
+#define ldlm_set_lock_changed(_l)       LDLM_SET_FLAG((_l), 1ULL <<  0)
 #define ldlm_clear_lock_changed(_l)     LDLM_CLEAR_FLAG((_l), 1ULL <<  0)
 
 /**
  * Server placed lock on granted list, or a recovering client wants the
  * lock added to the granted list, no questions asked. */
 #define LDLM_FL_BLOCK_GRANTED           0x0000000000000002ULL // bit   1
-#define ldlm_is_block_granted(_l)       LDLM_TEST_FLAG(( _l), 1ULL <<  1)
-#define ldlm_set_block_granted(_l)      LDLM_SET_FLAG((  _l), 1ULL <<  1)
+#define ldlm_is_block_granted(_l)       LDLM_TEST_FLAG((_l), 1ULL <<  1)
+#define ldlm_set_block_granted(_l)      LDLM_SET_FLAG((_l), 1ULL <<  1)
 #define ldlm_clear_block_granted(_l)    LDLM_CLEAR_FLAG((_l), 1ULL <<  1)
 
 /**
  * Server placed lock on conv list, or a recovering client wants the lock
  * added to the conv list, no questions asked. */
 #define LDLM_FL_BLOCK_CONV              0x0000000000000004ULL // bit   2
-#define ldlm_is_block_conv(_l)          LDLM_TEST_FLAG(( _l), 1ULL <<  2)
-#define ldlm_set_block_conv(_l)         LDLM_SET_FLAG((  _l), 1ULL <<  2)
+#define ldlm_is_block_conv(_l)          LDLM_TEST_FLAG((_l), 1ULL <<  2)
+#define ldlm_set_block_conv(_l)         LDLM_SET_FLAG((_l), 1ULL <<  2)
 #define ldlm_clear_block_conv(_l)       LDLM_CLEAR_FLAG((_l), 1ULL <<  2)
 
 /**
  * Server placed lock on wait list, or a recovering client wants the lock
  * added to the wait list, no questions asked. */
 #define LDLM_FL_BLOCK_WAIT              0x0000000000000008ULL // bit   3
-#define ldlm_is_block_wait(_l)          LDLM_TEST_FLAG(( _l), 1ULL <<  3)
-#define ldlm_set_block_wait(_l)         LDLM_SET_FLAG((  _l), 1ULL <<  3)
+#define ldlm_is_block_wait(_l)          LDLM_TEST_FLAG((_l), 1ULL <<  3)
+#define ldlm_set_block_wait(_l)         LDLM_SET_FLAG((_l), 1ULL <<  3)
 #define ldlm_clear_block_wait(_l)       LDLM_CLEAR_FLAG((_l), 1ULL <<  3)
 
 /** blocking or cancel packet was queued for sending. */
 #define LDLM_FL_AST_SENT                0x0000000000000020ULL // bit   5
-#define ldlm_is_ast_sent(_l)            LDLM_TEST_FLAG(( _l), 1ULL <<  5)
-#define ldlm_set_ast_sent(_l)           LDLM_SET_FLAG((  _l), 1ULL <<  5)
+#define ldlm_is_ast_sent(_l)            LDLM_TEST_FLAG((_l), 1ULL <<  5)
+#define ldlm_set_ast_sent(_l)           LDLM_SET_FLAG((_l), 1ULL <<  5)
 #define ldlm_clear_ast_sent(_l)         LDLM_CLEAR_FLAG((_l), 1ULL <<  5)
 
 /**
  * Lock is being replayed.  This could probably be implied by the fact that
  * one of BLOCK_{GRANTED,CONV,WAIT} is set, but that is pretty dangerous. */
 #define LDLM_FL_REPLAY                  0x0000000000000100ULL // bit   8
-#define ldlm_is_replay(_l)              LDLM_TEST_FLAG(( _l), 1ULL <<  8)
-#define ldlm_set_replay(_l)             LDLM_SET_FLAG((  _l), 1ULL <<  8)
+#define ldlm_is_replay(_l)              LDLM_TEST_FLAG((_l), 1ULL <<  8)
+#define ldlm_set_replay(_l)             LDLM_SET_FLAG((_l), 1ULL <<  8)
 #define ldlm_clear_replay(_l)           LDLM_CLEAR_FLAG((_l), 1ULL <<  8)
 
 /** Don't grant lock, just do intent. */
 #define LDLM_FL_INTENT_ONLY             0x0000000000000200ULL // bit   9
-#define ldlm_is_intent_only(_l)         LDLM_TEST_FLAG(( _l), 1ULL <<  9)
-#define ldlm_set_intent_only(_l)        LDLM_SET_FLAG((  _l), 1ULL <<  9)
+#define ldlm_is_intent_only(_l)         LDLM_TEST_FLAG((_l), 1ULL <<  9)
+#define ldlm_set_intent_only(_l)        LDLM_SET_FLAG((_l), 1ULL <<  9)
 #define ldlm_clear_intent_only(_l)      LDLM_CLEAR_FLAG((_l), 1ULL <<  9)
 
 /** lock request has intent */
 #define LDLM_FL_HAS_INTENT              0x0000000000001000ULL // bit  12
-#define ldlm_is_has_intent(_l)          LDLM_TEST_FLAG(( _l), 1ULL << 12)
-#define ldlm_set_has_intent(_l)         LDLM_SET_FLAG((  _l), 1ULL << 12)
+#define ldlm_is_has_intent(_l)          LDLM_TEST_FLAG((_l), 1ULL << 12)
+#define ldlm_set_has_intent(_l)         LDLM_SET_FLAG((_l), 1ULL << 12)
 #define ldlm_clear_has_intent(_l)       LDLM_CLEAR_FLAG((_l), 1ULL << 12)
 
 /** flock deadlock detected */
@@ -113,28 +113,28 @@
 
 /** discard (no writeback) on cancel */
 #define LDLM_FL_DISCARD_DATA            0x0000000000010000ULL // bit  16
-#define ldlm_is_discard_data(_l)        LDLM_TEST_FLAG(( _l), 1ULL << 16)
-#define ldlm_set_discard_data(_l)       LDLM_SET_FLAG((  _l), 1ULL << 16)
+#define ldlm_is_discard_data(_l)        LDLM_TEST_FLAG((_l), 1ULL << 16)
+#define ldlm_set_discard_data(_l)       LDLM_SET_FLAG((_l), 1ULL << 16)
 #define ldlm_clear_discard_data(_l)     LDLM_CLEAR_FLAG((_l), 1ULL << 16)
 
 /** Blocked by group lock - wait indefinitely */
 #define LDLM_FL_NO_TIMEOUT              0x0000000000020000ULL // bit  17
-#define ldlm_is_no_timeout(_l)          LDLM_TEST_FLAG(( _l), 1ULL << 17)
-#define ldlm_set_no_timeout(_l)         LDLM_SET_FLAG((  _l), 1ULL << 17)
+#define ldlm_is_no_timeout(_l)          LDLM_TEST_FLAG((_l), 1ULL << 17)
+#define ldlm_set_no_timeout(_l)         LDLM_SET_FLAG((_l), 1ULL << 17)
 #define ldlm_clear_no_timeout(_l)       LDLM_CLEAR_FLAG((_l), 1ULL << 17)
 
 /**
  * Server told not to wait if blocked. For AGL, OST will not send glimpse
  * callback. */
 #define LDLM_FL_BLOCK_NOWAIT            0x0000000000040000ULL // bit  18
-#define ldlm_is_block_nowait(_l)        LDLM_TEST_FLAG(( _l), 1ULL << 18)
-#define ldlm_set_block_nowait(_l)       LDLM_SET_FLAG((  _l), 1ULL << 18)
+#define ldlm_is_block_nowait(_l)        LDLM_TEST_FLAG((_l), 1ULL << 18)
+#define ldlm_set_block_nowait(_l)       LDLM_SET_FLAG((_l), 1ULL << 18)
 #define ldlm_clear_block_nowait(_l)     LDLM_CLEAR_FLAG((_l), 1ULL << 18)
 
 /** return blocking lock */
 #define LDLM_FL_TEST_LOCK               0x0000000000080000ULL // bit  19
-#define ldlm_is_test_lock(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 19)
-#define ldlm_set_test_lock(_l)          LDLM_SET_FLAG((  _l), 1ULL << 19)
+#define ldlm_is_test_lock(_l)           LDLM_TEST_FLAG((_l), 1ULL << 19)
+#define ldlm_set_test_lock(_l)          LDLM_SET_FLAG((_l), 1ULL << 19)
 #define ldlm_clear_test_lock(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 19)
 
 /**
@@ -143,81 +143,81 @@
  * is for clients (like liblustre) that cannot be expected to reliably
  * response to blocking AST. */
 #define LDLM_FL_CANCEL_ON_BLOCK         0x0000000000800000ULL // bit  23
-#define ldlm_is_cancel_on_block(_l)     LDLM_TEST_FLAG(( _l), 1ULL << 23)
-#define ldlm_set_cancel_on_block(_l)    LDLM_SET_FLAG((  _l), 1ULL << 23)
+#define ldlm_is_cancel_on_block(_l)     LDLM_TEST_FLAG((_l), 1ULL << 23)
+#define ldlm_set_cancel_on_block(_l)    LDLM_SET_FLAG((_l), 1ULL << 23)
 #define ldlm_clear_cancel_on_block(_l)  LDLM_CLEAR_FLAG((_l), 1ULL << 23)
 
 /**
  * measure lock contention and return -EUSERS if locking contention is high */
 #define LDLM_FL_DENY_ON_CONTENTION        0x0000000040000000ULL // bit  30
-#define ldlm_is_deny_on_contention(_l)    LDLM_TEST_FLAG(( _l), 1ULL << 30)
-#define ldlm_set_deny_on_contention(_l)   LDLM_SET_FLAG((  _l), 1ULL << 30)
+#define ldlm_is_deny_on_contention(_l)    LDLM_TEST_FLAG((_l), 1ULL << 30)
+#define ldlm_set_deny_on_contention(_l)   LDLM_SET_FLAG((_l), 1ULL << 30)
 #define ldlm_clear_deny_on_contention(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 30)
 
 /**
  * These are flags that are mapped into the flags and ASTs of blocking
  * locks Add FL_DISCARD to blocking ASTs */
 #define LDLM_FL_AST_DISCARD_DATA        0x0000000080000000ULL // bit  31
-#define ldlm_is_ast_discard_data(_l)    LDLM_TEST_FLAG(( _l), 1ULL << 31)
-#define ldlm_set_ast_discard_data(_l)   LDLM_SET_FLAG((  _l), 1ULL << 31)
+#define ldlm_is_ast_discard_data(_l)    LDLM_TEST_FLAG((_l), 1ULL << 31)
+#define ldlm_set_ast_discard_data(_l)   LDLM_SET_FLAG((_l), 1ULL << 31)
 #define ldlm_clear_ast_discard_data(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 31)
 
 /**
  * Used for marking lock as a target for -EINTR while cp_ast sleep emulation
  * + race with upcoming bl_ast. */
 #define LDLM_FL_FAIL_LOC                0x0000000100000000ULL // bit  32
-#define ldlm_is_fail_loc(_l)            LDLM_TEST_FLAG(( _l), 1ULL << 32)
-#define ldlm_set_fail_loc(_l)           LDLM_SET_FLAG((  _l), 1ULL << 32)
+#define ldlm_is_fail_loc(_l)            LDLM_TEST_FLAG((_l), 1ULL << 32)
+#define ldlm_set_fail_loc(_l)           LDLM_SET_FLAG((_l), 1ULL << 32)
 #define ldlm_clear_fail_loc(_l)         LDLM_CLEAR_FLAG((_l), 1ULL << 32)
 
 /**
  * Used while processing the unused list to know that we have already
  * handled this lock and decided to skip it. */
 #define LDLM_FL_SKIPPED                 0x0000000200000000ULL // bit  33
-#define ldlm_is_skipped(_l)             LDLM_TEST_FLAG(( _l), 1ULL << 33)
-#define ldlm_set_skipped(_l)            LDLM_SET_FLAG((  _l), 1ULL << 33)
+#define ldlm_is_skipped(_l)             LDLM_TEST_FLAG((_l), 1ULL << 33)
+#define ldlm_set_skipped(_l)            LDLM_SET_FLAG((_l), 1ULL << 33)
 #define ldlm_clear_skipped(_l)          LDLM_CLEAR_FLAG((_l), 1ULL << 33)
 
 /** this lock is being destroyed */
 #define LDLM_FL_CBPENDING               0x0000000400000000ULL // bit  34
-#define ldlm_is_cbpending(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 34)
-#define ldlm_set_cbpending(_l)          LDLM_SET_FLAG((  _l), 1ULL << 34)
+#define ldlm_is_cbpending(_l)           LDLM_TEST_FLAG((_l), 1ULL << 34)
+#define ldlm_set_cbpending(_l)          LDLM_SET_FLAG((_l), 1ULL << 34)
 #define ldlm_clear_cbpending(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 34)
 
 /** not a real flag, not saved in lock */
 #define LDLM_FL_WAIT_NOREPROC           0x0000000800000000ULL // bit  35
-#define ldlm_is_wait_noreproc(_l)       LDLM_TEST_FLAG(( _l), 1ULL << 35)
-#define ldlm_set_wait_noreproc(_l)      LDLM_SET_FLAG((  _l), 1ULL << 35)
+#define ldlm_is_wait_noreproc(_l)       LDLM_TEST_FLAG((_l), 1ULL << 35)
+#define ldlm_set_wait_noreproc(_l)      LDLM_SET_FLAG((_l), 1ULL << 35)
 #define ldlm_clear_wait_noreproc(_l)    LDLM_CLEAR_FLAG((_l), 1ULL << 35)
 
 /** cancellation callback already run */
 #define LDLM_FL_CANCEL                  0x0000001000000000ULL // bit  36
-#define ldlm_is_cancel(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 36)
-#define ldlm_set_cancel(_l)             LDLM_SET_FLAG((  _l), 1ULL << 36)
+#define ldlm_is_cancel(_l)              LDLM_TEST_FLAG((_l), 1ULL << 36)
+#define ldlm_set_cancel(_l)             LDLM_SET_FLAG((_l), 1ULL << 36)
 #define ldlm_clear_cancel(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 36)
 
 /** whatever it might mean */
 #define LDLM_FL_LOCAL_ONLY              0x0000002000000000ULL // bit  37
-#define ldlm_is_local_only(_l)          LDLM_TEST_FLAG(( _l), 1ULL << 37)
-#define ldlm_set_local_only(_l)         LDLM_SET_FLAG((  _l), 1ULL << 37)
+#define ldlm_is_local_only(_l)          LDLM_TEST_FLAG((_l), 1ULL << 37)
+#define ldlm_set_local_only(_l)         LDLM_SET_FLAG((_l), 1ULL << 37)
 #define ldlm_clear_local_only(_l)       LDLM_CLEAR_FLAG((_l), 1ULL << 37)
 
 /** don't run the cancel callback under ldlm_cli_cancel_unused */
 #define LDLM_FL_FAILED                  0x0000004000000000ULL // bit  38
-#define ldlm_is_failed(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 38)
-#define ldlm_set_failed(_l)             LDLM_SET_FLAG((  _l), 1ULL << 38)
+#define ldlm_is_failed(_l)              LDLM_TEST_FLAG((_l), 1ULL << 38)
+#define ldlm_set_failed(_l)             LDLM_SET_FLAG((_l), 1ULL << 38)
 #define ldlm_clear_failed(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 38)
 
 /** lock cancel has already been sent */
 #define LDLM_FL_CANCELING               0x0000008000000000ULL // bit  39
-#define ldlm_is_canceling(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 39)
-#define ldlm_set_canceling(_l)          LDLM_SET_FLAG((  _l), 1ULL << 39)
+#define ldlm_is_canceling(_l)           LDLM_TEST_FLAG((_l), 1ULL << 39)
+#define ldlm_set_canceling(_l)          LDLM_SET_FLAG((_l), 1ULL << 39)
 #define ldlm_clear_canceling(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 39)
 
 /** local lock (ie, no srv/cli split) */
 #define LDLM_FL_LOCAL                   0x0000010000000000ULL // bit  40
-#define ldlm_is_local(_l)               LDLM_TEST_FLAG(( _l), 1ULL << 40)
-#define ldlm_set_local(_l)              LDLM_SET_FLAG((  _l), 1ULL << 40)
+#define ldlm_is_local(_l)               LDLM_TEST_FLAG((_l), 1ULL << 40)
+#define ldlm_set_local(_l)              LDLM_SET_FLAG((_l), 1ULL << 40)
 #define ldlm_clear_local(_l)            LDLM_CLEAR_FLAG((_l), 1ULL << 40)
 
 /**
@@ -233,8 +233,8 @@
  * That change is pretty high-risk, though, and would need a lot more
  * testing. */
 #define LDLM_FL_LVB_READY               0x0000020000000000ULL // bit  41
-#define ldlm_is_lvb_ready(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 41)
-#define ldlm_set_lvb_ready(_l)          LDLM_SET_FLAG((  _l), 1ULL << 41)
+#define ldlm_is_lvb_ready(_l)           LDLM_TEST_FLAG((_l), 1ULL << 41)
+#define ldlm_set_lvb_ready(_l)          LDLM_SET_FLAG((_l), 1ULL << 41)
 #define ldlm_clear_lvb_ready(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 41)
 
 /**
@@ -245,28 +245,28 @@
  * to know to exclude each other's locks from the calculation as they walk
  * the granted list. */
 #define LDLM_FL_KMS_IGNORE              0x0000040000000000ULL // bit  42
-#define ldlm_is_kms_ignore(_l)          LDLM_TEST_FLAG(( _l), 1ULL << 42)
-#define ldlm_set_kms_ignore(_l)         LDLM_SET_FLAG((  _l), 1ULL << 42)
+#define ldlm_is_kms_ignore(_l)          LDLM_TEST_FLAG((_l), 1ULL << 42)
+#define ldlm_set_kms_ignore(_l)         LDLM_SET_FLAG((_l), 1ULL << 42)
 #define ldlm_clear_kms_ignore(_l)       LDLM_CLEAR_FLAG((_l), 1ULL << 42)
 
 /** completion AST to be executed */
 #define LDLM_FL_CP_REQD                 0x0000080000000000ULL // bit  43
-#define ldlm_is_cp_reqd(_l)             LDLM_TEST_FLAG(( _l), 1ULL << 43)
-#define ldlm_set_cp_reqd(_l)            LDLM_SET_FLAG((  _l), 1ULL << 43)
+#define ldlm_is_cp_reqd(_l)             LDLM_TEST_FLAG((_l), 1ULL << 43)
+#define ldlm_set_cp_reqd(_l)            LDLM_SET_FLAG((_l), 1ULL << 43)
 #define ldlm_clear_cp_reqd(_l)          LDLM_CLEAR_FLAG((_l), 1ULL << 43)
 
 /** cleanup_resource has already handled the lock */
 #define LDLM_FL_CLEANED                 0x0000100000000000ULL // bit  44
-#define ldlm_is_cleaned(_l)             LDLM_TEST_FLAG(( _l), 1ULL << 44)
-#define ldlm_set_cleaned(_l)            LDLM_SET_FLAG((  _l), 1ULL << 44)
+#define ldlm_is_cleaned(_l)             LDLM_TEST_FLAG((_l), 1ULL << 44)
+#define ldlm_set_cleaned(_l)            LDLM_SET_FLAG((_l), 1ULL << 44)
 #define ldlm_clear_cleaned(_l)          LDLM_CLEAR_FLAG((_l), 1ULL << 44)
 
 /**
  * optimization hint: LDLM can run blocking callback from current context
  * w/o involving separate thread. in order to decrease cs rate */
 #define LDLM_FL_ATOMIC_CB               0x0000200000000000ULL // bit  45
-#define ldlm_is_atomic_cb(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 45)
-#define ldlm_set_atomic_cb(_l)          LDLM_SET_FLAG((  _l), 1ULL << 45)
+#define ldlm_is_atomic_cb(_l)           LDLM_TEST_FLAG((_l), 1ULL << 45)
+#define ldlm_set_atomic_cb(_l)          LDLM_SET_FLAG((_l), 1ULL << 45)
 #define ldlm_clear_atomic_cb(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 45)
 
 /**
@@ -282,14 +282,14 @@
  * is used when ELC RPC is already prepared and is waiting for rpc_lock,
  * too late to send a separate CANCEL RPC. */
 #define LDLM_FL_BL_AST                  0x0000400000000000ULL // bit  46
-#define ldlm_is_bl_ast(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 46)
-#define ldlm_set_bl_ast(_l)             LDLM_SET_FLAG((  _l), 1ULL << 46)
+#define ldlm_is_bl_ast(_l)              LDLM_TEST_FLAG((_l), 1ULL << 46)
+#define ldlm_set_bl_ast(_l)             LDLM_SET_FLAG((_l), 1ULL << 46)
 #define ldlm_clear_bl_ast(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 46)
 
 /** whatever it might mean */
 #define LDLM_FL_BL_DONE                 0x0000800000000000ULL // bit  47
-#define ldlm_is_bl_done(_l)             LDLM_TEST_FLAG(( _l), 1ULL << 47)
-#define ldlm_set_bl_done(_l)            LDLM_SET_FLAG((  _l), 1ULL << 47)
+#define ldlm_is_bl_done(_l)             LDLM_TEST_FLAG((_l), 1ULL << 47)
+#define ldlm_set_bl_done(_l)            LDLM_SET_FLAG((_l), 1ULL << 47)
 #define ldlm_clear_bl_done(_l)          LDLM_CLEAR_FLAG((_l), 1ULL << 47)
 
 /**
@@ -297,8 +297,8 @@
  * to aging.  Used by MGC locks, they are cancelled only at unmount or
  * by callback. */
 #define LDLM_FL_NO_LRU                  0x0001000000000000ULL // bit  48
-#define ldlm_is_no_lru(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 48)
-#define ldlm_set_no_lru(_l)             LDLM_SET_FLAG((  _l), 1ULL << 48)
+#define ldlm_is_no_lru(_l)              LDLM_TEST_FLAG((_l), 1ULL << 48)
+#define ldlm_set_no_lru(_l)             LDLM_SET_FLAG((_l), 1ULL << 48)
 #define ldlm_clear_no_lru(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 48)
 
 /**
@@ -306,8 +306,8 @@
  *
  * Protected by lock and resource locks. */
 #define LDLM_FL_FAIL_NOTIFIED           0x0002000000000000ULL // bit  49
-#define ldlm_is_fail_notified(_l)       LDLM_TEST_FLAG(( _l), 1ULL << 49)
-#define ldlm_set_fail_notified(_l)      LDLM_SET_FLAG((  _l), 1ULL << 49)
+#define ldlm_is_fail_notified(_l)       LDLM_TEST_FLAG((_l), 1ULL << 49)
+#define ldlm_set_fail_notified(_l)      LDLM_SET_FLAG((_l), 1ULL << 49)
 #define ldlm_clear_fail_notified(_l)    LDLM_CLEAR_FLAG((_l), 1ULL << 49)
 
 /**
@@ -317,14 +317,14 @@
  *
  * Protected by lock and resource locks. */
 #define LDLM_FL_DESTROYED               0x0004000000000000ULL // bit  50
-#define ldlm_is_destroyed(_l)           LDLM_TEST_FLAG(( _l), 1ULL << 50)
-#define ldlm_set_destroyed(_l)          LDLM_SET_FLAG((  _l), 1ULL << 50)
+#define ldlm_is_destroyed(_l)           LDLM_TEST_FLAG((_l), 1ULL << 50)
+#define ldlm_set_destroyed(_l)          LDLM_SET_FLAG((_l), 1ULL << 50)
 #define ldlm_clear_destroyed(_l)        LDLM_CLEAR_FLAG((_l), 1ULL << 50)
 
 /** flag whether this is a server namespace lock */
 #define LDLM_FL_SERVER_LOCK             0x0008000000000000ULL // bit  51
-#define ldlm_is_server_lock(_l)         LDLM_TEST_FLAG(( _l), 1ULL << 51)
-#define ldlm_set_server_lock(_l)        LDLM_SET_FLAG((  _l), 1ULL << 51)
+#define ldlm_is_server_lock(_l)         LDLM_TEST_FLAG((_l), 1ULL << 51)
+#define ldlm_set_server_lock(_l)        LDLM_SET_FLAG((_l), 1ULL << 51)
 #define ldlm_clear_server_lock(_l)      LDLM_CLEAR_FLAG((_l), 1ULL << 51)
 
 /**
@@ -335,8 +335,8 @@
  * because it works only for SMP so user needs to add extra macros like
  * LASSERT_SPIN_LOCKED for uniprocessor kernels. */
 #define LDLM_FL_RES_LOCKED              0x0010000000000000ULL // bit  52
-#define ldlm_is_res_locked(_l)          LDLM_TEST_FLAG(( _l), 1ULL << 52)
-#define ldlm_set_res_locked(_l)         LDLM_SET_FLAG((  _l), 1ULL << 52)
+#define ldlm_is_res_locked(_l)          LDLM_TEST_FLAG((_l), 1ULL << 52)
+#define ldlm_set_res_locked(_l)         LDLM_SET_FLAG((_l), 1ULL << 52)
 #define ldlm_clear_res_locked(_l)       LDLM_CLEAR_FLAG((_l), 1ULL << 52)
 
 /**
@@ -345,14 +345,14 @@
  *
  * Protected by lock and resource locks. */
 #define LDLM_FL_WAITED                  0x0020000000000000ULL // bit  53
-#define ldlm_is_waited(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 53)
-#define ldlm_set_waited(_l)             LDLM_SET_FLAG((  _l), 1ULL << 53)
+#define ldlm_is_waited(_l)              LDLM_TEST_FLAG((_l), 1ULL << 53)
+#define ldlm_set_waited(_l)             LDLM_SET_FLAG((_l), 1ULL << 53)
 #define ldlm_clear_waited(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 53)
 
 /** Flag whether this is a server namespace lock. */
 #define LDLM_FL_NS_SRV                  0x0040000000000000ULL // bit  54
-#define ldlm_is_ns_srv(_l)              LDLM_TEST_FLAG(( _l), 1ULL << 54)
-#define ldlm_set_ns_srv(_l)             LDLM_SET_FLAG((  _l), 1ULL << 54)
+#define ldlm_is_ns_srv(_l)              LDLM_TEST_FLAG((_l), 1ULL << 54)
+#define ldlm_set_ns_srv(_l)             LDLM_SET_FLAG((_l), 1ULL << 54)
 #define ldlm_clear_ns_srv(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 54)
 
 /** Flag whether this lock can be reused. Used by exclusive open. */
diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 43ee9f0eb4d4..2a4294d41b5a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -313,7 +313,7 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 #define OBD_IOC_CLIENT_RECOVER	 _IOW ('f', 133, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_PING_TARGET	    _IOW ('f', 136, OBD_IOC_DATA_TYPE)
 
-#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 139      )
+#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 139)
 #define OBD_IOC_NO_TRANSNO	     _IOW ('f', 140, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_SET_READONLY	   _IOW ('f', 141, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_ABORT_RECOVERY	 _IOR ('f', 142, OBD_IOC_DATA_TYPE)
@@ -557,9 +557,9 @@ do {									   \
 		if (__timeout == 0) {					  \
 			schedule();					       \
 		} else {						       \
-			long interval = info->lwi_interval?	  \
+			long interval = info->lwi_interval ?	  \
 					     min_t(long,	     \
-						 info->lwi_interval,__timeout):\
+						 info->lwi_interval, __timeout) : \
 					     __timeout;			\
 			long remaining = schedule_timeout(interval);\
 			__timeout = cfs_time_sub(__timeout,		    \
diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index 48ad60b22122..3341b5da6ac0 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -2065,7 +2065,7 @@ struct ptlrpc_service_part {
 	 * rqbd list and incoming requests waiting for preprocess,
 	 * threads starting & stopping are also protected by this lock.
 	 */
-	spinlock_t			scp_lock  __cfs_cacheline_aligned;
+	spinlock_t scp_lock __cfs_cacheline_aligned;
 	/** total # req buffer descs allocated */
 	int				scp_nrqbds_total;
 	/** # posted request buffers for receiving */
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 9ad8c268da10..76a2546e0f41 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -1300,7 +1300,7 @@ struct md_ops {
 			   const struct lu_fid *,
 			   struct ptlrpc_request **);
 	int (*m_setattr)(struct obd_export *, struct md_op_data *, void *,
-			 int , void *, int, struct ptlrpc_request **,
+			 int, void *, int, struct ptlrpc_request **,
 			 struct md_open_data **mod);
 	int (*m_sync)(struct obd_export *, const struct lu_fid *,
 		      struct obd_capa *, struct ptlrpc_request **);
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h
index 18aec796a724..3986ca4cddaa 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -585,7 +585,7 @@ do {									      \
 		   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
 		    !obd_alloc_fail(ptr, #ptr, "km", size,		    \
 				    __FILE__, __LINE__) ||		    \
-		    OBD_FREE_RTN0(ptr)))){				    \
+		    OBD_FREE_RTN0(ptr)))) {				    \
 		OBD_ALLOC_POST(ptr, size, "kmalloced");		       \
 	}								     \
 } while (0)
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index a4c252febfe4..ab670fcf852d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -602,7 +602,7 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 	    (LDLM_FL_FAILED|LDLM_FL_LOCAL_ONLY)) {
 		if (lock->l_req_mode == lock->l_granted_mode &&
 		    lock->l_granted_mode != LCK_NL &&
-		    NULL == data)
+		    data == NULL)
 			ldlm_lock_decref_internal(lock, lock->l_req_mode);
 
 		/* Need to wake up the waiter if we were evicted */
@@ -614,7 +614,7 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
 		       LDLM_FL_BLOCK_CONV))) {
-		if (NULL == data)
+		if (data == NULL)
 			/* mds granted the lock in the reply */
 			goto granted;
 		/* CP AST RPC: lock get granted, wake it up */
@@ -627,10 +627,10 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 	obd = class_exp2obd(lock->l_conn_export);
 
 	/* if this is a local lock, there is no import */
-	if (NULL != obd)
+	if (obd != NULL)
 		imp = obd->u.cli.cl_import;
 
-	if (NULL != imp) {
+	if (imp != NULL) {
 		spin_lock(&imp->imp_lock);
 		fwd.fwd_generation = imp->imp_generation;
 		spin_unlock(&imp->imp_lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 4bb3173bcd5f..cc212b97abaa 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -47,8 +47,8 @@
 
 struct kmem_cache *ldlm_resource_slab, *ldlm_lock_slab;
 
-int ldlm_srv_namespace_nr = 0;
-int ldlm_cli_namespace_nr = 0;
+int ldlm_srv_namespace_nr;
+int ldlm_cli_namespace_nr;
 
 struct mutex ldlm_srv_namespace_lock;
 LIST_HEAD(ldlm_srv_namespace_list);
diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c
index 42d615fbd664..d39fecebd12d 100644
--- a/drivers/staging/lustre/lustre/libcfs/fail.c
+++ b/drivers/staging/lustre/lustre/libcfs/fail.c
@@ -35,10 +35,10 @@
 
 #include "../../include/linux/libcfs/libcfs.h"
 
-unsigned long cfs_fail_loc = 0;
+unsigned long cfs_fail_loc;
 EXPORT_SYMBOL(cfs_fail_loc);
 
-unsigned int cfs_fail_val = 0;
+unsigned int cfs_fail_val;
 EXPORT_SYMBOL(cfs_fail_val);
 
 DECLARE_WAIT_QUEUE_HEAD(cfs_race_waitq);
diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c
index 0ed063145230..286641bb1b41 100644
--- a/drivers/staging/lustre/lustre/libcfs/hash.c
+++ b/drivers/staging/lustre/lustre/libcfs/hash.c
@@ -588,13 +588,13 @@ EXPORT_SYMBOL(cfs_hash_bd_move_locked);
 
 enum {
 	/** always set, for sanity (avoid ZERO intent) */
-	CFS_HS_LOOKUP_MASK_FIND     = 1 << 0,
+	CFS_HS_LOOKUP_MASK_FIND     = BIT(0),
 	/** return entry with a ref */
-	CFS_HS_LOOKUP_MASK_REF      = 1 << 1,
+	CFS_HS_LOOKUP_MASK_REF      = BIT(1),
 	/** add entry if not existing */
-	CFS_HS_LOOKUP_MASK_ADD      = 1 << 2,
+	CFS_HS_LOOKUP_MASK_ADD      = BIT(2),
 	/** delete entry, ignore other masks */
-	CFS_HS_LOOKUP_MASK_DEL      = 1 << 3,
+	CFS_HS_LOOKUP_MASK_DEL      = BIT(3),
 };
 
 typedef enum cfs_hash_lookup_intent {
@@ -677,8 +677,8 @@ cfs_hash_bd_findadd_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd,
 			   int noref)
 {
 	return cfs_hash_bd_lookup_intent(hs, bd, key, hnode,
-					 CFS_HS_LOOKUP_IT_ADD |
-					 (!noref * CFS_HS_LOOKUP_MASK_REF));
+					 (!noref * CFS_HS_LOOKUP_MASK_REF) |
+					 CFS_HS_LOOKUP_IT_ADD);
 }
 EXPORT_SYMBOL(cfs_hash_bd_findadd_locked);
 
@@ -756,7 +756,7 @@ cfs_hash_multi_bd_findadd_locked(struct cfs_hash *hs,
 	unsigned	   i;
 
 	LASSERT(hnode != NULL);
-	intent = CFS_HS_LOOKUP_IT_PEEK | (!noref * CFS_HS_LOOKUP_MASK_REF);
+	intent = (!noref * CFS_HS_LOOKUP_MASK_REF) | CFS_HS_LOOKUP_IT_PEEK;
 
 	cfs_hash_for_each_bd(bds, n, i) {
 		ehnode = cfs_hash_bd_lookup_intent(hs, &bds[i], key,
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
index 2c199c7259fe..29308ba85393 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
@@ -63,12 +63,12 @@ cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab)
 
 	/* NB: cptab can be NULL, pcl will be for HW CPUs on that case */
 	LIBCFS_ALLOC(pcl, sizeof(*pcl));
-	if (pcl == NULL)
+	if (!pcl)
 		return NULL;
 
 	pcl->pcl_cptab = cptab;
 	pcl->pcl_locks = cfs_percpt_alloc(cptab, sizeof(*lock));
-	if (pcl->pcl_locks == NULL) {
+	if (!pcl->pcl_locks) {
 		LIBCFS_FREE(pcl, sizeof(*pcl));
 		return NULL;
 	}
@@ -164,7 +164,7 @@ cfs_percpt_atomic_alloc(struct cfs_cpt_table *cptab, int init_val)
 	int		i;
 
 	refs = cfs_percpt_alloc(cptab, sizeof(*ref));
-	if (refs == NULL)
+	if (!refs)
 		return NULL;
 
 	cfs_percpt_for_each(ref, i, refs)
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
index 1debdda72e72..f4e08daba4d9 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
@@ -84,7 +84,7 @@ cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
 	count = cfs_cpt_number(cptab);
 
 	LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
-	if (arr == NULL)
+	if (!arr)
 		return NULL;
 
 	arr->va_size	= size = L1_CACHE_ALIGN(size);
@@ -93,7 +93,7 @@ cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
 
 	for (i = 0; i < count; i++) {
 		LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
-		if (arr->va_ptrs[i] == NULL) {
+		if (!arr->va_ptrs[i]) {
 			cfs_percpt_free((void *)&arr->va_ptrs[0]);
 			return NULL;
 		}
@@ -160,7 +160,7 @@ cfs_array_free(void *vars)
 	arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
 
 	for (i = 0; i < arr->va_count; i++) {
-		if (arr->va_ptrs[i] == NULL)
+		if (!arr->va_ptrs[i])
 			continue;
 
 		LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
@@ -182,7 +182,7 @@ cfs_array_alloc(int count, unsigned int size)
 	int			i;
 
 	LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
-	if (arr == NULL)
+	if (!arr)
 		return NULL;
 
 	arr->va_count	= count;
@@ -191,7 +191,7 @@ cfs_array_alloc(int count, unsigned int size)
 	for (i = 0; i < count; i++) {
 		LIBCFS_ALLOC(arr->va_ptrs[i], size);
 
-		if (arr->va_ptrs[i] == NULL) {
+		if (!arr->va_ptrs[i]) {
 			cfs_array_free((void *)&arr->va_ptrs[0]);
 			return NULL;
 		}
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
index fbbc8a7e308d..328a27860411 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
@@ -71,13 +71,12 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id,
 	 * Skip this function for digest, because we use shash logic at
 	 * cfs_crypto_hash_alloc.
 	 */
-	if (key != NULL) {
+	if (key != NULL)
 		err = crypto_hash_setkey(desc->tfm, key, key_len);
-	} else if ((*type)->cht_key != 0) {
+	else if ((*type)->cht_key != 0)
 		err = crypto_hash_setkey(desc->tfm,
 					 (unsigned char *)&((*type)->cht_key),
 					 (*type)->cht_size);
-	}
 
 	if (err != 0) {
 		crypto_free_hash(desc->tfm);
diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c
index effa2af58c13..5a2e5ea00570 100644
--- a/drivers/staging/lustre/lustre/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c
@@ -124,7 +124,7 @@ int cfs_trace_refill_stock(struct cfs_trace_cpu_data *tcd, gfp_t gfp,
 	 * from here: this will lead to infinite recursion.
 	 */
 
-	for (i = 0; i + tcd->tcd_cur_stock_pages < TCD_STOCK_PAGES ; ++ i) {
+	for (i = 0; i + tcd->tcd_cur_stock_pages < TCD_STOCK_PAGES ; ++i) {
 		struct cfs_trace_page *tage;
 
 		tage = cfs_tage_alloc(gfp);
@@ -370,7 +370,7 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
 	/* indent message according to the nesting level */
 	while (depth-- > 0) {
 		*(debug_buf++) = '.';
-		++ tage->used;
+		++tage->used;
 	}
 
 	strcpy(debug_buf, file);
diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c
index 48009b775845..02d18f558fdf 100644
--- a/drivers/staging/lustre/lustre/libcfs/workitem.c
+++ b/drivers/staging/lustre/lustre/libcfs/workitem.c
@@ -45,7 +45,7 @@
 
 #define CFS_WS_NAME_LEN	 16
 
-typedef struct cfs_wi_sched {
+struct cfs_wi_sched {
 	struct list_head		ws_list;	/* chain on global list */
 	/** serialised workitems */
 	spinlock_t		ws_lock;
@@ -73,7 +73,7 @@ typedef struct cfs_wi_sched {
 	unsigned int		ws_starting:1;
 	/** scheduler name */
 	char			ws_name[CFS_WS_NAME_LEN];
-} cfs_wi_sched_t;
+};
 
 static struct cfs_workitem_data {
 	/** serialize */
@@ -87,19 +87,19 @@ static struct cfs_workitem_data {
 } cfs_wi_data;
 
 static inline void
-cfs_wi_sched_lock(cfs_wi_sched_t *sched)
+cfs_wi_sched_lock(struct cfs_wi_sched *sched)
 {
 	spin_lock(&sched->ws_lock);
 }
 
 static inline void
-cfs_wi_sched_unlock(cfs_wi_sched_t *sched)
+cfs_wi_sched_unlock(struct cfs_wi_sched *sched)
 {
 	spin_unlock(&sched->ws_lock);
 }
 
 static inline int
-cfs_wi_sched_cansleep(cfs_wi_sched_t *sched)
+cfs_wi_sched_cansleep(struct cfs_wi_sched *sched)
 {
 	cfs_wi_sched_lock(sched);
 	if (sched->ws_stopping) {
@@ -221,7 +221,7 @@ EXPORT_SYMBOL(cfs_wi_schedule);
 static int
 cfs_wi_scheduler (void *arg)
 {
-	struct cfs_wi_sched	*sched = (cfs_wi_sched_t *)arg;
+	struct cfs_wi_sched	*sched = (struct cfs_wi_sched *)arg;
 
 	cfs_block_allsigs();
 
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index 769b61193d87..d407fcc9904d 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -660,7 +660,7 @@ static int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump,
 	int mode;
 	int err;
 
-	mode = (0755 & ~current_umask()) | S_IFDIR;
+	mode = (~current_umask() & 0755) | S_IFDIR;
 	op_data = ll_prep_md_op_data(NULL, dir, NULL, filename,
 				     strlen(filename), mode, LUSTRE_OPC_MKDIR,
 				     lump);
@@ -838,11 +838,11 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
 	/* We don't swab objects for directories */
 	switch (le32_to_cpu(lmm->lmm_magic)) {
 	case LOV_MAGIC_V1:
-		if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+		if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
 			lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
 		break;
 	case LOV_MAGIC_V3:
-		if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+		if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
 			lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
 		break;
 	default:
@@ -1554,7 +1554,7 @@ out_req:
 
 		switch (lmm->lmm_magic) {
 		case LOV_USER_MAGIC_V1:
-			if (LOV_USER_MAGIC_V1 == cpu_to_le32(LOV_USER_MAGIC_V1))
+			if (cpu_to_le32(LOV_USER_MAGIC_V1) == LOV_USER_MAGIC_V1)
 				break;
 			/* swab objects first so that stripes num will be sane */
 			lustre_swab_lov_user_md_objects(
@@ -1563,7 +1563,7 @@ out_req:
 			lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
 			break;
 		case LOV_USER_MAGIC_V3:
-			if (LOV_USER_MAGIC_V3 == cpu_to_le32(LOV_USER_MAGIC_V3))
+			if (cpu_to_le32(LOV_USER_MAGIC_V3) == LOV_USER_MAGIC_V3)
 				break;
 			/* swab objects first so that stripes num will be sane */
 			lustre_swab_lov_user_md_objects(
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index dcd0c6d65efb..e332326011d1 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -94,7 +94,7 @@ void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
 		op_data->op_handle = *fh;
 	op_data->op_capa1 = ll_mdscapa_get(inode);
 
-	if (LLIF_DATA_MODIFIED & ll_i2info(inode)->lli_flags)
+	if (ll_i2info(inode)->lli_flags & LLIF_DATA_MODIFIED)
 		op_data->op_bias |= MDS_DATA_MODIFIED;
 }
 
@@ -270,7 +270,7 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode,
 	int lockmode;
 	__u64 flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK;
 	struct lustre_handle lockh;
-	ldlm_policy_data_t policy = {.l_inodebits = {MDS_INODELOCK_OPEN}};
+	ldlm_policy_data_t policy = {.l_inodebits = {MDS_INODELOCK_OPEN} };
 	int rc = 0;
 
 	/* clear group lock, if present */
@@ -1433,7 +1433,7 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
 	 * little endian.  We convert it to host endian before
 	 * passing it to userspace.
 	 */
-	if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
+	if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) {
 		int stripe_count;
 
 		stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
@@ -2494,8 +2494,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	default: {
 		int err;
 
-		if (LLIOC_STOP ==
-		     ll_iocontrol_call(inode, file, cmd, arg, &err))
+		if (ll_iocontrol_call(inode, file, cmd, arg, &err) ==
+		     LLIOC_STOP)
 			return err;
 
 		return obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
@@ -2670,7 +2670,7 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
 	};
 	struct md_op_data *op_data;
 	struct lustre_handle lockh = {0};
-	ldlm_policy_data_t flock = {{0}};
+	ldlm_policy_data_t flock = { {0} };
 	__u64 flags = 0;
 	int rc;
 	int rc2 = 0;
@@ -2850,7 +2850,7 @@ ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
 	fid = &ll_i2info(inode)->lli_fid;
 	CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid));
 
-	rc = md_lock_match(ll_i2mdexp(inode), LDLM_FL_BLOCK_GRANTED|flags,
+	rc = md_lock_match(ll_i2mdexp(inode), flags | LDLM_FL_BLOCK_GRANTED,
 			   fid, LDLM_IBITS, &policy, mode, lockh);
 
 	return rc;
diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c
index 7bdae723fedd..e31cad82d5af 100644
--- a/drivers/staging/lustre/lustre/llite/llite_close.c
+++ b/drivers/staging/lustre/lustre/llite/llite_close.c
@@ -293,14 +293,13 @@ static void ll_done_writing(struct inode *inode)
 		goto out;
 
 	rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, NULL);
-	if (rc == -EAGAIN) {
+	if (rc == -EAGAIN)
 		/* MDS has instructed us to obtain Size-on-MDS attribute from
 		 * OSTs and send setattr to back to MDS. */
 		rc = ll_som_update(inode, op_data);
-	} else if (rc) {
+	else if (rc)
 		CERROR("inode %lu mdc done_writing failed: rc = %d\n",
 		       inode->i_ino, rc);
-	}
 out:
 	ll_finish_md_op_data(op_data);
 	if (och) {
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index ec8fff463208..2de64c23383b 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -71,7 +71,7 @@ struct ll_dentry_data {
 	struct rcu_head			lld_rcu_head;
 };
 
-#define ll_d2d(de) ((struct ll_dentry_data*)((de)->d_fsdata))
+#define ll_d2d(de) ((struct ll_dentry_data *)((de)->d_fsdata))
 
 #define LLI_INODE_MAGIC		 0x111d0de5
 #define LLI_INODE_DEAD		  0xdeadd00d
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index b4ed6c89af3d..c60eb46e9c7e 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1219,14 +1219,13 @@ static int ll_setattr_done_writing(struct inode *inode,
 	ll_pack_inode2opdata(inode, op_data, NULL);
 
 	rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, mod);
-	if (rc == -EAGAIN) {
+	if (rc == -EAGAIN)
 		/* MDS has instructed us to obtain Size-on-MDS attribute
 		 * from OSTs and send setattr to back to MDS. */
 		rc = ll_som_update(inode, op_data);
-	} else if (rc) {
+	else if (rc)
 		CERROR("inode %lu mdc truncate failed: rc = %d\n",
 		       inode->i_ino, rc);
-	}
 	return rc;
 }
 
@@ -2201,7 +2200,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
 	}
 
 	/* When called by ll_setattr_raw, file is i1. */
-	if (LLIF_DATA_MODIFIED & ll_i2info(i1)->lli_flags)
+	if (ll_i2info(i1)->lli_flags & LLIF_DATA_MODIFIED)
 		op_data->op_bias |= MDS_DATA_MODIFIED;
 
 	return op_data;
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index 486dca6077de..2fc24a946590 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -1325,7 +1325,7 @@ void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
 		lprocfs_oh_clear(&io_extents->pp_extents[cur].pp_w_hist);
 	}
 
-	for(i = 0; (count >= (1 << LL_HIST_START << i)) &&
+	for (i = 0; (count >= (1 << LL_HIST_START << i)) &&
 	     (i < (LL_HIST_MAX - 1)); i++);
 	if (rw == 0) {
 		io_extents->pp_extents[cur].pp_r_hist.oh_buckets[i]++;
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c
index 991d20c5065d..3e2825514f7e 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -656,7 +656,7 @@ static int ll_read_ahead_pages(const struct lu_env *env,
 						page_idx, mapping);
 			if (rc == 1) {
 				(*reserved_pages)--;
-				count ++;
+				count++;
 			} else if (rc == -ENOLCK)
 				break;
 		} else if (stride_ria) {
@@ -890,7 +890,7 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras,
 	if (!stride_io_mode(ras) && (stride_gap != 0 ||
 	     ras->ras_consecutive_stride_requests == 0)) {
 		ras->ras_stride_pages = ras->ras_consecutive_pages;
-		ras->ras_stride_length = stride_gap +ras->ras_consecutive_pages;
+		ras->ras_stride_length = stride_gap+ras->ras_consecutive_pages;
 	}
 	LASSERT(ras->ras_request_index == 0);
 	LASSERT(ras->ras_consecutive_stride_requests == 0);
@@ -902,7 +902,7 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras,
 	}
 
 	ras->ras_stride_pages = ras->ras_consecutive_pages;
-	ras->ras_stride_length = stride_gap +ras->ras_consecutive_pages;
+	ras->ras_stride_length = stride_gap+ras->ras_consecutive_pages;
 
 	RAS_CDEBUG(ras);
 	return;
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index f97371dd8539..8f4cca1ef109 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -659,7 +659,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
 		 * revalidate.
 		 */
 		/* unlinked and re-created with the same name */
-		if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->fid1))){
+		if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->fid1))) {
 			entry->se_inode = NULL;
 			iput(child);
 			child = NULL;
@@ -1215,7 +1215,7 @@ do_it:
 			while (1) {
 				l_wait_event(thread->t_ctl_waitq,
 					     !sa_received_empty(sai) ||
-					     sai->sai_sent == sai->sai_replied||
+					     sai->sai_sent == sai->sai_replied ||
 					     !thread_is_running(thread),
 					     &lwi);
 
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index a659962e09c8..75a8ea21bc24 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -698,7 +698,7 @@ static int vvp_io_fault_start(const struct lu_env *env,
 
 		/* return +1 to stop cl_io_loop() and ll_fault() will catch
 		 * and retry. */
-		result = +1;
+		result = 1;
 		goto out;
 	}
 
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index c9e0536e9f2a..f8146acd883d 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -1849,7 +1849,7 @@ static int lmv_early_cancel(struct obd_export *exp, struct md_op_data *op_data,
 	struct obd_device      *obd = exp->exp_obd;
 	struct lmv_obd	 *lmv = &obd->u.lmv;
 	struct lmv_tgt_desc    *tgt;
-	ldlm_policy_data_t      policy = {{0}};
+	ldlm_policy_data_t      policy = { {0} };
 	int		     rc = 0;
 
 	if (!fid_is_sane(fid))
diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c
index bf3629151d68..b5b25803d4f1 100644
--- a/drivers/staging/lustre/lustre/lov/lov_io.c
+++ b/drivers/staging/lustre/lustre/lov/lov_io.c
@@ -729,6 +729,8 @@ static int lov_io_fault_start(const struct lu_env *env,
 	fio = &ios->cis_io->u.ci_fault;
 	lio = cl2lov_io(env, ios);
 	sub = lov_sub_get(env, lio, lov_page_stripe(fio->ft_page));
+	if (IS_ERR(sub))
+		return PTR_ERR(sub);
 	sub->sub_io->u.ci_fault.ft_nob = fio->ft_nob;
 	lov_sub_put(sub);
 	return lov_io_start(env, ios);
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index c5c67d982ef2..906503b05979 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -1487,7 +1487,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 		struct obd_quotactl *oqctl;
 
 		if (qctl->qc_valid == QC_OSTIDX) {
-			if (qctl->qc_idx < 0 || count <= qctl->qc_idx)
+			if (count <= qctl->qc_idx)
 				return -EINVAL;
 
 			tgt = lov->lov_tgts[qctl->qc_idx];
@@ -1672,7 +1672,7 @@ static int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, u64 fm_start,
 				break;
 		}
 		*stripe_count = j;
-		last_stripe = (start_stripe + j - 1) %lsm->lsm_stripe_count;
+		last_stripe = (start_stripe + j - 1) % lsm->lsm_stripe_count;
 	}
 
 	return last_stripe;
@@ -1862,7 +1862,7 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key,
 			fm_local->fm_start = lun_start;
 			fm_local->fm_flags &= ~FIEMAP_FLAG_DEVICE_ORDER;
 			memcpy(&fm_key->fiemap, fm_local, sizeof(*fm_local));
-			*vallen=fiemap_count_to_size(fm_local->fm_extent_count);
+			*vallen = fiemap_count_to_size(fm_local->fm_extent_count);
 			rc = obd_get_info(NULL,
 					  lov->lov_tgts[ost_index]->ltd_exp,
 					  keylen, key, vallen, fm_local, lsm);
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index bcb6c00c49ff..e6b3bf932a84 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -826,7 +826,7 @@ resend:
 		LASSERT(lmm && lmmsize == 0);
 		LASSERTF(einfo->ei_type == LDLM_FLOCK, "lock type %d\n",
 			 einfo->ei_type);
-		policy = (ldlm_policy_data_t *)lmm;
+		policy = lmm;
 		res_id.name[3] = LDLM_FLOCK;
 		req = NULL;
 	} else if (it->it_op & IT_OPEN) {
diff --git a/drivers/staging/lustre/lustre/obdclass/capa.c b/drivers/staging/lustre/lustre/obdclass/capa.c
index d8d1a66ad68e..99af0176f413 100644
--- a/drivers/staging/lustre/lustre/obdclass/capa.c
+++ b/drivers/staging/lustre/lustre/obdclass/capa.c
@@ -58,7 +58,7 @@
 #define NR_CAPAHASH 32
 #define CAPA_HASH_SIZE 3000	      /* for MDS & OSS */
 
-struct kmem_cache *capa_cachep = NULL;
+struct kmem_cache *capa_cachep;
 
 /* lock for capa hash/capa_list/fo_capa_keys */
 DEFINE_SPINLOCK(capa_lock);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index fd1a4c5421e8..da0066a20fa0 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -307,7 +307,7 @@ static void cl_io_locks_sort(struct cl_io *io)
 					 */
 				default:
 					LBUG();
-				case +1:
+				case 1:
 					list_move_tail(&curr->cill_linkage,
 							   &prev->cill_linkage);
 					done = 0;
@@ -335,7 +335,7 @@ int cl_queue_match(const struct list_head *queue,
 
        list_for_each_entry(scan, queue, cill_linkage) {
 	       if (cl_lock_descr_match(&scan->cill_descr, need))
-		       return +1;
+		       return 1;
        }
        return 0;
 }
@@ -353,7 +353,7 @@ static int cl_queue_merge(const struct list_head *queue,
 	       CDEBUG(D_VFSTRACE, "lock: %d: [%lu, %lu]\n",
 		      scan->cill_descr.cld_mode, scan->cill_descr.cld_start,
 		      scan->cill_descr.cld_end);
-	       return +1;
+	       return 1;
        }
        return 0;
 
@@ -600,7 +600,7 @@ int cl_io_lock_add(const struct lu_env *env, struct cl_io *io,
 	int result;
 
 	if (cl_lockset_merge(&io->ci_lockset, &link->cill_descr))
-		result = +1;
+		result = 1;
 	else {
 		list_add(&link->cill_linkage, &io->ci_lockset.cls_todo);
 		result = 0;
@@ -918,7 +918,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
 		 */
 		 cl_page_list_for_each(pg, &queue->c2_qin) {
 			pg->cp_sync_io = NULL;
-			cl_sync_io_note(anchor, +1);
+			cl_sync_io_note(anchor, 1);
 		 }
 
 		 /* wait for the IO to be finished. */
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index b081167f9767..7c6583a2e884 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -2027,7 +2027,7 @@ static struct cl_lock *cl_lock_hold_mutex(const struct lu_env *env,
 		cl_lock_mutex_get(env, lock);
 		if (lock->cll_state < CLS_FREEING &&
 		    !(lock->cll_flags & CLF_CANCELLED)) {
-			cl_lock_hold_mod(env, lock, +1);
+			cl_lock_hold_mod(env, lock, 1);
 			lu_ref_add(&lock->cll_holders, scope, source);
 			lu_ref_add(&lock->cll_reference, scope, source);
 			break;
@@ -2115,7 +2115,7 @@ void cl_lock_hold_add(const struct lu_env *env, struct cl_lock *lock,
 	LINVRNT(cl_lock_invariant(env, lock));
 	LASSERT(lock->cll_state != CLS_FREEING);
 
-	cl_lock_hold_mod(env, lock, +1);
+	cl_lock_hold_mod(env, lock, 1);
 	cl_lock_get(lock);
 	lu_ref_add(&lock->cll_holders, scope, source);
 	lu_ref_add(&lock->cll_reference, scope, source);
@@ -2157,7 +2157,7 @@ void cl_lock_user_add(const struct lu_env *env, struct cl_lock *lock)
 	LINVRNT(cl_lock_is_mutexed(lock));
 	LINVRNT(cl_lock_invariant(env, lock));
 
-	cl_lock_used_mod(env, lock, +1);
+	cl_lock_used_mod(env, lock, 1);
 }
 EXPORT_SYMBOL(cl_lock_user_add);
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 163fe0cd7f9a..05e29f815b87 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -653,7 +653,8 @@ static inline void cl_env_do_detach(struct cl_env *cle)
 	cle->ce_owner = NULL;
 }
 
-static int cl_env_store_init(void) {
+static int cl_env_store_init(void)
+{
 	cl_env_hash = cfs_hash_create("cl_env",
 				      HASH_CL_ENV_BITS, HASH_CL_ENV_BITS,
 				      HASH_CL_ENV_BKT_BITS, 0,
@@ -661,7 +662,7 @@ static int cl_env_store_init(void) {
 				      CFS_HASH_MAX_THETA,
 				      &cl_env_hops,
 				      CFS_HASH_RW_BKTLOCK);
-	return cl_env_hash != NULL ? 0 :-ENOMEM;
+	return cl_env_hash != NULL ? 0 : -ENOMEM;
 }
 
 static void cl_env_store_fini(void)
@@ -693,10 +694,10 @@ static struct lu_env *cl_env_new(__u32 ctx_tags, __u32 ses_tags, void *debug)
 		INIT_LIST_HEAD(&cle->ce_linkage);
 		cle->ce_magic = &cl_env_init0;
 		env = &cle->ce_lu;
-		rc = lu_env_init(env, LCT_CL_THREAD|ctx_tags);
+		rc = lu_env_init(env, ctx_tags | LCT_CL_THREAD);
 		if (rc == 0) {
 			rc = lu_context_init(&cle->ce_ses,
-					     LCT_SESSION | ses_tags);
+					     ses_tags | LCT_SESSION);
 			if (rc == 0) {
 				lu_context_enter(&cle->ce_ses);
 				env->le_ses = &cle->ce_ses;
@@ -1074,7 +1075,7 @@ static struct lu_kmem_descr cl_object_caches[] = {
 	{
 		.ckd_cache = &cl_env_kmem,
 		.ckd_name  = "cl_env_kmem",
-		.ckd_size  = sizeof (struct cl_env)
+		.ckd_size  = sizeof(struct cl_env)
 	},
 	{
 		.ckd_cache = NULL
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 2c705d76211f..b1511547444a 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -53,9 +53,9 @@ EXPORT_SYMBOL(obd_devs);
 struct list_head obd_types;
 DEFINE_RWLOCK(obd_dev_lock);
 
-__u64 obd_max_pages = 0;
+__u64 obd_max_pages;
 EXPORT_SYMBOL(obd_max_pages);
-__u64 obd_max_alloc = 0;
+__u64 obd_max_alloc;
 EXPORT_SYMBOL(obd_max_alloc);
 __u64 obd_alloc;
 EXPORT_SYMBOL(obd_alloc);
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(obd_pages);
 static DEFINE_SPINLOCK(obd_updatemax_lock);
 
 /* The following are visible and mutable through /proc/sys/lustre/. */
-unsigned int obd_alloc_fail_rate = 0;
+unsigned int obd_alloc_fail_rate;
 EXPORT_SYMBOL(obd_alloc_fail_rate);
 unsigned int obd_debug_peer_on_timeout;
 EXPORT_SYMBOL(obd_debug_peer_on_timeout);
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(obd_timeout);
 unsigned int obd_timeout_set;
 EXPORT_SYMBOL(obd_timeout_set);
 /* Adaptive timeout defs here instead of ptlrpc module for /proc/sys/ access */
-unsigned int at_min = 0;
+unsigned int at_min;
 EXPORT_SYMBOL(at_min);
 unsigned int at_max = 600;
 EXPORT_SYMBOL(at_max);
@@ -138,7 +138,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 	if (ptr == NULL ||
 	    (cfs_rand() & OBD_ALLOC_FAIL_MASK) < obd_alloc_fail_rate) {
 		CERROR("%s%salloc of %s (%llu bytes) failed at %s:%d\n",
-		       ptr ? "force " :"", type, name, (__u64)size, file,
+		       ptr ? "force " : "", type, name, (__u64)size, file,
 		       line);
 		CERROR("%llu total bytes and %llu total pages"
 			" (%llu bytes) allocated by Lustre\n",
@@ -470,7 +470,7 @@ int obd_init_checks(void)
 		return -EOVERFLOW;
 	}
 	if (do_div(div64val, 256) != (u64val & 255)) {
-		CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val &255);
+		CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val & 255);
 		return -EOVERFLOW;
 	}
 	if (u64val >> 8 != div64val) {
diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c
index b67b0feb03e0..6b645a15d7a5 100644
--- a/drivers/staging/lustre/lustre/obdclass/dt_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c
@@ -778,7 +778,7 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
 		return PTR_ERR(it);
 
 	rc = iops->load(env, it, rdpg->rp_hash);
-	if (rc == 0) {
+	if (rc == 0)
 		/*
 		 * Iterator didn't find record with exactly the key requested.
 		 *
@@ -790,9 +790,8 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
 		 *     state)---position it on the next item.
 		 */
 		rc = iops->next(env, it);
-	} else if (rc > 0) {
+	else if (rc > 0)
 		rc = 0;
-	}
 
 	/* Fill containers one after the other. There might be multiple
 	 * containers per physical page.
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 0ca730948f7a..64af0abd970d 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -178,9 +178,9 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
 	type->typ_md_ops = kzalloc(sizeof(*type->typ_md_ops), GFP_NOFS);
 	type->typ_name = kzalloc(strlen(name) + 1, GFP_NOFS);
 
-	if (type->typ_dt_ops == NULL ||
-	    type->typ_md_ops == NULL ||
-	    type->typ_name == NULL)
+	if (!type->typ_dt_ops ||
+	    !type->typ_md_ops ||
+	    !type->typ_name)
 		goto failed;
 
 	*(type->typ_dt_ops) = *dt_ops;
@@ -293,13 +293,13 @@ struct obd_device *class_newdev(const char *type_name, const char *name)
 	}
 
 	type = class_get_type(type_name);
-	if (type == NULL) {
+	if (!type) {
 		CERROR("OBD: unknown type: %s\n", type_name);
 		return ERR_PTR(-ENODEV);
 	}
 
 	newdev = obd_device_alloc();
-	if (newdev == NULL) {
+	if (!newdev) {
 		result = ERR_PTR(-ENOMEM);
 		goto out_type;
 	}
@@ -339,7 +339,7 @@ struct obd_device *class_newdev(const char *type_name, const char *name)
 	}
 	write_unlock(&obd_dev_lock);
 
-	if (result == NULL && i >= class_devno_max()) {
+	if (!result && i >= class_devno_max()) {
 		CERROR("all %u OBD devices used, increase MAX_OBD_DEVICES\n",
 		       class_devno_max());
 		result = ERR_PTR(-EOVERFLOW);
@@ -442,6 +442,7 @@ EXPORT_SYMBOL(class_uuid2dev);
 struct obd_device *class_uuid2obd(struct obd_uuid *uuid)
 {
 	int dev = class_uuid2dev(uuid);
+
 	if (dev < 0)
 		return NULL;
 	return class_num2obd(dev);
@@ -462,7 +463,7 @@ struct obd_device *class_num2obd(int num)
 
 	if (num < class_devno_max()) {
 		obd = obd_devs[num];
-		if (obd == NULL)
+		if (!obd)
 			return NULL;
 
 		LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
@@ -489,6 +490,7 @@ int get_devices_count(void)
 	read_lock(&obd_dev_lock);
 	for (index = 0; index <= max_index; index++) {
 		struct obd_device *obd = class_num2obd(index);
+
 		if (obd != NULL)
 			dev_count++;
 	}
@@ -507,7 +509,7 @@ void class_obd_list(void)
 	for (i = 0; i < class_devno_max(); i++) {
 		struct obd_device *obd = class_num2obd(i);
 
-		if (obd == NULL)
+		if (!obd)
 			continue;
 		if (obd->obd_stopping)
 			status = "ST";
@@ -523,7 +525,6 @@ void class_obd_list(void)
 			 atomic_read(&obd->obd_refcount));
 	}
 	read_unlock(&obd_dev_lock);
-	return;
 }
 
 /* Search for a client OBD connected to tgt_uuid.  If grp_uuid is
@@ -539,13 +540,13 @@ struct obd_device *class_find_client_obd(struct obd_uuid *tgt_uuid,
 	for (i = 0; i < class_devno_max(); i++) {
 		struct obd_device *obd = class_num2obd(i);
 
-		if (obd == NULL)
+		if (!obd)
 			continue;
 		if ((strncmp(obd->obd_type->typ_name, typ_name,
 			     strlen(typ_name)) == 0)) {
 			if (obd_uuid_equals(tgt_uuid,
 					    &obd->u.cli.cl_target_uuid) &&
-			    ((grp_uuid)? obd_uuid_equals(grp_uuid,
+			    ((grp_uuid) ? obd_uuid_equals(grp_uuid,
 							 &obd->obd_uuid) : 1)) {
 				read_unlock(&obd_dev_lock);
 				return obd;
@@ -566,7 +567,7 @@ struct obd_device *class_devices_in_group(struct obd_uuid *grp_uuid, int *next)
 {
 	int i;
 
-	if (next == NULL)
+	if (!next)
 		i = 0;
 	else if (*next >= 0 && *next < class_devno_max())
 		i = *next;
@@ -577,10 +578,10 @@ struct obd_device *class_devices_in_group(struct obd_uuid *grp_uuid, int *next)
 	for (; i < class_devno_max(); i++) {
 		struct obd_device *obd = class_num2obd(i);
 
-		if (obd == NULL)
+		if (!obd)
 			continue;
 		if (obd_uuid_equals(grp_uuid, &obd->obd_uuid)) {
-			if (next != NULL)
+			if (next)
 				*next = i+1;
 			read_unlock(&obd_dev_lock);
 			return obd;
@@ -608,7 +609,7 @@ int class_notify_sptlrpc_conf(const char *fsname, int namelen)
 	for (i = 0; i < class_devno_max(); i++) {
 		obd = class_num2obd(i);
 
-		if (obd == NULL || obd->obd_set_up == 0 || obd->obd_stopping)
+		if (!obd || obd->obd_set_up == 0 || obd->obd_stopping)
 			continue;
 
 		/* only notify mdc, osc, mdt, ost */
@@ -658,27 +659,27 @@ void obd_cleanup_caches(void)
 
 int obd_init_caches(void)
 {
-	LASSERT(obd_device_cachep == NULL);
+	LASSERT(!obd_device_cachep);
 	obd_device_cachep = kmem_cache_create("ll_obd_dev_cache",
 						 sizeof(struct obd_device),
 						 0, 0, NULL);
 	if (!obd_device_cachep)
 		goto out;
 
-	LASSERT(obdo_cachep == NULL);
+	LASSERT(!obdo_cachep);
 	obdo_cachep = kmem_cache_create("ll_obdo_cache", sizeof(struct obdo),
 					   0, 0, NULL);
 	if (!obdo_cachep)
 		goto out;
 
-	LASSERT(import_cachep == NULL);
+	LASSERT(!import_cachep);
 	import_cachep = kmem_cache_create("ll_import_cache",
 					     sizeof(struct obd_import),
 					     0, 0, NULL);
 	if (!import_cachep)
 		goto out;
 
-	LASSERT(capa_cachep == NULL);
+	LASSERT(!capa_cachep);
 	capa_cachep = kmem_cache_create("capa_cache",
 					   sizeof(struct obd_capa), 0, 0, NULL);
 	if (!capa_cachep)
@@ -723,9 +724,11 @@ EXPORT_SYMBOL(class_exp2obd);
 struct obd_device *class_conn2obd(struct lustre_handle *conn)
 {
 	struct obd_export *export;
+
 	export = class_conn2export(conn);
 	if (export) {
 		struct obd_device *obd = export->exp_obd;
+
 		class_export_put(export);
 		return obd;
 	}
@@ -736,7 +739,8 @@ EXPORT_SYMBOL(class_conn2obd);
 struct obd_import *class_exp2cliimp(struct obd_export *exp)
 {
 	struct obd_device *obd = exp->exp_obd;
-	if (obd == NULL)
+
+	if (!obd)
 		return NULL;
 	return obd->u.cli.cl_import;
 }
@@ -745,7 +749,8 @@ EXPORT_SYMBOL(class_exp2cliimp);
 struct obd_import *class_conn2cliimp(struct lustre_handle *conn)
 {
 	struct obd_device *obd = class_conn2obd(conn);
-	if (obd == NULL)
+
+	if (!obd)
 		return NULL;
 	return obd->u.cli.cl_import;
 }
@@ -870,7 +875,7 @@ struct obd_export *class_new_export(struct obd_device *obd,
 	}
 
 	hash = cfs_hash_getref(obd->obd_uuid_hash);
-	if (hash == NULL) {
+	if (!hash) {
 		rc = -ENODEV;
 		goto exit_unlock;
 	}
@@ -954,7 +959,7 @@ static void class_import_destroy(struct obd_import *imp)
 		kfree(imp_conn);
 	}
 
-	LASSERT(imp->imp_sec == NULL);
+	LASSERT(!imp->imp_sec);
 	class_decref(imp->imp_obd, "import", imp);
 	OBD_FREE_RCU(imp, sizeof(*imp), &imp->imp_handle);
 }
@@ -1001,6 +1006,7 @@ EXPORT_SYMBOL(class_import_put);
 static void init_imp_at(struct imp_at *at)
 {
 	int i;
+
 	at_init(&at->iat_net_latency, 0, 0);
 	for (i = 0; i < IMP_AT_MAX_PORTALS; i++) {
 		/* max service estimates are tracked on the server side, so
@@ -1078,7 +1084,7 @@ void __class_export_add_lock_ref(struct obd_export *exp, struct ldlm_lock *lock)
 		LCONSOLE_WARN("setting export %p for lock %p which already has export %p\n",
 			      exp, lock, lock->l_exp_refs_target);
 	}
-	if ((lock->l_exp_refs_nr ++) == 0) {
+	if ((lock->l_exp_refs_nr++) == 0) {
 		list_add(&lock->l_exp_refs_link, &exp->exp_locks_list);
 		lock->l_exp_refs_target = exp;
 	}
@@ -1115,6 +1121,7 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd,
 		  struct obd_uuid *cluuid)
 {
 	struct obd_export *export;
+
 	LASSERT(conn != NULL);
 	LASSERT(obd != NULL);
 	LASSERT(cluuid != NULL);
@@ -1187,7 +1194,7 @@ int class_disconnect(struct obd_export *export)
 {
 	int already_disconnected;
 
-	if (export == NULL) {
+	if (!export) {
 		CWARN("attempting to free NULL export %p\n", export);
 		return -EINVAL;
 	}
@@ -1226,6 +1233,7 @@ int class_connected_export(struct obd_export *exp)
 {
 	if (exp) {
 		int connected;
+
 		spin_lock(&exp->exp_lock);
 		connected = exp->exp_conn_cnt > 0;
 		spin_unlock(&exp->exp_lock);
@@ -1335,7 +1343,7 @@ void class_disconnect_stale_exports(struct obd_device *obd,
 		evicted++;
 		CDEBUG(D_HA, "%s: disconnect stale client %s@%s\n",
 		       obd->obd_name, exp->exp_client_uuid.uuid,
-		       exp->exp_connection == NULL ? "<unknown>" :
+		       !exp->exp_connection ? "<unknown>" :
 		       libcfs_nid2str(exp->exp_connection->c_peer.nid));
 		print_export_data(exp, "EVICTING", 0);
 	}
@@ -1418,7 +1426,7 @@ int obd_export_evict_by_nid(struct obd_device *obd, const char *nid)
 
 	do {
 		doomed_exp = cfs_hash_lookup(nid_hash, &nid_key);
-		if (doomed_exp == NULL)
+		if (!doomed_exp)
 			break;
 
 		LASSERTF(doomed_exp->exp_connection->c_peer.nid == nid_key,
@@ -1471,7 +1479,7 @@ int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid)
 
 	doomed_exp = cfs_hash_lookup(uuid_hash, &doomed_uuid);
 
-	if (doomed_exp == NULL) {
+	if (!doomed_exp) {
 		CERROR("%s: can't disconnect %s: no exports found\n",
 		       obd->obd_name, uuid);
 	} else {
@@ -1488,7 +1496,7 @@ int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid)
 EXPORT_SYMBOL(obd_export_evict_by_uuid);
 
 #if LUSTRE_TRACKS_LOCK_EXP_REFS
-void (*class_export_dump_hook)(struct obd_export*) = NULL;
+void (*class_export_dump_hook)(struct obd_export *) = NULL;
 EXPORT_SYMBOL(class_export_dump_hook);
 #endif
 
@@ -1545,6 +1553,7 @@ EXPORT_SYMBOL(dump_exports);
 void obd_exports_barrier(struct obd_device *obd)
 {
 	int waited = 2;
+
 	LASSERT(list_empty(&obd->obd_exports));
 	spin_lock(&obd->obd_dev_lock);
 	while (!list_empty(&obd->obd_unlinked_exports)) {
@@ -1661,8 +1670,8 @@ static void obd_zombie_export_add(struct obd_export *exp)
  */
 static void obd_zombie_import_add(struct obd_import *imp)
 {
-	LASSERT(imp->imp_sec == NULL);
-	LASSERT(imp->imp_rq_pool == NULL);
+	LASSERT(!imp->imp_sec);
+	LASSERT(!imp->imp_rq_pool);
 	spin_lock(&obd_zombie_impexp_lock);
 	LASSERT(list_empty(&imp->imp_zombie_chain));
 	zombies_count++;
@@ -1792,6 +1801,7 @@ EXPORT_SYMBOL(kuc_len);
 struct kuc_hdr *kuc_ptr(void *p)
 {
 	struct kuc_hdr *lh = ((struct kuc_hdr *)p) - 1;
+
 	LASSERT(lh->kuc_magic == KUC_MAGIC);
 	return lh;
 }
@@ -1837,6 +1847,7 @@ EXPORT_SYMBOL(kuc_alloc);
 inline void kuc_free(void *p, int payload_len)
 {
 	struct kuc_hdr *lh = kuc_ptr(p);
+
 	kfree(lh);
 }
 EXPORT_SYMBOL(kuc_free);
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 6218ef34ee80..245ac2e9b2dd 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -73,8 +73,6 @@
 #include "../../include/lustre_ver.h"
 #include "../../include/lustre/lustre_build_version.h"
 
-int proc_version;
-
 /* buffer MUST be at least the size of obd_ioctl_hdr */
 int obd_ioctl_getdata(char **buf, int *len, void *arg)
 {
diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c
index facc8351fcea..78d92269aab6 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog.c
@@ -326,7 +326,7 @@ repeat:
 		 * swabbing is done at the beginning of the loop. */
 		for (rec = (struct llog_rec_hdr *)buf;
 		     (char *)rec < buf + LLOG_CHUNK_SIZE;
-		     rec = (struct llog_rec_hdr *)((char *)rec + rec->lrh_len)){
+		     rec = (struct llog_rec_hdr *)((char *)rec + rec->lrh_len)) {
 
 			CDEBUG(D_OTHER, "processing rec 0x%p type %#x\n",
 			       rec, rec->lrh_type);
@@ -522,7 +522,7 @@ int llog_reverse_process(const struct lu_env *env,
 			rec = (void *)rec + rec->lrh_len;
 			if (LLOG_REC_HDR_NEEDS_SWABBING(rec))
 				lustre_swab_llog_rec(rec);
-			idx ++;
+			idx++;
 		}
 		LASSERT(idx == index);
 		tail = (void *)rec + rec->lrh_len - sizeof(*tail);
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
index c49dfe541925..1f0004c5554b 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_counters.c
@@ -41,7 +41,7 @@
 #include "../include/lprocfs_status.h"
 #include "../include/obd_support.h"
 
-struct lprocfs_stats *obd_memory = NULL;
+struct lprocfs_stats *obd_memory;
 EXPORT_SYMBOL(obd_memory);
 
 void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount)
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 8e472327c880..48d543682144 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -1689,8 +1689,8 @@ EXPORT_SYMBOL(lu_context_refill);
  * predefined when the lu_device type are registered, during the module probe
  * phase.
  */
-__u32 lu_context_tags_default = 0;
-__u32 lu_session_tags_default = 0;
+__u32 lu_context_tags_default;
+__u32 lu_session_tags_default;
 
 void lu_context_tags_update(__u32 tags)
 {
@@ -1784,15 +1784,15 @@ int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags,
 EXPORT_SYMBOL(lu_env_refill_by_tags);
 
 
-typedef struct lu_site_stats{
+struct lu_site_stats {
 	unsigned	lss_populated;
 	unsigned	lss_max_search;
 	unsigned	lss_total;
 	unsigned	lss_busy;
-} lu_site_stats_t;
+};
 
 static void lu_site_stats_get(struct cfs_hash *hs,
-			      lu_site_stats_t *stats, int populated)
+			      struct lu_site_stats *stats, int populated)
 {
 	struct cfs_hash_bd bd;
 	int	   i;
@@ -1841,7 +1841,7 @@ static void lu_site_stats_get(struct cfs_hash *hs,
 static unsigned long lu_cache_shrink_count(struct shrinker *sk,
 					   struct shrink_control *sc)
 {
-	lu_site_stats_t stats;
+	struct lu_site_stats stats;
 	struct lu_site *s;
 	struct lu_site *tmp;
 	unsigned long cached = 0;
@@ -2001,7 +2001,7 @@ static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx)
  */
 int lu_site_stats_print(const struct lu_site *s, struct seq_file *m)
 {
-	lu_site_stats_t stats;
+	struct lu_site_stats stats;
 
 	memset(&stats, 0, sizeof(stats));
 	lu_site_stats_get(s->ls_obj_hash, &stats, 1);
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c
index 93805ac93c5a..32b40eab8d8e 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_config.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c
@@ -61,7 +61,7 @@ int class_find_param(char *buf, char *key, char **valp)
 		return 1;
 
 	ptr = strstr(buf, key);
-	if (ptr == NULL)
+	if (!ptr)
 		return 1;
 
 	if (valp)
@@ -92,11 +92,11 @@ struct cfg_interop_param *class_find_old_param(const char *param,
 	char *value = NULL;
 	int   name_len = 0;
 
-	if (param == NULL || ptr == NULL)
+	if (!param || !ptr)
 		return NULL;
 
 	value = strchr(param, '=');
-	if (value == NULL)
+	if (!value)
 		name_len = strlen(param);
 	else
 		name_len = value - param;
@@ -144,7 +144,7 @@ int class_get_next_param(char **params, char *copy)
 
 	while (1) {
 		q1 = strpbrk(str, " '\"");
-		if (q1 == NULL) {
+		if (!q1) {
 			len = strlen(str);
 			memcpy(copy, str, len);
 			copy[len] = '\0';
@@ -165,7 +165,7 @@ int class_get_next_param(char **params, char *copy)
 		/* search for the matching closing quote */
 		str = q1 + 1;
 		q2 = strchr(str, *q1);
-		if (q2 == NULL) {
+		if (!q2) {
 			CERROR("Unbalanced quota in parameters: \"%s\"\n",
 			       *params);
 			return -EINVAL;
@@ -243,7 +243,7 @@ static int class_parse_value(char *buf, int opc, void *value, char **endh,
 
 	/* nid separators or end of nids */
 	endp = strpbrk(buf, ",: /");
-	if (endp == NULL)
+	if (!endp)
 		endp = buf + strlen(buf);
 
 	tmp = *endp;
@@ -841,14 +841,14 @@ int class_add_profile(int proflen, char *prof, int osclen, char *osc,
 
 	LASSERT(proflen == (strlen(prof) + 1));
 	lprof->lp_profile = kmemdup(prof, proflen, GFP_NOFS);
-	if (lprof->lp_profile == NULL) {
+	if (!lprof->lp_profile) {
 		err = -ENOMEM;
 		goto free_lprof;
 	}
 
 	LASSERT(osclen == (strlen(osc) + 1));
 	lprof->lp_dt = kmemdup(osc, osclen, GFP_NOFS);
-	if (lprof->lp_dt == NULL) {
+	if (!lprof->lp_dt) {
 		err = -ENOMEM;
 		goto free_lp_profile;
 	}
@@ -856,7 +856,7 @@ int class_add_profile(int proflen, char *prof, int osclen, char *osc,
 	if (mdclen > 0) {
 		LASSERT(mdclen == (strlen(mdc) + 1));
 		lprof->lp_md = kmemdup(mdc, mdclen, GFP_NOFS);
-		if (lprof->lp_md == NULL) {
+		if (!lprof->lp_md) {
 			err = -ENOMEM;
 			goto free_lp_dt;
 		}
@@ -931,8 +931,8 @@ static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
 
 /* We can't call ll_process_config or lquota_process_config directly because
  * it lives in a module that must be loaded after this one. */
-static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
-static int (*quota_process_config)(struct lustre_cfg *lcfg) = NULL;
+static int (*client_process_config)(struct lustre_cfg *lcfg);
+static int (*quota_process_config)(struct lustre_cfg *lcfg);
 
 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
 {
@@ -963,15 +963,15 @@ struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
 	int			 name_len = 0;
 	int			 new_len = 0;
 
-	if (cfg == NULL || new_name == NULL)
+	if (!cfg || !new_name)
 		return ERR_PTR(-EINVAL);
 
 	param = lustre_cfg_string(cfg, 1);
-	if (param == NULL)
+	if (!param)
 		return ERR_PTR(-EINVAL);
 
 	value = strchr(param, '=');
-	if (value == NULL)
+	if (!value)
 		name_len = strlen(param);
 	else
 		name_len = value - param;
@@ -1000,7 +1000,7 @@ struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
 
 	kfree(new_param);
 	kfree(bufs);
-	if (new_cfg == NULL)
+	if (!new_cfg)
 		return ERR_PTR(-ENOMEM);
 
 	new_cfg->lcfg_num = cfg->lcfg_num;
@@ -1178,7 +1178,7 @@ int class_process_config(struct lustre_cfg *lcfg)
 	}
 	/* Commands that require a device */
 	obd = class_name2obd(lustre_cfg_string(lcfg, 0));
-	if (obd == NULL) {
+	if (!obd) {
 		if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
 			CERROR("this lcfg command requires a device name\n");
 		else
@@ -1451,18 +1451,17 @@ int class_config_llog_handler(const struct lu_env *env,
 		lustre_cfg_bufs_init(&bufs, lcfg);
 
 		if (clli && clli->cfg_instance &&
-		    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
+		    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
 			inst = 1;
 			inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
 				   sizeof(clli->cfg_instance) * 2 + 4;
-			inst_name = kzalloc(inst_len, GFP_NOFS);
+			inst_name = kasprintf(GFP_NOFS, "%s-%p",
+					      lustre_cfg_string(lcfg, 0),
+					      clli->cfg_instance);
 			if (!inst_name) {
 				rc = -ENOMEM;
 				goto out;
 			}
-			sprintf(inst_name, "%s-%p",
-				lustre_cfg_string(lcfg, 0),
-				clli->cfg_instance);
 			lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
 			CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
 			       lcfg->lcfg_command, inst_name);
@@ -1482,7 +1481,7 @@ int class_config_llog_handler(const struct lu_env *env,
 		 * moving them to index [1] and [2], and insert MGC's
 		 * obdname at index [0].
 		 */
-		if (clli && clli->cfg_instance == NULL &&
+		if (clli && !clli->cfg_instance &&
 		    lcfg->lcfg_command == LCFG_SPTLRPC_CONF) {
 			lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1],
 					    bufs.lcfg_buflen[1]);
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index f9cf5cea643d..856d859c385e 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -553,7 +553,7 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg,
 	oap->oap_cmd = crt == CRT_WRITE ? OBD_BRW_WRITE : OBD_BRW_READ;
 	oap->oap_page_off = opg->ops_from;
 	oap->oap_count = opg->ops_to - opg->ops_from;
-	oap->oap_brw_flags = OBD_BRW_SYNC | brw_flags;
+	oap->oap_brw_flags = brw_flags | OBD_BRW_SYNC;
 
 	if (!client_is_remote(osc_export(obj)) &&
 			capable(CFS_CAP_SYS_RESOURCE)) {
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 12113dfd87b8..114c5508a0a0 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -433,7 +433,7 @@ int osc_setattr_async_base(struct obd_export *exp, struct obd_info *oinfo,
 		req->rq_interpret_reply =
 			(ptlrpc_interpterer_t)osc_setattr_interpret;
 
-		CLASSERT (sizeof(*sa) <= sizeof(req->rq_async_args));
+		CLASSERT(sizeof(*sa) <= sizeof(req->rq_async_args));
 		sa = ptlrpc_req_async_args(req);
 		sa->sa_oa = oinfo->oi_oa;
 		sa->sa_upcall = upcall;
@@ -575,7 +575,7 @@ int osc_punch_base(struct obd_export *exp, struct obd_info *oinfo,
 	ptlrpc_request_set_replen(req);
 
 	req->rq_interpret_reply = (ptlrpc_interpterer_t)osc_setattr_interpret;
-	CLASSERT (sizeof(*sa) <= sizeof(req->rq_async_args));
+	CLASSERT(sizeof(*sa) <= sizeof(req->rq_async_args));
 	sa = ptlrpc_req_async_args(req);
 	sa->sa_oa = oinfo->oi_oa;
 	sa->sa_upcall = upcall;
@@ -600,7 +600,7 @@ static int osc_sync_interpret(const struct lu_env *env,
 
 	body = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY);
 	if (body == NULL) {
-		CERROR ("can't unpack ost_body\n");
+		CERROR("can't unpack ost_body\n");
 		rc = -EPROTO;
 		goto out;
 	}
@@ -1100,7 +1100,7 @@ static void handle_short_read(int nob_read, u32 page_count,
 
 	/* skip bytes read OK */
 	while (nob_read > 0) {
-		LASSERT (page_count > 0);
+		LASSERT(page_count > 0);
 
 		if (pga[i]->count > nob_read) {
 			/* EOF inside this page */
@@ -1571,7 +1571,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
 	}
 
 	if (rc != req->rq_bulk->bd_nob_transferred) {
-		CERROR ("Unexpected rc %d (%d transferred)\n",
+		CERROR("Unexpected rc %d (%d transferred)\n",
 			rc, req->rq_bulk->bd_nob_transferred);
 		return -EPROTO;
 	}
@@ -1586,7 +1586,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
 		char *router;
 		cksum_type_t cksum_type;
 
-		cksum_type = cksum_type_unpack(body->oa.o_valid &OBD_MD_FLFLAGS?
+		cksum_type = cksum_type_unpack(body->oa.o_valid&OBD_MD_FLFLAGS ?
 					       body->oa.o_flags : 0);
 		client_cksum = osc_checksum_bulk(rc, aa->aa_page_count,
 						 aa->aa_ppga, OST_READ,
@@ -1654,7 +1654,7 @@ static int osc_brw_redo_request(struct ptlrpc_request *request,
 		  "redo for recoverable error %d", rc);
 
 	rc = osc_brw_prep_request(lustre_msg_get_opc(request->rq_reqmsg) ==
-					OST_WRITE ? OBD_BRW_WRITE :OBD_BRW_READ,
+					OST_WRITE ? OBD_BRW_WRITE : OBD_BRW_READ,
 				  aa->aa_cli, aa->aa_oa,
 				  NULL /* lsm unused by osc currently */,
 				  aa->aa_page_count, aa->aa_ppga,
@@ -3101,7 +3101,7 @@ static int osc_import_event(struct obd_device *obd,
 
 		/* See bug 7198 */
 		if (ocd->ocd_connect_flags & OBD_CONNECT_REQPORTAL)
-			imp->imp_client->cli_request_portal =OST_REQUEST_PORTAL;
+			imp->imp_client->cli_request_portal = OST_REQUEST_PORTAL;
 
 		rc = obd_notify_observer(obd, obd, OBD_NOTIFY_OCD, NULL);
 		break;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index c83a34a01e65..1800db1e0797 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1164,12 +1164,11 @@ static int ptlrpc_check_status(struct ptlrpc_request *req)
 		return err < 0 ? err : -EINVAL;
 	}
 
-	if (err < 0) {
+	if (err < 0)
 		DEBUG_REQ(D_INFO, req, "status is %d", err);
-	} else if (err > 0) {
+	else if (err > 0)
 		/* XXX: translate this error from net to host */
 		DEBUG_REQ(D_INFO, req, "status is %d", err);
-	}
 
 	return err;
 }
@@ -2954,7 +2953,7 @@ void ptlrpc_init_xid(void)
 	}
 
 	/* Always need to be aligned to a power-of-two for multi-bulk BRW */
-	CLASSERT((PTLRPC_BULK_OPS_COUNT & (PTLRPC_BULK_OPS_COUNT - 1)) == 0);
+	CLASSERT(((PTLRPC_BULK_OPS_COUNT - 1) & PTLRPC_BULK_OPS_COUNT) == 0);
 	ptlrpc_last_xid &= PTLRPC_BULK_OPS_MASK;
 }
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 1eae3896c037..f5b324539a07 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -200,12 +200,15 @@ int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt)
 	return rc;
 }
 
-/* Must be called with imp_lock held! */
-static void ptlrpc_deactivate_and_unlock_import(struct obd_import *imp)
+/*
+ * This acts as a barrier; all existing requests are rejected, and
+ * no new requests will be accepted until the import is valid again.
+ */
+void ptlrpc_deactivate_import(struct obd_import *imp)
 {
-	assert_spin_locked(&imp->imp_lock);
-
 	CDEBUG(D_HA, "setting import %s INVALID\n", obd2cli_tgt(imp->imp_obd));
+
+	spin_lock(&imp->imp_lock);
 	imp->imp_invalid = 1;
 	imp->imp_generation++;
 	spin_unlock(&imp->imp_lock);
@@ -213,16 +216,6 @@ static void ptlrpc_deactivate_and_unlock_import(struct obd_import *imp)
 	ptlrpc_abort_inflight(imp);
 	obd_import_event(imp->imp_obd, imp, IMP_EVENT_INACTIVE);
 }
-
-/*
- * This acts as a barrier; all existing requests are rejected, and
- * no new requests will be accepted until the import is valid again.
- */
-void ptlrpc_deactivate_import(struct obd_import *imp)
-{
-	spin_lock(&imp->imp_lock);
-	ptlrpc_deactivate_and_unlock_import(imp);
-}
 EXPORT_SYMBOL(ptlrpc_deactivate_import);
 
 static unsigned int
@@ -906,7 +899,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
 	}
 
 	/* Determine what recovery state to move the import to. */
-	if (MSG_CONNECT_RECONNECT & msg_flags) {
+	if (msg_flags & MSG_CONNECT_RECONNECT) {
 		memset(&old_hdl, 0, sizeof(old_hdl));
 		if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg),
 			    sizeof(old_hdl))) {
@@ -931,7 +924,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
 			 * eviction. If it is in recovery - we are safe to
 			 * participate since we can reestablish all of our state
 			 * with server again */
-			if ((MSG_CONNECT_RECOVERING & msg_flags)) {
+			if ((msg_flags & MSG_CONNECT_RECOVERING)) {
 				CDEBUG(level, "%s@%s changed server handle from %#llx to %#llx but is still in recovery\n",
 				       obd2cli_tgt(imp->imp_obd),
 				       imp->imp_connection->c_remote_uuid.uuid,
@@ -952,7 +945,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
 			imp->imp_remote_handle =
 				     *lustre_msg_get_handle(request->rq_repmsg);
 
-			if (!(MSG_CONNECT_RECOVERING & msg_flags)) {
+			if (!(msg_flags & MSG_CONNECT_RECOVERING)) {
 				IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED);
 				rc = 0;
 				goto finish;
@@ -968,7 +961,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
 			CDEBUG(D_HA, "%s: reconnected but import is invalid; marking evicted\n",
 			       imp->imp_obd->obd_name);
 			IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED);
-		} else if (MSG_CONNECT_RECOVERING & msg_flags) {
+		} else if (msg_flags & MSG_CONNECT_RECOVERING) {
 			CDEBUG(D_HA, "%s: reconnected to %s during replay\n",
 			       imp->imp_obd->obd_name,
 			       obd2cli_tgt(imp->imp_obd));
@@ -981,7 +974,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
 		} else {
 			IMPORT_SET_STATE(imp, LUSTRE_IMP_RECOVER);
 		}
-	} else if ((MSG_CONNECT_RECOVERING & msg_flags) && !imp->imp_invalid) {
+	} else if ((msg_flags & MSG_CONNECT_RECOVERING) && !imp->imp_invalid) {
 		LASSERT(imp->imp_replayable);
 		imp->imp_remote_handle =
 				*lustre_msg_get_handle(request->rq_repmsg);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index d14c20008850..5d19cfcfe7e9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -789,17 +789,17 @@ enum rmf_flags {
 	/**
 	 * The field is a string, must be NUL-terminated.
 	 */
-	RMF_F_STRING = 1 << 0,
+	RMF_F_STRING = BIT(0),
 	/**
 	 * The field's buffer size need not match the declared \a rmf_size.
 	 */
-	RMF_F_NO_SIZE_CHECK = 1 << 1,
+	RMF_F_NO_SIZE_CHECK = BIT(1),
 	/**
 	 * The field's buffer size must be a whole multiple of the declared \a
 	 * rmf_size and the \a rmf_swabber function must work on the declared \a
 	 * rmf_size worth of bytes.
 	 */
-	RMF_F_STRUCT_ARRAY = 1 << 2
+	RMF_F_STRUCT_ARRAY = BIT(2)
 };
 
 struct req_capsule;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index 53f9af1f2f3e..84eb3da5a9c9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -54,7 +54,7 @@ static struct ll_rpc_opcode {
 	{ OST_SETATTR,      "ost_setattr" },
 	{ OST_READ,	 "ost_read" },
 	{ OST_WRITE,	"ost_write" },
-	{ OST_CREATE ,      "ost_create" },
+	{ OST_CREATE,       "ost_create" },
 	{ OST_DESTROY,      "ost_destroy" },
 	{ OST_GET_INFO,     "ost_get_info" },
 	{ OST_CONNECT,      "ost_connect" },
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index 84937ad90570..e9f8aa0df978 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -883,7 +883,7 @@ void lustre_msg_clear_flags(struct lustre_msg *msg, int flags)
 	case LUSTRE_MSG_MAGIC_V2: {
 		struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
 		LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
-		pb->pb_flags &= ~(MSG_GEN_FLAG_MASK & flags);
+		pb->pb_flags &= ~(flags & MSG_GEN_FLAG_MASK);
 		return;
 	}
 	default:
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
index a243db60f697..d905b77b758b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
@@ -46,6 +46,7 @@
 #include "../include/obd_class.h"
 #include "../include/lustre_net.h"
 #include "../include/lustre_sec.h"
+#include "ptlrpc_internal.h"
 
 struct plain_sec {
 	struct ptlrpc_sec       pls_base;
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index c1408342b1d0..b22d685a5034 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -33,7 +33,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
-#include <linux/time.h>
+#include <linux/ktime.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 
@@ -144,25 +144,22 @@ static void lirc_off(void)
 
 static unsigned int init_lirc_timer(void)
 {
-	struct timeval tv, now;
+	ktime_t kt, now, timeout;
 	unsigned int level, newlevel, timeelapsed, newtimer;
 	int count = 0;
 
-	do_gettimeofday(&tv);
-	tv.tv_sec++;                     /* wait max. 1 sec. */
+	kt = ktime_get();
+	/* wait max. 1 sec. */
+	timeout = ktime_add_ns(kt, NSEC_PER_SEC);
 	level = lirc_get_timer();
 	do {
 		newlevel = lirc_get_timer();
 		if (level == 0 && newlevel != 0)
 			count++;
 		level = newlevel;
-		do_gettimeofday(&now);
-	} while (count < 1000 && (now.tv_sec < tv.tv_sec
-			     || (now.tv_sec == tv.tv_sec
-				 && now.tv_usec < tv.tv_usec)));
-
-	timeelapsed = (now.tv_sec + 1 - tv.tv_sec)*1000000
-		     + (now.tv_usec - tv.tv_usec);
+		now = ktime_get();
+	} while (count < 1000 && (ktime_compare(now, timeout) < 0));
+	timeelapsed = ktime_to_us(ktime_sub(now, kt));
 	if (count >= 1000 && timeelapsed > 0) {
 		if (default_timer == 0) {
 			/* autodetect timer */
@@ -220,8 +217,8 @@ static void rbuf_write(int signal)
 
 static void lirc_lirc_irq_handler(void *blah)
 {
-	struct timeval tv;
-	static struct timeval lasttv;
+	ktime_t kt, delkt;
+	static ktime_t lastkt;
 	static int init;
 	long signal;
 	int data;
@@ -244,16 +241,14 @@ static void lirc_lirc_irq_handler(void *blah)
 
 #ifdef LIRC_TIMER
 	if (init) {
-		do_gettimeofday(&tv);
+		kt = ktime_get();
 
-		signal = tv.tv_sec - lasttv.tv_sec;
-		if (signal > 15)
+		delkt = ktime_sub(kt, lastkt);
+		if (ktime_compare(delkt, ktime_set(15, 0)) > 0)
 			/* really long time */
 			data = PULSE_MASK;
 		else
-			data = (int) (signal*1000000 +
-					 tv.tv_usec - lasttv.tv_usec +
-					 LIRC_SFH506_DELAY);
+			data = (int) (ktime_to_us(delkt) + LIRC_SFH506_DELAY);
 
 		rbuf_write(data); /* space */
 	} else {
@@ -301,7 +296,7 @@ static void lirc_lirc_irq_handler(void *blah)
 			data = 1;
 		rbuf_write(PULSE_BIT|data); /* pulse */
 	}
-	do_gettimeofday(&lasttv);
+	lastkt = ktime_get();
 #else
 	/* add your code here */
 #endif
diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index b247649a99eb..c14ca7e0945b 100644
--- a/drivers/staging/media/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
@@ -42,6 +42,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
+#include <linux/ktime.h>
 
 #include <media/lirc.h>
 #include <media/lirc_dev.h>
@@ -111,7 +112,7 @@ struct sasem_context {
 	} tx;
 
 	/* for dealing with repeat codes (wish there was a toggle bit!) */
-	struct timeval presstime;
+	ktime_t presstime;
 	char lastcode[8];
 	int codesaved;
 };
@@ -566,8 +567,8 @@ static void incoming_packet(struct sasem_context *context,
 {
 	int len = urb->actual_length;
 	unsigned char *buf = urb->transfer_buffer;
-	long ms;
-	struct timeval tv;
+	u64 ns;
+	ktime_t kt;
 
 	if (len != 8) {
 		dev_warn(&context->dev->dev,
@@ -584,9 +585,8 @@ static void incoming_packet(struct sasem_context *context,
 	 */
 
 	/* get the time since the last button press */
-	do_gettimeofday(&tv);
-	ms = (tv.tv_sec - context->presstime.tv_sec) * 1000 +
-	     (tv.tv_usec - context->presstime.tv_usec) / 1000;
+	kt = ktime_get();
+	ns = ktime_to_ns(ktime_sub(kt, context->presstime));
 
 	if (memcmp(buf, "\x08\0\0\0\0\0\0\0", 8) == 0) {
 		/*
@@ -600,10 +600,9 @@ static void incoming_packet(struct sasem_context *context,
 		 *   in that time and then get a false repeat of the previous
 		 *   press but it is long enough for a genuine repeat
 		 */
-		if ((ms < 250) && (context->codesaved != 0)) {
+		if ((ns < 250 * NSEC_PER_MSEC) && (context->codesaved != 0)) {
 			memcpy(buf, &context->lastcode, 8);
-			context->presstime.tv_sec = tv.tv_sec;
-			context->presstime.tv_usec = tv.tv_usec;
+			context->presstime = kt;
 		}
 	} else {
 		/* save the current valid code for repeats */
@@ -613,8 +612,7 @@ static void incoming_packet(struct sasem_context *context,
 		 * just for safety reasons
 		 */
 		context->codesaved = 1;
-		context->presstime.tv_sec = tv.tv_sec;
-		context->presstime.tv_usec = tv.tv_usec;
+		context->presstime = kt;
 	}
 
 	lirc_buffer_write(context->driver->rbuf, buf);
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 465796a686c4..35b4ce37691e 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -59,7 +59,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/serial_reg.h>
-#include <linux/time.h>
+#include <linux/ktime.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -212,7 +212,7 @@ static struct lirc_serial hardware[] = {
 
 #define RBUF_LEN 256
 
-static struct timeval lasttv = {0, 0};
+static ktime_t lastkt;
 
 static struct lirc_buffer rbuf;
 
@@ -551,10 +551,10 @@ static void frbwrite(int l)
 
 static irqreturn_t lirc_irq_handler(int i, void *blah)
 {
-	struct timeval tv;
+	ktime_t kt;
 	int counter, dcd;
 	u8 status;
-	long deltv;
+	ktime_t delkt;
 	int data;
 	static int last_dcd = -1;
 
@@ -574,7 +574,7 @@ static irqreturn_t lirc_irq_handler(int i, void *blah)
 		if ((status & hardware[type].signal_pin_change)
 		    && sense != -1) {
 			/* get current time */
-			do_gettimeofday(&tv);
+			kt = ktime_get();
 
 			/* New mode, written by Trent Piepho
 			   <xyzzy@u.washington.edu>. */
@@ -603,34 +603,20 @@ static irqreturn_t lirc_irq_handler(int i, void *blah)
 			dcd = (status & hardware[type].signal_pin) ? 1 : 0;
 
 			if (dcd == last_dcd) {
-				pr_warn("ignoring spike: %d %d %lx %lx %lx %lx\n",
-					dcd, sense,
-					tv.tv_sec, lasttv.tv_sec,
-					(unsigned long)tv.tv_usec,
-					(unsigned long)lasttv.tv_usec);
+				pr_warn("ignoring spike: %d %d %llx %llx\n",
+					dcd, sense, ktime_to_us(kt),
+					ktime_to_us(lastkt));
 				continue;
 			}
 
-			deltv = tv.tv_sec-lasttv.tv_sec;
-			if (tv.tv_sec < lasttv.tv_sec ||
-			    (tv.tv_sec == lasttv.tv_sec &&
-			     tv.tv_usec < lasttv.tv_usec)) {
-				pr_warn("AIEEEE: your clock just jumped backwards\n");
-				pr_warn("%d %d %lx %lx %lx %lx\n",
-					dcd, sense,
-					tv.tv_sec, lasttv.tv_sec,
-					(unsigned long)tv.tv_usec,
-					(unsigned long)lasttv.tv_usec);
-				data = PULSE_MASK;
-			} else if (deltv > 15) {
+			delkt = ktime_sub(kt, lastkt);
+			if (ktime_compare(delkt, ktime_set(15, 0)) > 0) {
 				data = PULSE_MASK; /* really long time */
 				if (!(dcd^sense)) {
 					/* sanity check */
-					pr_warn("AIEEEE: %d %d %lx %lx %lx %lx\n",
-						dcd, sense,
-						tv.tv_sec, lasttv.tv_sec,
-						(unsigned long)tv.tv_usec,
-						(unsigned long)lasttv.tv_usec);
+					pr_warn("AIEEEE: %d %d %llx %llx\n",
+						dcd, sense, ktime_to_us(kt),
+						ktime_to_us(lastkt));
 					/*
 					 * detecting pulse while this
 					 * MUST be a space!
@@ -638,11 +624,9 @@ static irqreturn_t lirc_irq_handler(int i, void *blah)
 					sense = sense ? 0 : 1;
 				}
 			} else
-				data = (int) (deltv*1000000 +
-					       tv.tv_usec -
-					       lasttv.tv_usec);
+				data = (int) ktime_to_us(delkt);
 			frbwrite(dcd^sense ? data : (data|PULSE_BIT));
-			lasttv = tv;
+			lastkt = kt;
 			last_dcd = dcd;
 			wake_up_interruptible(&rbuf.wait_poll);
 		}
@@ -799,7 +783,7 @@ static int set_use_inc(void *data)
 	unsigned long flags;
 
 	/* initialize timestamp */
-	do_gettimeofday(&lasttv);
+	lastkt = ktime_get();
 
 	spin_lock_irqsave(&hardware[type].lock, flags);
 
@@ -988,7 +972,7 @@ static int lirc_serial_resume(struct platform_device *dev)
 
 	spin_lock_irqsave(&hardware[type].lock, flags);
 	/* Enable Interrupt */
-	do_gettimeofday(&lasttv);
+	lastkt = ktime_get();
 	soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI);
 	off();
 
diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig
index d50de03de7b9..0b9b9b539f70 100644
--- a/drivers/staging/most/Kconfig
+++ b/drivers/staging/most/Kconfig
@@ -1,5 +1,6 @@
 menuconfig MOST
         tristate "MOST driver"
+	depends on HAS_DMA
         select MOSTCORE
         default n
         ---help---
diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c
index 0a13d8d0fa39..1a17e2af6a60 100644
--- a/drivers/staging/most/aim-cdev/cdev.c
+++ b/drivers/staging/most/aim-cdev/cdev.c
@@ -48,7 +48,6 @@ struct aim_channel {
 static struct list_head channel_list;
 static spinlock_t ch_list_lock;
 
-
 static struct aim_channel *get_channel(struct most_interface *iface, int id)
 {
 	struct aim_channel *channel, *tmp;
@@ -133,7 +132,7 @@ static int aim_close(struct inode *inode, struct file *filp)
 
 	while (0 != kfifo_out((struct kfifo *)&channel->fifo, &mbo, 1))
 		most_put_mbo(mbo);
-	if (channel->keep_mbo == true)
+	if (channel->keep_mbo)
 		most_put_mbo(channel->stacked_mbo);
 	ret = most_stop_channel(channel->iface, channel->channel_id);
 	atomic_dec(&channel->access_ref);
@@ -167,14 +166,14 @@ static ssize_t aim_write(struct file *filp, const char __user *buf,
 
 	mbo = most_get_mbo(channel->iface, channel->channel_id);
 
-	if (!mbo && channel->dev) {
+	if (!mbo) {
 		if ((filp->f_flags & O_NONBLOCK))
 			return -EAGAIN;
 		if (wait_event_interruptible(
 			    channel->wq,
 			    (mbo = most_get_mbo(channel->iface,
 						channel->channel_id)) ||
-			    (channel->dev == NULL)))
+			    (!channel->dev)))
 			return -ERESTARTSYS;
 	}
 
@@ -224,18 +223,18 @@ aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)
 	struct mbo *mbo;
 	struct aim_channel *channel = filp->private_data;
 
-	if (channel->keep_mbo == true) {
+	if (channel->keep_mbo) {
 		mbo = channel->stacked_mbo;
 		channel->keep_mbo = false;
 		goto start_copy;
 	}
 	while ((0 == kfifo_out(&channel->fifo, &mbo, 1))
-	       && (channel->dev != NULL)) {
+	       && (channel->dev)) {
 		if (filp->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 		if (wait_event_interruptible(channel->wq,
 					     (!kfifo_is_empty(&channel->fifo) ||
-					      (channel->dev == NULL))))
+					      (!channel->dev))))
 			return -ERESTARTSYS;
 	}
 
@@ -259,7 +258,7 @@ start_copy:
 
 	retval = not_copied ? proc_len - not_copied : proc_len;
 
-	if (channel->keep_mbo == true) {
+	if (channel->keep_mbo) {
 		channel->mbo_offs = retval;
 		channel->stacked_mbo = mbo;
 	} else {
@@ -300,7 +299,7 @@ static int aim_disconnect_channel(struct most_interface *iface, int channel_id)
 	}
 
 	channel = get_channel(iface, channel_id);
-	if (channel == NULL)
+	if (!channel)
 		return -ENXIO;
 
 	mutex_lock(&channel->io_mutex);
@@ -337,7 +336,7 @@ static int aim_rx_completion(struct mbo *mbo)
 		return -EINVAL;
 
 	channel = get_channel(mbo->ifp, mbo->hdm_channel_id);
-	if (channel == NULL)
+	if (!channel)
 		return -ENXIO;
 
 	kfifo_in(&channel->fifo, &mbo, 1);
@@ -370,7 +369,7 @@ static int aim_tx_completion(struct most_interface *iface, int channel_id)
 	}
 
 	channel = get_channel(iface, channel_id);
-	if (channel == NULL)
+	if (!channel)
 		return -ENXIO;
 	wake_up_interruptible(&channel->wq);
 	return 0;
@@ -413,7 +412,6 @@ static int aim_probe(struct most_interface *iface, int channel_id,
 
 	channel = kzalloc(sizeof(*channel), GFP_KERNEL);
 	if (!channel) {
-		pr_info("failed to alloc channel object\n");
 		retval = -ENOMEM;
 		goto error_alloc_channel;
 	}
diff --git a/drivers/staging/most/aim-network/networking.c b/drivers/staging/most/aim-network/networking.c
index c8ab2399faad..a1e1bce16296 100644
--- a/drivers/staging/most/aim-network/networking.c
+++ b/drivers/staging/most/aim-network/networking.c
@@ -295,7 +295,7 @@ static void most_net_rm_netdev_safe(struct net_dev_context *nd)
 
 	unregister_netdev(nd->dev);
 	free_netdev(nd->dev);
-	nd->dev = 0;
+	nd->dev = NULL;
 }
 
 static struct net_dev_context *get_net_dev_context(
diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c
index 860302eebda7..27449d20328a 100644
--- a/drivers/staging/most/aim-sound/sound.c
+++ b/drivers/staging/most/aim-sound/sound.c
@@ -486,7 +486,7 @@ static struct snd_pcm_ops pcm_ops = {
 };
 
 
-int split_arg_list(char *buf, char **card_name, char **pcm_format)
+static int split_arg_list(char *buf, char **card_name, char **pcm_format)
 {
 	*card_name = strsep(&buf, ".");
 	if (!*card_name)
@@ -497,7 +497,8 @@ int split_arg_list(char *buf, char **card_name, char **pcm_format)
 	return 0;
 }
 
-int audio_set_pcm_format(char *pcm_format, struct most_channel_config *cfg)
+static int audio_set_pcm_format(char *pcm_format,
+				struct most_channel_config *cfg)
 {
 	if (!strcmp(pcm_format, "1x8")) {
 		if (cfg->subbuffer_size != 1)
diff --git a/drivers/staging/most/aim-v4l2/Makefile b/drivers/staging/most/aim-v4l2/Makefile
index 28aa948d6609..69a7524b466c 100644
--- a/drivers/staging/most/aim-v4l2/Makefile
+++ b/drivers/staging/most/aim-v4l2/Makefile
@@ -3,4 +3,3 @@ obj-$(CONFIG_AIM_V4L2) += aim_v4l2.o
 aim_v4l2-objs := video.o
 
 ccflags-y += -Idrivers/staging/most/mostcore/
-ccflags-y += -Idrivers/media/video
diff --git a/drivers/staging/most/aim-v4l2/video.c b/drivers/staging/most/aim-v4l2/video.c
index d9687910e4a4..83332454974c 100644
--- a/drivers/staging/most/aim-v4l2/video.c
+++ b/drivers/staging/most/aim-v4l2/video.c
@@ -430,7 +430,7 @@ static struct most_video_dev *get_aim_dev(
 		}
 	}
 	spin_unlock(&list_lock);
-	return 0;
+	return NULL;
 }
 
 static int aim_rx_data(struct mbo *mbo)
diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
index a54cf2cedac3..e334206e2eb0 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
@@ -912,8 +912,3 @@ bool DIM_DetachBuffers(struct dim_channel *ch, u16 buffers_number)
 
 	return channel_detach_buffers(ch, buffers_number);
 }
-
-u32 DIM_ReadRegister(u8 register_index)
-{
-	return DIMCB_IoRead((u32 *)g.dim2 + register_index);
-}
diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h
index 8929af9712ef..ebb7d87a45fc 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hal.h
+++ b/drivers/staging/most/hdm-dim2/dim2_hal.h
@@ -105,17 +105,12 @@ bool DIM_EnqueueBuffer(struct dim_channel *ch, u32 buffer_addr,
 
 bool DIM_DetachBuffers(struct dim_channel *ch, u16 buffers_number);
 
-u32 DIM_ReadRegister(u8 register_index);
-
-
 u32 DIMCB_IoRead(u32 *ptr32);
 
 void DIMCB_IoWrite(u32 *ptr32, u32 value);
 
 void DIMCB_OnError(u8 error_id, const char *error_message);
 
-void DIMCB_OnFail(const char *filename, int linenum);
-
 
 #ifdef __cplusplus
 }
diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
index 6a5a3a2775f3..4481a0be15b9 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
@@ -166,16 +166,6 @@ void DIMCB_OnError(u8 error_id, const char *error_message)
 }
 
 /**
- * DIMCB_OnFail - callback from HAL to report unrecoverable errors
- * @filename: Source file where the error happened
- * @linenum: Line number of the file where the error happened
- */
-void DIMCB_OnFail(const char *filename, int linenum)
-{
-	pr_err("DIMCB_OnFail: file - %s, line no. - %d\n", filename, linenum);
-}
-
-/**
  * startup_dim - initialize the dim2 interface
  * @pdev: platform device
  *
@@ -248,7 +238,7 @@ static int try_start_dim_transfer(struct hdm_channel *hdm_ch)
 	unsigned long flags;
 	struct dim_ch_state_t st;
 
-	BUG_ON(hdm_ch == 0);
+	BUG_ON(!hdm_ch);
 	BUG_ON(!hdm_ch->is_initialized);
 
 	spin_lock_irqsave(&dim_lock, flags);
@@ -346,7 +336,7 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx)
 	unsigned long flags;
 	u8 *data;
 
-	BUG_ON(hdm_ch == 0);
+	BUG_ON(!hdm_ch);
 	BUG_ON(!hdm_ch->is_initialized);
 
 	spin_lock_irqsave(&dim_lock, flags);
@@ -419,7 +409,7 @@ static struct dim_channel **get_active_channels(struct dim2_hdm *dev,
 		if (dev->hch[ch_idx].is_initialized)
 			buffer[idx++] = &dev->hch[ch_idx].ch;
 	}
-	buffer[idx++] = 0;
+	buffer[idx++] = NULL;
 
 	return buffer;
 }
@@ -915,7 +905,7 @@ static int dim2_remove(struct platform_device *pdev)
 	 * break link to local platform_device_id struct
 	 * to prevent crash by unload platform device module
 	 */
-	pdev->id_entry = 0;
+	pdev->id_entry = NULL;
 
 	return 0;
 }
@@ -933,7 +923,6 @@ static struct platform_driver dim2_driver = {
 	.id_table = dim2_id,
 	.driver = {
 		.name = "hdm_dim2",
-		.owner = THIS_MODULE,
 	},
 };
 
diff --git a/drivers/staging/most/hdm-usb/Kconfig b/drivers/staging/most/hdm-usb/Kconfig
index a482c3fdf34b..ec1546312ee6 100644
--- a/drivers/staging/most/hdm-usb/Kconfig
+++ b/drivers/staging/most/hdm-usb/Kconfig
@@ -4,7 +4,7 @@
 
 config HDM_USB
 	tristate "USB HDM"
-	depends on USB
+	depends on USB && NET
 	select AIM_NETWORK
 	---help---
 	  Say Y here if you want to connect via USB to network tranceiver.
diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c
index 305303f2f17c..9bbefaaa0134 100644
--- a/drivers/staging/most/hdm-usb/hdm_usb.c
+++ b/drivers/staging/most/hdm-usb/hdm_usb.c
@@ -308,7 +308,7 @@ static int hdm_poison_channel(struct most_interface *iface, int channel)
 
 	mutex_lock(&mdev->io_mutex);
 	free_anchored_buffers(mdev, channel);
-	if (mdev->padding_active[channel] == true)
+	if (mdev->padding_active[channel])
 		mdev->padding_active[channel] = false;
 
 	if (mdev->conf[channel].data_type == MOST_CH_ASYNC) {
@@ -411,7 +411,7 @@ static void hdm_write_completion(struct urb *urb)
 	dev = &mdev->usb_device->dev;
 
 	if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
-	    (mdev->is_channel_healthy[channel] == false)) {
+	    (!mdev->is_channel_healthy[channel])) {
 		complete(&anchor->urb_compl);
 		return;
 	}
@@ -568,7 +568,6 @@ static void hdm_read_completion(struct urb *urb)
 	struct device *dev;
 	unsigned long flags;
 	unsigned int channel;
-	struct most_channel_config *conf;
 
 	mbo = urb->context;
 	anchor = mbo->priv;
@@ -577,13 +576,11 @@ static void hdm_read_completion(struct urb *urb)
 	dev = &mdev->usb_device->dev;
 
 	if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
-	    (mdev->is_channel_healthy[channel] == false)) {
+	    (!mdev->is_channel_healthy[channel])) {
 		complete(&anchor->urb_compl);
 		return;
 	}
 
-	conf = &mdev->conf[channel];
-
 	if (unlikely(urb->status && !(urb->status == -ENOENT ||
 				      urb->status == -ECONNRESET ||
 				      urb->status == -ESHUTDOWN))) {
@@ -608,7 +605,7 @@ static void hdm_read_completion(struct urb *urb)
 		}
 	} else {
 		mbo->processed_length = urb->actual_length;
-		if (mdev->padding_active[channel] == false) {
+		if (!mdev->padding_active[channel]) {
 			mbo->status = MBO_SUCCESS;
 		} else {
 			if (hdm_remove_padding(mdev, channel, mbo)) {
@@ -688,7 +685,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mb
 	list_add_tail(&anchor->list, &mdev->anchor_list[channel]);
 	spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
 
-	if ((mdev->padding_active[channel] == true) &&
+	if ((mdev->padding_active[channel]) &&
 	    (conf->direction & MOST_CH_TX))
 		if (hdm_add_padding(mdev, channel, mbo)) {
 			retval = -EIO;
diff --git a/drivers/staging/most/mostcore/Kconfig b/drivers/staging/most/mostcore/Kconfig
index 38abf1b21b66..47172546d728 100644
--- a/drivers/staging/most/mostcore/Kconfig
+++ b/drivers/staging/most/mostcore/Kconfig
@@ -4,6 +4,7 @@
 
 config MOSTCORE
 	tristate "MOST Core"
+	depends on HAS_DMA
 
 	---help---
 	  Say Y here if you want to enable MOST support.
diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
index 7bb16db42893..eb4e15938875 100644
--- a/drivers/staging/most/mostcore/core.c
+++ b/drivers/staging/most/mostcore/core.c
@@ -190,8 +190,7 @@ static void flush_channel_fifos(struct most_c_obj *c)
 	list_for_each_entry_safe(mbo, tmp, &c->fifo, list) {
 		list_del(&mbo->list);
 		spin_unlock_irqrestore(&c->fifo_lock, flags);
-		if (likely(mbo))
-			most_free_mbo_coherent(mbo);
+		most_free_mbo_coherent(mbo);
 		spin_lock_irqsave(&c->fifo_lock, flags);
 	}
 	spin_unlock_irqrestore(&c->fifo_lock, flags);
@@ -200,8 +199,7 @@ static void flush_channel_fifos(struct most_c_obj *c)
 	list_for_each_entry_safe(mbo, tmp, &c->halt_fifo, list) {
 		list_del(&mbo->list);
 		spin_unlock_irqrestore(&c->fifo_lock, hf_flags);
-		if (likely(mbo))
-			most_free_mbo_coherent(mbo);
+		most_free_mbo_coherent(mbo);
 		spin_lock_irqsave(&c->fifo_lock, hf_flags);
 	}
 	spin_unlock_irqrestore(&c->fifo_lock, hf_flags);
@@ -1341,7 +1339,7 @@ static void most_write_completion(struct mbo *mbo)
 	c = mbo->context;
 	if (mbo->status == MBO_E_INVAL)
 		pr_info("WARN: Tx MBO status: invalid\n");
-	if (unlikely((c->is_poisoned == true) || (mbo->status == MBO_E_CLOSE)))
+	if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE)))
 		trash_mbo(mbo);
 	else
 		arm_mbo(mbo);
@@ -1446,7 +1444,7 @@ static void most_read_completion(struct mbo *mbo)
 	struct most_c_obj *c;
 
 	c = mbo->context;
-	if (unlikely((c->is_poisoned == true) || (mbo->status == MBO_E_CLOSE)))
+	if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE)))
 		goto release_mbo;
 
 	if (mbo->status == MBO_E_INVAL) {
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index ad30ce4206ef..1aa449e5fecf 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -941,6 +941,7 @@ static const struct of_device_id spinand_dt[] = {
 	{ .compatible = "spinand,mt29f", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, spinand_dt);
 
 /*
  * Device name structure description
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index 9bd73ea5a1fa..61940284311c 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -3743,6 +3743,7 @@ static const struct of_device_id octeon_usb_match[] = {
 	},
 	{},
 };
+MODULE_DEVICE_TABLE(of, octeon_usb_match);
 
 static struct platform_driver octeon_usb_driver = {
 	.driver = {
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 3e9ee7ee6be2..498d6233648f 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -909,8 +909,10 @@ static void lcd_gotoxy(void)
 {
 	lcd_write_cmd(LCD_CMD_SET_DDRAM_ADDR
 		      | (lcd.addr.y ? lcd.hwidth : 0)
-		      /* we force the cursor to stay at the end of the
-			 line if it wants to go farther */
+		      /*
+		       * we force the cursor to stay at the end of the
+		       * line if it wants to go farther
+		       */
 		      | ((lcd.addr.x < lcd.bwidth) ? lcd.addr.x &
 			 (lcd.hwidth - 1) : lcd.bwidth - 1));
 }
@@ -1294,8 +1296,10 @@ static inline int handle_lcd_special_code(void)
 			if (lcd.flags & (LCD_FLAG_L))
 				lcd_backlight(1);
 			else if (lcd.light_tempo == 0)
-				/* switch off the light only when the tempo
-				   lighting is gone */
+				/*
+				 * switch off the light only when the tempo
+				 * lighting is gone
+				 */
 				lcd_backlight(0);
 		}
 	}
@@ -1323,8 +1327,10 @@ static void lcd_write_char(char c)
 		case '\b':
 			/* go back one char and clear it */
 			if (lcd.addr.x > 0) {
-				/* check if we're not at the
-				   end of the line */
+				/*
+				 * check if we're not at the
+				 * end of the line
+				 */
 				if (lcd.addr.x < lcd.bwidth)
 					/* back one char */
 					lcd_write_cmd(LCD_CMD_SHIFT);
@@ -1340,8 +1346,10 @@ static void lcd_write_char(char c)
 			lcd_clear_fast();
 			break;
 		case '\n':
-			/* flush the remainder of the current line and
-			   go to the beginning of the next line */
+			/*
+			 * flush the remainder of the current line and
+			 * go to the beginning of the next line
+			 */
 			for (; lcd.addr.x < lcd.bwidth; lcd.addr.x++)
 				lcd_write_data(' ');
 			lcd.addr.x = 0;
@@ -1364,8 +1372,10 @@ static void lcd_write_char(char c)
 		}
 	}
 
-	/* now we'll see if we're in an escape mode and if the current
-	   escape sequence can be understood. */
+	/*
+	 * now we'll see if we're in an escape mode and if the current
+	 * escape sequence can be understood.
+	 */
 	if (lcd.esc_seq.len >= 2) {
 		int processed = 0;
 
@@ -1388,8 +1398,10 @@ static void lcd_write_char(char c)
 		}
 
 		/* LCD special escape codes */
-		/* flush the escape sequence if it's been processed
-		   or if it is getting too long. */
+		/*
+		 * flush the escape sequence if it's been processed
+		 * or if it is getting too long.
+		 */
 		if (processed || (lcd.esc_seq.len >= LCD_ESCAPE_LEN))
 			lcd.esc_seq.len = -1;
 	} /* escape codes */
@@ -1403,8 +1415,10 @@ static ssize_t lcd_write(struct file *file,
 
 	for (; count-- > 0; (*ppos)++, tmp++) {
 		if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
-			/* let's be a little nice with other processes
-			   that need some CPU */
+			/*
+			 * let's be a little nice with other processes
+			 * that need some CPU
+			 */
 			schedule();
 
 		if (get_user(c, tmp))
@@ -1459,8 +1473,10 @@ static void panel_lcd_print(const char *s)
 	if (lcd.enabled && lcd.initialized) {
 		for (; count-- > 0; tmp++) {
 			if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
-				/* let's be a little nice with other processes
-				   that need some CPU */
+				/*
+				 * let's be a little nice with other processes
+				 * that need some CPU
+				 */
 				schedule();
 
 			lcd_write_char(*tmp);
@@ -1634,9 +1650,11 @@ static void lcd_init(void)
 	pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
 		    lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
 
-	/* before this line, we must NOT send anything to the display.
+	/*
+	 * before this line, we must NOT send anything to the display.
 	 * Since lcd_init_display() needs to write data, we have to
-	 * enable mark the LCD initialized just before. */
+	 * enable mark the LCD initialized just before.
+	 */
 	lcd.initialized = true;
 	lcd_init_display();
 
@@ -1770,7 +1788,8 @@ static void phys_scan_contacts(void)
 	phys_read |= (pmask_t) gndmask << 40;
 
 	if (bitmask != gndmask) {
-		/* since clearing the outputs changed some inputs, we know
+		/*
+		 * since clearing the outputs changed some inputs, we know
 		 * that some input signals are currently tied to some outputs.
 		 * So we'll scan them.
 		 */
@@ -1786,8 +1805,10 @@ static void phys_scan_contacts(void)
 		}
 		w_dtr(pprt, oldval);	/* disable all outputs */
 	}
-	/* this is easy: use old bits when they are flapping,
-	 * use new ones when stable */
+	/*
+	 * this is easy: use old bits when they are flapping,
+	 * use new ones when stable
+	 */
 	phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) |
 		    (phys_read & ~(phys_read ^ phys_read_prev));
 }
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index 935b48eef8b1..5dae7de03327 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -5384,9 +5384,8 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
 
 			cam_id = psta->mac_id + 3;/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
 
-			DBG_88E("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
-				pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
-				pparm->addr[5], cam_id);
+			DBG_88E("Write CAM, mac_addr =%pM, cam_entry=%d\n",
+				pparm->addr, cam_id);
 
 			write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
 
diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index b340e4a9d540..497fb068fdc8 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -273,7 +273,7 @@ u32	rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
 	struct	sta_priv *pstapriv = &padapter->stapriv;
 
 
-	if (psta == NULL)
+	if (!psta)
 		goto exit;
 
 	pfree_sta_queue = &pstapriv->free_sta_queue;
@@ -433,7 +433,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
 
-	if (hwaddr == NULL)
+	if (!hwaddr)
 		return NULL;
 
 	if (IS_MCAST(hwaddr))
@@ -473,7 +473,7 @@ u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
 
 	psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
 
-	if (psta == NULL) {
+	if (!psta) {
 		res = _FAIL;
 		RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
 		goto exit;
diff --git a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
index 2633a13b4e58..a108e8032327 100644
--- a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
@@ -127,7 +127,7 @@ static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm,
 
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 			ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n"));
-	if (NULL == pRaInfo) {
+	if (!pRaInfo) {
 		ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 				("odm_RateDown_8188E(): pRaInfo is NULL\n"));
 		return -1;
@@ -193,7 +193,7 @@ static int odm_RateUp_8188E(
 
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 			ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n"));
-	if (NULL == pRaInfo) {
+	if (!pRaInfo) {
 		ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 				("odm_RateUp_8188E(): pRaInfo is NULL\n"));
 		return -1;
@@ -624,7 +624,7 @@ int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm)
 
 u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 {
-	if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
+	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 		return 0;
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 		     ("macid =%d SGI =%d\n", macid, dm_odm->RAInfo[macid].RateSGI));
@@ -635,7 +635,7 @@ u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 {
 	u8 DecisionRate = 0;
 
-	if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
+	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 		return 0;
 	DecisionRate = dm_odm->RAInfo[macid].DecisionRate;
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
@@ -647,7 +647,7 @@ u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 {
 	u8 PTStage = 5;
 
-	if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
+	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 		return 0;
 	PTStage = dm_odm->RAInfo[macid].PTStage;
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
@@ -659,7 +659,7 @@ void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rate
 {
 	struct odm_ra_info *pRaInfo = NULL;
 
-	if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
+	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 		return;
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 		     ("macid =%d RateID = 0x%x RateMask = 0x%x SGIEnable =%d\n",
@@ -676,7 +676,7 @@ void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi)
 {
 	struct odm_ra_info *pRaInfo = NULL;
 
-	if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
+	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 		return;
 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 		     (" macid =%d Rssi =%d\n", macid, Rssi));
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 0a62bfa210fe..d5281409168d 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -467,7 +467,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 
 	DBG_88E("%s\n", __func__);
 	ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
-	if (ReservedPagePacket == NULL) {
+	if (!ReservedPagePacket) {
 		DBG_88E("%s: alloc ReservedPagePacket fail!\n", __func__);
 		return;
 	}
@@ -537,7 +537,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 
 	TotalPacketLen = BufIndex + QosNullLength;
 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
-	if (pmgntframe == NULL)
+	if (!pmgntframe)
 		goto exit;
 
 	/*  update attribute */
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
index 06d1e654483e..d6d009aafcf0 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
@@ -43,7 +43,7 @@ int	rtl8188eu_init_recv_priv(struct adapter *padapter)
 
 	precvpriv->pallocated_recv_buf =
 		kcalloc(NR_RECVBUFF, sizeof(struct recv_buf), GFP_KERNEL);
-	if (precvpriv->pallocated_recv_buf == NULL) {
+	if (!precvpriv->pallocated_recv_buf) {
 		res = _FAIL;
 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 				("alloc recv_buf fail!\n"));
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
index 594c1da9db23..44335605f2f6 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
@@ -649,7 +649,7 @@ static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
 		goto enqueue;
 
 	pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
-	if (pxmitbuf == NULL)
+	if (!pxmitbuf)
 		goto enqueue;
 
 	spin_unlock_bh(&pxmitpriv->lock);
diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h
index dba8af1ec41e..6e5fa735e800 100644
--- a/drivers/staging/rtl8188eu/include/wifi.h
+++ b/drivers/staging/rtl8188eu/include/wifi.h
@@ -27,11 +27,7 @@
 #endif
 #define BIT(x)	(1 << (x))
 
-
-#define WLAN_ETHHDR_LEN		14
-#define WLAN_ETHADDR_LEN	6
 #define WLAN_IEEE_OUI_LEN	3
-#define WLAN_ADDR_LEN		6
 #define WLAN_CRC_LEN		4
 #define WLAN_BSSID_LEN		6
 #define WLAN_BSS_TS_LEN		8
@@ -47,7 +43,6 @@
 
 #define WLAN_MIN_ETHFRM_LEN	60
 #define WLAN_MAX_ETHFRM_LEN	1514
-#define WLAN_ETHHDR_LEN		14
 
 #define P80211CAPTURE_VERSION	0x80211001
 
diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
index 218adaa574b5..eb8ecb7fbd16 100644
--- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
@@ -152,7 +152,7 @@ void rtw_indicate_sta_assoc_event(struct adapter *padapter, struct sta_info *pst
 	union iwreq_data wrqu;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 
-	if (psta == NULL)
+	if (!psta)
 		return;
 
 	if (psta->aid > NUM_STA)
@@ -176,7 +176,7 @@ void rtw_indicate_sta_disassoc_event(struct adapter *padapter, struct sta_info *
 	union iwreq_data wrqu;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 
-	if (psta == NULL)
+	if (!psta)
 		return;
 
 	if (psta->aid > NUM_STA)
diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
index acb4eb120b76..466cd76fc1c4 100644
--- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c
+++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
@@ -52,7 +52,7 @@ void *rtw_malloc2d(int h, int w, int size)
 	int j;
 
 	void **a = kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL);
-	if (a == NULL) {
+	if (!a) {
 		pr_info("%s: alloc memory fail!\n", __func__);
 		return NULL;
 	}
diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
index 3ebb8b206e46..d4734baffc8a 100644
--- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
@@ -94,7 +94,7 @@ int rtw_recv_indicatepkt(struct adapter *padapter,
 	pfree_recv_queue = &(precvpriv->free_recv_queue);
 
 	skb = precv_frame->pkt;
-	if (skb == NULL) {
+	if (!skb) {
 		RT_TRACE(_module_recv_osdep_c_, _drv_err_,
 			 ("rtw_recv_indicatepkt():skb == NULL something wrong!!!!\n"));
 		goto _recv_indicatepkt_drop;
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
index c28cabc23fc0..353e3fedb79e 100644
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
@@ -108,7 +108,6 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
 	case HW_VAR_MEDIA_STATUS:
 	{
 		enum rt_op_mode OpMode = *((enum rt_op_mode *)(val));
-		enum led_ctl_mode LedAction = LED_CTL_NO_LINK;
 		u8 btMsr = rtl92e_readb(dev, MSR);
 
 		btMsr &= 0xfc;
@@ -116,7 +115,6 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
 		switch (OpMode) {
 		case RT_OP_MODE_INFRASTRUCTURE:
 			btMsr |= MSR_INFRA;
-			LedAction = LED_CTL_LINK;
 			break;
 
 		case RT_OP_MODE_IBSS:
@@ -125,7 +123,6 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
 
 		case RT_OP_MODE_AP:
 			btMsr |= MSR_AP;
-			LedAction = LED_CTL_LINK;
 			break;
 
 		default:
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index d6b46dfd01e1..52e1e27cb7b0 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -1131,7 +1131,6 @@ static enum reset_type rtl819x_TxCheckStuck(struct net_device *dev)
 {
 	struct r8192_priv *priv = rtllib_priv(dev);
 	u8	QueueID;
-	u8	ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
 	bool	bCheckFwTxCnt = false;
 	struct rtl8192_tx_ring  *ring = NULL;
 	struct sk_buff *skb = NULL;
@@ -1140,13 +1139,10 @@ static enum reset_type rtl819x_TxCheckStuck(struct net_device *dev)
 
 	switch (priv->rtllib->ps) {
 	case RTLLIB_PS_DISABLED:
-		ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
 		break;
 	case (RTLLIB_PS_MBCAST|RTLLIB_PS_UNICAST):
-		ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
 		break;
 	default:
-		ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
 		break;
 	}
 	spin_lock_irqsave(&priv->irq_th_lock, flags);
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
index 7e3ca7ef997b..7e5613774a52 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
@@ -334,10 +334,9 @@ static int rtl8192_wx_get_range(struct net_device *dev,
 	/* ~130 Mb/s real (802.11n) */
 	range->throughput = 130 * 1000 * 1000;
 
-	if (priv->rf_set_sens != NULL) {
+	if (priv->rf_set_sens != NULL)
 		/* signal level threshold range */
 		range->sensitivity = priv->max_sens;
-	}
 
 	range->max_qual.qual = 100;
 	range->max_qual.level = 0;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
index 31233d895ee9..425b2ddfc916 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
@@ -48,7 +48,7 @@
 #include <linux/types.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <net/arp.h>
 
 #include "ieee80211.h"
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index 39e9892c3fa6..e4624e886007 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -19,7 +19,7 @@
 #include <linux/random.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/etherdevice.h>
 
 #include "dot11d.h"
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
index 3e502520648e..5b6cf0b12d09 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
@@ -32,7 +32,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
 			     union iwreq_data *wrqu, char *b)
 {
 	int ret;
-	struct iw_freq *fwrq = & wrqu->freq;
+	struct iw_freq *fwrq = &wrqu->freq;
 
 	down(&ieee->wx_sem);
 
@@ -57,11 +57,11 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
 		}
 	}
 
-	if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
+	if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
 		ret = -EOPNOTSUPP;
 		goto out;
 
-	}else { /* Set the channel */
+	} else { /* Set the channel */
 
 		if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
 			ret = -EINVAL;
@@ -71,7 +71,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
 		ieee->set_chan(ieee->dev, ieee->current_network.channel);
 
 		if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
-			if(ieee->state == IEEE80211_LINKED){
+			if(ieee->state == IEEE80211_LINKED) {
 
 			ieee80211_stop_send_beacons(ieee);
 			ieee80211_start_send_beacons(ieee);
@@ -89,7 +89,7 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
 			     struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b)
 {
-	struct iw_freq *fwrq = & wrqu->freq;
+	struct iw_freq *fwrq = &wrqu->freq;
 
 	if (ieee->current_network.channel == 0)
 		return -1;
@@ -191,14 +191,14 @@ EXPORT_SYMBOL(ieee80211_wx_set_wap);
 	spin_lock_irqsave(&ieee->lock, flags);
 
 	if (ieee->current_network.ssid[0] == '\0' ||
-		ieee->current_network.ssid_len == 0){
+		ieee->current_network.ssid_len == 0) {
 		ret = -1;
 		goto out;
 	}
 
 	if (ieee->state != IEEE80211_LINKED &&
 		ieee->state != IEEE80211_LINKED_SCANNING &&
-		ieee->ssid_set == 0){
+		ieee->ssid_set == 0) {
 		ret = -1;
 		goto out;
 	}
@@ -280,16 +280,16 @@ int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info
 	if (wrqu->mode == ieee->iw_mode)
 		goto out;
 
-	if (wrqu->mode == IW_MODE_MONITOR){
+	if (wrqu->mode == IW_MODE_MONITOR) {
 
 		ieee->dev->type = ARPHRD_IEEE80211;
-	}else{
+	} else {
 		ieee->dev->type = ARPHRD_ETHER;
 	}
 
-	if (!ieee->proto_started){
+	if (!ieee->proto_started) {
 		ieee->iw_mode = wrqu->mode;
-	}else{
+	} else {
 		ieee80211_stop_protocol(ieee);
 		ieee->iw_mode = wrqu->mode;
 		ieee80211_start_protocol(ieee);
@@ -308,7 +308,6 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 	HT_EXTCHNL_OFFSET chan_offset=0;
 	HT_CHANNEL_WIDTH bandwidth=0;
 	int b40M = 0;
-	static int count;
 	chan = ieee->current_network.channel;
 	netif_carrier_off(ieee->dev);
 
@@ -345,7 +344,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 	ieee->state = IEEE80211_LINKED;
 	ieee->link_change(ieee->dev);
 	// To prevent the immediately calling watch_dog after scan.
-	if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0)
 	{
 		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
 		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
@@ -357,7 +356,6 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 		ieee80211_start_send_beacons(ieee);
 
 	netif_carrier_on(ieee->dev);
-	count = 0;
 	up(&ieee->wx_sem);
 
 }
@@ -426,7 +424,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
 		ieee->current_network.ssid_len = len+1;
 		ieee->ssid_set = 1;
 	}
-	else{
+	else {
 		ieee->ssid_set = 0;
 		ieee->current_network.ssid[0] = '\0';
 		ieee->current_network.ssid_len = 0;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
index fff8d583c62f..1ab0aead298b 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -48,7 +48,7 @@
 #include <linux/types.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/if_vlan.h>
 
 #include "ieee80211.h"
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
index 785fd027a00d..a76748e3b506 100644
--- a/drivers/staging/rtl8192u/r8192U.h
+++ b/drivers/staging/rtl8192u/r8192U.h
@@ -335,11 +335,11 @@ typedef struct _tx_fwinfo_819x_usb {
 	u32	PacketID:13;
 } tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
 
-typedef struct rtl8192_rx_info {
+struct rtl8192_rx_info {
 	struct urb *urb;
 	struct net_device *dev;
 	u8 out_pipe;
-} rtl8192_rx_info ;
+};
 
 typedef struct rx_desc_819x_usb {
 	/* DOWRD 0 */
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 6f6fe38081bc..b143b36eb57d 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -37,17 +37,17 @@ unsigned int __fixunsdfsi(double d)
 
 double __adddf3(double a, double b)
 {
-	return a+b;
+	return a + b;
 }
 
 double __addsf3(float a, float b)
 {
-	return a+b;
+	return a + b;
 }
 
 double __subdf3(double a, double b)
 {
-	return a-b;
+	return a - b;
 }
 
 double __extendsfdf2(float a)
@@ -58,13 +58,13 @@ double __extendsfdf2(float a)
 
 #define CONFIG_RTL8192_IO_MAP
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "r8192U_hw.h"
 #include "r8192U.h"
 #include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
 #include "r8180_93cx6.h"   /* Card EEPROM */
 #include "r8192U_wx.h"
-#include "r819xU_phy.h" //added by WB 4.30.2008
+#include "r819xU_phy.h"
 #include "r819xU_phyreg.h"
 #include "r819xU_cmdpkt.h"
 #include "r8192U_dm.h"
@@ -72,13 +72,13 @@ double __extendsfdf2(float a)
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-// FIXME: check if 2.6.7 is ok
+/* FIXME: check if 2.6.7 is ok */
 
 #include "dot11d.h"
-//set here to open your trace code. //WB
+/* set here to open your trace code. */
 u32 rt_global_debug_component = COMP_DOWN	|
 				COMP_SEC	|
-				COMP_ERR; //always open err flags on
+				COMP_ERR; /* always open err flags on */
 
 #define TOTAL_CAM_ENTRY 32
 #define CAM_CONTENT_COUNT 8
@@ -109,14 +109,14 @@ MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
 
 static char *ifname = "wlan%d";
-static int hwwep = 1;  //default use hw. set 0 to use software security
+static int hwwep = 1;  /* default use hw. set 0 to use software security */
 static int channels = 0x3fff;
 
 
 
-module_param(ifname, charp, S_IRUGO|S_IWUSR);
-module_param(hwwep, int, S_IRUGO|S_IWUSR);
-module_param(channels, int, S_IRUGO|S_IWUSR);
+module_param(ifname, charp, S_IRUGO | S_IWUSR);
+module_param(hwwep, int, S_IRUGO | S_IWUSR);
+module_param(channels, int, S_IRUGO | S_IWUSR);
 
 MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
 MODULE_PARM_DESC(hwwep, " Try to use hardware security support. ");
@@ -143,23 +143,24 @@ struct CHANNEL_LIST {
 };
 
 static struct CHANNEL_LIST ChannelPlan[] = {
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24},		//FCC
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},							//IC
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	//ETSI
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},    //Spain. Change to ETSI.
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},	//France. Change to ETSI.
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},	//MKK					//MKK
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},//MKK1
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},	//Israel.
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},			// For 11a , TELEC
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},    //MIC
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}					//For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24},	/* FCC */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},								/* IC */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},			/* ETSI */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},							/* Spain. Change to ETSI. */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},							/* France. Change to ETSI. */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},			/* MKK */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},			/* MKK1 */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},							/* Israel. */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},			/* For 11a , TELEC */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},			/* MIC */
+	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}	/* For Global Domain. 1-11:active scan, 12-14 passive scan. */
 };
 
 static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
 {
 	int i, max_chan = -1, min_chan = -1;
 	struct ieee80211_device *ieee = priv->ieee80211;
+
 	switch (channel_plan) {
 	case COUNTRY_CODE_FCC:
 	case COUNTRY_CODE_IC:
@@ -173,7 +174,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
 	case COUNTRY_CODE_MIC:
 		Dot11d_Init(ieee);
 		ieee->bGlobalDomain = false;
-		//actually 8225 & 8256 rf chips only support B,G,24N mode
+		/* actually 8225 & 8256 rf chips only support B,G,24N mode */
 		if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) {
 			min_chan = 1;
 			max_chan = 14;
@@ -181,9 +182,9 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
 			RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __func__);
 		}
 		if (ChannelPlan[channel_plan].Len != 0) {
-			// Clear old channel map
+			/* Clear old channel map */
 			memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
-			// Set new channel map
+			/* Set new channel map */
 			for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
 				if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
 					break;
@@ -193,7 +194,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
 		break;
 
 	case COUNTRY_CODE_GLOBAL_DOMAIN:
-		GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
+		GET_DOT11D_INFO(ieee)->bEnabled = 0; /* this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings. */
 		Dot11d_Reset(ieee);
 		ieee->bGlobalDomain = true;
 		break;
@@ -209,10 +210,11 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
 static void CamResetAllEntry(struct net_device *dev)
 {
 	u32 ulcommand = 0;
-	//2004/02/11  In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
-	// However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
-	// In this condition, Cam can not be reset because upper layer will not set this static key again.
-	ulcommand |= BIT31|BIT30;
+	/* 2004/02/11  In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
+	 *  However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
+	 *  In this condition, Cam can not be reset because upper layer will not set this static key again.
+	 */
+	ulcommand |= BIT31 | BIT30;
 	write_nic_dword(dev, RWCAM, ulcommand);
 
 }
@@ -221,14 +223,14 @@ static void CamResetAllEntry(struct net_device *dev)
 void write_cam(struct net_device *dev, u8 addr, u32 data)
 {
 	write_nic_dword(dev, WCAMI, data);
-	write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff));
+	write_nic_dword(dev, RWCAM, BIT31 | BIT16 | (addr & 0xff));
 }
 
 u32 read_cam(struct net_device *dev, u8 addr)
 {
 	u32 data;
 
-	write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff));
+	write_nic_dword(dev, RWCAM, 0x80000000 | (addr & 0xff));
 	read_nic_dword(dev, 0xa8, &data);
 	return data;
 }
@@ -241,7 +243,7 @@ void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-				 indx|0xfe00, 0, &data, 1, HZ / 2);
+				 indx | 0xfe00, 0, &data, 1, HZ / 2);
 
 	if (status < 0)
 		netdev_err(dev, "write_nic_byte_E TimeOut! status: %d\n", status);
@@ -255,7 +257,7 @@ int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-				 indx|0xfe00, 0, data, 1, HZ / 2);
+				 indx | 0xfe00, 0, data, 1, HZ / 2);
 
 	if (status < 0) {
 		netdev_err(dev, "%s failure status: %d\n", __func__, status);
@@ -264,7 +266,7 @@ int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
 
 	return 0;
 }
-//as 92U has extend page from 4 to 16, so modify functions below.
+/* as 92U has extend page from 4 to 16, so modify functions below. */
 void write_nic_byte(struct net_device *dev, int indx, u8 data)
 {
 	int status;
@@ -274,7 +276,7 @@ void write_nic_byte(struct net_device *dev, int indx, u8 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, &data, 1, HZ / 2);
 
 	if (status < 0)
 		netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
@@ -293,7 +295,7 @@ void write_nic_word(struct net_device *dev, int indx, u16 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, &data, 2, HZ / 2);
 
 	if (status < 0)
 		netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
@@ -311,7 +313,7 @@ void write_nic_dword(struct net_device *dev, int indx, u32 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, &data, 4, HZ / 2);
 
 
 	if (status < 0)
@@ -329,7 +331,7 @@ int read_nic_byte(struct net_device *dev, int indx, u8 *data)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f, data, 1, HZ / 2);
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, data, 1, HZ / 2);
 
 	if (status < 0) {
 		netdev_err(dev, "%s failure status: %d\n", __func__, status);
@@ -349,7 +351,7 @@ int read_nic_word(struct net_device *dev, int indx, u16 *data)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f,
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
 				 data, 2, HZ / 2);
 
 	if (status < 0) {
@@ -368,7 +370,7 @@ static int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-				 indx|0xfe00, 0, data, 2, HZ / 2);
+				 indx | 0xfe00, 0, data, 2, HZ / 2);
 
 	if (status < 0) {
 		netdev_err(dev, "%s failure status: %d\n", __func__, status);
@@ -387,7 +389,7 @@ int read_nic_dword(struct net_device *dev, int indx, u32 *data)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-				 (indx&0xff)|0xff00, (indx>>8)&0x0f,
+				 (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
 				 data, 4, HZ / 2);
 
 	if (status < 0) {
@@ -427,6 +429,7 @@ static int proc_get_stats_ap(struct seq_file *m, void *v)
 
 	list_for_each_entry(target, &ieee->network_list, list) {
 		const char *wpa = "non_WPA";
+
 		if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
 			wpa = "WPA";
 
@@ -448,7 +451,7 @@ static int proc_get_registers(struct seq_file *m, void *v)
 		seq_printf(m, "\nD:  %2x > ", n);
 
 		for (i = 0; i < 16 && n <= max; i++, n++) {
-			read_nic_byte(dev, 0x000|n, &byte_rd);
+			read_nic_byte(dev, 0x000 | n, &byte_rd);
 			seq_printf(m, "%2x ", byte_rd);
 		}
 	}
@@ -458,7 +461,7 @@ static int proc_get_registers(struct seq_file *m, void *v)
 		seq_printf(m, "\nD:  %2x > ", n);
 
 		for (i = 0; i < 16 && n <= max; i++, n++) {
-			read_nic_byte(dev, 0x100|n, &byte_rd);
+			read_nic_byte(dev, 0x100 | n, &byte_rd);
 			seq_printf(m, "%2x ", byte_rd);
 		}
 	}
@@ -468,7 +471,7 @@ static int proc_get_registers(struct seq_file *m, void *v)
 		seq_printf(m, "\nD:  %2x > ", n);
 
 		for (i = 0; i < 16 && n <= max; i++, n++) {
-			read_nic_byte(dev, 0x300|n, &byte_rd);
+			read_nic_byte(dev, 0x300 | n, &byte_rd);
 			seq_printf(m, "%2x ", byte_rd);
 		}
 	}
@@ -608,8 +611,8 @@ static void rtl8192_proc_init_one(struct net_device *dev)
 		for (f = rtl8192_proc_files; f->name[0]; f++) {
 			if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
 					      &rtl8192_proc_fops, f->show)) {
-				RT_TRACE(COMP_ERR, "Unable to initialize "
-					 "/proc/net/rtl8192/%s/%s\n",
+				RT_TRACE(COMP_ERR,
+					 "Unable to initialize /proc/net/rtl8192/%s/%s\n",
 					 dev->name, f->name);
 				return;
 			}
@@ -657,14 +660,14 @@ void rtl8192_update_msr(struct net_device *dev)
 	if (priv->ieee80211->state == IEEE80211_LINKED) {
 
 		if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
-			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
+			msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
 		else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-			msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
+			msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
 		else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
-			msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
+			msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
 
 	} else {
-		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
+		msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
 	}
 
 	write_nic_byte(dev, MSR, msr);
@@ -673,12 +676,13 @@ void rtl8192_update_msr(struct net_device *dev)
 void rtl8192_set_chan(struct net_device *dev, short ch)
 {
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
 	RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch);
 	priv->chan = ch;
 
 	/* this hack should avoid frame TX during channel setting*/
 
-	//need to implement rf set channel here WB
+	/* need to implement rf set channel here */
 
 	if (priv->rf_set_chan)
 		priv->rf_set_chan(dev, priv->chan);
@@ -714,10 +718,10 @@ static int rtl8192_rx_initiate(struct net_device *dev)
 		usb_fill_bulk_urb(entry, priv->udev,
 				  usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
 				  RX_URB_SIZE, rtl8192_rx_isr, skb);
-		info = (struct rtl8192_rx_info *) skb->cb;
+		info = (struct rtl8192_rx_info *)skb->cb;
 		info->urb = entry;
 		info->dev = dev;
-		info->out_pipe = 3; //denote rx normal packet queue
+		info->out_pipe = 3; /* denote rx normal packet queue */
 		skb_queue_tail(&priv->rx_queue, skb);
 		usb_submit_urb(entry, GFP_KERNEL);
 	}
@@ -735,10 +739,10 @@ static int rtl8192_rx_initiate(struct net_device *dev)
 		usb_fill_bulk_urb(entry, priv->udev,
 				  usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
 				  RX_URB_SIZE, rtl8192_rx_isr, skb);
-		info = (struct rtl8192_rx_info *) skb->cb;
+		info = (struct rtl8192_rx_info *)skb->cb;
 		info->urb = entry;
 		info->dev = dev;
-		info->out_pipe = 9; //denote rx cmd packet queue
+		info->out_pipe = 9; /* denote rx cmd packet queue */
 		skb_queue_tail(&priv->rx_queue, skb);
 		usb_submit_urb(entry, GFP_KERNEL);
 	}
@@ -780,15 +784,15 @@ void rtl8192_set_rxconf(struct net_device *dev)
 
 
 	rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK;
-	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
+	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE << RX_FIFO_THRESHOLD_SHIFT);
 	rxconf = rxconf & ~MAX_RX_DMA_MASK;
-	rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
+	rxconf = rxconf | ((u32)7 << RCR_MXDMA_OFFSET);
 
 	rxconf = rxconf | RCR_ONLYERLPKT;
 
 	write_nic_dword(dev, RCR, rxconf);
 }
-//wait to be removed
+/* wait to be removed */
 void rtl8192_rx_enable(struct net_device *dev)
 {
 	rtl8192_rx_initiate(dev);
@@ -809,12 +813,12 @@ void rtl8192_rtx_disable(struct net_device *dev)
 	struct rtl8192_rx_info *info;
 
 	read_nic_byte(dev, CMDR, &cmd);
-	write_nic_byte(dev, CMDR, cmd & ~(CR_TE|CR_RE));
+	write_nic_byte(dev, CMDR, cmd & ~(CR_TE | CR_RE));
 	force_pci_posting(dev);
 	mdelay(10);
 
 	while ((skb = __skb_dequeue(&priv->rx_queue))) {
-		info = (struct rtl8192_rx_info *) skb->cb;
+		info = (struct rtl8192_rx_info *)skb->cb;
 		if (!info->urb)
 			continue;
 
@@ -872,14 +876,16 @@ inline u16 rtl8192_rate2rate(short rate)
 /* The prototype of rx_isr has changed since one version of Linux Kernel */
 static void rtl8192_rx_isr(struct urb *urb)
 {
-	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct sk_buff *skb = (struct sk_buff *)urb->context;
 	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
 	struct net_device *dev = info->dev;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int out_pipe = info->out_pipe;
 	int err;
+
 	if (!priv->up)
 		return;
+
 	if (unlikely(urb->status)) {
 		info->urb = NULL;
 		priv->stats.rxstaterr++;
@@ -905,7 +911,7 @@ static void rtl8192_rx_isr(struct urb *urb)
 			  usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
 			  RX_URB_SIZE, rtl8192_rx_isr, skb);
 
-	info = (struct rtl8192_rx_info *) skb->cb;
+	info = (struct rtl8192_rx_info *)skb->cb;
 	info->urb = urb;
 	info->dev = dev;
 	info->out_pipe = out_pipe;
@@ -933,13 +939,13 @@ static u32 rtl819xusb_rx_command_packet(struct net_device *dev,
 
 static void rtl8192_data_hard_stop(struct net_device *dev)
 {
-	//FIXME !!
+	/* FIXME !! */
 }
 
 
 static void rtl8192_data_hard_resume(struct net_device *dev)
 {
-	// FIXME !!
+	/* FIXME !! */
 }
 
 /* this function TX data frames when the ieee80211 stack requires this.
@@ -987,8 +993,6 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_push(skb, USB_HWDESC_HEADER_LEN);
 		rtl819xU_tx_cmd(dev, skb);
 		ret = 1;
-		spin_unlock_irqrestore(&priv->tx_lock, flags);
-		return ret;
 	} else {
 		skb_push(skb, priv->ieee80211->tx_headroom);
 		ret = rtl8192_tx(dev, skb);
@@ -999,9 +1003,6 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return ret;
 }
 
-
-void rtl8192_try_wake_queue(struct net_device *dev, int pri);
-
 static void rtl8192_tx_isr(struct urb *tx_urb)
 {
 	struct sk_buff *skb = (struct sk_buff *)tx_urb->context;
@@ -1031,16 +1032,16 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
 		atomic_dec(&priv->tx_pending[queue_index]);
 	}
 
-	//
-	// Handle HW Beacon:
-	// We had transfer our beacon frame to host controller at this moment.
-	//
-	//
-	// Caution:
-	// Handling the wait queue of command packets.
-	// For Tx command packets, we must not do TCB fragment because it is not handled right now.
-	// We must cut the packets to match the size of TX_CMD_PKT before we send it.
-	//
+	/*
+	 * Handle HW Beacon:
+	 * We had transfer our beacon frame to host controller at this moment.
+	 *
+	 *
+	 * Caution:
+	 * Handling the wait queue of command packets.
+	 * For Tx command packets, we must not do TCB fragment because it is not handled right now.
+	 * We must cut the packets to match the size of TX_CMD_PKT before we send it.
+	 */
 
 	/* Handle MPDU in wait queue. */
 	if (queue_index != BEACON_QUEUE) {
@@ -1051,7 +1052,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
 			if (skb)
 				priv->ieee80211->softmac_hard_start_xmit(skb, dev);
 
-			return; //modified by david to avoid further processing AMSDU
+			return; /* avoid further processing AMSDU */
 		}
 	}
 
@@ -1062,10 +1063,11 @@ static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_network *net;
 	u8 i = 0, basic_rate = 0;
+
 	net = &priv->ieee80211->current_network;
 
 	for (i = 0; i < net->rates_len; i++) {
-		basic_rate = net->rates[i]&0x7f;
+		basic_rate = net->rates[i] & 0x7f;
 		switch (basic_rate) {
 		case MGN_1M:
 			*rate_config |= RRSR_1M;
@@ -1106,7 +1108,7 @@ static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
 		}
 	}
 	for (i = 0; i < net->rates_ex_len; i++) {
-		basic_rate = net->rates_ex[i]&0x7f;
+		basic_rate = net->rates_ex[i] & 0x7f;
 		switch (basic_rate) {
 		case MGN_1M:
 			*rate_config |= RRSR_1M;
@@ -1157,17 +1159,19 @@ static void rtl8192_update_cap(struct net_device *dev, u16 cap)
 	u32 tmp = 0;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_network *net = &priv->ieee80211->current_network;
+
 	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
 	tmp = priv->basic_rate;
 	if (priv->short_preamble)
 		tmp |= BRSR_AckShortPmb;
 	write_nic_dword(dev, RRSR, tmp);
 
-	if (net->mode & (IEEE_G|IEEE_N_24G)) {
+	if (net->mode & (IEEE_G | IEEE_N_24G)) {
 		u8 slot_time = 0;
+
 		if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) /* short slot time */
 			slot_time = SHORT_SLOT_TIME;
-		else //long slot time
+		else /* long slot time */
 			slot_time = NON_SHORT_SLOT_TIME;
 		priv->slot_time = slot_time;
 		write_nic_byte(dev, SLOT_TIME, slot_time);
@@ -1181,13 +1185,14 @@ static void rtl8192_net_update(struct net_device *dev)
 	struct ieee80211_network *net;
 	u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
 	u16 rate_config = 0;
+
 	net = &priv->ieee80211->current_network;
 
 	rtl8192_config_rate(dev, &rate_config);
 	priv->basic_rate = rate_config & 0x15f;
 
 	write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]);
-	write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
+	write_nic_word(dev, BSSIDR + 4, ((u16 *)net->bssid)[2]);
 
 	rtl8192_update_msr(dev);
 	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
@@ -1196,9 +1201,9 @@ static void rtl8192_net_update(struct net_device *dev)
 		write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
 		write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
 		write_nic_byte(dev, BCN_ERR_THRESH, 100);
-		BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
-		// TODO: BcnIFS may required to be changed on ASIC
-		BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
+		BcnTimeCfg |= (BcnCW << BCN_TCFG_CW_SHIFT);
+		/* TODO: BcnIFS may required to be changed on ASIC */
+		BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS;
 
 		write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
 	}
@@ -1207,8 +1212,9 @@ static void rtl8192_net_update(struct net_device *dev)
 
 }
 
-//temporary hw beacon is not used any more.
-//open it when necessary
+/* temporary hw beacon is not used any more.
+ * open it when necessary
+ */
 void rtl819xusb_beacon_tx(struct net_device *dev, u16  tx_rate)
 {
 
@@ -1221,9 +1227,6 @@ inline u8 rtl8192_IsWirelessBMode(u16 rate)
 		return 0;
 }
 
-u16 N_DBPSOfRate(u16 DataRate);
-
-
 u16 N_DBPSOfRate(u16 DataRate)
 {
 	u16 N_DBPS = 24;
@@ -1287,28 +1290,28 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 
 	memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
 	/* Tx descriptor ought to be set according to the skb->cb */
-	pdesc->FirstSeg = 1;//bFirstSeg;
-	pdesc->LastSeg = 1;//bLastSeg;
+	pdesc->FirstSeg = 1;
+	pdesc->LastSeg = 1;
 	pdesc->CmdInit = tcb_desc->bCmdOrInit;
 	pdesc->TxBufferSize = tcb_desc->txbuf_size;
 	pdesc->OWN = 1;
 	pdesc->LINIP = tcb_desc->bLastIniPkt;
 
-	//----------------------------------------------------------------------------
-	// Fill up USB_OUT_CONTEXT.
-	//----------------------------------------------------------------------------
+	/*----------------------------------------------------------------------------
+	 * Fill up USB_OUT_CONTEXT.
+	 *----------------------------------------------------------------------------
+	 */
 	idx_pipe = 0x04;
 	usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
 			  skb->data, skb->len, rtl8192_tx_isr, skb);
 
 	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
 
-	if (!status) {
+	if (!status)
 		return 0;
-	} else {
-		DMESGE("Error TX CMD URB, error %d", status);
-		return -1;
-	}
+
+	DMESGE("Error TX CMD URB, error %d", status);
+	return -1;
 }
 
 /*
@@ -1320,7 +1323,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 */
 static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 {
-	u8 QueueSelect = 0x0;       //defualt set to
+	u8 QueueSelect = 0x0;       /* defualt set to */
 
 	switch (QueueID) {
 	case BE_QUEUE:
@@ -1346,8 +1349,8 @@ static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 		QueueSelect = QSLT_BEACON;
 		break;
 
-		// TODO: 2006.10.30 mark other queue selection until we verify it is OK
-		// TODO: Remove Assertions
+		/* TODO: 2006.10.30 mark other queue selection until we verify it is OK */
+		/* TODO: Remove Assertions */
 	case TXCMD_QUEUE:
 		QueueSelect = QSLT_CMD;
 		break;
@@ -1356,7 +1359,7 @@ static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 		break;
 
 	default:
-		RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
+		RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d\n", QueueID);
 		break;
 	}
 	return QueueSelect;
@@ -1453,7 +1456,7 @@ static u8 MRateToHwRate8190Pci(u8 rate)
 	case MGN_MCS15:
 		ret = DESC90_RATEMCS15;
 		break;
-	case (0x80|0x20):
+	case (0x80 | 0x20):
 		ret = DESC90_RATEMCS32;
 		break;
 
@@ -1478,7 +1481,6 @@ static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
 
 static void tx_zero_isr(struct urb *tx_urb)
 {
-	return;
 }
 
 /*
@@ -1497,6 +1499,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 	int status;
 	struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
 	unsigned int idx_pipe;
+
 	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
 	/* we are locked here so the two atomic_read and inc are executed
 	 * without interleaves
@@ -1517,7 +1520,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 	/* Fill Tx firmware info */
 	memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb));
 	/* DWORD 0 */
-	tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0;
+	tx_fwinfo->TxHT = (tcb_desc->data_rate & 0x80) ? 1 : 0;
 	tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
 	tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
 	tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
@@ -1525,7 +1528,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 		tx_fwinfo->AllowAggregation = 1;
 		/* DWORD 1 */
 		tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
-		tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
+		tx_fwinfo->RxAMD = tcb_desc->ampdu_density & 0x07;
 	} else {
 		tx_fwinfo->AllowAggregation = 0;
 		/* DWORD 1 */
@@ -1537,18 +1540,18 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 	tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0;
 	tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0;
 	tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0;
-	tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0;
+	tx_fwinfo->RtsHT = (tcb_desc->rts_rate & 0x80) ? 1 : 0;
 	tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
 	tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0;
 	tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0;
 	tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) :
-		              (tcb_desc->bRTSUseShortGI ? 1 : 0);
+			      (tcb_desc->bRTSUseShortGI ? 1 : 0);
 
 	/* Set Bandwidth and sub-channel settings. */
 	if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) {
 		if (tcb_desc->bPacketBW) {
 			tx_fwinfo->TxBandwidth = 1;
-			tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
+			tx_fwinfo->TxSubCarrier = 0;    /* use duplicated mode */
 		} else {
 			tx_fwinfo->TxBandwidth = 0;
 			tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
@@ -1600,7 +1603,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 	tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
 
 	/* Fill fields that are required to be initialized in all of the descriptors */
-	//DWORD 0
+	/* DWORD 0 */
 	tx_desc->FirstSeg = 1;
 	tx_desc->LastSeg = 1;
 	tx_desc->OWN = 1;
@@ -1616,9 +1619,14 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 
 	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
 	if (!status) {
-		//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+		/* We need to send 0 byte packet whenever
+		 * 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has
+		 * been transmitted. Otherwise, it will be halt to wait for
+		 * another packet.
+		 */
 		bool bSend0Byte = false;
 		u8 zero = 0;
+
 		if (udev->speed == USB_SPEED_HIGH) {
 			if (skb->len > 0 && skb->len % 512 == 0)
 				bSend0Byte = true;
@@ -1644,24 +1652,24 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
 		dev->trans_start = jiffies;
 		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
 		return 0;
-	} else {
-		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
-			 status);
-		return -1;
 	}
+
+	RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
+		 status);
+	return -1;
 }
 
 static short rtl8192_usb_initendpoints(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1),
+	priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB + 1),
 			       GFP_KERNEL);
 	if (priv->rx_urb == NULL)
 		return -ENOMEM;
 
 #ifndef JACKSON_NEW_RX
-	for (i = 0; i < (MAX_RX_URB+1); i++) {
+	for (i = 0; i < (MAX_RX_URB + 1); i++) {
 
 		priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
 
@@ -1715,7 +1723,7 @@ static void rtl8192_usb_deleteendpoints(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
 	if (priv->rx_urb) {
-		for (i = 0; i < (MAX_RX_URB+1); i++) {
+		for (i = 0; i < (MAX_RX_URB + 1); i++) {
 			usb_kill_urb(priv->rx_urb[i]);
 			usb_free_urb(priv->rx_urb[i]);
 		}
@@ -1724,10 +1732,9 @@ static void rtl8192_usb_deleteendpoints(struct net_device *dev)
 	}
 	kfree(priv->oldaddr);
 	priv->oldaddr = NULL;
-	if (priv->pp_rxskb) {
-		kfree(priv->pp_rxskb);
-		priv->pp_rxskb = NULL;
-	}
+
+	kfree(priv->pp_rxskb);
+	priv->pp_rxskb = NULL;
 }
 #else
 void rtl8192_usb_deleteendpoints(struct net_device *dev)
@@ -1738,7 +1745,7 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev)
 #ifndef JACKSON_NEW_RX
 
 	if (priv->rx_urb) {
-		for (i = 0; i < (MAX_RX_URB+1); i++) {
+		for (i = 0; i < (MAX_RX_URB + 1); i++) {
 			usb_kill_urb(priv->rx_urb[i]);
 			kfree(priv->rx_urb[i]->transfer_buffer);
 			usb_free_urb(priv->rx_urb[i]);
@@ -1752,11 +1759,9 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev)
 	priv->rx_urb = NULL;
 	kfree(priv->oldaddr);
 	priv->oldaddr = NULL;
-	if (priv->pp_rxskb) {
-		kfree(priv->pp_rxskb);
-		priv->pp_rxskb = 0;
 
-	}
+	kfree(priv->pp_rxskb);
+	priv->pp_rxskb = 0;
 
 #endif
 }
@@ -1767,16 +1772,21 @@ static void rtl8192_link_change(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee80211;
+
 	if (ieee->state == IEEE80211_LINKED) {
 		rtl8192_net_update(dev);
 		rtl8192_update_ratr_table(dev);
-		//add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
+		/* Add this as in pure N mode, wep encryption will use software
+		 * way, but there is no chance to set this as wep will not set
+		 * group key in wext.
+		 */
 		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
 			EnableHWSecurityConfig8192(dev);
 	}
 	/*update timing params*/
 	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
 		u32 reg = 0;
+
 		read_nic_dword(dev, RCR, &reg);
 		if (priv->ieee80211->state == IEEE80211_LINKED)
 			priv->ReceiveConfig = reg |= RCR_CBSSID;
@@ -1832,8 +1842,8 @@ static void rtl8192_qos_activate(struct work_struct *work)
 	/* For we just support b/g mode at present, let the slot time at 9/20 selection */
 	/* update the ac parameter to related registers */
 	for (i = 0; i <  QOS_QUEUE_NUM; i++) {
-		//Mode G/A: slotTimeTimer = 9; Mode B: 20
-		u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
+		/* Mode G/A: slotTimeTimer = 9; Mode B: 20 */
+		u1bAIFS = qos_parameters->aifs[i] * ((mode & (IEEE_G | IEEE_N_24G)) ? 9 : 20) + aSifsTime;
 		u1bAIFS <<= AC_PARAM_AIFS_OFFSET;
 		op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[i]);
 		op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET;
@@ -1859,7 +1869,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 	if (priv->ieee80211->state != IEEE80211_LINKED)
 		return ret;
 
-	if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+	if (priv->ieee80211->iw_mode != IW_MODE_INFRA)
 		return ret;
 
 	if (network->flags & NETWORK_HAS_QOS_MASK) {
@@ -1874,8 +1884,8 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 			network->qos_data.old_param_count =
 				network->qos_data.param_count;
 			queue_work(priv->priv_wq, &priv->qos_activate);
-			RT_TRACE(COMP_QOS, "QoS parameters change call "
-				 "qos_activate\n");
+			RT_TRACE(COMP_QOS,
+				 "QoS parameters change call qos_activate\n");
 		}
 	} else {
 		memcpy(&priv->ieee80211->current_network.qos_data.parameters,
@@ -1883,7 +1893,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 
 		if ((network->qos_data.active == 1) && (active_network == 1)) {
 			queue_work(priv->priv_wq, &priv->qos_activate);
-			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
+			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate\n");
 		}
 		network->qos_data.active = 0;
 		network->qos_data.supported = 0;
@@ -1923,7 +1933,7 @@ static int rtl8192_qos_association_resp(struct r8192_priv *priv,
 	if (priv->ieee80211->state != IEEE80211_LINKED)
 		return 0;
 
-	if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+	if (priv->ieee80211->iw_mode != IW_MODE_INFRA)
 		return 0;
 
 	spin_lock_irqsave(&priv->ieee80211->lock, flags);
@@ -1962,6 +1972,7 @@ static int rtl8192_handle_assoc_response(struct net_device *dev,
 					 struct ieee80211_network *network)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
 	rtl8192_qos_association_resp(priv, network);
 	return 0;
 }
@@ -1974,6 +1985,7 @@ static void rtl8192_update_ratr_table(struct net_device *dev)
 	u8 *pMcsRate = ieee->dot11HTOperationalRateSet;
 	u32 ratr_value = 0;
 	u8 rate_index = 0;
+
 	rtl8192_config_rate(dev, (u16 *)(&ratr_value));
 	ratr_value |= (*(u16 *)(pMcsRate)) << 12;
 	switch (ieee->mode) {
@@ -2005,7 +2017,7 @@ static void rtl8192_update_ratr_table(struct net_device *dev)
 		ratr_value |= 0x80000000;
 	else if (!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)
 		ratr_value |= 0x80000000;
-	write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
+	write_nic_dword(dev, RATR0 + rate_index * 4, ratr_value);
 	write_nic_byte(dev, UFWP, 1);
 }
 
@@ -2021,7 +2033,9 @@ static bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
 	int encrypt;
 
 	crypt = ieee->crypt[ieee->tx_keyidx];
-	//we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
+	/* we use connecting AP's capability instead of only security config
+	 * on our driver to distinguish whether it should use N mode or G mode
+	 */
 	encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name, "WEP")));
 
 	/* simply judge  */
@@ -2051,7 +2065,9 @@ static bool GetHalfNmodeSupportByAPs819xUsb(struct net_device *dev)
 static void rtl8192_refresh_supportrate(struct r8192_priv *priv)
 {
 	struct ieee80211_device *ieee = priv->ieee80211;
-	//we do not consider set support rate for ABG mode, only HT MCS rate is set here.
+	/* We do not consider set support rate for ABG mode, only
+	 * HT MCS rate is set here.
+	 */
 	if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
 		memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
 	else
@@ -2062,14 +2078,15 @@ static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 ret = 0;
+
 	switch (priv->rf_chip) {
 	case RF_8225:
 	case RF_8256:
 	case RF_PSEUDO_11N:
-		ret = WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B;
+		ret = WIRELESS_MODE_N_24G | WIRELESS_MODE_G | WIRELESS_MODE_B;
 		break;
 	case RF_8258:
-		ret = WIRELESS_MODE_A|WIRELESS_MODE_N_5G;
+		ret = WIRELESS_MODE_A | WIRELESS_MODE_N_5G;
 		break;
 	default:
 		ret = WIRELESS_MODE_B;
@@ -2082,7 +2099,7 @@ static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
 
-	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode) == 0)) {
+	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode & bSupportMode) == 0)) {
 		if (bSupportMode & WIRELESS_MODE_N_24G) {
 			wireless_mode = WIRELESS_MODE_N_24G;
 		} else if (bSupportMode & WIRELESS_MODE_N_5G) {
@@ -2098,7 +2115,7 @@ static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
 			wireless_mode = WIRELESS_MODE_B;
 		}
 	}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
+#ifdef TO_DO_LIST /* TODO: this function doesn't work well at this time, we should wait for FPGA */
 	ActUpdateChannelAccessSetting(pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting);
 #endif
 	priv->ieee80211->mode = wireless_mode;
@@ -2111,43 +2128,44 @@ static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
 	rtl8192_refresh_supportrate(priv);
 
 }
-//init priv variables here. only non_zero value should be initialized here.
+/* init priv variables here. only non_zero value should be initialized here. */
 static void rtl8192_init_priv_variable(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 i;
+
 	priv->card_8192 = NIC_8192U;
-	priv->chan = 1; //set to channel 1
-	priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
+	priv->chan = 1; /* set to channel 1 */
+	priv->ieee80211->mode = WIRELESS_MODE_AUTO; /* SET AUTO */
 	priv->ieee80211->iw_mode = IW_MODE_INFRA;
 	priv->ieee80211->ieee_up = 0;
 	priv->retry_rts = DEFAULT_RETRY_RTS;
 	priv->retry_data = DEFAULT_RETRY_DATA;
 	priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
-	priv->ieee80211->rate = 110; //11 mbps
+	priv->ieee80211->rate = 110; /* 11 mbps */
 	priv->ieee80211->short_slot = 1;
 	priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
 	priv->CckPwEnl = 6;
-	//for silent reset
+	/* for silent reset */
 	priv->IrpPendingCount = 1;
 	priv->ResetProgress = RESET_TYPE_NORESET;
 	priv->bForcedSilentReset = false;
 	priv->bDisableNormalResetCheck = false;
 	priv->force_reset = false;
 
-	priv->ieee80211->FwRWRF = 0;	//we don't use FW read/write RF until stable firmware is available.
+	priv->ieee80211->FwRWRF = 0;	/* we don't use FW read/write RF until stable firmware is available. */
 	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
 	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
 		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
 		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
-		IEEE_SOFTMAC_BEACONS;//added by amy 080604
+		IEEE_SOFTMAC_BEACONS;
 
 	priv->ieee80211->active_scan = 1;
 	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
 	priv->ieee80211->host_encrypt = 1;
 	priv->ieee80211->host_decrypt = 1;
-	priv->ieee80211->start_send_beacons = NULL; //-by amy 080604
-	priv->ieee80211->stop_send_beacons = NULL;  //-by amy 080604
+	priv->ieee80211->start_send_beacons = NULL;
+	priv->ieee80211->stop_send_beacons = NULL;
 	priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
 	priv->ieee80211->set_chan = rtl8192_set_chan;
 	priv->ieee80211->link_change = rtl8192_link_change;
@@ -2160,15 +2178,14 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
 	priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
 	priv->ieee80211->qos_support = 1;
 
-	//added by WB
 	priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
 	priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
 	priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
-	//added by david
+
 	priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
 	priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
 	priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
-	//added by amy
+
 	priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
 	priv->card_type = USB;
 #ifdef TO_DO_LIST
@@ -2182,30 +2199,29 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
 	priv->EarlyRxThreshold = 7;
 	priv->enable_gpio0 = 0;
 	priv->TransmitConfig =
-		(TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reserved.
-		(priv->ShortRetryLimit<<TCR_SRL_OFFSET)|	// Short retry limit
-		(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
-		(false ? TCR_SAT : 0);	// FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them
+		(TCR_MXDMA_2048 << TCR_MXDMA_OFFSET)	  | /* Max DMA Burst Size per Tx DMA Burst, 7: reserved. */
+		(priv->ShortRetryLimit << TCR_SRL_OFFSET) | /* Short retry limit */
+		(priv->LongRetryLimit << TCR_LRL_OFFSET)  | /* Long retry limit */
+		(false ? TCR_SAT : 0);	/* FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them */
 #ifdef TO_DO_LIST
 	if (Adapter->bInHctTest)
 		pHalData->ReceiveConfig	=	pHalData->CSMethod |
-						RCR_AMF | RCR_ADF |	//accept management/data
-						//guangan200710
-						RCR_ACF |	//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
-						RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
-						RCR_AICV | RCR_ACRC32 |			//accept ICV/CRC error packet
-						((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
-						(pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
+						RCR_AMF | RCR_ADF | /* accept management/data */
+						RCR_ACF | /* accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. */
+						RCR_AB | RCR_AM | RCR_APM | /* accept BC/MC/UC */
+						RCR_AICV | RCR_ACRC32 | /* accept ICV/CRC error packet */
+						((u32)7 << RCR_MXDMA_OFFSET) | /* Max DMA Burst Size per Tx DMA Burst, 7: unlimited. */
+						(pHalData->EarlyRxThreshold << RCR_FIFO_OFFSET) | /* Rx FIFO Threshold, 7: No Rx threshold. */
 						(pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0);
 	else
 
 #endif
 	priv->ReceiveConfig	=
-		RCR_AMF | RCR_ADF |		//accept management/data
-		RCR_ACF |			//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
-		RCR_AB | RCR_AM | RCR_APM |	//accept BC/MC/UC
-		((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
-		(priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
+		RCR_AMF | RCR_ADF | /* accept management/data */
+		RCR_ACF | /* accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. */
+		RCR_AB | RCR_AM | RCR_APM | /* accept BC/MC/UC */
+		((u32)7 << RCR_MXDMA_OFFSET) | /* Max DMA Burst Size per Rx DMA Burst, 7: unlimited. */
+		(priv->EarlyRxThreshold << RX_FIFO_THRESHOLD_SHIFT) | /* Rx FIFO Threshold, 7: No Rx threshold. */
 		(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0);
 
 	priv->AcmControl = 0;
@@ -2225,11 +2241,11 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
 	priv->rf_set_chan = rtl8192_phy_SwChnl;
 }
 
-//init lock here
+/* init lock here */
 static void rtl8192_init_priv_lock(struct r8192_priv *priv)
 {
 	spin_lock_init(&priv->tx_lock);
-	spin_lock_init(&priv->irq_lock);//added by thomas
+	spin_lock_init(&priv->irq_lock);
 	sema_init(&priv->wx_sem, 1);
 	sema_init(&priv->rf_sem, 1);
 	mutex_init(&priv->mutex);
@@ -2238,7 +2254,7 @@ static void rtl8192_init_priv_lock(struct r8192_priv *priv)
 static void rtl819x_watchdog_wqcallback(struct work_struct *work);
 
 static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
-//init tasklet and wait_queue here. only 2.6 above kernel is considered
+/* init tasklet and wait_queue here. only 2.6 above kernel is considered */
 #define DRV_NAME "wlan0"
 static void rtl8192_init_priv_task(struct net_device *dev)
 {
@@ -2264,15 +2280,18 @@ static void rtl8192_get_eeprom_size(struct net_device *dev)
 {
 	u16 curCR = 0;
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
 	RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
 	read_nic_word_E(dev, EPROM_CMD, &curCR);
 	RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
-	//whether need I consider BIT5?
+	/* whether need I consider BIT5? */
 	priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
 	RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __func__, priv->epromtype);
 }
 
-//used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
+/* used to swap endian. as ntohl & htonl are not necessary
+ * to swap endian, so use this instead.
+ */
 static inline u16 endian_swap(u16 *data)
 {
 	u16 tmp = *data;
@@ -2287,24 +2306,24 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u16 tmpValue = 0;
 	int i;
+
 	RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
-	wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
+	wEPROM_ID = eprom_read(dev, 0); /* first read EEPROM ID out; */
 	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
 
-	if (wEPROM_ID != RTL8190_EEPROM_ID) {
+	if (wEPROM_ID != RTL8190_EEPROM_ID)
 		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
-	} else {
+	else
 		bLoad_From_EEPOM = true;
-	}
 
 	if (bLoad_From_EEPOM) {
-		tmpValue = eprom_read(dev, EEPROM_VID>>1);
+		tmpValue = eprom_read(dev, EEPROM_VID >> 1);
 		priv->eeprom_vid = endian_swap(&tmpValue);
-		priv->eeprom_pid = eprom_read(dev, EEPROM_PID>>1);
-		tmpValue = eprom_read(dev, EEPROM_ChannelPlan>>1);
-		priv->eeprom_ChannelPlan = (tmpValue & 0xff00)>>8;
+		priv->eeprom_pid = eprom_read(dev, EEPROM_PID >> 1);
+		tmpValue = eprom_read(dev, EEPROM_ChannelPlan >> 1);
+		priv->eeprom_ChannelPlan = (tmpValue & 0xff00) >> 8;
 		priv->btxpowerdata_readfromEEPORM = true;
-		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
+		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID >> 1)) >> 8;
 	} else {
 		priv->eeprom_vid = 0;
 		priv->eeprom_pid = 0;
@@ -2313,74 +2332,77 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 		priv->eeprom_CustomerID = 0;
 	}
 	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
-	//set channelplan from eeprom
+	/* set channelplan from eeprom */
 	priv->ChannelPlan = priv->eeprom_ChannelPlan;
 	if (bLoad_From_EEPOM) {
 		int i;
+
 		for (i = 0; i < 6; i += 2) {
 			u16 tmp = 0;
-			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
+
+			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1));
 			*(u16 *)(&dev->dev_addr[i]) = tmp;
 		}
 	} else {
 		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
-		//should I set IDR0 here?
+		/* should I set IDR0 here? */
 	}
 	RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
+	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; /* default 1T2R */
 	priv->rf_chip = RF_8256;
 
 	if (priv->card_8192_version == (u8)VERSION_819xU_A) {
-		//read Tx power gain offset of legacy OFDM to HT rate
+		/* read Tx power gain offset of legacy OFDM to HT rate */
 		if (bLoad_From_EEPOM)
-			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
+			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff >> 1)) & 0xff00) >> 8;
 		else
 			priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
 		RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
-		//read ThermalMeter from EEPROM
+		/* read ThermalMeter from EEPROM */
 		if (bLoad_From_EEPOM)
-			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
+			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter >> 1)) & 0x00ff);
 		else
 			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
 		RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
-		//vivi, for tx power track
-		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
-		//read antenna tx power offset of B/C/D to A from EEPROM
+		/* for tx power track */
+		priv->TSSI_13dBm = priv->EEPROMThermalMeter * 100;
+		/* read antenna tx power offset of B/C/D to A from EEPROM */
 		if (bLoad_From_EEPOM)
-			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
+			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff >> 1)) & 0x0f00) >> 8;
 		else
 			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
 		RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
-		// Read CrystalCap from EEPROM
+		/* Read CrystalCap from EEPROM */
 		if (bLoad_From_EEPOM)
-			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
+			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap >> 1)) & 0x0f);
 		else
 			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
 		RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
-		//get per-channel Tx power level
+		/* get per-channel Tx power level */
 		if (bLoad_From_EEPOM)
-			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
+			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver >> 1)) & 0xff00) >> 8;
 		else
 			priv->EEPROM_Def_Ver = 1;
 		RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
 		if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */
 			int i;
+
 			if (bLoad_From_EEPOM)
-				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
+				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK >> 1)) & 0xff) >> 8;
 			else
 				priv->EEPROMTxPowerLevelCCK = 0x10;
 			RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
 			for (i = 0; i < 3; i++) {
 				if (bLoad_From_EEPOM) {
-					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
-					if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
+					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G + i) >> 1);
+					if (((EEPROM_TxPwIndex_OFDM_24G + i) % 2) == 0)
 						tmpValue = tmpValue & 0x00ff;
 					else
 						tmpValue = (tmpValue & 0xff00) >> 8;
 				} else {
 					tmpValue = 0x10;
 				}
-				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
+				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)tmpValue;
 				RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
 			}
 		} else if (priv->EEPROM_Def_Ver == 1) {
@@ -2394,7 +2416,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 			priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
 
 			if (bLoad_From_EEPOM)
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2) >> 1);
 			else
 				tmpValue = 0x1010;
 			*((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
@@ -2405,14 +2427,13 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 				tmpValue = 0x1010;
 			*((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
 			if (bLoad_From_EEPOM)
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1 + 2) >> 1);
 			else
 				tmpValue = 0x10;
 			priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
-		}//endif EEPROM_Def_Ver == 1
+		} /* endif EEPROM_Def_Ver == 1 */
 
-		//update HAL variables
-		//
+		/* update HAL variables */
 		for (i = 0; i < 14; i++) {
 			if (i <= 3)
 				priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
@@ -2440,18 +2461,19 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 			}
 		}
 		priv->TxPowerDiff = priv->EEPROMPwDiff;
-		// Antenna B gain offset to antenna A, bit0~3
+		/* Antenna B gain offset to antenna A, bit0~3 */
 		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
-		// Antenna C gain offset to antenna A, bit4~7
-		priv->AntennaTxPwDiff[1] = (priv->EEPROMTxPowerDiff & 0xf0)>>4;
-		// CrystalCap, bit12~15
+		/* Antenna C gain offset to antenna A, bit4~7 */
+		priv->AntennaTxPwDiff[1] = (priv->EEPROMTxPowerDiff & 0xf0) >> 4;
+		/* CrystalCap, bit12~15 */
 		priv->CrystalCap = priv->EEPROMCrystalCap;
-		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
-		// 92U does not enable TX power tracking.
+		/* ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
+		 * 92U does not enable TX power tracking.
+		 */
 		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
-	}//end if VersionID == VERSION_819xU_A
+	} /* end if VersionID == VERSION_819xU_A */
 
-	//added by vivi, for dlink led, 20080416
+	/* for dlink led */
 	switch (priv->eeprom_CustomerID) {
 	case EEPROM_CID_RUNTOP:
 		priv->CustomerID = RT_CID_819x_RUNTOP;
@@ -2483,16 +2505,15 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 	}
 
 
-	if (priv->rf_type == RF_1T2R) {
+	if (priv->rf_type == RF_1T2R)
 		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
-	} else {
+	else
 		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
-	}
 
-	// 2008/01/16 MH We can only know RF type in the function. So we have to init
-	// DIG RATR table again.
+	/* We can only know RF type in the function. So we have to init
+	 * DIG RATR table again.
+	 */
 	init_rate_adaptive(dev);
-	//we need init DIG RATR table here again.
 
 	RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
 }
@@ -2500,6 +2521,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
 static short rtl8192_get_channel_map(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
 	if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) {
 		netdev_err(dev, "rtl8180_init: Error channel plan! Set to default.\n");
 		priv->ChannelPlan = 0;
@@ -2521,11 +2543,13 @@ static short rtl8192_init(struct net_device *dev)
 	{
 		int i = 0;
 		u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
+
 		memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
 	}
 #else
 	{
 		u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4};
+
 		memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9);
 	}
 #endif
@@ -2561,8 +2585,7 @@ static void rtl8192_hwconfig(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u32 ratr_value = 0;
 
-	// Set RRSR, RATR, and BW_OPMODE registers
-	//
+	/* Set RRSR, RATR, and BW_OPMODE registers */
 	switch (priv->ieee80211->mode) {
 	case WIRELESS_MODE_B:
 		regBwOpMode = BW_OPMODE_20MHZ;
@@ -2570,7 +2593,7 @@ static void rtl8192_hwconfig(struct net_device *dev)
 		regRRSR = RATE_ALL_CCK;
 		break;
 	case WIRELESS_MODE_A:
-		regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+		regBwOpMode = BW_OPMODE_5G | BW_OPMODE_20MHZ;
 		regRATR = RATE_ALL_OFDM_AG;
 		regRRSR = RATE_ALL_OFDM_AG;
 		break;
@@ -2585,8 +2608,7 @@ static void rtl8192_hwconfig(struct net_device *dev)
 			regBwOpMode = BW_OPMODE_20MHZ;
 			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
 			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
-		}
-		else
+		} else
 #endif
 		{
 			regBwOpMode = BW_OPMODE_20MHZ;
@@ -2595,8 +2617,9 @@ static void rtl8192_hwconfig(struct net_device *dev)
 		}
 		break;
 	case WIRELESS_MODE_N_24G:
-		// It support CCK rate by default.
-		// CCK rate will be filtered out only when associated AP does not support it.
+		/* It support CCK rate by default. CCK rate will be filtered
+		 * out only when associated AP does not support it.
+		 */
 		regBwOpMode = BW_OPMODE_20MHZ;
 		regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
 		regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
@@ -2618,25 +2641,23 @@ static void rtl8192_hwconfig(struct net_device *dev)
 	regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
 	write_nic_dword(dev, RRSR, regRRSR);
 
-	//
-	// Set Retry Limit here
-	//
+	/* Set Retry Limit here */
 	write_nic_word(dev, RETRY_LIMIT,
 		       priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
 		       priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
-	// Set Contention Window here
+	/* Set Contention Window here */
 
-	// Set Tx AGC
+	/* Set Tx AGC */
 
-	// Set Tx Antenna including Feedback control
+	/* Set Tx Antenna including Feedback control */
 
-	// Set Auto Rate fallback control
+	/* Set Auto Rate fallback control */
 
 
 }
 
 
-//InitializeAdapter and PhyCfg
+/* InitializeAdapter and PhyCfg */
 static bool rtl8192_adapter_start(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
@@ -2644,9 +2665,10 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 	bool init_status = true;
 	u8 SECR_value = 0x0;
 	u8 tmp;
+
 	RT_TRACE(COMP_INIT, "====>%s()\n", __func__);
 	priv->Rf_Mode = RF_OP_By_SW_3wire;
-	//for ASIC power on sequence
+	/* for ASIC power on sequence */
 	write_nic_byte_E(dev, 0x5f, 0x80);
 	mdelay(50);
 	write_nic_byte_E(dev, 0x5f, 0xf0);
@@ -2655,21 +2677,21 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 	write_nic_byte(dev, 0x17, 0x37);
 	mdelay(10);
 	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
-	//config CPUReset Register
-	//Firmware Reset or not?
+	/* config CPUReset Register */
+	/* Firmware Reset or not? */
 	read_nic_dword(dev, CPU_GEN, &dwRegRead);
 	if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
-		dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
+		dwRegRead |= CPU_GEN_SYSTEM_RESET; /* do nothing here? */
 	else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
 		dwRegRead |= CPU_GEN_FIRMWARE_RESET;
 	else
 		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __func__,   priv->pFirmware->firmware_status);
 
 	write_nic_dword(dev, CPU_GEN, dwRegRead);
-	//config BB.
+	/* config BB. */
 	rtl8192_BBConfig(dev);
 
-	//Loopback mode or not
+	/* Loopback mode or not */
 	priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
 
 	read_nic_dword(dev, CPU_GEN, &dwRegRead);
@@ -2682,39 +2704,39 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 
 	write_nic_dword(dev, CPU_GEN, dwRegRead);
 
-	//after reset cpu, we need wait for a seconds to write in register.
+	/* after reset cpu, we need wait for a seconds to write in register. */
 	udelay(500);
 
-	//xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
+	/* add for new bitfile:usb suspend reset pin set to 1. Do we need? */
 	read_nic_byte_E(dev, 0x5f, &tmp);
-	write_nic_byte_E(dev, 0x5f, tmp|0x20);
+	write_nic_byte_E(dev, 0x5f, tmp | 0x20);
 
-	//Set Hardware
+	/* Set Hardware */
 	rtl8192_hwconfig(dev);
 
-	//turn on Tx/Rx
-	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
+	/* turn on Tx/Rx */
+	write_nic_byte(dev, CMDR, CR_RE | CR_TE);
 
-	//set IDR0 here
+	/* set IDR0 here */
 	write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
 	write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]);
 
-	//set RCR
+	/* set RCR */
 	write_nic_dword(dev, RCR, priv->ReceiveConfig);
 
-	//Initialize Number of Reserved Pages in Firmware Queue
+	/* Initialize Number of Reserved Pages in Firmware Queue */
 	write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
 			NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
 			NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
-			NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
+			NUM_OF_PAGE_IN_FW_QUEUE_VO << RSVD_FW_QUEUE_PAGE_VO_SHIFT);
 	write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |
 			NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
-	write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
-			NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
-	write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
+	write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW |
+			NUM_OF_PAGE_IN_FW_QUEUE_BCN << RSVD_FW_QUEUE_PAGE_BCN_SHIFT);
+	write_nic_dword(dev, RATR0 + 4 * 7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
 
-	//Set AckTimeout
-	// TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
+	/* Set AckTimeout */
+	/* TODO: (it value is only for FPGA version). need to be changed!! */
 	write_nic_byte(dev, ACK_TIMEOUT, 0x30);
 
 	if (priv->ResetProgress == RESET_TYPE_NORESET)
@@ -2727,58 +2749,63 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 		write_nic_byte(dev, SECR, SECR_value);
 	}
 
-	//Beacon related
+	/* Beacon related */
 	write_nic_word(dev, ATIMWND, 2);
 	write_nic_word(dev, BCN_INTERVAL, 100);
 
 #define DEFAULT_EDCA 0x005e4332
 	{
 		int i;
+
 		for (i = 0; i < QOS_QUEUE_NUM; i++)
 			write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
 	}
 
 	rtl8192_phy_configmac(dev);
 
-	if (priv->card_8192_version == (u8) VERSION_819xU_A) {
+	if (priv->card_8192_version == (u8)VERSION_819xU_A) {
 		rtl8192_phy_getTxPower(dev);
 		rtl8192_phy_setTxPower(dev, priv->chan);
 	}
 
-	//Firmware download
+	/* Firmware download */
 	init_status = init_firmware(dev);
 	if (!init_status) {
 		RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", __func__);
 		return init_status;
 	}
 	RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__);
-	//
+
 #ifdef TO_DO_LIST
 	if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
 		if (pMgntInfo->RegRfOff) { /* User disable RF via registry. */
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
+			RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
 			MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
-			// Those actions will be discard in MgntActSet_RF_State because of the same state
+			/* Those actions will be discard in MgntActSet_RF_State
+			 * because of the same state
+			 */
 			for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
 				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
 		} else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { /* H/W or S/W RF OFF before sleep. */
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
+			RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
 			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
 		} else {
 			pHalData->eRFPowerState = eRfOn;
 			pMgntInfo->RfOffReason = 0;
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
+			RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
 		}
 	} else {
 		if (pHalData->eRFPowerState == eRfOff) {
 			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
-			// Those actions will be discard in MgntActSet_RF_State because of the same state
+			/* Those actions will be discard in MgntActSet_RF_State
+			 * because of the same state
+			 */
 			for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
 				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
 		}
 	}
 #endif
-	//config RF.
+	/* config RF. */
 	if (priv->ResetProgress == RESET_TYPE_NORESET) {
 		rtl8192_phy_RFConfig(dev);
 		RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__);
@@ -2786,7 +2813,7 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 
 
 	if (priv->ieee80211->FwRWRF)
-		// We can force firmware to do RF-R/W
+		/* We can force firmware to do RF-R/W */
 		priv->Rf_Mode = RF_OP_By_FW;
 	else
 		priv->Rf_Mode = RF_OP_By_SW_3wire;
@@ -2798,8 +2825,9 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
 
 	if (priv->ResetProgress == RESET_TYPE_NORESET) {
-		//if D or C cut
+		/* if D or C cut */
 		u8 tmpvalue;
+
 		read_nic_byte(dev, 0x301, &tmpvalue);
 		if (tmpvalue == 0x03) {
 			priv->bDcut = true;
@@ -2813,6 +2841,7 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 		if (priv->bDcut) {
 			u32 i, TempCCk;
 			u32 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
+
 			for (i = 0; i < TxBBGainTableLength; i++) {
 				if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) {
 					priv->rfa_txpowertrackingindex = (u8)i;
@@ -2827,7 +2856,7 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 			for (i = 0; i < CCKTxBBGainTableLength; i++) {
 
 				if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {
-					priv->cck_present_attentuation_20Mdefault = (u8) i;
+					priv->cck_present_attentuation_20Mdefault = (u8)i;
 					break;
 				}
 			}
@@ -2863,6 +2892,7 @@ static bool HalTxCheckStuck819xUsb(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u16		RegTxCounter;
 	bool		bStuck = false;
+
 	read_nic_word(dev, 0x128, &RegTxCounter);
 	RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, RegTxCounter, priv->TxCounter);
 	if (priv->TxCounter == RegTxCounter)
@@ -2883,9 +2913,7 @@ static RESET_TYPE TxCheckStuck(struct net_device *dev)
 	u8			QueueID;
 	bool			bCheckFwTxCnt = false;
 
-	//
-	// Decide such threshold according to current power save mode
-	//
+	/* Decide such threshold according to current power save mode */
 
 	for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) {
 		if (QueueID == TXCMD_QUEUE)
@@ -2897,7 +2925,7 @@ static RESET_TYPE TxCheckStuck(struct net_device *dev)
 	}
 	if (bCheckFwTxCnt) {
 		if (HalTxCheckStuck819xUsb(dev)) {
-			RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
+			RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition!\n");
 			return RESET_TYPE_SILENT;
 		}
 	}
@@ -2910,32 +2938,34 @@ static bool HalRxCheckStuck819xUsb(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	bool bStuck = false;
 	static u8	rx_chk_cnt;
+
 	read_nic_word(dev, 0x130, &RegRxCounter);
 	RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, RegRxCounter, priv->RxCounter);
-	// If rssi is small, we should check rx for long time because of bad rx.
-	// or maybe it will continuous silent reset every 2 seconds.
+	/* If rssi is small, we should check rx for long time because of bad rx.
+	 * or maybe it will continuous silent reset every 2 seconds.
+	 */
 	rx_chk_cnt++;
-	if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) {
-		rx_chk_cnt = 0;	//high rssi, check rx stuck right now.
-	} else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
+	if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High + 5)) {
+		rx_chk_cnt = 0;	/* high rssi, check rx stuck right now. */
+	} else if (priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High + 5) &&
 		   ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M) ||
 		    (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M))) {
 		if (rx_chk_cnt < 2)
 			return bStuck;
-		else
-			rx_chk_cnt = 0;
+
+		rx_chk_cnt = 0;
 	} else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M) ||
 		    (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M)) &&
 		     priv->undecorated_smoothed_pwdb >= VeryLowRSSI) {
 		if (rx_chk_cnt < 4)
 			return bStuck;
-		else
-			rx_chk_cnt = 0;
+
+		rx_chk_cnt = 0;
 	} else {
 		if (rx_chk_cnt < 8)
 			return bStuck;
-		else
-			rx_chk_cnt = 0;
+
+		rx_chk_cnt = 0;
 	}
 
 	if (priv->RxCounter == RegRxCounter)
@@ -2988,14 +3018,18 @@ static RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev)
 	TxResetType = TxCheckStuck(dev);
 	if (rfState != eRfOff ||
 	    (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) {
-		// If driver is in the status of firmware download failure , driver skips RF initialization and RF is
-		// in turned off state. Driver should check whether Rx stuck and do silent reset. And
-		// if driver is in firmware download failure status, driver should initialize RF in the following
-		// silent reset procedure Emily, 2008.01.21
-
-		// Driver should not check RX stuck in IBSS mode because it is required to
-		// set Check BSSID in order to send beacon, however, if check BSSID is
-		// set, STA cannot hear any packet at all. Emily, 2008.04.12
+		/* If driver is in the status of firmware download failure,
+		 * driver skips RF initialization and RF is in turned off
+		 * state. Driver should check whether Rx stuck and do silent
+		 * reset. And if driver is in firmware download failure status,
+		 * driver should initialize RF in the following silent reset
+		 * procedure
+		 *
+		 * Driver should not check RX stuck in IBSS mode because it is
+		 * required to set Check BSSID in order to send beacon,
+		 * however, if check BSSID is set, STA cannot hear any packet
+		 * at all.
+		 */
 		RxResetType = RxCheckStuck(dev);
 	}
 	if (TxResetType == RESET_TYPE_NORMAL || RxResetType == RESET_TYPE_NORMAL) {
@@ -3029,7 +3063,7 @@ static void CamRestoreAllEntry(struct net_device *dev)
 	static u8	CAM_CONST_BROAD[] = {
 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-	RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
+	RT_TRACE(COMP_SEC, "CamRestoreAllEntry:\n");
 
 
 	if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
@@ -3085,12 +3119,11 @@ static void CamRestoreAllEntry(struct net_device *dev)
 			       CAM_CONST_ADDR[0], 0, NULL);
 	}
 }
-//////////////////////////////////////////////////////////////
-// This function is used to fix Tx/Rx stop bug temporarily.
-// This function will do "system reset" to NIC when Tx or Rx is stuck.
-// The method checking Tx/Rx stuck of this function is supported by FW,
-// which reports Tx and Rx counter to register 0x128 and 0x130.
-//////////////////////////////////////////////////////////////
+/* This function is used to fix Tx/Rx stop bug temporarily.
+ * This function will do "system reset" to NIC when Tx or Rx is stuck.
+ * The method checking Tx/Rx stuck of this function is supported by FW,
+ * which reports Tx and Rx counter to register 0x128 and 0x130.
+ */
 static void rtl819x_ifsilentreset(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
@@ -3099,15 +3132,15 @@ static void rtl819x_ifsilentreset(struct net_device *dev)
 	struct ieee80211_device *ieee = priv->ieee80211;
 
 
-	// 2007.07.20. If we need to check CCK stop, please uncomment this line.
-	//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
+	/* If we need to check CCK stop, please uncomment this line. */
+	/* bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); */
 
 	if (priv->ResetProgress == RESET_TYPE_NORESET) {
 RESET_START:
 
-		RT_TRACE(COMP_RESET, "=========>Reset progress!! \n");
+		RT_TRACE(COMP_RESET, "=========>Reset progress!!\n");
 
-		// Set the variable for reset.
+		/* Set the variable for reset. */
 		priv->ResetProgress = RESET_TYPE_SILENT;
 		down(&priv->wx_sem);
 		if (priv->up == 0) {
@@ -3177,7 +3210,7 @@ RESET_START:
 		priv->bForcedSilentReset = false;
 		priv->bResetInProgress = false;
 
-		// For test --> force write UFWP.
+		/* For test --> force write UFWP. */
 		write_nic_byte(dev, UFWP, 1);
 		RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
 	}
@@ -3192,7 +3225,7 @@ static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
 	*TotalRxBcnNum = 0;
 	*TotalRxDataNum = 0;
 
-	SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
+	SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++) % (priv->ieee80211->LinkDetectInfo.SlotNum);
 	priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
 	priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
 	for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) {
@@ -3218,21 +3251,21 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work)
 		return;
 	hal_dm_watchdog(dev);
 
-	//to get busy traffic condition
+	/* to get busy traffic condition */
 	if (ieee->state == IEEE80211_LINKED) {
 		if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
-		    ieee->LinkDetectInfo.NumTxOkInPeriod > 666 ) {
+		    ieee->LinkDetectInfo.NumTxOkInPeriod > 666) {
 			bBusyTraffic = true;
 		}
 		ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
 		ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
 		ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
 	}
-	//added by amy for AP roaming
+	/* for AP roaming */
 	if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) {
 
 		rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
-		if ((TotalRxBcnNum+TotalRxDataNum) == 0) {
+		if ((TotalRxBcnNum + TotalRxDataNum) == 0) {
 #ifdef TODO
 			if (rfState == eRfOff)
 				RT_TRACE(COMP_ERR, "========>%s()\n", __func__);
@@ -3248,7 +3281,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work)
 	}
 	priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
 	priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
-	//check if reset the driver
+	/* check if reset the driver */
 	if (check_reset_cnt++ >= 3) {
 		ResetType = rtl819x_ifcheck_resetornot(dev);
 		check_reset_cnt = 3;
@@ -3268,7 +3301,8 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work)
 
 static void watch_dog_timer_callback(unsigned long data)
 {
-	struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
+
 	queue_delayed_work(priv->priv_wq, &priv->watch_dog_wq, 0);
 	mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
 }
@@ -3276,6 +3310,7 @@ static int _rtl8192_up(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int init_status = 0;
+
 	priv->up = 1;
 	priv->ieee80211->ieee_up = 1;
 	RT_TRACE(COMP_INIT, "Bringing up iface");
@@ -3290,7 +3325,7 @@ static int _rtl8192_up(struct net_device *dev)
 	if (priv->ieee80211->state != IEEE80211_LINKED)
 		ieee80211_softmac_start_protocol(priv->ieee80211);
 	ieee80211_reset_queue(priv->ieee80211);
-	watch_dog_timer_callback((unsigned long) dev);
+	watch_dog_timer_callback((unsigned long)dev);
 	if (!netif_queue_stopped(dev))
 		netif_start_queue(dev);
 	else
@@ -3304,6 +3339,7 @@ static int rtl8192_open(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int ret;
+
 	down(&priv->wx_sem);
 	ret = rtl8192_up(dev);
 	up(&priv->wx_sem);
@@ -3364,7 +3400,9 @@ int rtl8192_down(struct net_device *dev)
 	for (i = 0; i < MAX_QUEUE_SIZE; i++)
 		skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]);
 
-	//as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt
+	/* as cancel_delayed_work will del work->timer, so if work is not
+	 * defined as struct delayed_work, it will corrupt
+	 */
 	rtl8192_cancel_deferred_work(priv);
 	deinit_hal_dm(dev);
 	del_timer_sync(&priv->watch_dog_timer);
@@ -3382,6 +3420,7 @@ void rtl8192_commit(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	int reset_status = 0;
+
 	if (priv->up == 0)
 		return;
 	priv->up = 0;
@@ -3430,7 +3469,7 @@ static int r8192_set_mac_adr(struct net_device *dev, void *mac)
 
 	down(&priv->wx_sem);
 
-	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	ether_addr_copy(dev->dev_addr, addr->sa_data);
 
 	schedule_work(&priv->reset_wq);
 	up(&priv->wx_sem);
@@ -3466,7 +3505,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 	switch (cmd) {
 	case RTL_IOCTL_WPA_SUPPLICANT:
-		//parse here for HW security
+		/* parse here for HW security */
 		if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) {
 			if (ipw->u.crypt.set_tx) {
 				if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) {
@@ -3485,8 +3524,12 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 				if (ieee->pairwise_key_type) {
 					memcpy((u8 *)key, ipw->u.crypt.key, 16);
 					EnableHWSecurityConfig8192(dev);
-					//we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
-					//added by WB.
+					/* We fill both index entry and 4th
+					 * entry for pairwise key as in IPW
+					 * interface, adhoc will only get here,
+					 * so we need index entry for its
+					 * default key serching!
+					 */
 					setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
 					if (ieee->auth_mode != 2)
 						setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8 *)ieee->ap_mac_addr, 0, key);
@@ -3508,11 +3551,11 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 				if (ieee->group_key_type) {
 					setKey(dev, ipw->u.crypt.idx,
-					       ipw->u.crypt.idx,		//KeyIndex
-					       ieee->group_key_type,	//KeyType
-					       broadcast_addr,	//MacAddr
-					       0,		//DefaultKey
-					       key);		//KeyContent
+					       ipw->u.crypt.idx, /* KeyIndex */
+					       ieee->group_key_type, /* KeyType */
+					       broadcast_addr, /* MacAddr */
+					       0,	       /* DefaultKey */
+					       key);	       /* KeyContent */
 				}
 			}
 		}
@@ -3536,107 +3579,107 @@ static u8 HwRateToMRate90(bool bIsHT, u8 rate)
 
 	if (!bIsHT) {
 		switch (rate) {
-			case DESC90_RATE1M:
-				ret_rate = MGN_1M;
-				break;
-			case DESC90_RATE2M:
-				ret_rate = MGN_2M;
-				break;
-			case DESC90_RATE5_5M:
-				ret_rate = MGN_5_5M;
-				break;
-			case DESC90_RATE11M:
-				ret_rate = MGN_11M;
-				break;
-			case DESC90_RATE6M:
-				ret_rate = MGN_6M;
-				break;
-			case DESC90_RATE9M:
-				ret_rate = MGN_9M;
-				break;
-			case DESC90_RATE12M:
-				ret_rate = MGN_12M;
-				break;
-			case DESC90_RATE18M:
-				ret_rate = MGN_18M;
-				break;
-			case DESC90_RATE24M:
-				ret_rate = MGN_24M;
-				break;
-			case DESC90_RATE36M:
-				ret_rate = MGN_36M;
-				break;
-			case DESC90_RATE48M:
-				ret_rate = MGN_48M;
-				break;
-			case DESC90_RATE54M:
-				ret_rate = MGN_54M;
-				break;
+		case DESC90_RATE1M:
+			ret_rate = MGN_1M;
+			break;
+		case DESC90_RATE2M:
+			ret_rate = MGN_2M;
+			break;
+		case DESC90_RATE5_5M:
+			ret_rate = MGN_5_5M;
+			break;
+		case DESC90_RATE11M:
+			ret_rate = MGN_11M;
+			break;
+		case DESC90_RATE6M:
+			ret_rate = MGN_6M;
+			break;
+		case DESC90_RATE9M:
+			ret_rate = MGN_9M;
+			break;
+		case DESC90_RATE12M:
+			ret_rate = MGN_12M;
+			break;
+		case DESC90_RATE18M:
+			ret_rate = MGN_18M;
+			break;
+		case DESC90_RATE24M:
+			ret_rate = MGN_24M;
+			break;
+		case DESC90_RATE36M:
+			ret_rate = MGN_36M;
+			break;
+		case DESC90_RATE48M:
+			ret_rate = MGN_48M;
+			break;
+		case DESC90_RATE54M:
+			ret_rate = MGN_54M;
+			break;
 
-			default:
-				ret_rate = 0xff;
-				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
-				break;
+		default:
+			ret_rate = 0xff;
+			RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+			break;
 		}
 
 	} else {
 		switch (rate) {
-			case DESC90_RATEMCS0:
-				ret_rate = MGN_MCS0;
-				break;
-			case DESC90_RATEMCS1:
-				ret_rate = MGN_MCS1;
-				break;
-			case DESC90_RATEMCS2:
-				ret_rate = MGN_MCS2;
-				break;
-			case DESC90_RATEMCS3:
-				ret_rate = MGN_MCS3;
-				break;
-			case DESC90_RATEMCS4:
-				ret_rate = MGN_MCS4;
-				break;
-			case DESC90_RATEMCS5:
-				ret_rate = MGN_MCS5;
-				break;
-			case DESC90_RATEMCS6:
-				ret_rate = MGN_MCS6;
-				break;
-			case DESC90_RATEMCS7:
-				ret_rate = MGN_MCS7;
-				break;
-			case DESC90_RATEMCS8:
-				ret_rate = MGN_MCS8;
-				break;
-			case DESC90_RATEMCS9:
-				ret_rate = MGN_MCS9;
-				break;
-			case DESC90_RATEMCS10:
-				ret_rate = MGN_MCS10;
-				break;
-			case DESC90_RATEMCS11:
-				ret_rate = MGN_MCS11;
-				break;
-			case DESC90_RATEMCS12:
-				ret_rate = MGN_MCS12;
-				break;
-			case DESC90_RATEMCS13:
-				ret_rate = MGN_MCS13;
-				break;
-			case DESC90_RATEMCS14:
-				ret_rate = MGN_MCS14;
-				break;
-			case DESC90_RATEMCS15:
-				ret_rate = MGN_MCS15;
-				break;
-			case DESC90_RATEMCS32:
-				ret_rate = 0x80|0x20;
-				break;
+		case DESC90_RATEMCS0:
+			ret_rate = MGN_MCS0;
+			break;
+		case DESC90_RATEMCS1:
+			ret_rate = MGN_MCS1;
+			break;
+		case DESC90_RATEMCS2:
+			ret_rate = MGN_MCS2;
+			break;
+		case DESC90_RATEMCS3:
+			ret_rate = MGN_MCS3;
+			break;
+		case DESC90_RATEMCS4:
+			ret_rate = MGN_MCS4;
+			break;
+		case DESC90_RATEMCS5:
+			ret_rate = MGN_MCS5;
+			break;
+		case DESC90_RATEMCS6:
+			ret_rate = MGN_MCS6;
+			break;
+		case DESC90_RATEMCS7:
+			ret_rate = MGN_MCS7;
+			break;
+		case DESC90_RATEMCS8:
+			ret_rate = MGN_MCS8;
+			break;
+		case DESC90_RATEMCS9:
+			ret_rate = MGN_MCS9;
+			break;
+		case DESC90_RATEMCS10:
+			ret_rate = MGN_MCS10;
+			break;
+		case DESC90_RATEMCS11:
+			ret_rate = MGN_MCS11;
+			break;
+		case DESC90_RATEMCS12:
+			ret_rate = MGN_MCS12;
+			break;
+		case DESC90_RATEMCS13:
+			ret_rate = MGN_MCS13;
+			break;
+		case DESC90_RATEMCS14:
+			ret_rate = MGN_MCS14;
+			break;
+		case DESC90_RATEMCS15:
+			ret_rate = MGN_MCS15;
+			break;
+		case DESC90_RATEMCS32:
+			ret_rate = 0x80 | 0x20;
+			break;
 
-			default:
-				ret_rate = 0xff;
-				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
-				break;
+		default:
+			ret_rate = 0xff;
+			RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+			break;
 		}
 	}
 
@@ -3672,13 +3715,11 @@ static void UpdateRxPktTimeStamp8190(struct net_device *dev,
 	}
 }
 
-//by amy 080606
-
-static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
+static long rtl819x_translate_todbm(u8 signal_strength_index) /* 0-100 index. */
 {
-	long	signal_power; // in dBm.
+	long	signal_power; /* in dBm. */
 
-	// Translate to dBm (x=0.5y-95).
+	/* Translate to dBm (x=0.5y-95). */
 	signal_power = (long)((signal_strength_index + 1) >> 1);
 	signal_power -= 95;
 
@@ -3686,10 +3727,11 @@ static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
 }
 
 
-/* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to
-    be a local static. Otherwise, it may increase when we return from S3/S4. The
-    value will be kept in memory or disk. Declare the value in the adaptor
-    and it will be reinitialized when returned from S3/S4. */
+/* We can not declare RSSI/EVM total value of sliding window to
+ * be a local static. Otherwise, it may increase when we return from S3/S4. The
+ * value will be kept in memory or disk. Declare the value in the adaptor
+ * and it will be reinitialized when returned from S3/S4.
+ */
 static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 				    struct ieee80211_rx_stats *pprevious_stats,
 				    struct ieee80211_rx_stats *pcurrent_stats)
@@ -3707,17 +3749,17 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 	struct rtl_80211_hdr_3addr *hdr;
 	u16 sc;
 	unsigned int frag, seq;
+
 	hdr = (struct rtl_80211_hdr_3addr *)buffer;
 	sc = le16_to_cpu(hdr->seq_ctl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
 	seq = WLAN_GET_SEQ_SEQ(sc);
-	//cosa add 04292008 to record the sequence number
+	/* to record the sequence number */
 	pcurrent_stats->Seq_Num = seq;
-	//
-	// Check whether we should take the previous packet into accounting
-	//
+
+	/* Check whether we should take the previous packet into accounting */
 	if (!pprevious_stats->bIsAMPDU) {
-		// if previous packet is not aggregated packet
+		/* if previous packet is not aggregated packet */
 		bcheck = true;
 	}
 
@@ -3732,13 +3774,12 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 	if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
 		slide_rssi_index = 0;
 
-	// <1> Showed on UI for user, in dbm
-	tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
+	/* <1> Showed on UI for user, in dbm */
+	tmp_val = priv->stats.slide_rssi_total / slide_rssi_statistics;
 	priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
 	pcurrent_stats->rssi = priv->stats.signal_strength;
-	//
-	// If the previous packet does not match the criteria, neglect it
-	//
+
+	/* If the previous packet does not match the criteria, neglect it */
 	if (!pprevious_stats->bPacketMatchBSSID) {
 		if (!pprevious_stats->bToSelfBA)
 			return;
@@ -3748,44 +3789,42 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 		return;
 
 
-	//rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
+	/* only rtl8190 supported
+	 * rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
+	 */
 
-	//
-	// Check RSSI
-	//
+	/* Check RSSI */
 	priv->stats.num_process_phyinfo++;
 
 	/* record the general signal strength to the sliding window. */
 
 
-	// <2> Showed on UI for engineering
-	// hardware does not provide rssi information for each rf path in CCK
+	/* <2> Showed on UI for engineering
+	 * hardware does not provide rssi information for each rf path in CCK
+	 */
 	if (!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) {
 		for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) {
 			if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
 				continue;
 
-			//Fixed by Jacken 2008-03-20
 			if (priv->stats.rx_rssi_percentage[rfpath] == 0)
 				priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
 			if (pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath]) {
 				priv->stats.rx_rssi_percentage[rfpath] =
-					((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
-					 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+					((priv->stats.rx_rssi_percentage[rfpath] * (Rx_Smooth_Factor - 1)) +
+					 (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (Rx_Smooth_Factor);
 				priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
 			} else {
 				priv->stats.rx_rssi_percentage[rfpath] =
-					((priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
-					 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+					((priv->stats.rx_rssi_percentage[rfpath] * (Rx_Smooth_Factor - 1)) +
+					 (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (Rx_Smooth_Factor);
 			}
-			RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath]  = %d \n", priv->stats.rx_rssi_percentage[rfpath]);
+			RT_TRACE(COMP_DBG, "priv->stats.rx_rssi_percentage[rfPath]  = %d\n", priv->stats.rx_rssi_percentage[rfpath]);
 		}
 	}
 
 
-	//
-	// Check PWDB.
-	//
+	/* Check PWDB. */
 	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
 		 pprevious_stats->bIsCCK ? "CCK" : "OFDM",
 		 pprevious_stats->RxPWDBAll);
@@ -3802,7 +3841,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 		slide_beacon_adc_pwdb_index++;
 		if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
 			slide_beacon_adc_pwdb_index = 0;
-		pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
+		pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total / slide_beacon_adc_pwdb_statistics;
 		if (pprevious_stats->RxPWDBAll >= 3)
 			pprevious_stats->RxPWDBAll -= 3;
 	}
@@ -3817,20 +3856,18 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 			priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
 		if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
 			priv->undecorated_smoothed_pwdb =
-				(((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
-				 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+				(((priv->undecorated_smoothed_pwdb) * (Rx_Smooth_Factor - 1)) +
+				 (pprevious_stats->RxPWDBAll)) / (Rx_Smooth_Factor);
 			priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
 		} else {
 			priv->undecorated_smoothed_pwdb =
-				(((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
-				 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+				(((priv->undecorated_smoothed_pwdb) * (Rx_Smooth_Factor - 1)) +
+				 (pprevious_stats->RxPWDBAll)) / (Rx_Smooth_Factor);
 		}
 
 	}
 
-	//
-	// Check EVM
-	//
+	/* Check EVM */
 	/* record the general EVM to the sliding window. */
 	if (pprevious_stats->SignalQuality) {
 		if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
@@ -3846,22 +3883,22 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
 			if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
 				slide_evm_index = 0;
 
-			// <1> Showed on UI for user, in percentage.
-			tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
+			/* <1> Showed on UI for user, in percentage. */
+			tmp_val = priv->stats.slide_evm_total / slide_evm_statistics;
 			priv->stats.signal_quality = tmp_val;
-			//cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
+			/* Showed on UI for user in Windows Vista, for Link quality. */
 			priv->stats.last_signal_strength_inpercent = tmp_val;
 		}
 
-		// <2> Showed on UI for engineering
+		/* <2> Showed on UI for engineering */
 		if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
 			for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { /* 2 spatial stream */
 				if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
 					if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */
 						priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
 					priv->stats.rx_evm_percentage[nspatial_stream] =
-						((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
-						 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
+						((priv->stats.rx_evm_percentage[nspatial_stream] * (Rx_Smooth_Factor - 1)) +
+						 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] * 1)) / (Rx_Smooth_Factor);
 				}
 			}
 		}
@@ -3913,16 +3950,12 @@ static u8 rtl819x_evm_dbtopercentage(char value)
 		ret_val = 100;
 	return ret_val;
 }
-//
-//	Description:
-//	We want good-looking for signal strength/quality
-//	2007/7/19 01:09, by cosa.
-//
+/* We want good-looking for signal strength/quality */
 static long rtl819x_signal_scale_mapping(long currsig)
 {
 	long retsig;
 
-	// Step 1. Scale mapping.
+	/* Step 1. Scale mapping. */
 	if (currsig >= 61 && currsig <= 100)
 		retsig = 90 + ((currsig - 60) / 4);
 	else if (currsig >= 41 && currsig <= 60)
@@ -3990,7 +4023,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 
 	is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
 
-	// Record it for next packet processing
+	/* Record it for next packet processing */
 	memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
 	pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
 	pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
@@ -4013,13 +4046,9 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 	precord_stats->RxMIMOSignalQuality[1] = -1;
 
 	if (is_cck_rate) {
-		//
-		// (1)Hardware does not provide RSSI for CCK
-		//
+		/* (1)Hardware does not provide RSSI for CCK */
 
-		//
-		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
-		//
+		/* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
 		u8 report;
 
 		priv->stats.numqry_phystatusCCK++;
@@ -4028,9 +4057,6 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 			report = pcck_buf->cck_agc_rpt & 0xc0;
 			report >>= 6;
 			switch (report) {
-				//Fixed by Jacken from Bryant 2008-03-20
-				//Original value is -38 , -26 , -14 , -2
-				//Fixed value is -35 , -23 , -11 , 6
 			case 0x3:
 				rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
 				break;
@@ -4049,16 +4075,16 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 			report >>= 5;
 			switch (report) {
 			case 0x3:
-				rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+				rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1);
 				break;
 			case 0x2:
-				rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+				rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1);
 				break;
 			case 0x1:
-				rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+				rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1);
 				break;
 			case 0x0:
-				rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+				rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1);
 				break;
 			}
 		}
@@ -4067,9 +4093,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
 		pstats->RecvSignalPower = pwdb_all;
 
-		//
-		// (3) Get Signal Quality (EVM)
-		//
+		/* (3) Get Signal Quality (EVM) */
 
 		if (pstats->RxPWDBAll > 40) {
 			sq = 100;
@@ -4081,7 +4105,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 			else if (pcck_buf->sq_rpt < 20)
 				sq = 100;
 			else
-				sq = ((64-sq) * 100) / 44;
+				sq = ((64 - sq) * 100) / 44;
 		}
 		pstats->SignalQuality = precord_stats->SignalQuality = sq;
 		pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
@@ -4089,11 +4113,10 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 
 	} else {
 		priv->stats.numqry_phystatusHT++;
-		//
-		// (1)Get RSSI for HT rate
-		//
+
+		/* (1)Get RSSI for HT rate */
 		for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) {
-			// 2008/01/30 MH we will judge RF RX path now.
+			/* We will judge RF RX path now. */
 			if (priv->brfpath_rxenable[i])
 				rf_rx_num++;
 			else
@@ -4102,11 +4125,9 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 			if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
 				continue;
 
-			//Fixed by Jacken from Bryant 2008-03-20
-			//Original value is 106
-			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
+			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i] & 0x3F) * 2) - 106;
 
-			//Get Rx snr value in DB
+			/* Get Rx snr value in DB */
 			tmp_rxsnr =	pofdm_buf->rxsnr_X[i];
 			rx_snrX = (char)(tmp_rxsnr);
 			rx_snrX /= 2;
@@ -4117,39 +4138,39 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 			total_rssi += RSSI;
 
 			/* Record Signal Strength for next packet */
-			pstats->RxMIMOSignalStrength[i] = (u8) RSSI;
-			precord_stats->RxMIMOSignalStrength[i] = (u8) RSSI;
+			pstats->RxMIMOSignalStrength[i] = (u8)RSSI;
+			precord_stats->RxMIMOSignalStrength[i] = (u8)RSSI;
 		}
 
 
-		//
-		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
-		//
-		//Fixed by Jacken from Bryant 2008-03-20
-		//Original value is 106
-		rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1)& 0x7f) -106;
+		/* (2)PWDB, Average PWDB cacluated by hardware
+		 * (for rate adaptive)
+		 */
+		rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106;
 		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
 
 		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
 		pstats->RxPower = precord_stats->RxPower =  rx_pwr_all;
 
-		//
-		// (3)EVM of HT rate
-		//
+		/* (3)EVM of HT rate */
 		if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 &&
 		    pdrvinfo->RxRate <= DESC90_RATEMCS15)
-			max_spatial_stream = 2; //both spatial stream make sense
+			max_spatial_stream = 2; /* both spatial stream make sense */
 		else
-			max_spatial_stream = 1; //only spatial stream 1 makes sense
+			max_spatial_stream = 1; /* only spatial stream 1 makes sense */
 
 		for (i = 0; i < max_spatial_stream; i++) {
 			tmp_rxevm =	pofdm_buf->rxevm_X[i];
 			rx_evmX = (char)(tmp_rxevm);
 
-			// Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment
-			// will set the most significant bit to "zero" when doing shifting operation which may change a negative
-			// value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
-			rx_evmX /= 2;	//dbm
+			/* Do not use shift operation like "rx_evmX >>= 1"
+			 * because the compiler of free build environment will
+			 * set the most significant bit to "zero" when doing
+			 * shifting operation which may change a negative value
+			 * to positive one, then the dbm value (which is
+			 * supposed to be negative) is not correct anymore.
+			 */
+			rx_evmX /= 2;	/* dbm */
 
 			evm = rtl819x_evm_dbtopercentage(rx_evmX);
 			if (i == 0) /* Fill value in RFD, Get the first spatial stream only */
@@ -4162,17 +4183,19 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
 		rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
 		prxsc =	(phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
 		if (pdrvinfo->BW)	/* 40M channel */
-			priv->stats.received_bwtype[1+prxsc->rxsc]++;
-		else				//20M channel
+			priv->stats.received_bwtype[1 + prxsc->rxsc]++;
+		else			/* 20M channel */
 			priv->stats.received_bwtype[0]++;
 	}
 
-	//UI BSS List signal strength(in percentage), make it good looking, from 0~100.
-	//It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
+	/* UI BSS List signal strength(in percentage), make it good looking,
+	 * from 0~100. It is assigned to the BSS List in
+	 * GetValueFromBeaconOrProbeRsp().
+	 */
 	if (is_cck_rate) {
 		pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));
 	} else {
-		// We can judge RX path number now.
+		/* We can judge RX path number now. */
 		if (rf_rx_num != 0)
 			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num)));
 	}
@@ -4191,17 +4214,19 @@ static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
 					  struct ieee80211_rx_stats *pstats,
 					  rx_drvinfo_819x_usb  *pdrvinfo)
 {
-	// TODO: We must only check packet for current MAC address. Not finish
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	/* TODO: We must only check packet for current MAC address.
+	 * Not finish
+	 */
+	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
 	struct net_device *dev = info->dev;
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 	bool bpacket_match_bssid, bpacket_toself;
 	bool bPacketBeacon = false, bToSelfBA = false;
 	static struct ieee80211_rx_stats  previous_stats;
-	struct rtl_80211_hdr_3addr *hdr;//by amy
+	struct rtl_80211_hdr_3addr *hdr;
 	u16 fc, type;
 
-	// Get Signal Quality for only RX data queue (but not command queue)
+	/* Get Signal Quality for only RX data queue (but not command queue) */
 
 	u8 *tmp_buf;
 	u8  *praddr;
@@ -4233,11 +4258,10 @@ static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
 		priv->stats.numpacket_matchbssid++;
 	if (bpacket_toself)
 		priv->stats.numpacket_toself++;
-	//
-	// Process PHY information for previous packet (RSSI/PWDB/EVM)
-	//
-	// Because phy information is contained in the last packet of AMPDU only, so driver
-	// should process phy information of previous packet
+	/* Process PHY information for previous packet (RSSI/PWDB/EVM)
+	 * Because phy information is contained in the last packet of AMPDU
+	 * only, so driver should process phy information of previous packet
+	 */
 	rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
 	rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid, bpacket_toself, bPacketBeacon, bToSelfBA);
 	rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
@@ -4263,9 +4287,9 @@ UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
 					  struct ieee80211_rx_stats *stats)
 {
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	u32 rcvType = 1;   //0: Total, 1:OK, 2:CRC, 3:ICV
+	u32 rcvType = 1;   /* 0: Total, 1:OK, 2:CRC, 3:ICV */
 	u32 rateIndex;
-	u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
+	u32 preamble_guardinterval;  /* 1: short preamble/GI, 0: long preamble/GI */
 
 
 	if (stats->bCRC)
@@ -4274,9 +4298,9 @@ UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
 		rcvType = 3;
 
 	if (stats->bShortPreamble)
-		preamble_guardinterval = 1;// short
+		preamble_guardinterval = 1; /* short */
 	else
-		preamble_guardinterval = 0;// long
+		preamble_guardinterval = 0; /* long */
 
 	switch (stats->rate) {
 	/* CCK rate */
@@ -4371,7 +4395,7 @@ UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
 		break;
 	}
 	priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
-	priv->stats.received_rate_histogram[0][rateIndex]++; //total
+	priv->stats.received_rate_histogram[0][rateIndex]++; /* total */
 	priv->stats.received_rate_histogram[rcvType][rateIndex]++;
 }
 
@@ -4380,14 +4404,12 @@ static void query_rxdesc_status(struct sk_buff *skb,
 				struct ieee80211_rx_stats *stats,
 				bool bIsRxAggrSubframe)
 {
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
 	struct net_device *dev = info->dev;
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 	rx_drvinfo_819x_usb  *driver_info = NULL;
 
-	//
-	//Get Rx Descriptor Information
-	//
+	/* Get Rx Descriptor Information */
 	rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
 
 	stats->Length = desc->Length;
@@ -4395,7 +4417,7 @@ static void query_rxdesc_status(struct sk_buff *skb,
 	stats->RxBufShift = 0;
 	stats->bICV = desc->ICV;
 	stats->bCRC = desc->CRC32;
-	stats->bHwError = stats->bCRC|stats->bICV;
+	stats->bHwError = stats->bCRC | stats->bICV;
 	/* RTL8190 set this bit to indicate that Hw does not decrypt packet */
 	stats->Decrypted = !desc->SWDec;
 
@@ -4403,15 +4425,14 @@ static void query_rxdesc_status(struct sk_buff *skb,
 	    (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
 		stats->bHwError = false;
 	else
-		stats->bHwError = stats->bCRC|stats->bICV;
+		stats->bHwError = stats->bCRC | stats->bICV;
 
 	if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
 		stats->bHwError |= 1;
-	//
-	//Get Driver Info
-	//
-	// TODO: Need to verify it on FGPA platform
-	//Driver info are written to the RxBuffer following rx desc
+	/* Get Driver Info */
+	/* TODO: Need to verify it on FGPA platform
+	 * Driver info are written to the RxBuffer following rx desc
+	 */
 	if (stats->RxDrvInfoSize != 0) {
 		driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) +
 						      stats->RxBufShift);
@@ -4419,13 +4440,16 @@ static void query_rxdesc_status(struct sk_buff *skb,
 		/* TODO */
 		if (!stats->bHwError) {
 			u8	ret_rate;
+
 			ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
 			if (ret_rate == 0xff) {
-				// Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
-				// Special Error Handling here, 2008.05.16, by Emily
+				/* Abnormal Case: Receive CRC OK packet with Rx
+				 * descriptor indicating non supported rate.
+				 * Special Error Handling here
+				 */
 
 				stats->bHwError = 1;
-				stats->rate = MGN_1M;	//Set 1M rate by default
+				stats->rate = MGN_1M; /* Set 1M rate by default */
 			} else {
 				stats->rate = ret_rate;
 			}
@@ -4441,13 +4465,10 @@ static void query_rxdesc_status(struct sk_buff *skb,
 		stats->bIsAMPDU = (driver_info->PartAggr == 1);
 		stats->bFirstMPDU = (driver_info->PartAggr == 1) && (driver_info->FirstAGGR == 1);
 		stats->TimeStampLow = driver_info->TSFL;
-		// xiong mask it, 070514
 
 		UpdateRxPktTimeStamp8190(dev, stats);
 
-		//
-		// Rx A-MPDU
-		//
+		/* Rx A-MPDU */
 		if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1)
 			RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
 				 driver_info->FirstAGGR, driver_info->PartAggr);
@@ -4455,9 +4476,7 @@ static void query_rxdesc_status(struct sk_buff *skb,
 	}
 
 	skb_pull(skb, sizeof(rx_desc_819x_usb));
-	//
-	// Get Total offset of MPDU Frame Body
-	//
+	/* Get Total offset of MPDU Frame Body */
 	if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
 		stats->bShift = 1;
 		skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
@@ -4471,7 +4490,7 @@ static void query_rxdesc_status(struct sk_buff *skb,
 
 static void rtl8192_rx_nomal(struct sk_buff *skb)
 {
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
 	struct net_device *dev = info->dev;
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 	struct ieee80211_rx_stats stats = {
@@ -4497,9 +4516,9 @@ static void rtl8192_rx_nomal(struct sk_buff *skb)
 		ieee80211_hdr = (struct rtl_80211_hdr_1addr *)skb->data;
 		unicast_packet = false;
 		if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
-			//TODO
+			/* TODO */
 		} else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) {
-			//TODO
+			/* TODO */
 		} else {
 			/* unicast packet */
 			unicast_packet = true;
@@ -4527,20 +4546,20 @@ static void rtl819xusb_process_received_packet(struct net_device *dev,
 	u16     frame_len = 0;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	// Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
-	//porting by amy 080508
+	/* Get shifted bytes of Starting address of 802.11 header. */
 	pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
 	frame = pstats->virtual_address;
 	frame_len = pstats->packetlength;
-#ifdef TODO	// by amy about HCT
+#ifdef TODO	/* about HCT */
 	if (!Adapter->bInHctTest)
 		CountRxErrStatistics(Adapter, pRfd);
 #endif
-#ifdef ENABLE_PS  //by amy for adding ps function in future
+#ifdef ENABLE_PS  /* for adding ps function in future */
 	RT_RF_POWER_STATE rtState;
-	// When RF is off, we should not count the packet for hw/sw synchronize
-	// reason, ie. there may be a duration while sw switch is changed and hw
-	// switch is being changed. 2006.12.04, by shien chang.
+	/* When RF is off, we should not count the packet for hw/sw synchronize
+	 * reason, ie. there may be a duration while sw switch is changed and
+	 * hw switch is being changed.
+	 */
 	Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8 *)(&rtState));
 	if (rtState == eRfOff)
 		return;
@@ -4550,8 +4569,7 @@ static void rtl819xusb_process_received_packet(struct net_device *dev,
 #ifdef TODO
 	RmMonitorSignalStrength(Adapter, pRfd);
 #endif
-	/* 2007/01/16 MH Add RX command packet handle here. */
-	/* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
+	/* We have to release RFD and return if rx pkt is cmd pkt. */
 	if (rtl819xusb_rx_command_packet(dev, pstats))
 		return;
 
@@ -4567,14 +4585,12 @@ static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
 {
 	rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
 
-	//
-	//Get Rx Descriptor Information
-	//
+	/* Get Rx Descriptor Information */
 	stats->virtual_address = (u8 *)skb->data;
 	stats->Length = desc->Length;
 	stats->RxDrvInfoSize = 0;
 	stats->RxBufShift = 0;
-	stats->packetlength = stats->Length-scrclng;
+	stats->packetlength = stats->Length - scrclng;
 	stats->fraglength = stats->packetlength;
 	stats->fragoffset = 0;
 	stats->ntotalfrag = 1;
@@ -4596,12 +4612,9 @@ static void rtl8192_rx_cmd(struct sk_buff *skb)
 	if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
 
 		query_rx_cmdpkt_desc_status(skb, &stats);
-		// this is to be done by amy 080508     prfd->queue_id = 1;
-
+		/* prfd->queue_id = 1; */
 
-		//
-		//  Process the command packet received.
-		//
+		/* Process the command packet received. */
 
 		rtl819xusb_process_received_packet(dev, &stats);
 
@@ -4666,6 +4679,7 @@ static int rtl8192_usb_probe(struct usb_interface *intf,
 	struct r8192_priv *priv = NULL;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	int ret;
+
 	RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
 
 	dev = alloc_ieee80211(sizeof(struct r8192_priv));
@@ -4680,11 +4694,11 @@ static int rtl8192_usb_probe(struct usb_interface *intf,
 
 	dev->netdev_ops = &rtl8192_netdev_ops;
 
-	dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
+	dev->wireless_handlers = (struct iw_handler_def *)&r8192_wx_handlers_def;
 
 	dev->type = ARPHRD_ETHER;
 
-	dev->watchdog_timeo = HZ*3;	//modified by john, 0805
+	dev->watchdog_timeo = HZ * 3;
 
 	if (dev_alloc_name(dev, ifname) < 0) {
 		RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
@@ -4726,7 +4740,7 @@ fail:
 	return ret;
 }
 
-//detach all the work and timer structure declared or inititialize in r8192U_init function.
+/* detach all the work and timer structure declared or inititialize in r8192U_init function. */
 static void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
 {
 
@@ -4740,10 +4754,9 @@ static void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
 static void rtl8192_usb_disconnect(struct usb_interface *intf)
 {
 	struct net_device *dev = usb_get_intfdata(intf);
-
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	if (dev) {
 
+	if (dev) {
 		unregister_netdev(dev);
 
 		RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
@@ -4755,7 +4768,6 @@ static void rtl8192_usb_disconnect(struct usb_interface *intf)
 		rtl8192_usb_deleteendpoints(dev);
 		destroy_workqueue(priv->priv_wq);
 		mdelay(10);
-
 	}
 	free_ieee80211(dev);
 	RT_TRACE(COMP_DOWN, "wlan driver removed\n");
@@ -4832,6 +4844,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev)
 	u8 SECR_value = 0x0;
 	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee80211;
+
 	SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
 	if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) {
 		SECR_value |= SCR_RxUseDK;
@@ -4840,12 +4853,16 @@ void EnableHWSecurityConfig8192(struct net_device *dev)
 		SECR_value |= SCR_RxUseDK;
 		SECR_value |= SCR_TxUseDK;
 	}
-	//add HWSec active enable here.
-	//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
+	/* add HWSec active enable here.
+	 * default using hwsec. when peer AP is in N mode only and
+	 * pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates
+	 * it), use software security. when peer AP is in b,g,n mode mixed and
+	 * pairwise_key_type is none_aes, use g mode hw security.
+	 */
 
 	ieee->hwsec_active = 1;
 
-	if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { /* add hwsec_support flag to totol control hw_sec on/off */
+	if ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { /* add hwsec_support flag to totol control hw_sec on/off */
 		ieee->hwsec_active = 0;
 		SECR_value &= ~SCR_RxDecEnable;
 	}
@@ -4862,39 +4879,40 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
 	u32 TargetContent = 0;
 	u16 usConfig = 0;
 	u8 i;
+
 	if (EntryNo >= TOTAL_CAM_ENTRY)
 		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
 
 	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev, EntryNo, KeyIndex, KeyType, MacAddr);
 
 	if (DefaultKey)
-		usConfig |= BIT15 | (KeyType<<2);
+		usConfig |= BIT15 | (KeyType << 2);
 	else
-		usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
+		usConfig |= BIT15 | (KeyType << 2) | KeyIndex;
 
 
 	for (i = 0; i < CAM_CONTENT_COUNT; i++) {
-		TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
-		TargetCommand |= BIT31|BIT16;
+		TargetCommand  = i + CAM_CONTENT_COUNT * EntryNo;
+		TargetCommand |= BIT31 | BIT16;
 
 		if (i == 0) { /* MAC|Config */
-			TargetContent = (u32)(*(MacAddr+0)) << 16|
-					(u32)(*(MacAddr+1)) << 24|
+			TargetContent = (u32)(*(MacAddr + 0)) << 16 |
+					(u32)(*(MacAddr + 1)) << 24 |
 					(u32)usConfig;
 
 			write_nic_dword(dev, WCAMI, TargetContent);
 			write_nic_dword(dev, RWCAM, TargetCommand);
 		} else if (i == 1) { /* MAC */
-			TargetContent = (u32)(*(MacAddr+2))	 |
-					(u32)(*(MacAddr+3)) <<  8|
-					(u32)(*(MacAddr+4)) << 16|
-					(u32)(*(MacAddr+5)) << 24;
+			TargetContent = (u32)(*(MacAddr + 2))	 |
+					(u32)(*(MacAddr + 3)) <<  8 |
+					(u32)(*(MacAddr + 4)) << 16 |
+					(u32)(*(MacAddr + 5)) << 24;
 			write_nic_dword(dev, WCAMI, TargetContent);
 			write_nic_dword(dev, RWCAM, TargetCommand);
 		} else {
-			//Key Material
+			/* Key Material */
 			if (KeyContent != NULL) {
-				write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)));
+				write_nic_dword(dev, WCAMI, (u32)(*(KeyContent + i - 2)));
 				write_nic_dword(dev, RWCAM, TargetCommand);
 			}
 		}
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index 0a7f58c59df5..076d5083c723 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -60,10 +60,6 @@ struct	__queue	{
 #define LIST_CONTAINOR(ptr, type, member) \
 	((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
 
-#ifndef BIT
-	#define BIT(x)	(1 << (x))
-#endif
-
 static inline u32 _down_sema(struct semaphore *sema)
 {
 	if (down_interruptible(sema))
diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h
index 17f513122f48..7a352c45344f 100644
--- a/drivers/staging/rtl8712/wifi.h
+++ b/drivers/staging/rtl8712/wifi.h
@@ -28,15 +28,7 @@
 
 #include <linux/compiler.h>
 
-#ifdef BIT
-#undef BIT
-#endif
-#define BIT(x)	(1 << (x))
-
-#define WLAN_ETHHDR_LEN		14
-#define WLAN_ETHADDR_LEN	6
 #define WLAN_IEEE_OUI_LEN	3
-#define WLAN_ADDR_LEN		6
 #define WLAN_CRC_LEN		4
 #define WLAN_BSSID_LEN		6
 #define WLAN_BSS_TS_LEN		8
@@ -52,7 +44,6 @@
 
 #define WLAN_MIN_ETHFRM_LEN	60
 #define WLAN_MAX_ETHFRM_LEN	1514
-#define WLAN_ETHHDR_LEN		14
 
 #define P80211CAPTURE_VERSION	0x80211001
 
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
index be9a3d560a43..fca22ba896b3 100644
--- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
@@ -5934,11 +5934,8 @@ int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
 			   macid = aid+1; */
 			cam_id = psta->mac_id + 3;
 
-			DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, "
-				  "cam_entry =%d\n", pparm->addr[0],
-				  pparm->addr[1], pparm->addr[2],
-				  pparm->addr[3], pparm->addr[4],
-				  pparm->addr[5], cam_id);
+			DBG_8723A("Write CAM, mac_addr =%pM, "
+				  "cam_entry =%d\n", pparm->addr, cam_id);
 
 			rtl8723a_cam_write(padapter, cam_id, ctrl,
 					   pparm->addr, pparm->key);
diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c
index 3d40bab1d9c8..038b57b3afe2 100644
--- a/drivers/staging/rtl8723au/core/rtw_security.c
+++ b/drivers/staging/rtl8723au/core/rtw_security.c
@@ -245,8 +245,8 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter,
 	arcfour_encrypt(&mycontext, payload, payload, length);
 
 	/* calculate icv and compare the icv */
-	actual_crc = le32_to_cpu(getcrc32(payload, length - 4));
-	expected_crc = le32_to_cpu(get_unaligned_le32(&payload[length - 4]));
+	actual_crc = getcrc32(payload, length - 4);
+	expected_crc = get_unaligned_le32(&payload[length - 4]);
 
 	if (actual_crc != expected_crc) {
 		RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
@@ -608,7 +608,6 @@ int rtw_tkip_encrypt23a(struct rtw_adapter *padapter,
 	u8 hw_hdr_offset = 0;
 	struct arc4context mycontext;
 	int curfragnum, length;
-	u32 prwskeylen;
 	u8 *pframe, *payload, *iv, *prwskey;
 	union pn48 dot11txpn;
 	struct sta_info *stainfo;
@@ -655,8 +654,6 @@ int rtw_tkip_encrypt23a(struct rtw_adapter *padapter,
 	else
 		prwskey = &stainfo->dot118021x_UncstKey.skey[0];
 
-	prwskeylen = 16;
-
 	/* 4 start to encrypt each fragment */
 	for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 		iv = pframe + pattrib->hdrlen;
@@ -719,7 +716,6 @@ int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
 	u32 actual_crc, expected_crc;
 	struct arc4context mycontext;
 	int length;
-	u32 prwskeylen;
 	u8 *pframe, *payload, *iv, *prwskey;
 	union pn48 dot11txpn;
 	struct sta_info *stainfo;
@@ -749,12 +745,10 @@ int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
 			goto exit;
 		}
 		prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
-		prwskeylen = 16;
 	} else {
 		RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
 			 "%s: stainfo!= NULL!!!\n", __func__);
 		prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-		prwskeylen = 16;
 	}
 
 	iv = pframe + prxattrib->hdrlen;
@@ -773,8 +767,8 @@ int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
 	arcfour_init(&mycontext, rc4key, 16);
 	arcfour_encrypt(&mycontext, payload, payload, length);
 
-	actual_crc = le32_to_cpu(getcrc32(payload, length - 4));
-	expected_crc = le32_to_cpu(get_unaligned_le32(&payload[length - 4]));
+	actual_crc = getcrc32(payload, length - 4);
+	expected_crc = get_unaligned_le32(&payload[length - 4]);
 
 	if (actual_crc != expected_crc) {
 		RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
@@ -1288,7 +1282,6 @@ int rtw_aes_encrypt23a(struct rtw_adapter *padapter,
 {	/* exclude ICV */
 	/* Intermediate Buffers */
 	int curfragnum, length;
-	u32 prwskeylen;
 	u8 *pframe, *prwskey;
 	u8 hw_hdr_offset = 0;
 	struct sta_info *stainfo;
@@ -1335,8 +1328,6 @@ int rtw_aes_encrypt23a(struct rtw_adapter *padapter,
 	else
 		prwskey = &stainfo->dot118021x_UncstKey.skey[0];
 
-	prwskeylen = 16;
-
 	for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 		/* 4 the last fragment */
 		if ((curfragnum + 1) == pattrib->nr_frags) {
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c
index 68156a13d00f..9926b0790e75 100644
--- a/drivers/staging/rtl8723au/hal/usb_halinit.c
+++ b/drivers/staging/rtl8723au/hal/usb_halinit.c
@@ -834,12 +834,11 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
 			rtl8723au_read32(Adapter, rOFDM0_TRxPathEnable);
 		Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
 			rtl8723au_read32(Adapter, rFPGA0_RFMOD);
-		if (pHalData->rf_type ==  RF_2T2R) {
+		if (pHalData->rf_type ==  RF_2T2R)
 			PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
 				     0x380038, 0);
-		} else if (pHalData->rf_type ==  RF_1T1R) {
+		else if (pHalData->rf_type ==  RF_1T1R)
 			PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0);
-		}
 		PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
 		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
 
diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h
index 4dcc9253be51..d1fa95d28904 100644
--- a/drivers/staging/rtl8723au/include/rtw_cmd.h
+++ b/drivers/staging/rtl8723au/include/rtw_cmd.h
@@ -725,11 +725,9 @@ void rtw_disassoc_cmd23a_callback(struct rtw_adapter  *padapter, struct cmd_obj
 void rtw_joinbss_cmd23a_callback(struct rtw_adapter  *padapter, struct cmd_obj *pcmd);
 void rtw_createbss_cmd23a_callback(struct rtw_adapter  *padapter, struct cmd_obj *pcmd);
 void rtw_getbbrfreg_cmdrsp_callback23a(struct rtw_adapter  *padapter, struct cmd_obj *pcmd);
-void rtw_readtssi_cmdrsp_callback(struct rtw_adapter*	padapter,  struct cmd_obj *pcmd);
 
 void rtw_setstaKey_cmdrsp_callback23a(struct rtw_adapter  *padapter,  struct cmd_obj *pcmd);
 void rtw_setassocsta_cmdrsp_callback23a(struct rtw_adapter  *padapter,  struct cmd_obj *pcmd);
-void rtw_getrttbl_cmdrsp_callback(struct rtw_adapter  *padapter,  struct cmd_obj *pcmd);
 
 struct _cmd_callback {
 	u32	cmd_code;
diff --git a/drivers/staging/speakup/devsynth.c b/drivers/staging/speakup/devsynth.c
index 71c728acf4ca..d1ffdf4c0c4b 100644
--- a/drivers/staging/speakup/devsynth.c
+++ b/drivers/staging/speakup/devsynth.c
@@ -22,7 +22,7 @@ static ssize_t speakup_file_write(struct file *fp, const char __user *buffer,
 	unsigned long flags;
 	u_char buf[256];
 
-	if (synth == NULL)
+	if (!synth)
 		return -ENODEV;
 	while (count > 0) {
 		bytes = min(count, sizeof(buf));
@@ -45,7 +45,7 @@ static ssize_t speakup_file_read(struct file *fp, char __user *buf,
 
 static int speakup_file_open(struct inode *ip, struct file *fp)
 {
-	if (synth == NULL)
+	if (!synth)
 		return -ENODEV;
 	if (xchg(&dev_opened, 1))
 		return -EBUSY;
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index 958add4839bc..fdfeb42b2b8f 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -368,7 +368,7 @@ static ssize_t synth_show(struct kobject *kobj, struct kobj_attribute *attr,
 {
 	int rv;
 
-	if (synth == NULL)
+	if (!synth)
 		rv = sprintf(buf, "%s\n", "none");
 	else
 		rv = sprintf(buf, "%s\n", synth->name);
@@ -459,14 +459,14 @@ static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr,
 	unsigned long flags;
 
 	p_header = spk_var_header_by_name(attr->attr.name);
-	if (p_header == NULL) {
+	if (!p_header) {
 		pr_warn("p_header is null, attr->attr.name is %s\n",
 			attr->attr.name);
 		return -EINVAL;
 	}
 
 	var = spk_get_punc_var(p_header->var_id);
-	if (var == NULL) {
+	if (!var) {
 		pr_warn("var is null, p_header->var_id is %i\n",
 				p_header->var_id);
 		return -EINVAL;
@@ -501,14 +501,14 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr,
 		return -EINVAL;
 
 	p_header = spk_var_header_by_name(attr->attr.name);
-	if (p_header == NULL) {
+	if (!p_header) {
 		pr_warn("p_header is null, attr->attr.name is %s\n",
 			attr->attr.name);
 		return -EINVAL;
 	}
 
 	var = spk_get_punc_var(p_header->var_id);
-	if (var == NULL) {
+	if (!var) {
 		pr_warn("var is null, p_header->var_id is %i\n",
 				p_header->var_id);
 		return -EINVAL;
@@ -546,7 +546,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
 	unsigned long flags;
 
 	param = spk_var_header_by_name(attr->attr.name);
-	if (param == NULL)
+	if (!param)
 		return -EINVAL;
 
 	spin_lock_irqsave(&speakup_info.spinlock, flags);
@@ -622,9 +622,9 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
 	unsigned long flags;
 
 	param = spk_var_header_by_name(attr->attr.name);
-	if (param == NULL)
+	if (!param)
 		return -EINVAL;
-	if (param->data == NULL)
+	if (!param->data)
 		return 0;
 	ret = 0;
 	cp = (char *)buf;
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index 98af3b1f2d2a..aa5ab6c80ed4 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -7,7 +7,7 @@
 #include <linux/workqueue.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <asm/cmpxchg.h>
+#include <linux/atomic.h>
 
 #include "speakup.h"
 
diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c
index 66ac999a0323..3b5835b28128 100644
--- a/drivers/staging/speakup/serialio.c
+++ b/drivers/staging/speakup/serialio.c
@@ -101,7 +101,7 @@ static void start_serial_interrupt(int irq)
 {
 	int rv;
 
-	if (synth->read_buff_add == NULL)
+	if (!synth->read_buff_add)
 		return;
 
 	rv = request_irq(irq, synth_readbuf_handler, IRQF_SHARED,
@@ -127,7 +127,7 @@ void spk_stop_serial_interrupt(void)
 	if (speakup_info.port_tts == 0)
 		return;
 
-	if (synth->read_buff_add == NULL)
+	if (!synth->read_buff_add)
 		return;
 
 	/* Turn off interrupts */
diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c
index b5a23d42f4d5..09063b82326f 100644
--- a/drivers/staging/speakup/speakup_dectlk.c
+++ b/drivers/staging/speakup/speakup_dectlk.c
@@ -291,10 +291,9 @@ static void do_catch_up(struct spk_synth *synth)
 
 static void synth_flush(struct spk_synth *synth)
 {
-	if (in_escape) {
+	if (in_escape)
 		/* if in command output ']' so we don't get an error */
 		spk_serial_out(']');
-	}
 	in_escape = 0;
 	is_flushing = 1;
 	spk_serial_out(SYNTH_CLEAR);
diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c
index 75bf40c14c79..b2afec63a6dd 100644
--- a/drivers/staging/speakup/varhandlers.c
+++ b/drivers/staging/speakup/varhandlers.c
@@ -90,7 +90,7 @@ void speakup_register_var(struct var_t *var)
 	struct st_var_header *p_header;
 
 	BUG_ON(!var || var->var_id < 0 || var->var_id >= MAXVARS);
-	if (var_ptrs[0] == NULL) {
+	if (!var_ptrs[0]) {
 		for (i = 0; i < MAXVARS; i++) {
 			p_header = &var_headers[i];
 			var_ptrs[p_header->var_id] = p_header;
@@ -130,7 +130,7 @@ struct st_var_header *spk_get_var_header(enum var_id_t var_id)
 	if (var_id < 0 || var_id >= MAXVARS)
 		return NULL;
 	p_header = var_ptrs[var_id];
-	if (p_header->data == NULL)
+	if (!p_header->data)
 		return NULL;
 	return p_header;
 }
@@ -163,7 +163,7 @@ struct punc_var_t *spk_get_punc_var(enum var_id_t var_id)
 	struct punc_var_t *where;
 
 	where = punc_vars;
-	while ((where->var_id != -1) && (rv == NULL)) {
+	while ((where->var_id != -1) && (!rv)) {
 		if (where->var_id == var_id)
 			rv = where;
 		else
@@ -183,7 +183,7 @@ int spk_set_num_var(int input, struct st_var_header *var, int how)
 	char *cp;
 	struct var_t *var_data = var->data;
 
-	if (var_data == NULL)
+	if (!var_data)
 		return -ENODATA;
 
 	if (how == E_NEW_DEFAULT) {
@@ -221,9 +221,9 @@ int spk_set_num_var(int input, struct st_var_header *var, int how)
 	if (var_data->u.n.multiplier != 0)
 		val *= var_data->u.n.multiplier;
 	val += var_data->u.n.offset;
-	if (var->var_id < FIRST_SYNTH_VAR || synth == NULL)
+	if (var->var_id < FIRST_SYNTH_VAR || !synth)
 		return ret;
-	if (synth->synth_adjust != NULL) {
+	if (synth->synth_adjust) {
 		int status = synth->synth_adjust(var);
 
 		return (status != 0) ? status : ret;
@@ -247,7 +247,7 @@ int spk_set_string_var(const char *page, struct st_var_header *var, int len)
 {
 	struct var_t *var_data = var->data;
 
-	if (var_data == NULL)
+	if (!var_data)
 		return -ENODATA;
 	if (len > MAXVARLEN)
 		return -E2BIG;
@@ -288,7 +288,7 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
 			if (*cp < SPACE)
 				break;
 			if (mask < PUNC) {
-				if (!(spk_chartab[*cp]&PUNC))
+				if (!(spk_chartab[*cp] & PUNC))
 					break;
 			} else if (spk_chartab[*cp]&B_NUM)
 				break;
@@ -313,7 +313,7 @@ char *spk_strlwr(char *s)
 {
 	char *p;
 
-	if (s == NULL)
+	if (!s)
 		return NULL;
 
 	for (p = s; *p; p++)
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
index 1f9ba8beb061..824d460911ec 100644
--- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
@@ -1138,4 +1138,3 @@ module_i2c_driver(synaptics_rmi4_driver);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("naveen.gaddipati@stericsson.com, js.ha@stericsson.com");
 MODULE_DESCRIPTION("synaptics rmi4 i2c touch Driver");
-MODULE_ALIAS("i2c:synaptics_rmi4_ts");
diff --git a/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset b/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset
index 28f8f1233fc6..b0498ff32405 100644
--- a/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset
+++ b/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset
@@ -1,3 +1,5 @@
+This file describes sysfs entries beneath /devices/platform/visorchipset.
+
 What:		install/error
 Date:		7/18/2014
 KernelVersion: 	TBD
diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt
index 8d078e4de3b8..25f93f2a1e33 100644
--- a/drivers/staging/unisys/Documentation/overview.txt
+++ b/drivers/staging/unisys/Documentation/overview.txt
@@ -1,76 +1,282 @@
+1. Overview
+-----------
 
-Overview
-
-This document describes the driver set for Unisys Secure Partitioning (s-Par®).
+This document describes the driver set for Unisys Secure Partitioning
+(s-Par(R)).
 
 s-Par is firmware that provides hardware partitioning capabilities for
 splitting large-scale Intel x86 servers into multiple isolated
 partitions. s-Par provides a set of para-virtualized device drivers to
 allow guest partitions on the same server to share devices that would
-normally be unsharable; specifically, PCI network interfaces and host
-bus adapters that do not support shared access via SR-IOV. The shared
-device is owned and managed by a small, single-purpose service
-partition, which communicates with each guest partition sharing that
-device through an area of shared memory called a channel. Additional
-drivers provide support interfaces for communicating with s-Par
-services, logging and diagnostics, and accessing the Linux console
-from the s-Par user interface.
-
-The driver stack consists of a set of support modules, a set of bus
-modules, and a set of device driver modules. The support modules
-handle a number of common functions across each of the other
-drivers. The bus modules provide organization for the device driver
-modules, which provide the shared device functionality.
-
-These drivers are for the Unisys virtual PCI hardware model where the
-hypervisor need not intervene (other than normal interrupt handling)
-in the interactions between the client drivers and the virtual adapter
-firmware in the adapter service partition.
-
-Driver Descriptions
-
-Device Modules
-
-The modules in this section handle shared devices and the virtual
-buses required to support them. These modules use functions in and
-depend on the modules described in the support modules section.
-
-visorchipset
-
-The visorchipset module receives device creation and destruction
-events from the Command service partition of s-Par, as well as
-controlling registration of shared device drivers with the s-Par
-driver core. The events received are used to populate other s-Par
-modules with their assigned shared devices. Visorchipset is required
-for shared device drivers to function properly. Visorchipset also
-stores information for handling dump disk device creation during
-kdump.
-
-In operation, the visorchipset module processes device creation and
-destruction messages sent by s-Par's Command service partition through
-a channel. These messages result in creation (or destruction) of each
-virtual bus and virtual device. Each bus and device is also associated
-with a communication channel, which is used to communicate with one or
-more IO service partitions to perform device IO on behalf of the
-guest.
-
-virthba
-
-The virthba module provides access to a shared SCSI host bus adapter
-and one or more disk devices, by proxying SCSI commands between the
-guest and the service partition that owns the shared SCSI adapter,
-using a channel between the guest and the service partition. The disks
-that appear on the shared bus are defined by the s-Par configuration
-and enforced by the service partition, while the guest driver handles
-sending commands and handling responses. Each disk is shared as a
-whole to a guest. Sharing the bus adapter in this way provides
-resiliency; should the device encounter an error, only the service
+normally be unsharable, specifically:
+
+* visornic - network interface
+* visorhba - scsi disk adapter
+* visorhid - keyboard and mouse
+
+These drivers conform to the standard Linux bus/device model described
+within Documentation/driver-model/, and utilize a driver named visorbus to
+present the virtual busses involved. Drivers in the 'visor*' driver set are
+commonly referred to as "guest drivers" or "client drivers".  All drivers
+except visorbus expose a device of a specific usable class to the Linux guest
+environment (e.g., block, network, or input), and are collectively referred
+to as "function drivers".
+
+The back-end for each device is owned and managed by a small,
+single-purpose service partition in the s-Par firmware, which communicates
+with each guest partition sharing that device through an area of shared memory
+called a "channel". In s-Par nomenclature, the back-end is often referred to
+as the "service partition", "IO partition" (for virtual network and scsi disk
+devices), or "console partition" (for virtual keyboard and mouse devices).
+
+Each virtual device requires exactly 1 dedicated channel, which the guest
+driver and back-end use to communicate.  The hypervisor need not intervene
+(other than normal interrupt handling) in the interactions that occur across
+this channel.
+
+NOT covered in this document:
+
+* s-Par also supports sharing physical PCI adapters via SR-IOV, but
+  because this requires no specific support in the guest partitions, it will
+  not be discussed in this document.  Shared SR-IOV devices should be used
+  wherever possible for highest performance.
+
+* Because the s-Par back-end provides a standard EFI framebuffer to each
+  guest, the already-existing efifb Linux driver is used to provide guest
+  video access. Thus, the only s-Par-unique support that is necessary to
+  provide a guest graphics console are for keyboard and mouse (via visorhid).
+
+
+2. Driver Descriptions
+----------------------
+
+2.1. visorbus
+-------------
+
+2.1.1. Overview
+---------------
+
+The visorbus driver handles the virtual busses on which all of the virtual
+devices reside. It provides a registration function named
+visorbus_register_visor_driver() that is called by each of the function
+drivers at initialization time, which the function driver uses to tell
+visorbus about the device classes (via specifying a list of device type
+GUIDs) it wants to handle. For use by function drivers, visorbus provides
+implementation for struct visor_driver and struct visor_device, as well
+as utility functions for communicating with the back-end.
+
+visorbus is associated with ACPI id "PNP0A07" in modules.alias, so if built
+as a module it will typically be loaded automatically via standard udev or
+systemd (God help us) configurations.
+
+visorbus can similarly force auto-loading of function drivers for virtual
+devices it discovers, as it includes a MODALIAS environment variable of this
+form in the hotplug uevent environment when each virtual device is
+discovered:
+
+    visorbus:<device type GUID>
+
+visorbus notifies each function driver when a device of its registered class
+arrives and departs, by calling the function driver's probe() and remove()
+methods.
+
+The actual struct device objects that correspond to each virtual bus and
+each virtual device are created and owned by visorbus.  These device objects
+are created in response to messages from the s-Par back-end received on a
+special control channel called the "controlvm channel" (each guest partition
+has access to exactly 1 controlvm channel), and have a lifetime that is
+independent of the function drivers that control them.
+
+2.1.2. "struct visor device" Function Driver Interfaces
+-------------------------------------------------------
+
+The interface between visorbus and its function drivers is defined in
+visorbus.h, and described below.
+
+When a visor function driver loads, it calls visorbus_register_visor_driver()
+to register itself with visorbus. The significant information passed in this
+exchange is as follows:
+
+* the GUID(s) of the channel type(s) that are handled by this driver, as
+  well as a "friendly name" identifying each (this will be published under
+  /sys/devices/visorbus<x>/dev<y>)
+
+* the addresses of callback functions to be called whenever a virtual
+  device/channel with the appropriate channel-type GUID(s) appears or
+  disappears
+
+* the address of a "channel_interrupt" function, which will be automatically
+  called at specific intervals to enable the driver to poll the device
+  channel for activity
+
+The following functions implemented within each function driver will be
+called automatically by the visorbus driver at appropriate times:
+
+* The probe() function notifies about the creation of each new virtual
+  device/channel instance.
+
+* The remove() function notifies about the destruction of a virtual
+  device/channel instance.
+
+* The channel_interrupt() function is called at frequent intervals to
+  give the function driver an opportunity to poll the virtual device channel
+  for requests.  Information is passed to this function to enable the
+  function driver to use the visorchannel_signalinsert() and
+  visorchannel_signalremove() functions to respond to and initiate activity
+  over the channel.  (Note that since it is the visorbus driver that
+  determines when this is called, it is very easy to switch to
+  interrupt-driven mechanisms when available for particular virtual device
+  types.)
+
+* The pause() function is called should it ever be necessary to direct the
+  function driver to temporarily stop accessing the device channel.  An
+  example of when this is needed is when the service partition implementing
+  the back-end of the virtual device needs to be recovered.  After a
+  successful return of pause(), the function driver must not access the
+  device channel until a subsequent resume() occurs.
+
+* The resume() function is the "book-end" to pause(), and is described above.
+
+If/when a function driver creates a Linux device (that needs to be accessed
+from usermode), it calls visorbus_registerdevnode(), passing the major and
+minor number of the device.  (Of course not all function drivers will need
+to do this.)  This simply creates the appropriate "devmajorminor" sysfs entry
+described below, so that a hotplug script can use it to create a device node.
+
+2.1.3. sysfs Advertised Information
+-----------------------------------
+
+Because visorbus is a standard Linux bus driver in the model described in
+Documentation/driver-model/, the hierarchy of s-Par virtual devices is
+published in the sysfs tree beneath /bus/visorbus/, e.g.,
+/sys/bus/visorbus/devices/ might look like:
+
+    vbus1:dev1 -> ../../../devices/visorbus1/vbus1:dev1
+    vbus1:dev2 -> ../../../devices/visorbus1/vbus1:dev2
+    vbus1:dev3 -> ../../../devices/visorbus1/vbus1:dev3
+    vbus2:dev0 -> ../../../devices/visorbus2/vbus2:dev0
+    vbus2:dev1 -> ../../../devices/visorbus2/vbus2:dev1
+    vbus2:dev2 -> ../../../devices/visorbus2/vbus2:dev2
+    visorbus1 -> ../../../devices/visorbus1
+    visorbus2 -> ../../../devices/visorbus2
+
+visor_device notes:
+
+* Each visorbus<n> entry denotes the existence of a struct visor_device
+  denoting virtual bus #<n>.  A unique s-Par channel exists for each such
+  virtual bus.
+
+* Virtual bus numbers uniquely identify s-Par back-end service partitions.
+  In this example, bus 1 corresponds to the s-Par console partition
+  (controls keyboard, video, and mouse), whereas bus 2 corresponds to the
+  s-Par IO partition (controls network and disk).
+
+* Each vbus<x>:dev<y> entry denotes the existence of a struct visor_device
+  denoting virtual device #<y> outboard of virtual bus #<x>.  A unique s-Par
+  channel exists for each such virtual device.
+
+* If a function driver has loaded and claimed a particular device, the
+  bus/visorbus/devices/vbus<x>:dev<y>/driver symlink will indicate that
+  function driver.
+
+Every active visorbus device will have a sysfs subtree under:
+
+    /sys/devices/visorbus<x>/vbus<x>:dev<y>/
+
+The following files exist under /sys/devices/visorbus<x>/vbus<x>:dev<y>:
+
+    subsystem                 link to sysfs tree that describes the
+                              visorbus bus type; e.g.:
+                                  ../../../bus/visorbus
+
+    driver                    link to sysfs tree that describes the
+                              function driver controlling this device;
+                              e.g.:
+                                  ../../../bus/visorbus/drivers/visorhba
+                              Note that this "driver" link will not exist
+                              if the appropriate function driver has not
+                              been loaded yet.
+
+    devmajorminor
+
+        <devname>             if applicable, each file here identifies (via
+        ...                   its file contents) the
+                              "<major>:<minor>" needed for a device node to
+                              enable access from usermode.  There is exactly
+                              one file here for each different device node
+                              that can be accessed (from usermode).  Note
+                              that this info is provided by a particular
+                              function driver, so these will not exist
+                              until AFTER the appropriate function driver
+                              controlling this device class is loaded.
+
+    channel                   properties of the device channel (all in
+                              ascii text format)
+
+        clientpartition       handle identifying the guest (client) side
+                              of this channel, e.g. 0x10000000.
+
+        nbytes                total size of this channel in bytes
+
+        physaddr              the guest physical address for the base of
+                              the channel
+
+        typeguid              a GUID identifying the channel type, in
+                              xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx notation
+
+        typename              a "friendly name" for this channel type, e.g.,
+                              "keyboard".  Note that this name is provided by
+                              a particular function driver, so "typename"
+                              will return an empty string until AFTER the
+                              appropriate function driver controlling this
+                              channel type is loaded
+
+        zoneguid              a GUID identifying the channel zone, in
+                              xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx notation
+
+
+2.2. visorhba
+-------------
+
+The visorhba driver registers with visorbus as the function driver to
+handle virtual scsi disk devices, specified using the
+SPAR_VHBA_CHANNEL_PROTOCOL_UUID type in the visorbus_register_visor_driver()
+call. visorhba uses scsi_add_host() to expose a Linux block device
+(e.g., /sys/block/) in the guest environment for each s-Par virtual device.
+
+visorhba provides access to a shared SCSI host bus adapter and one or more
+disk devices, by proxying SCSI commands between the guest and the service
+partition that owns the shared SCSI adapter, using a channel between the
+guest and the service partition. The disks that appear on the shared bus
+are defined by the s-Par configuration and enforced by the service partition,
+while the guest driver handles sending commands and handling responses. Each
+disk is shared as a whole to a guest. Sharing the bus adapter in this way
+provides resiliency; should the device encounter an error, only the service
 partition is rebooted, and the device is reinitialized. This allows
 guests to continue running and to recover from the error.
 
-virtnic
+When compiled as a module, visorhba can be autoloaded by visorbus in
+standard udev/systemd environments, as it includes the modules.alias
+definition:
+
+    "visorbus:"+SPAR_VHBA_CHANNEL_PROTOCOL_UUID_STR
+
+i.e.:
+
+    alias visorbus:414815ed-c58c-11da-95a9-00e08161165f visorhba
+
 
-The virtnic module provides a paravirtualized network interface to a
+2.3. visornic
+-------------
+
+The visornic driver registers with visorbus as the function driver to
+handle virtual network devices, specified using the
+SPAR_VNIC_CHANNEL_PROTOCOL_UUID type in the visorbus_register_visor_driver()
+call. visornic uses register_netdev() to expose a Linux device of class net
+(e.g., /sys/class/net/) in the guest environment for each s-Par virtual
+device.
+
+visornic provides a paravirtualized network interface to a
 guest by proxying buffer information between the guest and the service
 partition that owns the shared network interface, using a channel
 between the guest and the service partition. The connectivity of this
@@ -79,96 +285,72 @@ partitions is defined by the s-Par configuration and enforced by the
 service partition; the guest driver handles communication and link
 status.
 
-visorserial
-
-The visorserial module allows the console of the linux guest to be
-accessed via the s-Par console serial channel. It creates devices in
-/dev/visorserialclientX which behave like a serial terminal and are
-connected to the diagnostics system in s-Par. By assigning a getty to
-the terminal in the guest, a user could log into and access the guest
-from the s-Par diagnostics SWITCH RUN terminal.
-
-visorbus
-
-The visorbus module handles the bus functions for most functional
-drivers except visorserial, visordiag, virthba, and virtnic. It
-maintains the sysfs subtree /sys/devices/visorbus*/. It is responsible
-for device creation and destruction of the devices on its bus.
-
-visorclientbus
-
-The visorclientbus module forwards the bus functions for virthba, and
-virtnic to the virtpci driver.
-
-virtpci
-
-The virtpci module handles the bus functions for virthba, and virtnic.
-
-s-Par Integration Modules
-
-The modules in this section provide integration with s-Par guest
-partition services like diagnostics and remote desktop. These modules
-depend on functions in the modules described in the support modules
-section.
-
-visorvideoclient
-
-The visorvideoclient module provides functionality for video support
-for the Unisys s-Par Partition Desktop application. The guest OS must
-also have the UEFI GOP protocol enabled for the partition desktop to
-function.  visorconinclient The visorconinclient module provides
-keyboard and mouse support for the Unisys s-Par Partition Desktop
-application.
+When compiled as a module, visornic can be autoloaded by visorbus in
+standard udev/systemd environments, as it includes the modules.alias
+definition:
 
-sparstop
+    "visorbus:"+SPAR_VNIC_CHANNEL_PROTOCOL_UUID_STR
 
-The sparstop module handles requests from the Unisys s-Par platform to
-shutdown the linux guest. It allows a program on the guest to perform
-clean-up functions on the guest before the guest is shut down or
-rebooted using ACPI.
+i.e.:
 
-visordiag
+    alias visorbus:8cd5994d-c58e-11da-95a9-00e08161165f visornic
 
-This driver provides the ability for the guest to write information
-into the s-Par diagnostics subsystem. It creates a set of devices
-named /dev/visordiag.X which can be written to by the guest to add
-text to the s-Par system log.
 
-Support Modules
+2.4. visorhid
+-------------
 
-The modules described in this section provide functions and
-abstractions to support the modules described in the previous
-sections, to avoid having duplicated functionality.
+The visorhid driver registers with visorbus as the function driver to
+handle human input devices, specified using the
+SPAR_KEYBOARD_CHANNEL_PROTOCOL_UUID and SPAR_MOUSE_CHANNEL_PROTOCOL_UUID
+types in the visorbus_register_visor_driver() call. visorhid uses
+input_register_device() to expose devices of class input
+(e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices.
+A s-Par virtual keyboard device maps 1-to-1 with a Linux input device
+named "visor Keyboard", while a s-Par virtual mouse device has 2 Linux input
+devices created for it: 1 named "visor Wheel", and 1 named "visor Mouse".
 
-visornoop
+By registering as input class devices, modern versions of X will
+automatically find and properly use s-Par virtual keyboard and mouse devices.
+As the s-Par back-end reports keyboard and mouse activity via events on the
+virtual device channel, the visorhid driver delivers the activity to the
+Linux environment by calling input_report_key() and input_report_abs().
 
-The visornoop module is a placeholder that responds to device
-create/destroy messages that are currently not in use by linux guests.
+You can interact with the guest console using the usyscon Partition Desktop
+(a.k.a., "pd") application, provided as part of s-Par.  After installing the
+usyscon Partition Desktop into a Linux environment via the
+usyscon_partitiondesktop-*.rpm, or into a Windows environment via
+PartitionDesktop.msi, you will be able to launch a console for your guest
+Linux environment by clicking the console icon in the s-Par web UI.
 
-visoruislib
+When compiled as a module, visorhid can be autoloaded by visorbus in
+standard udev/systemd environments, as it includes the modules.alias
+definition:
 
-The visoruislib module is a support library, used to handle requests
-from virtpci.
+    "visorbus:"+SPAR_MOUSE_CHANNEL_PROTOCOL_UUID_STR
+    "visorbus:"+SPAR_KEYBOARD_CHANNEL_PROTOCOL_UUID_STR
 
-visorchannelstub
+i.e.:
 
-The visorchannelstub module provides support routines for storing and
-retrieving data from a channel.
+    alias visorbus:c73416d0-b0b8-44af-b304-9d2ae99f1b3d visorhid
+    alias visorbus:addf07d4-94a9-46e2-81c3-61abcdbdbd87 visorhid
 
-visorchannel
 
-The visorchannel module is a support library that abstracts reading
-and writing a channel in memory.
+3. Minimum Required Driver Set
+------------------------------
 
-visorutil
+visorbus is required for every Linux guest running under s-Par.
 
-The visorutil module is a support library required by all other s-Par
-driver modules. Among its features it abstracts reading, writing, and
-manipulating a block of memory.
+visorhba is typically required for a Linux guest running under s-Par, as it
+is required if your guest boot disk is a virtual device provided by the s-Par
+back-end, which is the default configuration.  However, for advanced
+configurations where the Linux guest boots via an SR-IOV-provided HBA or
+SAN disk for example, visorhba is not technically required.
 
-Minimum Required Driver Set
+visornic is typically required for a Linux guest running under s-Par, as it
+is required if your guest network interface is a virtual device provided by
+the s-Par back-end, which is the default configuration.  However, for
+configurations where the Linux guest is provided with an SR-IOV NIC
+for example, visornic is not technically required.
 
-The drivers required to boot a Linux guest are visorchipset, visorbus,
-visorvideoclient, visorconinclient, visoruislib, visorchannelstub,
-visorchannel, and visorutil. The other drivers are required by the
-product configurations that are currently being marketed.
+visorhid is only required for a Linux guest running under s-Par if you
+require graphics-mode access to your guest console.
diff --git a/drivers/staging/unisys/TODO b/drivers/staging/unisys/TODO
index 034ac61c44f2..d863f266bf76 100644
--- a/drivers/staging/unisys/TODO
+++ b/drivers/staging/unisys/TODO
@@ -1,19 +1,14 @@
 TODO:
-	-checkpatch warnings
-	-move /proc entries to /sys
-	-proper major number(s)
-	-add other drivers needed for full functionality:
-		-visorclientbus
-		-visorbus
-		-visordiag
-		-virtnic
-		-visornoop
-		-visorserial
-		-visorvideoclient
-		-visorconinclient
-		-sparstop
-	-move individual drivers into proper driver subsystems
-		
+	- enhance visornic to use channel_interrupt() hook instead of a
+	  kernel thread
+	- enhance visorhba to use channel_interrupt() hook instead of a
+	  kernel thread
+	- teach visorbus to handle virtual interrupts triggered by s-Par
+	  back-end, and call function driver's channel_interrupt() function
+	  when they occur
+	- enhance debugfs interfaces (e.g., per device, etc.)
+	- upgrade/remove deprecated workqueue operations
+	- move individual drivers into proper driver subsystems
 
 Patches to:
 	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c
index 2309f5f2b238..a272b48bab28 100644
--- a/drivers/staging/unisys/visorbus/visorbus_main.c
+++ b/drivers/staging/unisys/visorbus/visorbus_main.c
@@ -37,6 +37,8 @@ static int visorbus_debugref;
 #define POLLJIFFIES_TESTWORK         100
 #define POLLJIFFIES_NORMALCHANNEL     10
 
+static int busreg_rc = -ENODEV; /* stores the result from bus registration */
+
 static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env);
 static int visorbus_match(struct device *xdev, struct device_driver *xdrv);
 static void fix_vbus_dev_info(struct visor_device *visordev);
@@ -863,6 +865,9 @@ int visorbus_register_visor_driver(struct visor_driver *drv)
 {
 	int rc = 0;
 
+	if (busreg_rc < 0)
+		return -ENODEV; /*can't register on a nonexistent bus*/
+
 	drv->driver.name = drv->name;
 	drv->driver.bus = &visorbus_type;
 	drv->driver.probe = visordriver_probe_device;
@@ -885,6 +890,8 @@ int visorbus_register_visor_driver(struct visor_driver *drv)
 	if (rc < 0)
 		return rc;
 	rc = register_driver_attributes(drv);
+	if (rc < 0)
+		driver_unregister(&drv->driver);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(visorbus_register_visor_driver);
@@ -1260,10 +1267,8 @@ remove_bus_instance(struct visor_device *dev)
 static int
 create_bus_type(void)
 {
-	int rc = 0;
-
-	rc = bus_register(&visorbus_type);
-	return rc;
+	busreg_rc = bus_register(&visorbus_type);
+	return busreg_rc;
 }
 
 /** Remove the one-and-only one instance of the visor bus type (visorbus_type).
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index 8c9da7ea7845..9d3c1e282062 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -1189,16 +1189,16 @@ visornic_rx(struct uiscmdrsp *cmdrsp)
 	spin_lock_irqsave(&devdata->priv_lock, flags);
 	atomic_dec(&devdata->num_rcvbuf_in_iovm);
 
-	/* update rcv stats - call it with priv_lock held */
-	devdata->net_stats.rx_packets++;
-	devdata->net_stats.rx_bytes = skb->len;
-
 	/* set length to how much was ACTUALLY received -
 	 * NOTE: rcv_done_len includes actual length of data rcvd
 	 * including ethhdr
 	 */
 	skb->len = cmdrsp->net.rcv.rcv_done_len;
 
+	/* update rcv stats - call it with priv_lock held */
+	devdata->net_stats.rx_packets++;
+	devdata->net_stats.rx_bytes += skb->len;
+
 	/* test enabled while holding lock */
 	if (!(devdata->enabled && devdata->enab_dis_acked)) {
 		/* don't process it unless we're in enable mode and until
@@ -1924,13 +1924,16 @@ static int visornic_probe(struct visor_device *dev)
 			"%s debugfs_create_dir %s failed\n",
 			__func__, netdev->name);
 		err = -ENOMEM;
-		goto cleanup_xmit_cmdrsp;
+		goto cleanup_register_netdev;
 	}
 
 	dev_info(&dev->device, "%s success netdev=%s\n",
 		 __func__, netdev->name);
 	return 0;
 
+cleanup_register_netdev:
+	unregister_netdev(netdev);
+
 cleanup_napi_add:
 	del_timer_sync(&devdata->irq_poll_timer);
 	netif_napi_del(&devdata->napi);
@@ -2128,8 +2131,9 @@ static int visornic_init(void)
 	if (!dev_num_pool)
 		goto cleanup_workqueue;
 
-	visorbus_register_visor_driver(&visornic_driver);
-	return 0;
+	err = visorbus_register_visor_driver(&visornic_driver);
+	if (!err)
+		return 0;
 
 cleanup_workqueue:
 	if (visornic_timeout_reset_workqueue) {
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index c7b75dfc2d5f..ecbe94f41e22 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -564,7 +564,7 @@ CARDvSafeResetRx(
 )
 {
 	unsigned int uu;
-	PSRxDesc    pDesc;
+	struct vnt_rx_desc *pDesc;
 
 	/* initialize RD index */
 	pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
@@ -573,17 +573,17 @@ CARDvSafeResetRx(
 	/* init state, all RD is chip's */
 	for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) {
 		pDesc = &(pDevice->aRD0Ring[uu]);
-		pDesc->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
-		pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC;
-		pDesc->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
+		pDesc->rd0.res_count = cpu_to_le16(pDevice->rx_buf_sz);
+		pDesc->rd0.owner = OWNED_BY_NIC;
+		pDesc->rd1.req_count = cpu_to_le16(pDevice->rx_buf_sz);
 	}
 
 	/* init state, all RD is chip's */
 	for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) {
 		pDesc = &(pDevice->aRD1Ring[uu]);
-		pDesc->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
-		pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC;
-		pDesc->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
+		pDesc->rd0.res_count = cpu_to_le16(pDevice->rx_buf_sz);
+		pDesc->rd0.owner = OWNED_BY_NIC;
+		pDesc->rd1.req_count = cpu_to_le16(pDevice->rx_buf_sz);
 	}
 
 	/* set perPkt mode */
diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h
index 3c9007e34c0f..9fbc7172484e 100644
--- a/drivers/staging/vt6655/desc.h
+++ b/drivers/staging/vt6655/desc.h
@@ -167,54 +167,42 @@
  * leads error.
  */
 
-typedef struct tagDEVICE_RD_INFO {
+struct vnt_rd_info {
 	struct sk_buff *skb;
 	dma_addr_t  skb_dma;
-} DEVICE_RD_INFO,   *PDEVICE_RD_INFO;
+};
 
+struct vnt_rdes0 {
+	volatile __le16 res_count;
 #ifdef __BIG_ENDIAN
-
-typedef struct tagRDES0 {
-	volatile __le16 wResCount;
 	union {
-		volatile u16    f15Reserved;
+		volatile u16 f15_reserved;
 		struct {
-			volatile u8 f8Reserved1;
-			volatile u8 f1Owner:1;
-			volatile u8 f7Reserved:7;
-		} __attribute__ ((__packed__));
-	} __attribute__ ((__packed__));
-} __attribute__ ((__packed__))
-SRDES0, *PSRDES0;
-
+			volatile u8 f8_reserved1;
+			volatile u8 owner:1;
+			volatile u8 f7_reserved:7;
+		} __packed;
+	} __packed;
 #else
-
-typedef struct tagRDES0 {
-	__le16         wResCount;
-	unsigned short f15Reserved:15;
-	unsigned short f1Owner:1;
-} __attribute__ ((__packed__))
-SRDES0;
-
+	u16 f15_reserved:15;
+	u16 owner:1;
 #endif
+} __packed;
 
-typedef struct tagRDES1 {
-	__le16	       wReqCount;
-	unsigned short wReserved;
-} __attribute__ ((__packed__))
-SRDES1;
+struct vnt_rdes1 {
+	__le16 req_count;
+	u16 reserved;
+} __packed;
 
 /* Rx descriptor*/
-typedef struct tagSRxDesc {
-	volatile SRDES0 m_rd0RD0;
-	volatile SRDES1 m_rd1RD1;
+struct vnt_rx_desc {
+	volatile struct vnt_rdes0 rd0;
+	volatile struct vnt_rdes1 rd1;
 	volatile __le32 buff_addr;
 	volatile __le32 next_desc;
-	struct tagSRxDesc *next __aligned(8);
-	volatile PDEVICE_RD_INFO pRDInfo __aligned(8);
-} __attribute__ ((__packed__))
-SRxDesc, *PSRxDesc;
-typedef const SRxDesc *PCSRxDesc;
+	struct vnt_rx_desc *next __aligned(8);
+	struct vnt_rd_info *rd_info __aligned(8);
+} __packed;
 
 struct vnt_tdes0 {
 	volatile u8 tsr0;
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index c9fa6ef42d34..d1917d04af30 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -258,9 +258,9 @@ struct vnt_private {
 	struct vnt_tx_desc *apTD0Rings;
 	struct vnt_tx_desc *apTD1Rings;
 
-	volatile PSRxDesc           aRD0Ring;
-	volatile PSRxDesc           aRD1Ring;
-	volatile PSRxDesc           pCurrRD[TYPE_MAXRD];
+	struct vnt_rx_desc *aRD0Ring;
+	struct vnt_rx_desc *aRD1Ring;
+	struct vnt_rx_desc *pCurrRD[TYPE_MAXRD];
 
 	OPTIONS                     sOpts;
 
@@ -410,9 +410,9 @@ struct vnt_private {
 	struct ieee80211_low_level_stats low_stats;
 };
 
-static inline PDEVICE_RD_INFO alloc_rd_info(void)
+static inline struct vnt_rd_info *alloc_rd_info(void)
 {
-	return kzalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC);
+	return kzalloc(sizeof(struct vnt_rd_info), GFP_ATOMIC);
 }
 
 static inline struct vnt_td_info *alloc_td_info(void)
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 0d8f123c57fe..86c24a1ab4fa 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -155,7 +155,7 @@ static void device_init_td1_ring(struct vnt_private *pDevice);
 
 static int  device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx);
 static int  device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx);
-static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pDesc);
+static bool device_alloc_rx_buf(struct vnt_private *, struct vnt_rx_desc *);
 static void device_init_registers(struct vnt_private *pDevice);
 static void device_free_tx_buf(struct vnt_private *, struct vnt_tx_desc *);
 static void device_free_td0_ring(struct vnt_private *pDevice);
@@ -520,8 +520,8 @@ static bool device_init_rings(struct vnt_private *pDevice)
 
 	/*allocate all RD/TD rings a single pool*/
 	vir_pool = dma_zalloc_coherent(&pDevice->pcid->dev,
-					 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
-					 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+					 pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc) +
+					 pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc) +
 					 pDevice->sOpts.nTxDescs[0] * sizeof(struct vnt_tx_desc) +
 					 pDevice->sOpts.nTxDescs[1] * sizeof(struct vnt_tx_desc),
 					 &pDevice->pool_dma, GFP_ATOMIC);
@@ -532,11 +532,11 @@ static bool device_init_rings(struct vnt_private *pDevice)
 
 	pDevice->aRD0Ring = vir_pool;
 	pDevice->aRD1Ring = vir_pool +
-		pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
+		pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc);
 
 	pDevice->rd0_pool_dma = pDevice->pool_dma;
 	pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
-		pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
+		pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc);
 
 	pDevice->tx0_bufs = dma_zalloc_coherent(&pDevice->pcid->dev,
 						  pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
@@ -549,8 +549,8 @@ static bool device_init_rings(struct vnt_private *pDevice)
 		dev_err(&pDevice->pcid->dev, "allocate buf dma memory failed\n");
 
 		dma_free_coherent(&pDevice->pcid->dev,
-				    pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
-				    pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+				    pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc) +
+				    pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc) +
 				    pDevice->sOpts.nTxDescs[0] * sizeof(struct vnt_tx_desc) +
 				    pDevice->sOpts.nTxDescs[1] * sizeof(struct vnt_tx_desc),
 				    vir_pool, pDevice->pool_dma
@@ -559,19 +559,19 @@ static bool device_init_rings(struct vnt_private *pDevice)
 	}
 
 	pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
-		pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
+		pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc);
 
 	pDevice->td1_pool_dma = pDevice->td0_pool_dma +
 		pDevice->sOpts.nTxDescs[0] * sizeof(struct vnt_tx_desc);
 
 	/* vir_pool: pvoid type */
 	pDevice->apTD0Rings = vir_pool
-		+ pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
-		+ pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
+		+ pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc)
+		+ pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc);
 
 	pDevice->apTD1Rings = vir_pool
-		+ pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
-		+ pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
+		+ pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc)
+		+ pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc)
 		+ pDevice->sOpts.nTxDescs[0] * sizeof(struct vnt_tx_desc);
 
 	pDevice->tx1_bufs = pDevice->tx0_bufs +
@@ -595,8 +595,8 @@ static bool device_init_rings(struct vnt_private *pDevice)
 static void device_free_rings(struct vnt_private *pDevice)
 {
 	dma_free_coherent(&pDevice->pcid->dev,
-			    pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
-			    pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
+			    pDevice->sOpts.nRxDescs0 * sizeof(struct vnt_rx_desc) +
+			    pDevice->sOpts.nRxDescs1 * sizeof(struct vnt_rx_desc) +
 			    pDevice->sOpts.nTxDescs[0] * sizeof(struct vnt_tx_desc) +
 			    pDevice->sOpts.nTxDescs[1] * sizeof(struct vnt_tx_desc)
 			    ,
@@ -617,18 +617,19 @@ static void device_init_rd0_ring(struct vnt_private *pDevice)
 {
 	int i;
 	dma_addr_t      curr = pDevice->rd0_pool_dma;
-	PSRxDesc        pDesc;
+	struct vnt_rx_desc *pDesc;
 
 	/* Init the RD0 ring entries */
-	for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
+	for (i = 0; i < pDevice->sOpts.nRxDescs0;
+	     i ++, curr += sizeof(struct vnt_rx_desc)) {
 		pDesc = &(pDevice->aRD0Ring[i]);
-		pDesc->pRDInfo = alloc_rd_info();
+		pDesc->rd_info = alloc_rd_info();
 
 		if (!device_alloc_rx_buf(pDevice, pDesc))
 			dev_err(&pDevice->pcid->dev, "can not alloc rx bufs\n");
 
 		pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
-		pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
+		pDesc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc));
 	}
 
 	if (i > 0)
@@ -640,18 +641,19 @@ static void device_init_rd1_ring(struct vnt_private *pDevice)
 {
 	int i;
 	dma_addr_t      curr = pDevice->rd1_pool_dma;
-	PSRxDesc        pDesc;
+	struct vnt_rx_desc *pDesc;
 
 	/* Init the RD1 ring entries */
-	for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
+	for (i = 0; i < pDevice->sOpts.nRxDescs1;
+	     i ++, curr += sizeof(struct vnt_rx_desc)) {
 		pDesc = &(pDevice->aRD1Ring[i]);
-		pDesc->pRDInfo = alloc_rd_info();
+		pDesc->rd_info = alloc_rd_info();
 
 		if (!device_alloc_rx_buf(pDevice, pDesc))
 			dev_err(&pDevice->pcid->dev, "can not alloc rx bufs\n");
 
 		pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
-		pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
+		pDesc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc));
 	}
 
 	if (i > 0)
@@ -664,15 +666,15 @@ static void device_free_rd0_ring(struct vnt_private *pDevice)
 	int i;
 
 	for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
-		PSRxDesc        pDesc = &(pDevice->aRD0Ring[i]);
-		PDEVICE_RD_INFO  pRDInfo = pDesc->pRDInfo;
+		struct vnt_rx_desc *pDesc = &(pDevice->aRD0Ring[i]);
+		struct vnt_rd_info *rd_info = pDesc->rd_info;
 
-		dma_unmap_single(&pDevice->pcid->dev, pRDInfo->skb_dma,
+		dma_unmap_single(&pDevice->pcid->dev, rd_info->skb_dma,
 				 pDevice->rx_buf_sz, DMA_FROM_DEVICE);
 
-		dev_kfree_skb(pRDInfo->skb);
+		dev_kfree_skb(rd_info->skb);
 
-		kfree(pDesc->pRDInfo);
+		kfree(pDesc->rd_info);
 	}
 }
 
@@ -681,15 +683,15 @@ static void device_free_rd1_ring(struct vnt_private *pDevice)
 	int i;
 
 	for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
-		PSRxDesc        pDesc = &(pDevice->aRD1Ring[i]);
-		PDEVICE_RD_INFO  pRDInfo = pDesc->pRDInfo;
+		struct vnt_rx_desc *pDesc = &(pDevice->aRD1Ring[i]);
+		struct vnt_rd_info *rd_info = pDesc->rd_info;
 
-		dma_unmap_single(&pDevice->pcid->dev, pRDInfo->skb_dma,
+		dma_unmap_single(&pDevice->pcid->dev, rd_info->skb_dma,
 				 pDevice->rx_buf_sz, DMA_FROM_DEVICE);
 
-		dev_kfree_skb(pRDInfo->skb);
+		dev_kfree_skb(rd_info->skb);
 
-		kfree(pDesc->pRDInfo);
+		kfree(pDesc->rd_info);
 	}
 }
 
@@ -774,16 +776,16 @@ static void device_free_td1_ring(struct vnt_private *pDevice)
 
 static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx)
 {
-	PSRxDesc    pRD;
+	struct vnt_rx_desc *pRD;
 	int works = 0;
 
 	for (pRD = pDevice->pCurrRD[uIdx];
-	     pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
+	     pRD->rd0.owner == OWNED_BY_HOST;
 	     pRD = pRD->next) {
 		if (works++ > 15)
 			break;
 
-		if (!pRD->pRDInfo->skb)
+		if (!pRD->rd_info->skb)
 			break;
 
 		if (vnt_receive_frame(pDevice, pRD)) {
@@ -793,7 +795,7 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx)
 				break;
 			}
 		}
-		pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
+		pRD->rd0.owner = OWNED_BY_NIC;
 	}
 
 	pDevice->pCurrRD[uIdx] = pRD;
@@ -801,9 +803,10 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx)
 	return works;
 }
 
-static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD)
+static bool device_alloc_rx_buf(struct vnt_private *pDevice,
+				struct vnt_rx_desc *pRD)
 {
-	PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
+	struct vnt_rd_info *pRDInfo = pRD->rd_info;
 
 	pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
 	if (pRDInfo->skb == NULL)
@@ -814,11 +817,11 @@ static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD)
 			       skb_put(pRDInfo->skb, skb_tailroom(pRDInfo->skb)),
 			       pDevice->rx_buf_sz, DMA_FROM_DEVICE);
 
-	*((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */
+	*((unsigned int *)&pRD->rd0) = 0; /* FIX cast */
 
-	pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
-	pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
-	pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
+	pRD->rd0.res_count = cpu_to_le16(pDevice->rx_buf_sz);
+	pRD->rd0.owner = OWNED_BY_NIC;
+	pRD->rd1.req_count = cpu_to_le16(pDevice->rx_buf_sz);
 	pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
 
 	return true;
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
index e14eed160a19..700032e9c477 100644
--- a/drivers/staging/vt6655/dpc.c
+++ b/drivers/staging/vt6655/dpc.c
@@ -132,9 +132,9 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
 	return true;
 }
 
-bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd)
+bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd)
 {
-	PDEVICE_RD_INFO rd_info = curr_rd->pRDInfo;
+	struct vnt_rd_info *rd_info = curr_rd->rd_info;
 	struct sk_buff *skb;
 	u16 frame_size;
 
@@ -143,8 +143,8 @@ bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd)
 	dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma,
 			 priv->rx_buf_sz, DMA_FROM_DEVICE);
 
-	frame_size = le16_to_cpu(curr_rd->m_rd1RD1.wReqCount)
-			- le16_to_cpu(curr_rd->m_rd0RD0.wResCount);
+	frame_size = le16_to_cpu(curr_rd->rd1.req_count)
+			- le16_to_cpu(curr_rd->rd0.res_count);
 
 	if ((frame_size > 2364) || (frame_size < 33)) {
 		/* Frame Size error drop this packet.*/
diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h
index ad495719a251..e80b30816968 100644
--- a/drivers/staging/vt6655/dpc.h
+++ b/drivers/staging/vt6655/dpc.h
@@ -31,6 +31,6 @@
 
 #include "device.h"
 
-bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd);
+bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd);
 
 #endif /* __RXTX_H__ */
diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig
index 51bbf468fe45..59ccecc316df 100644
--- a/drivers/staging/wilc1000/Kconfig
+++ b/drivers/staging/wilc1000/Kconfig
@@ -1,6 +1,5 @@
 config WILC1000
 	tristate "WILC1000 support (WiFi only)"
-	depends on BROKEN
 	depends on !S390
 	depends on CFG80211 && WEXT_CORE && INET
 	depends on MMC || SPI
diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile
index 6be8a920706a..bdeffea8db83 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/staging/wilc1000/Makefile
@@ -1,6 +1,4 @@
 obj-$(CONFIG_WILC1000) += wilc1000.o
-obj-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += wilc_exported_buf.o
-
 
 ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT
 ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO
@@ -13,12 +11,9 @@ ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \
 ccflags-y += -I$(src)/ -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \
 		-DPLL_WORKAROUND -DCONNECT_DIRECT  -DAGING_ALG \
 		-DWILC_PARSE_SCAN_IN_HOST -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP \
-		-Wno-unused-function -DUSE_WIRELESS -DWILC_DEBUGFS
+		-Wno-unused-function -DWILC_DEBUGFS
 #ccflags-y += -DTCP_ACK_FILTER
 
-ccflags-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += -DMEMORY_STATIC \
-								-DWILC_PREALLOC_AT_BOOT
-
 ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \
 								-DWILC_PREALLOC_AT_INSMOD
 
@@ -26,7 +21,7 @@ ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC
 
 
 wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
-			wilc_memory.o wilc_msgqueue.o \
+			wilc_msgqueue.o \
 			coreconfigurator.o host_interface.o \
 			wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o
 
diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c
index 16a0abc970c0..544c12d6d963 100644
--- a/drivers/staging/wilc1000/coreconfigurator.c
+++ b/drivers/staging/wilc1000/coreconfigurator.c
@@ -87,14 +87,6 @@ typedef enum {
 	FRAME_SUBTYPE_FORCE_32BIT  = 0xFFFFFFFF
 } tenuFrmSubtype;
 
-/* Basic Frame Classes */
-typedef enum {
-	CLASS1_FRAME_TYPE      = 0x00,
-	CLASS2_FRAME_TYPE      = 0x01,
-	CLASS3_FRAME_TYPE      = 0x02,
-	FRAME_CLASS_FORCE_32BIT  = 0xFFFFFFFF
-} tenuFrameClass;
-
 /* Element ID  of various Information Elements */
 typedef enum {
 	ISSID               = 0,   /* Service Set Identifier         */
@@ -170,14 +162,6 @@ static struct semaphore SemHandlePktResp;
 
 static tstrConfigPktInfo gstrConfigPktInfo;
 
-static u8 g_seqno;
-
-static s16 g_wid_num          = -1;
-
-static u16 Res_Len;
-
-static u8 g_oper_mode    = SET_CFG;
-
 /* WID Switches */
 static tstrWID gastrWIDs[] = {
 	{WID_FIRMWARE_VERSION,          WID_STR},
@@ -314,160 +298,6 @@ u16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID));
 /*****************************************************************************/
 /* Functions                                                                 */
 /*****************************************************************************/
-INLINE u8 ascii_hex_to_dec(u8 num)
-{
-	if ((num >= '0') && (num <= '9'))
-		return (num - '0');
-	else if ((num >= 'A') && (num <= 'F'))
-		return (10 + (num - 'A'));
-	else if ((num >= 'a') && (num <= 'f'))
-		return (10 + (num - 'a'));
-
-	return INVALID;
-}
-
-INLINE u8 get_hex_char(u8 inp)
-{
-	u8 *d2htab = "0123456789ABCDEF";
-
-	return d2htab[inp & 0xF];
-}
-
-/* This function extracts the MAC address held in a string in standard format */
-/* into another buffer as integers.                                           */
-INLINE u16 extract_mac_addr(char *str, u8 *buff)
-{
-	*buff = 0;
-	while (*str != '\0') {
-		if ((*str == ':') || (*str == '-'))
-			*(++buff) = 0;
-		else
-			*buff = (*buff << 4) + ascii_hex_to_dec(*str);
-
-		str++;
-	}
-
-	return MAC_ADDR_LEN;
-}
-
-/* This function creates MAC address in standard format from a buffer of      */
-/* integers.                                                                  */
-INLINE void create_mac_addr(u8 *str, u8 *buff)
-{
-	u32 i = 0;
-	u32 j = 0;
-
-	for (i = 0; i < MAC_ADDR_LEN; i++) {
-		str[j++] = get_hex_char((u8)((buff[i] >> 4) & 0x0F));
-		str[j++] = get_hex_char((u8)(buff[i] & 0x0F));
-		str[j++] = ':';
-	}
-	str[--j] = '\0';
-}
-
-/* This function converts the IP address string in dotted decimal format to */
-/* unsigned integer. This functionality is similar to the library function  */
-/* inet_addr() but is reimplemented here since I could not confirm that     */
-/* inet_addr is platform independent.                                       */
-/* ips=>IP Address String in dotted decimal format                          */
-/* ipn=>Pointer to IP Address in integer format                             */
-INLINE u8 conv_ip_to_int(u8 *ips, u32 *ipn)
-{
-	u8 i   = 0;
-	u8 ipb = 0;
-	*ipn = 0;
-	/* Integer to string for each component */
-	while (ips[i] != '\0') {
-		if (ips[i] == '.') {
-			*ipn = ((*ipn) << 8) | ipb;
-			ipb = 0;
-		} else {
-			ipb = ipb * 10 + ascii_hex_to_dec(ips[i]);
-		}
-
-		i++;
-	}
-
-	/* The last byte of the IP address is read in here */
-	*ipn = ((*ipn) << 8) | ipb;
-
-	return 0;
-}
-
-/* This function converts the IP address from integer format to dotted    */
-/* decimal string format. Alternative to std library fn inet_ntoa().      */
-/* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B)  */
-/* ipn=>IP Address in integer format                                      */
-INLINE u8 conv_int_to_ip(u8 *ips, u32 ipn)
-{
-	u8 i   = 0;
-	u8 ipb = 0;
-	u8 cnt = 0;
-	u8 ipbsize = 0;
-
-	for (cnt = 4; cnt > 0; cnt--) {
-		ipb = (ipn >> (8 * (cnt - 1))) & 0xFF;
-
-		if (ipb >= 100)
-			ipbsize = 2;
-		else if (ipb >= 10)
-			ipbsize = 1;
-		else
-			ipbsize = 0;
-
-		switch (ipbsize) {
-		case 2:
-			ips[i++] = get_hex_char(ipb / 100);
-			ipb %= 100;
-
-		case 1:
-			ips[i++] = get_hex_char(ipb / 10);
-			ipb %= 10;
-
-		default:
-			ips[i++] = get_hex_char(ipb);
-		}
-
-		if (cnt > 1)
-			ips[i++] = '.';
-	}
-
-	ips[i] = '\0';
-
-	return i;
-}
-
-INLINE tenuWIDtype get_wid_type(u32 wid_num)
-{
-	/* Check for iconfig specific WID types first */
-	if ((wid_num == WID_BSSID) ||
-	    (wid_num == WID_MAC_ADDR) ||
-	    (wid_num == WID_IP_ADDRESS) ||
-	    (wid_num == WID_HUT_DEST_ADDR)) {
-		return WID_ADR;
-	}
-
-	if ((WID_1X_SERV_ADDR == wid_num) ||
-	    (WID_STACK_IP_ADDR == wid_num) ||
-	    (WID_STACK_NETMASK_ADDR == wid_num)) {
-		return WID_IP;
-	}
-
-	/* Next check for standard WID types */
-	if (wid_num < 0x1000)
-		return WID_CHAR;
-	else if (wid_num < 0x2000)
-		return WID_SHORT;
-	else if (wid_num < 0x3000)
-		return WID_INT;
-	else if (wid_num < 0x4000)
-		return WID_STR;
-	else if (wid_num < 0x5000)
-		return WID_BIN_DATA;
-
-	return WID_UNDEF;
-}
-
 
 /* This function extracts the beacon period field from the beacon or probe   */
 /* response frame.                                                           */
@@ -507,14 +337,6 @@ INLINE u32 get_beacon_timestamp_hi(u8 *data)
 	return time_stamp;
 }
 
-/* This function extracts the 'frame type' bits from the MAC header of the   */
-/* input frame.                                                              */
-/* Returns the value in the LSB of the returned value.                       */
-INLINE tenuBasicFrmType get_type(u8 *header)
-{
-	return ((tenuBasicFrmType)(header[0] & 0x0C));
-}
-
 /* This function extracts the 'frame type and sub type' bits from the MAC    */
 /* header of the input frame.                                                */
 /* Returns the value in the LSB of the returned value.                       */
@@ -668,6 +490,7 @@ INLINE u16 get_asoc_id(u8 *data)
 s32 CoreConfiguratorInit(void)
 {
 	s32 s32Error = WILC_SUCCESS;
+
 	PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n");
 
 	sema_init(&SemHandleSendPkt, 1);
@@ -1064,881 +887,6 @@ s32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults)
 }
 #endif
 
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessCharWid                                         */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_CHAR and       */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessCharWid(char *pcPacket, s32 *ps32PktLen,
-		    tstrWID *pstrWID, s8 *ps8WidVal)
-{
-	u8 *pu8val = (u8 *)ps8WidVal;
-	u8 u8val = 0;
-	s32 s32PktLen = *ps32PktLen;
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val);
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid >> 8) & 0xFF;
-	if (g_oper_mode == SET_CFG) {
-		u8val = *pu8val;
-
-		/* Length */
-		pcPacket[s32PktLen++] = sizeof(u8);
-
-
-		/* Value */
-		pcPacket[s32PktLen++] = u8val;
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessShortWid                                        */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_SHORT and      */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessShortWid(char *pcPacket, s32 *ps32PktLen,
-		     tstrWID *pstrWID, s8 *ps8WidVal)
-{
-	u16 *pu16val = (u16 *)ps8WidVal;
-	u16 u16val = 0;
-	s32 s32PktLen = *ps32PktLen;
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val);
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		u16val = *pu16val;
-
-		/* Length */
-		pcPacket[s32PktLen++] = sizeof(u16);
-
-		/* Value */
-		pcPacket[s32PktLen++] = (u8)(u16val & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u16val >> 8) & 0xFF);
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessIntWid                                          */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_INT and        */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessIntWid(char *pcPacket, s32 *ps32PktLen,
-		   tstrWID *pstrWID, s8 *ps8WidVal)
-{
-	u32 *pu32val = (u32 *)ps8WidVal;
-	u32 u32val = 0;
-	s32 s32PktLen = *ps32PktLen;
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val);
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		u32val = *pu32val;
-
-		/* Length */
-		pcPacket[s32PktLen++] = sizeof(u32);
-
-		/* Value */
-		pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF);
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessIPwid                                           */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_IP and         */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessIPwid(char *pcPacket, s32 *ps32PktLen,
-		  tstrWID *pstrWID, u8 *pu8ip)
-{
-	u32 u32val = 0;
-	s32 s32PktLen = *ps32PktLen;
-
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n");
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		/* Length */
-		pcPacket[s32PktLen++] = sizeof(u32);
-
-		/* Convert the IP Address String to Integer */
-		conv_ip_to_int(pu8ip, &u32val);
-
-		/* Value */
-		pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF);
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessStrWid                                          */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_STR and        */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessStrWid(char *pcPacket, s32 *ps32PktLen,
-		   tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
-{
-	u16 u16MsgLen = 0;
-	u16 idx    = 0;
-	s32 s32PktLen = *ps32PktLen;
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n");
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		/* Message Length */
-		u16MsgLen = (u16)s32ValueSize;
-
-		/* Length */
-		pcPacket[s32PktLen++] = (u8)u16MsgLen;
-
-		/* Value */
-		for (idx = 0; idx < u16MsgLen; idx++)
-			pcPacket[s32PktLen++] = pu8val[idx];
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessAdrWid                                          */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_ADR and        */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Value to set                                          */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    :                                                          */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessAdrWid(char *pcPacket, s32 *ps32PktLen,
-		   tstrWID *pstrWID, u8 *pu8val)
-{
-	u16 u16MsgLen = 0;
-	s32 s32PktLen = *ps32PktLen;
-
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n");
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		/* Message Length */
-		u16MsgLen = MAC_ADDR_LEN;
-
-		/* Length */
-		pcPacket[s32PktLen++] = (u8)u16MsgLen;
-
-		/* Value */
-		extract_mac_addr(pu8val, pcPacket + s32PktLen);
-		s32PktLen += u16MsgLen;
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ProcessBinWid                                          */
-/*                                                                           */
-/*  Description   : This function processes a WID of type WID_BIN_DATA and        */
-/*                  updates the cfg packet with the supplied value.          */
-/*                                                                           */
-/*  Inputs        : 1) Pointer to WID cfg structure                          */
-/*                  2) Name of file containing the binary data in text mode  */
-/*                                                                           */
-/*  Globals       :                                                          */
-/*                                                                           */
-/*  Processing    : The binary data is expected to be supplied through a     */
-/*                  file in text mode. This file is expected to be in the    */
-/*                  finject format. It is parsed, converted to binary format */
-/*                  and copied into g_cfg_pkt for further processing. This   */
-/*                  is obviously a round-about way of processing involving   */
-/*                  multiple (re)conversions between bin & ascii formats.    */
-/*                  But it is done nevertheless to retain uniformity and for */
-/*                  ease of debugging.                                       */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : None                                                     */
-/*                                                                           */
-
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-void ProcessBinWid(char *pcPacket, s32 *ps32PktLen,
-		   tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
-{
-	u16 u16MsgLen = 0;
-	u16 idx    = 0;
-	s32 s32PktLen = *ps32PktLen;
-	u8 u8checksum = 0;
-
-	if (pstrWID == NULL) {
-		PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n");
-		return;
-	}
-
-	/* WID */
-	pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
-	pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
-
-	if (g_oper_mode == SET_CFG) {
-		/* Message Length */
-		u16MsgLen = (u16)s32ValueSize;
-
-		/* Length */
-		/* pcPacket[s32PktLen++] = (u8)u16MsgLen; */
-		pcPacket[s32PktLen++] = (u8)(u16MsgLen  & 0xFF);
-		pcPacket[s32PktLen++] = (u8)((u16MsgLen >> 8) & 0xFF);
-
-		/* Value */
-		for (idx = 0; idx < u16MsgLen; idx++)
-			pcPacket[s32PktLen++] = pu8val[idx];
-
-		/* checksum */
-		for (idx = 0; idx < u16MsgLen; idx++)
-			u8checksum += pcPacket[MSG_HEADER_LEN + idx + 4];
-
-		pcPacket[s32PktLen++] = u8checksum;
-	}
-	*ps32PktLen = s32PktLen;
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : further_process_response                                 */
-/*                                                                           */
-/*  Description   : This function parses the response frame got from the     */
-/*                  device.                                                  */
-/*                                                                           */
-/*  Inputs        : 1) The received response frame                           */
-/*                  2) WID                                                   */
-/*                  3) WID Length                                            */
-/*                  4) Output file handle                                    */
-/*                  5) Process Wid Number(i.e wid from --widn switch)        */
-/*                  6) Index the array in the Global Wid Structure.          */
-/*                                                                           */
-/*  Globals       : g_wid_num, gastrWIDs                                     */
-/*                                                                           */
-/*  Processing    : This function parses the response of the device depending*/
-/*                  WID type and writes it to the output file in Hex or      */
-/*                  decimal notation depending on the --getx or --get switch.*/
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : 0 on Success & -2 on Failure                             */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2009   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-s32 further_process_response(u8 *resp,
-				     u16 u16WIDid,
-				     u16 cfg_len,
-				     bool process_wid_num,
-				     u32 cnt,
-				     tstrWID *pstrWIDresult)
-{
-	u32 retval = 0;
-	u32 idx = 0;
-	u8 cfg_chr  = 0;
-	u16 cfg_sht  = 0;
-	u32 cfg_int  = 0;
-	u8 cfg_str[256] = {0};
-	tenuWIDtype enuWIDtype = WID_UNDEF;
-
-	if (process_wid_num)
-		enuWIDtype = get_wid_type(g_wid_num);
-	else
-		enuWIDtype = gastrWIDs[cnt].enuWIDtype;
-
-
-	switch (enuWIDtype) {
-	case WID_CHAR:
-		cfg_chr = resp[idx];
-		/*Set local copy of WID*/
-		*(pstrWIDresult->ps8WidVal) = cfg_chr;
-		break;
-
-	case WID_SHORT:
-	{
-		u16 *pu16val = (u16 *)(pstrWIDresult->ps8WidVal);
-		cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]);
-		/*Set local copy of WID*/
-		/* pstrWIDresult->ps8WidVal = (s8*)(s32)cfg_sht; */
-		*pu16val = cfg_sht;
-		break;
-	}
-
-	case WID_INT:
-	{
-		u32 *pu32val = (u32 *)(pstrWIDresult->ps8WidVal);
-		cfg_int = MAKE_WORD32(
-				MAKE_WORD16(resp[idx], resp[idx + 1]),
-				MAKE_WORD16(resp[idx + 2], resp[idx + 3])
-				);
-		/*Set local copy of WID*/
-		/* pstrWIDresult->ps8WidVal = (s8*)cfg_int; */
-		*pu32val = cfg_int;
-		break;
-	}
-
-	case WID_STR:
-		memcpy(cfg_str, resp + idx, cfg_len);
-		/* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */
-		if (pstrWIDresult->s32ValueSize >= cfg_len) {
-			memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); /* mostafa: no need currently for the extra NULL byte */
-			pstrWIDresult->s32ValueSize = cfg_len;
-		} else {
-			PRINT_ER("allocated WID buffer length is smaller than the received WID Length\n");
-			retval = -2;
-		}
-
-		break;
-
-	case WID_ADR:
-		create_mac_addr(cfg_str, resp + idx);
-
-		strncpy(pstrWIDresult->ps8WidVal, cfg_str, strlen(cfg_str));
-		pstrWIDresult->ps8WidVal[strlen(cfg_str)] = '\0';
-		break;
-
-	case WID_IP:
-		cfg_int = MAKE_WORD32(
-				MAKE_WORD16(resp[idx], resp[idx + 1]),
-				MAKE_WORD16(resp[idx + 2], resp[idx + 3])
-				);
-		conv_int_to_ip(cfg_str, cfg_int);
-		break;
-
-	case WID_BIN_DATA:
-		if (pstrWIDresult->s32ValueSize >= cfg_len) {
-			memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len);
-			pstrWIDresult->s32ValueSize = cfg_len;
-		} else {
-			PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n", retval);
-			retval = -2;
-		}
-		break;
-
-	default:
-		PRINT_ER("ERROR: Check config database: Error(%d)\n", retval);
-		retval = -2;
-		break;
-	}
-
-	return retval;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/*  Function Name : ParseResponse                                           */
-/*                                                                           */
-/*  Description   : This function parses the command-line options and        */
-/*                  creates the config packets which can be sent to the WLAN */
-/*                  station.                                                 */
-/*                                                                           */
-/*  Inputs        : 1) The received response frame                           */
-/*                                                                           */
-/*  Globals       : g_opt_list, gastrWIDs	                                 */
-/*                                                                           */
-/*  Processing    : This function parses the options and creates different   */
-/*                  types of packets depending upon the WID-type             */
-/*                  corresponding to the option.                             */
-/*                                                                           */
-/*  Outputs       : None                                                     */
-/*                                                                           */
-/*  Returns       : 0 on Success & -1 on Failure                             */
-/*                                                                           */
-/*  Issues        : None                                                     */
-/*                                                                           */
-/*  Revision History:                                                        */
-/*                                                                           */
-/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
-/*         08 01 2008   Ittiam          Draft                                */
-/*                                                                           */
-/*****************************************************************************/
-
-s32 ParseResponse(u8 *resp, tstrWID *pstrWIDcfgResult)
-{
-	u16 u16RespLen = 0;
-	u16 u16WIDid  = 0;
-	u16 cfg_len  = 0;
-	tenuWIDtype enuWIDtype = WID_UNDEF;
-	bool num_wid_processed = false;
-	u32 cnt = 0;
-	u32 idx = 0;
-	u32 ResCnt = 0;
-	/* Check whether the received frame is a valid response */
-	if (RESP_MSG_TYPE != resp[0]) {
-		PRINT_INFO(CORECONFIG_DBG, "Received Message format incorrect.\n");
-		return -1;
-	}
-
-	/* Extract Response Length */
-	u16RespLen = MAKE_WORD16(resp[2], resp[3]);
-	Res_Len = u16RespLen;
-
-	for (idx = MSG_HEADER_LEN; idx < u16RespLen; ) {
-		u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]);
-		cfg_len = resp[idx + 2];
-		/* Incase of Bin Type Wid, the length is given by two byte field      */
-		enuWIDtype = get_wid_type(u16WIDid);
-		if (WID_BIN_DATA == enuWIDtype) {
-			cfg_len |= ((u16)resp[idx + 3] << 8) & 0xFF00;
-			idx++;
-		}
-		idx += 3;
-		if ((u16WIDid == g_wid_num) && (!num_wid_processed)) {
-			num_wid_processed = true;
-
-			if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, true, 0, &pstrWIDcfgResult[ResCnt])) {
-				return -2;
-			}
-			ResCnt++;
-		} else {
-			for (cnt = 0; cnt < g_num_total_switches; cnt++) {
-				if (gastrWIDs[cnt].u16WIDid == u16WIDid) {
-					if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, false, cnt,
-									   &pstrWIDcfgResult[ResCnt])) {
-						return -2;
-					}
-					ResCnt++;
-				}
-			}
-		}
-		idx += cfg_len;
-		/* In case if BIN type Wid, The last byte of the Cfg packet is the    */
-		/* Checksum. The WID Length field does not accounts for the checksum. */
-		/* The Checksum is discarded.                                         */
-		if (WID_BIN_DATA == enuWIDtype) {
-			idx++;
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  @brief              parses the write response [just detects its status: success or failure]
- *  @details
- *  @param[in]  pu8RespBuffer The Response to be parsed
- *  @return     Error code indicating Write Operation status:
- *                            WRITE_RESP_SUCCESS (1) => Write Success.
- *                            WILC_FAIL (-100)               => Write Failure.
- *  @note
- *  @author		Ittiam
- *  @date		11 Aug 2009
- *  @version	1.0
- */
-
-s32 ParseWriteResponse(u8 *pu8RespBuffer)
-{
-	s32 s32Error = WILC_FAIL;
-	u16 u16WIDtype = (u16)WID_NIL;
-
-	/* Check whether the received frame is a valid response */
-	if (RESP_MSG_TYPE != pu8RespBuffer[0]) {
-		PRINT_ER("Received Message format incorrect.\n");
-		return WILC_FAIL;
-	}
-
-	u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]);
-
-	/* Check for WID_STATUS ID and then check the length and status value */
-	if ((u16WIDtype == WID_STATUS) &&
-	    (pu8RespBuffer[6] == 1) &&
-	    (pu8RespBuffer[7] == WRITE_RESP_SUCCESS)) {
-		s32Error = WRITE_RESP_SUCCESS;
-		return s32Error;
-	}
-
-	/* If the length or status are not as expected return failure    */
-	s32Error = WILC_FAIL;
-	return s32Error;
-
-}
-
-/**
- *  @brief                      creates the header of the Configuration Packet
- *  @details
- *  @param[in,out] pcpacket The Configuration Packet
- *  @param[in,out] ps32PacketLength Length of the Configuration Packet
- *  @return             Error code indicating success/failure
- *  @note
- *  @author		aismail
- *  @date		18 Feb 2012
- *  @version		1.0
- */
-
-s32 CreatePacketHeader(char *pcpacket, s32 *ps32PacketLength)
-{
-	s32 s32Error = WILC_SUCCESS;
-	u16 u16MsgLen = (u16)(*ps32PacketLength);
-	u16 u16MsgInd = 0;
-
-	/* The format of the message is:                                         */
-	/* +-------------------------------------------------------------------+ */
-	/* | Message Type | Message ID |  Message Length |Message body         | */
-	/* +-------------------------------------------------------------------+ */
-	/* |     1 Byte   |   1 Byte   |     2 Bytes     | Message Length - 4  | */
-	/* +-------------------------------------------------------------------+ */
-
-	/* The format of a message body of a message type 'W' is:                */
-	/* +-------------------------------------------------------------------+ */
-	/* | WID0      | WID0 Length | WID0 Value  | ......................... | */
-	/* +-------------------------------------------------------------------+ */
-	/* | 2 Bytes   | 1 Byte      | WID0 Length | ......................... | */
-	/* +-------------------------------------------------------------------+ */
-
-
-
-	/* Message Type */
-	if (g_oper_mode == SET_CFG)
-		pcpacket[u16MsgInd++] = WRITE_MSG_TYPE;
-	else
-		pcpacket[u16MsgInd++] = QUERY_MSG_TYPE;
-
-	/* Sequence Number */
-	pcpacket[u16MsgInd++] = g_seqno++;
-
-	/* Message Length */
-	pcpacket[u16MsgInd++] = (u8)(u16MsgLen & 0xFF);
-	pcpacket[u16MsgInd++] = (u8)((u16MsgLen >> 8) & 0xFF);
-
-	*ps32PacketLength = u16MsgLen;
-
-	return s32Error;
-}
-
-/**
- *  @brief              creates Configuration packet based on the Input WIDs
- *  @details
- *  @param[in]  pstrWIDs WIDs to be sent in the configuration packet
- *  @param[in]  u32WIDsCount number of WIDs to be sent in the configuration packet
- *  @param[out]         ps8packet The created Configuration Packet
- *  @param[out]         ps32PacketLength Length of the created Configuration Packet
- *  @return     Error code indicating success/failure
- *  @note
- *  @author
- *  @date		1 Mar 2012
- *  @version	1.0
- */
-
-s32 CreateConfigPacket(s8 *ps8packet, s32 *ps32PacketLength,
-			       tstrWID *pstrWIDs, u32 u32WIDsCount)
-{
-	s32 s32Error = WILC_SUCCESS;
-	u32 u32idx = 0;
-	*ps32PacketLength = MSG_HEADER_LEN;
-	for (u32idx = 0; u32idx < u32WIDsCount; u32idx++) {
-		switch (pstrWIDs[u32idx].enuWIDtype) {
-		case WID_CHAR:
-			ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-				       pstrWIDs[u32idx].ps8WidVal);
-			break;
-
-		case WID_SHORT:
-			ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-					pstrWIDs[u32idx].ps8WidVal);
-			break;
-
-		case WID_INT:
-			ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-				      pstrWIDs[u32idx].ps8WidVal);
-			break;
-
-		case WID_STR:
-			ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-				      pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
-			break;
-
-		case WID_IP:
-			ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-				     pstrWIDs[u32idx].ps8WidVal);
-			break;
-
-		case WID_BIN_DATA:
-			ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
-				      pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
-			break;
-
-		default:
-			PRINT_ER("ERROR: Check Config database\n");
-		}
-	}
-
-	CreatePacketHeader(ps8packet, ps32PacketLength);
-
-	return s32Error;
-}
-
-s32 ConfigWaitResponse(char *pcRespBuffer, s32 s32MaxRespBuffLen, s32 *ps32BytesRead,
-			       bool bRespRequired)
-{
-	s32 s32Error = WILC_SUCCESS;
-	/*bug 3878*/
-	/*removed to caller function*/
-	/*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer;
-	 * gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen;
-	 * gstrConfigPktInfo.bRespRequired = bRespRequired;*/
-
-
-	if (gstrConfigPktInfo.bRespRequired) {
-		down(&SemHandlePktResp);
-
-		*ps32BytesRead = gstrConfigPktInfo.s32BytesRead;
-	}
-
-	memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
-
-	return s32Error;
-}
-
-s32 ConfigProvideResponse(char *pcRespBuffer, s32 s32RespLen)
-{
-	s32 s32Error = WILC_SUCCESS;
-
-	if (gstrConfigPktInfo.bRespRequired) {
-		if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) {
-			memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen);
-			gstrConfigPktInfo.s32BytesRead = s32RespLen;
-		} else {
-			memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen);
-			gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen;
-			PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size\n");
-		}
-
-		up(&SemHandlePktResp);
-	}
-
-	return s32Error;
-}
-
-/**
- *  @brief              writes the received packet pu8RxPacket in the global Rx FIFO buffer
- *  @details
- *  @param[in]  pu8RxPacket The received packet
- *  @param[in]  s32RxPacketLen Length of the received packet
- *  @return     Error code indicating success/failure
- *  @note
- *
- *  @author	mabubakr
- *  @date		1 Mar 2012
- *  @version	1.0
- */
-
-s32 ConfigPktReceived(u8 *pu8RxPacket, s32 s32RxPacketLen)
-{
-	s32 s32Error = WILC_SUCCESS;
-	u8 u8MsgType = 0;
-
-	u8MsgType = pu8RxPacket[0];
-
-	switch (u8MsgType) {
-	case 'R':
-		ConfigProvideResponse(pu8RxPacket, s32RxPacketLen);
-
-		break;
-
-	case 'N':
-		PRINT_INFO(CORECONFIG_DBG, "NetworkInfo packet received\n");
-		NetworkInfoReceived(pu8RxPacket, s32RxPacketLen);
-		break;
-
-	case 'I':
-		GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen);
-		break;
-
-	case 'S':
-		host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen);
-		break;
-
-	default:
-		PRINT_ER("ConfigPktReceived(): invalid received msg type at the Core Configurator\n");
-		break;
-	}
-
-	return s32Error;
-}
-
 /**
  *  @brief              Deinitializes the Core Configurator
  *  @details
@@ -1980,6 +928,7 @@ s32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs,
 			  u32 u32WIDsCount, bool bRespRequired, u32 drvHandler)
 {
 	s32 counter = 0, ret = 0;
+
 	if (gpstrWlanOps == NULL) {
 		PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n");
 		return 1;
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 66fa677015db..59a1a9d93d6a 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -531,8 +531,8 @@ typedef enum {
 /*							Global Variabls	                                                                 */
 /*																			 */
 /*****************************************************************************/
-
-
+/* Zero is not used, because a zero ID means termination */
+static tstrWILC_WFIDrv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
 tstrWILC_WFIDrv *terminated_handle;
 tstrWILC_WFIDrv *gWFiDrvHandle;
 #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
@@ -578,7 +578,7 @@ u8 gu8Flushed11iMode;
 u8 gu8FlushedAuthType;
 u32 gu32FlushedJoinReqSize;
 u32 gu32FlushedInfoElemAsocSize;
-u32 gu8FlushedJoinReqDrvHandler;
+tstrWILC_WFIDrv *gu8FlushedJoinReqDrvHandler;
 #define REAL_JOIN_REQ 0
 #define FLUSHED_JOIN_REQ 1
 #define FLUSHED_BYTE_POS 79     /* Position the byte indicating flushing in the flushed request */
@@ -592,6 +592,56 @@ static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
 extern void chip_sleep_manually(u32 u32SleepTime);
 extern int linux_wlan_get_num_conn_ifcs(void);
 
+static int add_handler_in_list(tstrWILC_WFIDrv *handler)
+{
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
+		if (!wfidrv_list[i]) {
+			wfidrv_list[i] = handler;
+			return 0;
+		}
+	}
+
+	return -ENOBUFS;
+}
+
+static int remove_handler_in_list(tstrWILC_WFIDrv *handler)
+{
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
+		if (wfidrv_list[i] == handler) {
+			wfidrv_list[i] = NULL;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int get_id_from_handler(tstrWILC_WFIDrv *handler)
+{
+	int i;
+
+	if (!handler)
+		return 0;
+
+	for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
+		if (wfidrv_list[i] == handler)
+			return i;
+	}
+
+	return 0;
+}
+
+static tstrWILC_WFIDrv *get_handler_from_id(int id)
+{
+	if (id <= 0 || id > ARRAY_SIZE(wfidrv_list))
+		return NULL;
+	return wfidrv_list[id];
+}
+
 /**
  *  @brief Handle_SetChannel
  *  @details    Sending config packet to firmware to set channel
@@ -616,7 +666,8 @@ static s32 Handle_SetChannel(tstrWILC_WFIDrv *drvHandler, tstrHostIFSetChan *pst
 
 	PRINT_D(HOSTINF_DBG, "Setting channel\n");
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to set channel\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -637,12 +688,13 @@ static s32 Handle_SetChannel(tstrWILC_WFIDrv *drvHandler, tstrHostIFSetChan *pst
  *  @date
  *  @version	1.0
  */
-static s32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler *pstrHostIfSetDrvHandler)
+static s32 Handle_SetWfiDrvHandler(tstrWILC_WFIDrv *drvHandler,
+				   tstrHostIfSetDrvHandler *pstrHostIfSetDrvHandler)
 {
 
 	s32 s32Error = WILC_SUCCESS;
 	tstrWID	strWID;
-	tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)((pstrHostIfSetDrvHandler->u32Address));
+	tstrWILC_WFIDrv *pstrWFIDrv = drvHandler;
 
 
 	/*prepare configuration packet*/
@@ -653,10 +705,10 @@ static s32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler *pstrHostIfSetDrvHand
 
 	/*Sending Cfg*/
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 pstrHostIfSetDrvHandler->u32Address);
 
-
-	if ((pstrHostIfSetDrvHandler->u32Address) == (u32)NULL)
+	if (pstrWFIDrv == NULL)
 		up(&hSemDeinitDrvHandle);
 
 
@@ -698,10 +750,11 @@ static s32 Handle_SetOperationMode(tstrWILC_WFIDrv *drvHandler, tstrHostIfSetOpe
 	/*Sending Cfg*/
 	PRINT_INFO(HOSTINF_DBG, "pstrWFIDrv= %p\n", pstrWFIDrv);
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 
-	if ((pstrHostIfSetOperationMode->u32Mode) == (u32)NULL)
+	if ((pstrHostIfSetOperationMode->u32Mode) == IDLE_MODE)
 		up(&hSemDeinitDrvHandle);
 
 
@@ -747,8 +800,8 @@ s32 Handle_set_IPAddress(tstrWILC_WFIDrv *drvHandler, u8 *pu8IPAddr, u8 idx)
 	strWID.ps8WidVal = (u8 *)pu8IPAddr;
 	strWID.s32ValueSize = IP_ALEN;
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
-
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 
 	host_int_get_ipaddress(drvHandler, firmwareIPAddress, idx);
@@ -788,10 +841,11 @@ s32 Handle_get_IPAddress(tstrWILC_WFIDrv *drvHandler, u8 *pu8IPAddr, u8 idx)
 	/*prepare configuration packet*/
 	strWID.u16WIDid = (u16)WID_IP_ADDRESS;
 	strWID.enuWIDtype = WID_STR;
-	strWID.ps8WidVal = WILC_MALLOC(IP_ALEN);
+	strWID.ps8WidVal = kmalloc(IP_ALEN, GFP_KERNEL);
 	strWID.s32ValueSize = IP_ALEN;
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 	PRINT_INFO(HOSTINF_DBG, "%pI4\n", strWID.ps8WidVal);
 
@@ -837,7 +891,7 @@ static s32 Handle_SetMacAddress(tstrWILC_WFIDrv *drvHandler, tstrHostIfSetMacAdd
 	s32 s32Error = WILC_SUCCESS;
 	tstrWID	strWID;
 	tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
-	u8 *mac_buf = WILC_MALLOC(ETH_ALEN);
+	u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
 
 	if (mac_buf == NULL) {
 		PRINT_ER("No buffer to send mac address\n");
@@ -850,9 +904,10 @@ static s32 Handle_SetMacAddress(tstrWILC_WFIDrv *drvHandler, tstrHostIfSetMacAdd
 	strWID.enuWIDtype = WID_STR;
 	strWID.ps8WidVal = mac_buf;
 	strWID.s32ValueSize = ETH_ALEN;
-	PRINT_D(GENERIC_DBG, "mac addr = :%x:%x:%x:%x:%x:%x\n", strWID.ps8WidVal[0], strWID.ps8WidVal[1], strWID.ps8WidVal[2], strWID.ps8WidVal[3], strWID.ps8WidVal[4], strWID.ps8WidVal[5]);
+	PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", strWID.ps8WidVal);
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to set mac address\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -890,7 +945,8 @@ static s32 Handle_GetMacAddress(tstrWILC_WFIDrv *drvHandler, tstrHostIfGetMacAdd
 	strWID.s32ValueSize = ETH_ALEN;
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, false, (u32)drvHandler);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, false,
+				 get_id_from_handler(drvHandler));
 	if (s32Error) {
 		PRINT_ER("Failed to get mac address\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -1198,7 +1254,8 @@ static s32 Handle_CfgParam(tstrWILC_WFIDrv *drvHandler, tstrHostIFCfgParamAttr *
 		}
 		u8WidCnt++;
 	}
-	s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, false,
+				 get_id_from_handler(pstrWFIDrv));
 
 	if (s32Error)
 		PRINT_ER("Error in setting CFG params\n");
@@ -1282,7 +1339,7 @@ static s32 Handle_Scan(tstrWILC_WFIDrv *drvHandler, tstrHostIFscanAttr *pstrHost
 
 	for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++)
 		valuesize += ((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen) + 1);
-	pu8HdnNtwrksWidVal = WILC_MALLOC(valuesize + 1);
+	pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
 	strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal;
 	if (strWIDList[u32WidsCount].ps8WidVal != NULL) {
 		pu8Buffer = strWIDList[u32WidsCount].ps8WidVal;
@@ -1355,7 +1412,8 @@ static s32 Handle_Scan(tstrWILC_WFIDrv *drvHandler, tstrHostIFscanAttr *pstrHost
 	else if (pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE)
 		gbScanWhileConnected = false;
 
-	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false,
+				 get_id_from_handler(pstrWFIDrv));
 
 	if (s32Error) {
 		PRINT_ER("Failed to send scan paramters config packet\n");
@@ -1432,7 +1490,8 @@ static s32 Handle_ScanDone(tstrWILC_WFIDrv *drvHandler, tenuScanEvent enuEvent)
 		strWID.s32ValueSize = sizeof(char);
 
 		/*Sending Cfg*/
-		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+					 get_id_from_handler(pstrWFIDrv));
 		if (s32Error != WILC_SUCCESS) {
 			PRINT_ER("Failed to set abort running scan\n");
 			WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -1492,8 +1551,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 	PRINT_D(GENERIC_DBG, "Handling connect request\n");
 
 	#ifndef CONNECT_DIRECT
-	memset(gapu8RcvdSurveyResults[0], 0, MAX_SURVEY_RESULT_FRAG_SIZE);
-	memset(gapu8RcvdSurveyResults[1], 0, MAX_SURVEY_RESULT_FRAG_SIZE);
+	memset(gapu8RcvdSurveyResults, 0, sizeof(gapu8RcvdSurveyResults));
 
 
 	PRINT_D(HOSTINF_DBG, "Getting site survey results\n");
@@ -1558,13 +1616,13 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 		PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n");
 
 		if (pstrHostIFconnectAttr->pu8bssid != NULL) {
-			pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = WILC_MALLOC(6);
+			pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = kmalloc(6, GFP_KERNEL);
 			memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
 		}
 
 		pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen;
 		if (pstrHostIFconnectAttr->pu8ssid != NULL) {
-			pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1);
+			pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssidLen + 1, GFP_KERNEL);
 			memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid,
 				    pstrHostIFconnectAttr->ssidLen);
 			pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0';
@@ -1572,7 +1630,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 
 		pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen;
 		if (pstrHostIFconnectAttr->pu8IEs != NULL) {
-			pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = WILC_MALLOC(pstrHostIFconnectAttr->IEsLen);
+			pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->IEsLen, GFP_KERNEL);
 			memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs,
 				    pstrHostIFconnectAttr->IEsLen);
 		}
@@ -1629,7 +1687,8 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 		gu32WidConnRstHack = 0;
 		/* ////////////////////// */
 
-		s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false, (u32)pstrWFIDrv);
+		s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false,
+					 get_id_from_handler(pstrWFIDrv));
 		if (s32Error) {
 			PRINT_ER("Handle_Connect()] failed to send config packet\n");
 			WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -1665,13 +1724,13 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 	#endif /*WILC_PARSE_SCAN_IN_HOST*/
 
 	if (pstrHostIFconnectAttr->pu8bssid != NULL) {
-		pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = WILC_MALLOC(6);
+		pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = kmalloc(6, GFP_KERNEL);
 		memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
 	}
 
 	pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen;
 	if (pstrHostIFconnectAttr->pu8ssid != NULL) {
-		pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1);
+		pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssidLen + 1, GFP_KERNEL);
 		memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid,
 			    pstrHostIFconnectAttr->ssidLen);
 		pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0';
@@ -1679,7 +1738,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 
 	pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen;
 	if (pstrHostIFconnectAttr->pu8IEs != NULL) {
-		pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = WILC_MALLOC(pstrHostIFconnectAttr->IEsLen);
+		pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->IEsLen, GFP_KERNEL);
 		memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs,
 			    pstrHostIFconnectAttr->IEsLen);
 	}
@@ -1721,7 +1780,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 		if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
 
 			gu32FlushedInfoElemAsocSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
-			gu8FlushedInfoElemAsoc =  WILC_MALLOC(gu32FlushedInfoElemAsocSize);
+			gu8FlushedInfoElemAsoc =  kmalloc(gu32FlushedInfoElemAsocSize, GFP_KERNEL);
 			memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
 			       gu32FlushedInfoElemAsocSize);
 		}
@@ -1766,7 +1825,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 	strWIDList[u32WidsCount].u16WIDid = (u16)WID_JOIN_REQ_EXTENDED;
 	strWIDList[u32WidsCount].enuWIDtype = WID_STR;
 	strWIDList[u32WidsCount].s32ValueSize = MAX_SSID_LEN + 7;
-	strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize);
+	strWIDList[u32WidsCount].ps8WidVal = kmalloc(strWIDList[u32WidsCount].s32ValueSize, GFP_KERNEL);
 
 	if (strWIDList[u32WidsCount].ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
@@ -1798,12 +1857,12 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 
 	/*Sending NoA attributes during connection*/
 	strWIDList[u32WidsCount].s32ValueSize = 112; /* 79; */
-	strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize);
+	strWIDList[u32WidsCount].ps8WidVal = kmalloc(strWIDList[u32WidsCount].s32ValueSize, GFP_KERNEL);
 
 	/*BugID_5137*/
 	if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
 		gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize;
-		gu8FlushedJoinReq = WILC_MALLOC(gu32FlushedJoinReqSize);
+		gu8FlushedJoinReq = kmalloc(gu32FlushedJoinReqSize, GFP_KERNEL);
 	}
 	if (strWIDList[u32WidsCount].ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
@@ -1940,7 +1999,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 	/*BugID_5137*/
 	if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
 		memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize);
-		gu8FlushedJoinReqDrvHandler = (u32)pstrWFIDrv;
+		gu8FlushedJoinReqDrvHandler = pstrWFIDrv;
 	}
 
 	PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
@@ -1948,11 +2007,12 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 	if (pstrHostIFconnectAttr->pu8bssid != NULL) {
 		memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->pu8bssid, ETH_ALEN);
 
-		PRINT_D(GENERIC_DBG, "save Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5]));
-		PRINT_D(GENERIC_DBG, "save bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5]));
+		PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->pu8bssid);
+		PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
 	}
 
-	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Handle_Connect()] failed to send config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -1978,7 +2038,7 @@ static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler, tstrHostIFconnectAttr *ps
 
 			if (pstrHostIFconnectAttr->pu8IEs != NULL) {
 				strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen;
-				strConnectInfo.pu8ReqIEs = WILC_MALLOC(pstrHostIFconnectAttr->IEsLen);
+				strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->IEsLen, GFP_KERNEL);
 				memcpy(strConnectInfo.pu8ReqIEs,
 					    pstrHostIFconnectAttr->pu8IEs,
 					    pstrHostIFconnectAttr->IEsLen);
@@ -2081,7 +2141,8 @@ static s32 Handle_FlushConnect(tstrWILC_WFIDrv *drvHandler)
 
 	#endif
 
-	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false, gu8FlushedJoinReqDrvHandler);
+	s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, false,
+				 get_id_from_handler(gu8FlushedJoinReqDrvHandler));
 	if (s32Error) {
 		PRINT_ER("Handle_Flush_Connect()] failed to send config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -2136,7 +2197,7 @@ static s32 Handle_ConnectTimeout(tstrWILC_WFIDrv *drvHandler)
 
 		if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
 			strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
-			strConnectInfo.pu8ReqIEs = WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
+			strConnectInfo.pu8ReqIEs = kmalloc(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
 			memcpy(strConnectInfo.pu8ReqIEs,
 				    pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
 				    pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
@@ -2166,7 +2227,8 @@ static s32 Handle_ConnectTimeout(tstrWILC_WFIDrv *drvHandler)
 
 	PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error)
 		PRINT_ER("Failed to send dissconect config packet\n");
 
@@ -2191,11 +2253,11 @@ static s32 Handle_ConnectTimeout(tstrWILC_WFIDrv *drvHandler)
 	memset(u8ConnectedSSID, 0, ETH_ALEN);
 	/*BugID_5213*/
 	/*Freeing flushed join request params on connect timeout*/
-	if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+	if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 		kfree(gu8FlushedJoinReq);
 		gu8FlushedJoinReq = NULL;
 	}
-	if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+	if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 		kfree(gu8FlushedInfoElemAsoc);
 		gu8FlushedInfoElemAsoc = NULL;
 	}
@@ -2426,7 +2488,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(tstrWILC_WFIDrv *drvHandler, tstrRcvdGnrlAsy
 								strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
 
 
-								strConnectInfo.pu8RespIEs = WILC_MALLOC(pstrConnectRespInfo->u16RespIEsLen);
+								strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL);
 								memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
 									    pstrConnectRespInfo->u16RespIEsLen);
 							}
@@ -2470,7 +2532,7 @@ static s32 Handle_RcvdGnrlAsyncInfo(tstrWILC_WFIDrv *drvHandler, tstrRcvdGnrlAsy
 
 			if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
 				strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
-				strConnectInfo.pu8ReqIEs = WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
+				strConnectInfo.pu8ReqIEs = kmalloc(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
 				memcpy(strConnectInfo.pu8ReqIEs,
 					    pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
 					    pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
@@ -2617,11 +2679,11 @@ static s32 Handle_RcvdGnrlAsyncInfo(tstrWILC_WFIDrv *drvHandler, tstrRcvdGnrlAsy
 			/*BugID_5213*/
 			/*Freeing flushed join request params on receiving*/
 			/*MAC_DISCONNECTED while connected*/
-			if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+			if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 				kfree(gu8FlushedJoinReq);
 				gu8FlushedJoinReq = NULL;
 			}
-			if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+			if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 				kfree(gu8FlushedInfoElemAsoc);
 				gu8FlushedInfoElemAsoc = NULL;
 			}
@@ -2706,7 +2768,7 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWIDList[2].s32ValueSize = sizeof(char);
 
 
-			pu8keybuf = WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
+			pu8keybuf = kmalloc(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, GFP_KERNEL);
 
 
 			if (pu8keybuf == NULL) {
@@ -2726,7 +2788,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWIDList[3].ps8WidVal = (s8 *)pu8keybuf;
 
 
-			s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, true,
+						 get_id_from_handler(pstrWFIDrv));
 			kfree(pu8keybuf);
 
 
@@ -2735,7 +2798,7 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 
 		if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
 			PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
-			pu8keybuf = WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2);
+			pu8keybuf = kmalloc(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2, GFP_KERNEL);
 			if (pu8keybuf == NULL) {
 				PRINT_ER("No buffer to send Key\n");
 				return -1;
@@ -2754,7 +2817,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWID.ps8WidVal	= (s8 *)pu8keybuf;
 			strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2;
 
-			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+						 get_id_from_handler(pstrWFIDrv));
 			kfree(pu8keybuf);
 		} else if (pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY)	  {
 
@@ -2766,7 +2830,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWID.ps8WidVal = s8idxarray;
 			strWID.s32ValueSize = 1;
 
-			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+						 get_id_from_handler(pstrWFIDrv));
 		} else {
 			strWID.u16WIDid	= (u16)WID_KEY_ID;
 			strWID.enuWIDtype	= WID_CHAR;
@@ -2775,7 +2840,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 
 			PRINT_D(HOSTINF_DBG, "Setting default key index\n");
 
-			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+						 get_id_from_handler(pstrWFIDrv));
 		}
 		up(&(pstrWFIDrv->hSemTestKeyBlock));
 		break;
@@ -2783,7 +2849,7 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 	case WPARxGtk:
 			#ifdef WILC_AP_EXTERNAL_MLME
 		if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP)	{
-			pu8keybuf = WILC_MALLOC(RX_MIC_KEY_MSG_LEN);
+			pu8keybuf = kmalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
 			if (pu8keybuf == NULL) {
 				PRINT_ER("No buffer to send RxGTK Key\n");
 				ret = -1;
@@ -2821,7 +2887,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWIDList[1].ps8WidVal	= (s8 *)pu8keybuf;
 			strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN;
 
-			s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, true,
+						 get_id_from_handler(pstrWFIDrv));
 
 			kfree(pu8keybuf);
 
@@ -2834,7 +2901,7 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 		if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
 			PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
 
-			pu8keybuf = WILC_MALLOC(RX_MIC_KEY_MSG_LEN);
+			pu8keybuf = kmalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
 			if (pu8keybuf == NULL) {
 				PRINT_ER("No buffer to send RxGTK Key\n");
 				ret = -1;
@@ -2867,7 +2934,8 @@ static int Handle_Key(tstrWILC_WFIDrv *drvHandler, tstrHostIFkeyAttr *pstrHostIF
 			strWID.ps8WidVal	= (s8 *)pu8keybuf;
 			strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN;
 
-			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+						 get_id_from_handler(pstrWFIDrv));
 
 			kfree(pu8keybuf);
 
@@ -2888,7 +2956,7 @@ _WPARxGtk_end_case_:
 		if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP)	{
 
 
-			pu8keybuf = WILC_MALLOC(PTK_KEY_MSG_LEN + 1);
+			pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
 
 
 
@@ -2924,7 +2992,8 @@ _WPARxGtk_end_case_:
 			strWIDList[1].ps8WidVal	= (s8 *)pu8keybuf;
 			strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN + 1;
 
-			s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, true,
+						 get_id_from_handler(pstrWFIDrv));
 			kfree(pu8keybuf);
 
 			/* ////////////////////////// */
@@ -2935,7 +3004,7 @@ _WPARxGtk_end_case_:
 		if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
 
 
-			pu8keybuf = WILC_MALLOC(PTK_KEY_MSG_LEN);
+			pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
 
 
 
@@ -2965,7 +3034,8 @@ _WPARxGtk_end_case_:
 			strWID.ps8WidVal	= (s8 *)pu8keybuf;
 			strWID.s32ValueSize = PTK_KEY_MSG_LEN;
 
-			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+			s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+						 get_id_from_handler(pstrWFIDrv));
 			kfree(pu8keybuf);
 
 			/* ////////////////////////// */
@@ -2985,7 +3055,7 @@ _WPAPtk_end_case_:
 
 		PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
 
-		pu8keybuf = WILC_MALLOC((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1);
+		pu8keybuf = kmalloc((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
 		if (pu8keybuf == NULL) {
 			PRINT_ER("No buffer to send PMKSA Key\n");
 			return -1;
@@ -3004,7 +3074,8 @@ _WPAPtk_end_case_:
 		strWID.ps8WidVal = (s8 *)pu8keybuf;
 		strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1;
 
-		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+					 get_id_from_handler(pstrWFIDrv));
 
 		kfree(pu8keybuf);
 		break;
@@ -3053,7 +3124,8 @@ static void Handle_Disconnect(tstrWILC_WFIDrv *drvHandler)
 
 	memset(u8ConnectedSSID, 0, ETH_ALEN);
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 
 	if (s32Error) {
 		PRINT_ER("Failed to send dissconect config packet\n");
@@ -3117,11 +3189,11 @@ static void Handle_Disconnect(tstrWILC_WFIDrv *drvHandler)
 
 
 		/*BugID_5137*/
-		if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+		if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 			kfree(gu8FlushedJoinReq);
 			gu8FlushedJoinReq = NULL;
 		}
-		if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (u32)drvHandler) {
+		if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
 			kfree(gu8FlushedInfoElemAsoc);
 			gu8FlushedInfoElemAsoc = NULL;
 		}
@@ -3166,7 +3238,8 @@ static s32 Switch_Log_Terminal(tstrWILC_WFIDrv *drvHandler)
 	strWID.ps8WidVal = &dummy;
 	strWID.s32ValueSize = sizeof(char);
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 
 	if (s32Error) {
@@ -3211,7 +3284,8 @@ static s32 Handle_GetChnl(tstrWILC_WFIDrv *drvHandler)
 
 	PRINT_D(HOSTINF_DBG, "Getting channel value\n");
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	/*get the value by searching the local copy*/
 	if (s32Error) {
 		PRINT_ER("Failed to get channel number\n");
@@ -3255,7 +3329,8 @@ static void Handle_GetRssi(tstrWILC_WFIDrv *drvHandler)
 	/*Sending Cfg*/
 	PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to get RSSI value\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -3286,7 +3361,8 @@ static void Handle_GetLinkspeed(tstrWILC_WFIDrv *drvHandler)
 	/*Sending Cfg*/
 	PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to get LINKSPEED value\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -3336,7 +3412,8 @@ s32 Handle_GetStatistics(tstrWILC_WFIDrv *drvHandler, tstrStatistics *pstrStatis
 	strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->u32TxFailureCount));
 	u32WidsCount++;
 
-	s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, false, (u32)drvHandler);
+	s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, false,
+				 get_id_from_handler(drvHandler));
 
 	if (s32Error) {
 		PRINT_ER("Failed to send scan paramters config packet\n");
@@ -3374,7 +3451,7 @@ static s32 Handle_Get_InActiveTime(tstrWILC_WFIDrv *drvHandler, tstrHostIfStaIna
 	strWID.u16WIDid = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
 	strWID.enuWIDtype = WID_STR;
 	strWID.s32ValueSize = ETH_ALEN;
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 
 
 	stamac = strWID.ps8WidVal;
@@ -3384,7 +3461,8 @@ static s32 Handle_Get_InActiveTime(tstrWILC_WFIDrv *drvHandler, tstrHostIfStaIna
 	PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
 
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	/*get the value by searching the local copy*/
 	if (s32Error) {
 		PRINT_ER("Failed to SET incative time\n");
@@ -3398,7 +3476,8 @@ static s32 Handle_Get_InActiveTime(tstrWILC_WFIDrv *drvHandler, tstrHostIfStaIna
 	strWID.s32ValueSize = sizeof(u32);
 
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	/*get the value by searching the local copy*/
 	if (s32Error) {
 		PRINT_ER("Failed to get incative time\n");
@@ -3443,7 +3522,7 @@ static void Handle_AddBeacon(tstrWILC_WFIDrv *drvHandler, tstrHostIFSetBeacon *p
 	strWID.u16WIDid = (u16)WID_ADD_BEACON;
 	strWID.enuWIDtype = WID_BIN;
 	strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen + pstrSetBeaconParam->u32TailLen + 16;
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3479,7 +3558,8 @@ static void Handle_AddBeacon(tstrWILC_WFIDrv *drvHandler, tstrHostIFSetBeacon *p
 
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to send add beacon config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -3524,7 +3604,8 @@ static void Handle_DelBeacon(tstrWILC_WFIDrv *drvHandler, tstrHostIFDelBeacon *p
 	/* TODO: build del beacon message*/
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 
 		PRINT_ER("Failed to send delete beacon config packet\n");
@@ -3612,7 +3693,7 @@ static void Handle_AddStation(tstrWILC_WFIDrv *drvHandler, tstrWILC_AddStaParam
 	strWID.enuWIDtype = WID_BIN;
 	strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
 
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3620,7 +3701,8 @@ static void Handle_AddStation(tstrWILC_WFIDrv *drvHandler, tstrWILC_AddStaParam
 	pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error != WILC_SUCCESS) {
 
 		PRINT_ER("Failed to send add station config packet\n");
@@ -3659,7 +3741,7 @@ static void Handle_DelAllSta(tstrWILC_WFIDrv *drvHandler, tstrHostIFDelAllSta *p
 
 	PRINT_D(HOSTINF_DBG, "Handling delete station\n");
 
-	strWID.ps8WidVal = WILC_MALLOC((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1);
+	strWID.ps8WidVal = kmalloc((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3677,7 +3759,8 @@ static void Handle_DelAllSta(tstrWILC_WFIDrv *drvHandler, tstrHostIFDelAllSta *p
 	}
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 
 		PRINT_ER("Failed to send add station config packet\n");
@@ -3715,7 +3798,7 @@ static void Handle_DelStation(tstrWILC_WFIDrv *drvHandler, tstrHostIFDelSta *pst
 
 	PRINT_D(HOSTINF_DBG, "Handling delete station\n");
 
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3724,7 +3807,8 @@ static void Handle_DelStation(tstrWILC_WFIDrv *drvHandler, tstrHostIFDelSta *pst
 	memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN);
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 
 		PRINT_ER("Failed to send add station config packet\n");
@@ -3759,7 +3843,7 @@ static void Handle_EditStation(tstrWILC_WFIDrv *drvHandler, tstrWILC_AddStaParam
 	strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
 
 	PRINT_D(HOSTINF_DBG, "Handling edit station\n");
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3767,7 +3851,8 @@ static void Handle_EditStation(tstrWILC_WFIDrv *drvHandler, tstrWILC_AddStaParam
 	pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 
 		PRINT_ER("Failed to send edit station config packet\n");
@@ -3834,7 +3919,7 @@ static int Handle_RemainOnChan(tstrWILC_WFIDrv *drvHandler, tstrHostIfRemainOnCh
 	strWID.u16WIDid	= (u16)WID_REMAIN_ON_CHAN;
 	strWID.enuWIDtype	= WID_STR;
 	strWID.s32ValueSize = 2;
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
@@ -3843,7 +3928,8 @@ static int Handle_RemainOnChan(tstrWILC_WFIDrv *drvHandler, tstrHostIfRemainOnCh
 	strWID.ps8WidVal[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error != WILC_SUCCESS)
 		PRINT_ER("Failed to set remain on channel\n");
 
@@ -3886,7 +3972,7 @@ static int Handle_RegisterFrame(tstrWILC_WFIDrv *drvHandler, tstrHostIfRegisterF
 	/*prepare configuration packet*/
 	strWID.u16WIDid = (u16)WID_REGISTER_FRAME;
 	strWID.enuWIDtype = WID_STR;
-	strWID.ps8WidVal = WILC_MALLOC(sizeof(u16) + 2);
+	strWID.ps8WidVal = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -3901,7 +3987,8 @@ static int Handle_RegisterFrame(tstrWILC_WFIDrv *drvHandler, tstrHostIfRegisterF
 
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to frame register config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -3943,7 +4030,7 @@ static u32 Handle_ListenStateExpired(tstrWILC_WFIDrv *drvHandler, tstrHostIfRema
 		strWID.u16WIDid	= (u16)WID_REMAIN_ON_CHAN;
 		strWID.enuWIDtype	= WID_STR;
 		strWID.s32ValueSize = 2;
-		strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+		strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 
 		if (strWID.ps8WidVal == NULL)
 			PRINT_ER("Failed to allocate memory\n");
@@ -3952,7 +4039,8 @@ static u32 Handle_ListenStateExpired(tstrWILC_WFIDrv *drvHandler, tstrHostIfRema
 		strWID.ps8WidVal[1] = FALSE_FRMWR_CHANNEL;
 
 		/*Sending Cfg*/
-		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+		s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+					 get_id_from_handler(pstrWFIDrv));
 		if (s32Error != WILC_SUCCESS) {
 			PRINT_ER("Failed to set remain on channel\n");
 			goto _done_;
@@ -3997,7 +4085,7 @@ static void ListenTimerCB(unsigned long arg)
 	strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -4037,7 +4125,8 @@ static void Handle_PowerManagement(tstrWILC_WFIDrv *drvHandler, tstrHostIfPowerM
 	PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to send power management config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -4069,7 +4158,7 @@ static void Handle_SetMulticastFilter(tstrWILC_WFIDrv *drvHandler, tstrHostIFSet
 	strWID.u16WIDid = (u16)WID_SETUP_MULTICAST_FILTER;
 	strWID.enuWIDtype = WID_BIN;
 	strWID.s32ValueSize = sizeof(tstrHostIFSetMulti) + ((strHostIfSetMulti->u32count) * ETH_ALEN);
-	strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize);
+	strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
 	if (strWID.ps8WidVal == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 
@@ -4088,7 +4177,8 @@ static void Handle_SetMulticastFilter(tstrWILC_WFIDrv *drvHandler, tstrHostIFSet
 		memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN));
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false, (u32)drvHandler);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, false,
+				 get_id_from_handler(drvHandler));
 	if (s32Error) {
 		PRINT_ER("Failed to send setup multicast config packet\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -4130,7 +4220,7 @@ static s32 Handle_AddBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 
 	strWID.u16WIDid = (u16)WID_11E_P_ACTION_REQ;
 	strWID.enuWIDtype = WID_STR;
-	strWID.ps8WidVal = WILC_MALLOC(BLOCK_ACK_REQ_SIZE);
+	strWID.ps8WidVal = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
 	strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
 	ptr = strWID.ps8WidVal;
 	/* *ptr++ = 0x14; */
@@ -4156,7 +4246,8 @@ static s32 Handle_AddBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 	/* Group Buffer Timeout */
 	*ptr++ = 0;
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error)
 		PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
 
@@ -4180,7 +4271,8 @@ static s32 Handle_AddBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 	*ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
 	/*Ack-Policy */
 	*ptr++ = 3;
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 	if (strWID.ps8WidVal != NULL)
 		kfree(strWID.ps8WidVal);
@@ -4215,7 +4307,7 @@ static s32 Handle_DelBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 
 	strWID.u16WIDid = (u16)WID_11E_P_ACTION_REQ;
 	strWID.enuWIDtype = WID_STR;
-	strWID.ps8WidVal = WILC_MALLOC(BLOCK_ACK_REQ_SIZE);
+	strWID.ps8WidVal = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
 	strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
 	ptr = strWID.ps8WidVal;
 	/* *ptr++ = 0x14; */
@@ -4230,7 +4322,8 @@ static s32 Handle_DelBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 	/* Delba Reason */
 	*ptr++ = 32; /* Unspecific QOS reason */
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error)
 		PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
 
@@ -4248,7 +4341,8 @@ static s32 Handle_DelBASession(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASessionI
 	/* TID*/
 	*ptr++ = strHostIfBASessionInfo->u8Ted;
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 	if (strWID.ps8WidVal != NULL)
 		kfree(strWID.ps8WidVal);
@@ -4285,7 +4379,7 @@ static s32 Handle_DelAllRxBASessions(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASe
 
 	strWID.u16WIDid = (u16)WID_DEL_ALL_RX_BA;
 	strWID.enuWIDtype = WID_STR;
-	strWID.ps8WidVal = WILC_MALLOC(BLOCK_ACK_REQ_SIZE);
+	strWID.ps8WidVal = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
 	strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
 	ptr = strWID.ps8WidVal;
 	*ptr++ = 0x14;
@@ -4299,7 +4393,8 @@ static s32 Handle_DelAllRxBASessions(tstrWILC_WFIDrv *drvHandler, tstrHostIfBASe
 	/* Delba Reason */
 	*ptr++ = 32; /* Unspecific QOS reason */
 
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error)
 		PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
 
@@ -4332,7 +4427,7 @@ static int hostIFthread(void *pvArg)
 	memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
 
 	while (1) {
-		WILC_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret);
+		wilc_mq_recv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret);
 		pstrWFIDrv = (tstrWILC_WFIDrv *)strHostIFmsg.drvHandler;
 		if (strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT) {
 			PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
@@ -4344,13 +4439,13 @@ static int hostIFthread(void *pvArg)
 		if ((!g_wilc_initialized)) {
 			PRINT_D(GENERIC_DBG, "--WAIT--");
 			usleep_range(200 * 1000, 200 * 1000);
-			WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+			wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 			continue;
 		}
 
 		if (strHostIFmsg.u16MsgId == HOST_IF_MSG_CONNECT && pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) {
 			PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
-			WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+			wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 			usleep_range(2 * 1000, 2 * 1000);
 			continue;
 		}
@@ -4474,7 +4569,8 @@ static int hostIFthread(void *pvArg)
 			break;
 
 		case HOST_IF_MSG_SET_WFIDRV_HANDLER:
-			Handle_SetWfiDrvHandler(&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler);
+			Handle_SetWfiDrvHandler(strHostIFmsg.drvHandler,
+						&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler);
 			break;
 
 		case HOST_IF_MSG_SET_OPERATION_MODE:
@@ -4557,7 +4653,7 @@ static void TimerCB_Scan(unsigned long arg)
 	strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED;
 
 	/* send the message */
-	WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 }
 
 static void TimerCB_Connect(unsigned long arg)
@@ -4571,7 +4667,7 @@ static void TimerCB_Connect(unsigned long arg)
 	strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED;
 
 	/* send the message */
-	WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 }
 
 
@@ -4642,7 +4738,7 @@ s32 host_int_remove_wep_key(tstrWILC_WFIDrv *hWFIDrv, u8 u8keyIdx)
 	uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
 	down(&(pstrWFIDrv->hSemTestKeyBlock));
@@ -4690,7 +4786,7 @@ s32 host_int_set_WEPDefaultKeyID(tstrWILC_WFIDrv *hWFIDrv, u8 u8Index)
 	uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending message queue : Default key index\n");
 	down(&(pstrWFIDrv->hSemTestKeyBlock));
@@ -4744,7 +4840,7 @@ s32 host_int_add_wep_key_bss_sta(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey,
 
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
-	uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = WILC_MALLOC(u8WepKeylen);
+	uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = kmalloc(u8WepKeylen, GFP_KERNEL);
 
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
 		    pu8WepKey, u8WepKeylen);
@@ -4757,7 +4853,7 @@ s32 host_int_add_wep_key_bss_sta(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey,
 	uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending message queue :WEP Key\n");
 	down(&(pstrWFIDrv->hSemTestKeyBlock));
@@ -4813,7 +4909,7 @@ s32 host_int_add_wep_key_bss_ap(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey, u
 
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
-	uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = WILC_MALLOC((u8WepKeylen));
+	uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = kmalloc(u8WepKeylen, GFP_KERNEL);
 
 
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
@@ -4832,7 +4928,7 @@ s32 host_int_add_wep_key_bss_ap(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey, u
 	strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
 	uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type;
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 
 	if (s32Error)
 		PRINT_ER("Error in sending message queue :WEP Key\n");
@@ -4896,7 +4992,7 @@ s32 host_int_add_ptk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen,
 
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
-	uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = WILC_MALLOC(u8PtkKeylen);
+	uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = kmalloc(u8PtkKeylen, GFP_KERNEL);
 
 
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
@@ -4931,7 +5027,7 @@ s32 host_int_add_ptk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen,
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 
 	if (s32Error)
 		PRINT_ER("Error in sending message queue:  PTK Key\n");
@@ -4982,7 +5078,7 @@ s32 host_int_add_rx_gtk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKe
 		u8KeyLen += TX_MIC_KEY_LEN;
 	if (KeyRSC != NULL) {
 		strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
-		uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = WILC_MALLOC(u32KeyRSClen);
+		uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
 
 		memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq,
 			    KeyRSC, u32KeyRSClen);
@@ -5004,7 +5100,7 @@ s32 host_int_add_rx_gtk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKe
 
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
-	uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = WILC_MALLOC(u8KeyLen);
+	uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = kmalloc(u8KeyLen, GFP_KERNEL);
 
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
 		    pu8RxGtk, u8GtkKeylen);
@@ -5033,7 +5129,7 @@ s32 host_int_add_rx_gtk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKe
 
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending message queue:  RX GTK\n");
 	/* ////////////// */
@@ -5096,7 +5192,7 @@ s32 host_int_set_pmkid_info(tstrWILC_WFIDrv *hWFIDrv, tstrHostIFpmkidAttr *pu8Pm
 	}
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
 
@@ -5198,7 +5294,7 @@ s32 host_int_get_MacAddress(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8MacAddress)
 	strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress.u8MacAddress = pu8MacAddress;
 	strHostIFmsg.drvHandler = hWFIDrv;
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send get mac address\n");
 		return WILC_FAIL;
@@ -5232,7 +5328,7 @@ s32 host_int_set_MacAddress(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8MacAddress)
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress.u8MacAddress, pu8MacAddress, ETH_ALEN);
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send message queue: Set mac address\n");
 		WILC_ERRORREPORT(s32Error, s32Error);
@@ -5325,7 +5421,8 @@ s32 host_int_get_site_survey_results(tstrWILC_WFIDrv *hWFIDrv,
 	astrWIDList[1].ps8WidVal = ppu8RcvdSiteSurveyResults[1];
 	astrWIDList[1].s32ValueSize = u32MaxSiteSrvyFragLen;
 
-	s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, true,
+				 get_id_from_handler(pstrWFIDrv));
 
 	/*get the value by searching the local copy*/
 	if (s32Error) {
@@ -5459,14 +5556,14 @@ s32 host_int_set_join_req(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8bssid,
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	if (pu8bssid != NULL) {
-		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = WILC_MALLOC(6); /* will be deallocated by the receiving thread */
+		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = kmalloc(6, GFP_KERNEL); /* will be deallocated by the receiving thread */
 		memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid,
 			    pu8bssid, 6);
 	}
 
 	if (pu8ssid != NULL) {
 		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.ssidLen = ssidLen;
-		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = WILC_MALLOC(ssidLen); /* will be deallocated by the receiving thread */
+		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = kmalloc(ssidLen, GFP_KERNEL); /* will be deallocated by the receiving thread */
 		memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid,
 
 			    pu8ssid, ssidLen);
@@ -5474,7 +5571,7 @@ s32 host_int_set_join_req(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8bssid,
 
 	if (pu8IEs != NULL) {
 		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.IEsLen = IEsLen;
-		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */
+		strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = kmalloc(IEsLen, GFP_KERNEL); /* will be deallocated by the receiving thread */
 		memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs,
 			    pu8IEs, IEsLen);
 	}
@@ -5484,7 +5581,7 @@ s32 host_int_set_join_req(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8bssid,
 		PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", pstrWFIDrv->enuHostIFstate);
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send message queue: Set join request\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -5534,7 +5631,7 @@ s32 host_int_flush_join_req(tstrWILC_WFIDrv *hWFIDrv)
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send message queue: Flush join request\n");
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -5581,7 +5678,7 @@ s32 host_int_disconnect(tstrWILC_WFIDrv *hWFIDrv, u16 u16ReasonCode)
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Failed to send message queue: disconnect\n");
 	/* ////////////// */
@@ -5693,7 +5790,8 @@ s32 host_int_get_assoc_res_info(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8AssocRespInfo,
 
 
 	/* Sending Configuration packet */
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Failed to send association response config packet\n");
 		*pu32RcvdAssocRespInfoLen = 0;
@@ -5770,7 +5868,7 @@ s32 host_int_set_mac_chnl_num(tstrWILC_WFIDrv *hWFIDrv, u8 u8ChNum)
 	strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan.u8SetChan = u8ChNum;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -5792,7 +5890,7 @@ s32 host_int_wait_msg_queue_idle(void)
 
 	memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
 	strHostIFmsg.u16MsgId = HOST_IF_MSG_Q_IDLE;
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -5818,10 +5916,10 @@ s32 host_int_set_wfi_drv_handler(tstrWILC_WFIDrv *u32address)
 
 	memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
 	strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_WFIDRV_HANDLER;
-	strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address = u32address;
-	/* strHostIFmsg.drvHandler=hWFIDrv; */
+	strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address = get_id_from_handler(u32address);
+	strHostIFmsg.drvHandler = u32address;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -5848,7 +5946,7 @@ s32 host_int_set_operation_mode(tstrWILC_WFIDrv *hWFIDrv, u32 u32mode)
 	strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode.u32Mode = u32mode;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -5892,7 +5990,7 @@ s32 host_int_get_host_chnl_num(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8ChNo)
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error =	WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error =	wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Failed to send get host channel param's message queue ");
 	down(&(pstrWFIDrv->hSemGetCHNL));
@@ -5939,7 +6037,8 @@ s32 host_int_test_set_int_wid(tstrWILC_WFIDrv *hWFIDrv, u32 u32TestMemAddr)
 	strWID.s32ValueSize = sizeof(u32);
 
 	/*Sending Cfg*/
-	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(SET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	if (s32Error) {
 		PRINT_ER("Test Function: Failed to set wid value\n");
 		WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE);
@@ -5988,7 +6087,7 @@ s32 host_int_get_inactive_time(tstrWILC_WFIDrv *hWFIDrv, const u8 *mac, u32 *pu3
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Failed to send get host channel param's message queue ");
 
@@ -6031,7 +6130,8 @@ s32 host_int_test_get_int_wid(tstrWILC_WFIDrv *hWFIDrv, u32 *pu32TestMemAddr)
 	strWID.ps8WidVal = (s8 *)pu32TestMemAddr;
 	strWID.s32ValueSize = sizeof(u32);
 
-	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true, (u32)pstrWFIDrv);
+	s32Error = SendConfigPkt(GET_CFG, &strWID, 1, true,
+				 get_id_from_handler(pstrWFIDrv));
 	/*get the value by searching the local copy*/
 	if (s32Error) {
 		PRINT_ER("Test Function: Failed to get wid value\n");
@@ -6076,7 +6176,7 @@ s32 host_int_get_rssi(tstrWILC_WFIDrv *hWFIDrv, s8 *ps8Rssi)
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send get host channel param's message queue ");
 		return WILC_FAIL;
@@ -6113,7 +6213,7 @@ s32 host_int_get_link_speed(tstrWILC_WFIDrv *hWFIDrv, s8 *ps8lnkspd)
 	strHostIFmsg.drvHandler = hWFIDrv;
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
 		return WILC_FAIL;
@@ -6147,7 +6247,7 @@ s32 host_int_get_statistics(tstrWILC_WFIDrv *hWFIDrv, tstrStatistics *pstrStatis
 	strHostIFmsg.uniHostIFmsgBody.pUserData = (char *)pstrStatistics;
 	strHostIFmsg.drvHandler = hWFIDrv;
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Failed to send get host channel param's message queue ");
 		return WILC_FAIL;
@@ -6208,17 +6308,17 @@ s32 host_int_scan(tstrWILC_WFIDrv *hWFIDrv, u8 u8ScanSource,
 	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pvUserArg = pvUserArg;
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ChnlListLen = u8ChnlListLen;
-	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = WILC_MALLOC(u8ChnlListLen);        /* will be deallocated by the receiving thread */
+	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = kmalloc(u8ChnlListLen, GFP_KERNEL);        /* will be deallocated by the receiving thread */
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList,
 		    pu8ChnlFreqList, u8ChnlListLen);
 
 	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.IEsLen = IEsLen;
-	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = WILC_MALLOC(IEsLen);        /* will be deallocated by the receiving thread */
+	strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = kmalloc(IEsLen, GFP_KERNEL);        /* will be deallocated by the receiving thread */
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs,
 		    pu8IEs, IEsLen);
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error) {
 		PRINT_ER("Error in sending message queue scanning parameters: Error(%d)\n", s32Error);
 		WILC_ERRORREPORT(s32Error, WILC_FAIL);
@@ -6265,7 +6365,7 @@ s32 hif_set_cfg(tstrWILC_WFIDrv *hWFIDrv, tstrCfgParamVal *pstrCfgParamVal)
 	strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr.pstrCfgParamVal = *pstrCfgParamVal;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 
 	WILC_CATCH(s32Error)
 	{
@@ -6444,7 +6544,7 @@ static void GetPeriodicRSSI(unsigned long arg)
 		strHostIFmsg.drvHandler = pstrWFIDrv;
 
 		/* send the message */
-		s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+		s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 		if (s32Error) {
 			PRINT_ER("Failed to send get host channel param's message queue ");
 			return;
@@ -6476,6 +6576,7 @@ s32 host_int_init(tstrWILC_WFIDrv **phWFIDrv)
 {
 	s32 s32Error = WILC_SUCCESS;
 	tstrWILC_WFIDrv *pstrWFIDrv;
+	int err;
 
 	/*if(u32Intialized == 1)
 	 * {
@@ -6492,7 +6593,7 @@ s32 host_int_init(tstrWILC_WFIDrv **phWFIDrv)
 
 
 	/*Allocate host interface private structure*/
-	pstrWFIDrv  = WILC_MALLOC(sizeof(tstrWILC_WFIDrv));
+	pstrWFIDrv  = kmalloc(sizeof(tstrWILC_WFIDrv), GFP_KERNEL);
 	if (pstrWFIDrv == NULL) {
 		/* WILC_ERRORREPORT(s32Error,WILC_NO_MEM); */
 		s32Error = WILC_NO_MEM;
@@ -6503,6 +6604,11 @@ s32 host_int_init(tstrWILC_WFIDrv **phWFIDrv)
 	/*return driver handle to user*/
 	*phWFIDrv = pstrWFIDrv;
 	/*save into globl handle*/
+	err = add_handler_in_list(pstrWFIDrv);
+	if (err) {
+		s32Error = WILC_FAIL;
+		goto _fail_timer_2;
+	}
 
 	#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
 
@@ -6532,7 +6638,7 @@ s32 host_int_init(tstrWILC_WFIDrv **phWFIDrv)
 	PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
 
 	if (clients_count == 0)	{
-		s32Error = WILC_MsgQueueCreate(&gMsgQHostIF);
+		s32Error = wilc_mq_create(&gMsgQHostIF);
 
 		if (s32Error < 0) {
 			PRINT_ER("Failed to creat MQ\n");
@@ -6616,7 +6722,7 @@ _fail_timer_2:
 	del_timer_sync(&pstrWFIDrv->hScanTimer);
 	kthread_stop(HostIFthreadHandler);
 _fail_mq_:
-	WILC_MsgQueueDestroy(&gMsgQHostIF);
+	wilc_mq_destroy(&gMsgQHostIF);
 _fail_:
 	return s32Error;
 
@@ -6636,7 +6742,7 @@ s32 host_int_deinit(tstrWILC_WFIDrv *hWFIDrv)
 {
 	s32 s32Error = WILC_SUCCESS;
 	tstrHostIFmsg strHostIFmsg;
-
+	int ret;
 
 	/*obtain driver handle*/
 	tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
@@ -6711,13 +6817,13 @@ s32 host_int_deinit(tstrWILC_WFIDrv *hWFIDrv)
 		strHostIFmsg.drvHandler = hWFIDrv;
 
 
-		s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+		s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 		if (s32Error != WILC_SUCCESS)
 			PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", s32Error);
 
 		down(&hSemHostIFthrdEnd);
 
-		WILC_MsgQueueDestroy(&gMsgQHostIF);
+		wilc_mq_destroy(&gMsgQHostIF);
 		msgQ_created = 0;
 	}
 
@@ -6726,6 +6832,10 @@ s32 host_int_deinit(tstrWILC_WFIDrv *hWFIDrv)
 	/*Setting the gloabl driver handler with NULL*/
 	u32Intialized = 0;
 	/* gWFiDrvHandle = NULL; */
+	ret = remove_handler_in_list(pstrWFIDrv);
+	if (ret)
+		s32Error = WILC_NOT_FOUND;
+
 	if (pstrWFIDrv != NULL) {
 		kfree(pstrWFIDrv);
 		/* pstrWFIDrv=NULL; */
@@ -6754,11 +6864,11 @@ void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
 {
 	s32 s32Error = WILC_SUCCESS;
 	tstrHostIFmsg strHostIFmsg;
-	u32 drvHandler;
+	int id;
 	tstrWILC_WFIDrv *pstrWFIDrv = NULL;
 
-	drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-	pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
+	id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
+	pstrWFIDrv = get_handler_from_id(id);
 
 
 
@@ -6775,12 +6885,12 @@ void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
 	strHostIFmsg.drvHandler = pstrWFIDrv;
 
 	strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.u32Length = u32Length;
-	strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */
+	strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = kmalloc(u32Length, GFP_KERNEL); /* will be deallocated by the receiving thread */
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer,
 		    pu8Buffer, u32Length);
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", s32Error);
 }
@@ -6800,14 +6910,14 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
 {
 	s32 s32Error = WILC_SUCCESS;
 	tstrHostIFmsg strHostIFmsg;
-	u32 drvHandler;
+	int id;
 	tstrWILC_WFIDrv *pstrWFIDrv = NULL;
 
 	/*BugID_5348*/
 	down(&hSemHostIntDeinit);
 
-	drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-	pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
+	id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
+	pstrWFIDrv = get_handler_from_id(id);
 	PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
 
 
@@ -6835,12 +6945,12 @@ void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
 
 
 	strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.u32Length = u32Length;
-	strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */
+	strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = kmalloc(u32Length, GFP_KERNEL); /* will be deallocated by the receiving thread */
 	memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer,
 		    pu8Buffer, u32Length);
 
 	/* send the message */
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", s32Error);
 
@@ -6861,11 +6971,11 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
 {
 	s32 s32Error = WILC_SUCCESS;
 	tstrHostIFmsg strHostIFmsg;
-	u32 drvHandler;
+	int id;
 	tstrWILC_WFIDrv *pstrWFIDrv = NULL;
 
-	drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
-	pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
+	id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
+	pstrWFIDrv = get_handler_from_id(id);
 
 
 	PRINT_D(GENERIC_DBG, "Scan notification received %p\n", pstrWFIDrv);
@@ -6891,7 +7001,7 @@ void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
 		 *                        pu8Buffer, u32Length); */
 
 		/* send the message */
-		s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+		s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 		if (s32Error)
 			PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", s32Error);
 	}
@@ -6938,7 +7048,7 @@ s32 host_int_remain_on_channel(tstrWILC_WFIDrv *hWFIDrv, u32 u32SessionID, u32 u
 	strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -6981,7 +7091,7 @@ s32 host_int_ListenStateExpired(tstrWILC_WFIDrv *hWFIDrv, u32 u32SessionID)
 	strHostIFmsg.drvHandler = hWFIDrv;
 	strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7031,7 +7141,7 @@ s32 host_int_frame_register(tstrWILC_WFIDrv *hWFIDrv, u16 u16FrameType, bool bRe
 	strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.bReg = bReg;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7081,7 +7191,7 @@ s32 host_int_add_beacon(tstrWILC_WFIDrv *hWFIDrv, u32 u32Interval,
 	pstrSetBeaconParam->u32Interval = u32Interval;
 	pstrSetBeaconParam->u32DTIMPeriod = u32DTIMPeriod;
 	pstrSetBeaconParam->u32HeadLen = u32HeadLen;
-	pstrSetBeaconParam->pu8Head = WILC_MALLOC(u32HeadLen);
+	pstrSetBeaconParam->pu8Head = kmalloc(u32HeadLen, GFP_KERNEL);
 	if (pstrSetBeaconParam->pu8Head == NULL)
 		WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 	memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen);
@@ -7089,7 +7199,7 @@ s32 host_int_add_beacon(tstrWILC_WFIDrv *hWFIDrv, u32 u32Interval,
 
 	/* Bug 4599 : if tail length = 0 skip allocating & copying */
 	if (u32TailLen > 0) {
-		pstrSetBeaconParam->pu8Tail = WILC_MALLOC(u32TailLen);
+		pstrSetBeaconParam->pu8Tail = kmalloc(u32TailLen, GFP_KERNEL);
 		if (pstrSetBeaconParam->pu8Tail == NULL)
 			WILC_ERRORREPORT(s32Error, WILC_NO_MEM);
 		memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen);
@@ -7097,7 +7207,7 @@ s32 host_int_add_beacon(tstrWILC_WFIDrv *hWFIDrv, u32 u32Interval,
 		pstrSetBeaconParam->pu8Tail = NULL;
 	}
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 
@@ -7138,7 +7248,7 @@ s32 host_int_del_beacon(tstrWILC_WFIDrv *hWFIDrv)
 	strHostIFmsg.drvHandler = hWFIDrv;
 	PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	WILC_ERRORCHECK(s32Error);
 
 	WILC_CATCH(s32Error)
@@ -7179,7 +7289,7 @@ s32 host_int_add_station(tstrWILC_WFIDrv *hWFIDrv, tstrWILC_AddStaParam *pstrSta
 
 	memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam));
 	if (pstrAddStationMsg->u8NumRates > 0) {
-		u8 *rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates);
+		u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
 
 		WILC_NULLCHECK(s32Error, rates);
 
@@ -7188,7 +7298,7 @@ s32 host_int_add_station(tstrWILC_WFIDrv *hWFIDrv, tstrWILC_AddStaParam *pstrSta
 	}
 
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 
@@ -7233,7 +7343,7 @@ s32 host_int_del_station(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8MacAddr)
 	else
 		memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN);
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 
@@ -7288,7 +7398,7 @@ s32 host_int_del_allstation(tstrWILC_WFIDrv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN])
 	}
 
 	pstrDelAllStationMsg->u8Num_AssocSta = u8AssocNumb;
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 
 
 	if (s32Error)
@@ -7334,14 +7444,14 @@ s32 host_int_edit_station(tstrWILC_WFIDrv *hWFIDrv, tstrWILC_AddStaParam *pstrSt
 
 	memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam));
 	if (pstrAddStationMsg->u8NumRates > 0) {
-		u8 *rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates);
+		u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
 
 		WILC_NULLCHECK(s32Error, rates);
 		memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
 		pstrAddStationMsg->pu8Rates = rates;
 	}
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7377,7 +7487,7 @@ s32 host_int_set_power_mgmt(tstrWILC_WFIDrv *hWFIDrv, bool bIsEnabled, u32 u32Ti
 	pstrPowerMgmtParam->u32Timeout = u32Timeout;
 
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7410,7 +7520,7 @@ s32 host_int_setup_multicast_filter(tstrWILC_WFIDrv *hWFIDrv, bool bIsEnabled, u
 	pstrMulticastFilterParam->bIsEnabled = bIsEnabled;
 	pstrMulticastFilterParam->u32count = u32count;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7451,7 +7561,7 @@ static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
 	pu8IEs = ptstrNetworkInfo->pu8IEs;
 	u16IEsLen = ptstrNetworkInfo->u16IEsLen;
 
-	pNewJoinBssParam = WILC_MALLOC(sizeof(tstrJoinBssParam));
+	pNewJoinBssParam = kmalloc(sizeof(tstrJoinBssParam), GFP_KERNEL);
 	if (pNewJoinBssParam != NULL) {
 		memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam));
 		pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
@@ -7678,7 +7788,7 @@ static int host_int_addBASession(tstrWILC_WFIDrv *hWFIDrv, char *pBSSID, char TI
 	pBASessionInfo->u16SessionTimeout = SessionTimeout;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7709,7 +7819,7 @@ s32 host_int_delBASession(tstrWILC_WFIDrv *hWFIDrv, char *pBSSID, char TID)
 	pBASessionInfo->u8Ted = TID;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7742,7 +7852,7 @@ s32 host_int_del_All_Rx_BASession(tstrWILC_WFIDrv *hWFIDrv, char *pBSSID, char T
 	pBASessionInfo->u8Ted = TID;
 	strHostIFmsg.drvHandler = hWFIDrv;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7785,7 +7895,7 @@ s32 host_int_setup_ipaddress(tstrWILC_WFIDrv *hWFIDrv, u8 *u16ipadd, u8 idx)
 	strHostIFmsg.drvHandler = hWFIDrv;
 	strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
@@ -7824,7 +7934,7 @@ s32 host_int_get_ipaddress(tstrWILC_WFIDrv *hWFIDrv, u8 *u16ipadd, u8 idx)
 	strHostIFmsg.drvHandler = hWFIDrv;
 	strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx;
 
-	s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
+	s32Error = wilc_mq_send(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg));
 	if (s32Error)
 		WILC_ERRORREPORT(s32Error, s32Error);
 	WILC_CATCH(s32Error)
diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h
index e66dee9af5da..a107377ff6ec 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -23,6 +23,7 @@
 #define BIT1                    ((u32)(1 << 1))
 #define BIT0                    ((u32)(1 << 0))
 
+#define IDLE_MODE	0x00
 #define AP_MODE		0x01
 #define STATION_MODE	0x02
 #define GO_MODE	0x03
@@ -63,6 +64,7 @@
 #define WILC_SUPP_MCS_SET_SIZE	16
 #define WILC_ADD_STA_LENGTH	40 /* Not including the rates field cause it has variable length*/
 #define SCAN_EVENT_DONE_ABORTED
+#define NUM_CONCURRENT_IFC 2
 /*****************************************************************************/
 /* Data Types                                                                */
 /*****************************************************************************/
diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c
index b8d7d048439b..d87387719626 100644
--- a/drivers/staging/wilc1000/linux_mon.c
+++ b/drivers/staging/wilc1000/linux_mon.c
@@ -11,9 +11,6 @@
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 
-#ifdef WILC_FULLY_HOSTING_AP
-#include "wilc_host_ap.h"
-#endif
 #ifdef WILC_AP_EXTERNAL_MLME
 
 struct wilc_wfi_radiotap_hdr {
@@ -34,9 +31,7 @@ extern linux_wlan_t *g_linux_wlan;
 
 static struct net_device *wilc_wfi_mon; /* global monitor netdev */
 
-#if USE_WIRELESS
 extern int  mac_xmit(struct sk_buff *skb, struct net_device *dev);
-#endif
 
 
 u8 srcAdd[6];
@@ -222,11 +217,9 @@ static void mgmt_tx_complete(void *priv, int status)
  *      }*/
 
 	/* incase of fully hosting mode, the freeing will be done in response to the cfg packet */
-	#ifndef WILC_FULLY_HOSTING_AP
 	kfree(pv_data->buff);
 
 	kfree(pv_data);
-	#endif
 }
 static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
 {
@@ -244,33 +237,17 @@ static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
 		return WILC_FAIL;
 	}
 
-	#ifdef WILC_FULLY_HOSTING_AP
-	/* add space for the pointer to tx_complete_mon_data */
-	len += sizeof(struct tx_complete_mon_data *);
-	#endif
-
 	mgmt_tx->buff = kmalloc(len, GFP_ATOMIC);
 	if (mgmt_tx->buff == NULL) {
 		PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
+		kfree(mgmt_tx);
 		return WILC_FAIL;
 
 	}
 
 	mgmt_tx->size = len;
 
-	#ifndef WILC_FULLY_HOSTING_AP
 	memcpy(mgmt_tx->buff, buf, len);
-	#else
-	memcpy(mgmt_tx->buff, buf, len - sizeof(struct tx_complete_mon_data *));
-	memcpy((mgmt_tx->buff) + (len - sizeof(struct tx_complete_mon_data *)), &mgmt_tx, sizeof(struct tx_complete_mon_data *));
-
-	/* filter data frames to handle it's PS */
-	if (filter_monitor_data_frames((mgmt_tx->buff), len) == true) {
-		return;
-	}
-
-	#endif /* WILC_FULLY_HOSTING_AP */
-
 	g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, mgmt_tx_complete);
 
 	netif_wake_queue(dev);
@@ -367,7 +344,6 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
 	PRINT_INFO(HOSTAPD_DBG, "SKB netdevice name = %s\n", skb->dev->name);
 	PRINT_INFO(HOSTAPD_DBG, "MONITOR real dev name = %s\n", mon_priv->real_ndev->name);
 
-	#if USE_WIRELESS
 	/* Identify if Ethernet or MAC header (data or mgmt) */
 	memcpy(srcAdd, &skb->data[10], 6);
 	memcpy(bssid, &skb->data[16], 6);
@@ -378,7 +354,6 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
 		dev_kfree_skb(skb);
 	} else
 		ret = mac_xmit(skb, mon_priv->real_ndev);
-	#endif
 
 	/* return NETDEV_TX_OK; */
 	return ret;
@@ -389,81 +364,6 @@ static const struct net_device_ops wilc_wfi_netdev_ops = {
 
 };
 
-#ifdef WILC_FULLY_HOSTING_AP
-/*
- *  @brief                      WILC_mgm_HOSTAPD_ACK
- *  @details            report the status of transmitted mgmt frames to HOSTAPD
- *  @param[in]          priv : pointer to tx_complete_mon_data struct
- *				bStatus : status of transmission
- *  @author		Abd Al-Rahman Diab
- *  @date			9 May 2013
- *  @version		1.0
- */
-void WILC_mgm_HOSTAPD_ACK(void *priv, bool bStatus)
-{
-	struct sk_buff *skb;
-	struct wilc_wfi_radiotap_cb_hdr *cb_hdr;
-
-	struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv;
-	u8 *buf =  pv_data->buff;
-
-	/* len of the original frame without the added pointer at the tail */
-	u16 u16len = (pv_data->size) - sizeof(struct tx_complete_mon_data *);
-
-
-	/*if(bStatus == 1){
-	 *      if(INFO || buf[0] == 0x10 || buf[0] == 0xb0)
-	 *      PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",u16len,pv_data->buff);
-	 * }else{
-	 *              PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",u16len,pv_data->buff);
-	 *      }
-	 */
-
-	/* (skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 ||  skb->data[9] == 0xd0 ) */
-	{
-		skb = dev_alloc_skb(u16len + sizeof(struct wilc_wfi_radiotap_cb_hdr));
-
-		memcpy(skb_put(skb, u16len), pv_data->buff, u16len);
-
-		cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr));
-		memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr));
-
-		cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
-
-		cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr));
-
-		cb_hdr->hdr.it_present = cpu_to_le32(
-				(1 << IEEE80211_RADIOTAP_RATE) |
-				(1 << IEEE80211_RADIOTAP_TX_FLAGS));
-
-		cb_hdr->rate = 5; /* txrate->bitrate / 5; */
-
-
-		if (bStatus) {
-			/* success */
-			cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS;
-		} else {
-			cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL;
-		}
-
-		skb->dev = wilc_wfi_mon;
-		skb_set_mac_header(skb, 0);
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		skb->pkt_type = PACKET_OTHERHOST;
-		skb->protocol = htons(ETH_P_802_2);
-		memset(skb->cb, 0, sizeof(skb->cb));
-
-		netif_rx(skb);
-	}
-
-	/* incase of fully hosting mode, the freeing will be done in response to the cfg packet */
-	kfree(pv_data->buff);
-
-	kfree(pv_data);
-
-}
-#endif /* WILC_FULLY_HOSTING_AP */
-
 /**
  *  @brief      WILC_WFI_mon_setup
  *  @details
@@ -484,7 +384,6 @@ static void WILC_WFI_mon_setup(struct net_device *dev)
 	dev->type = ARPHRD_IEEE80211_RADIOTAP;
 	eth_zero_addr(dev->dev_addr);
 
-	#ifdef USE_WIRELESS
 	{
 		/* u8 * mac_add; */
 		unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x8f};
@@ -494,9 +393,6 @@ static void WILC_WFI_mon_setup(struct net_device *dev)
 		/* mac_add[ETH_ALEN-1]+=1; */
 		memcpy(dev->dev_addr, mac_add, ETH_ALEN);
 	}
-	#else
-	dev->dev_addr[0] = 0x12;
-	#endif
 
 }
 
diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c
index b3cc9f5c7937..63f44f81d9ed 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -2,9 +2,7 @@
 #include "linux_wlan_common.h"
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
-#ifdef USE_WIRELESS
 #include "wilc_wfi_cfgoperations.h"
-#endif
 
 #include "linux_wlan_common.h"
 
@@ -39,17 +37,6 @@
 #include "linux_wlan_spi.h"
 #endif
 
-#ifdef WILC_FULLY_HOSTING_AP
-#include "wilc_host_ap.h"
-#endif
-
-#ifdef STATIC_MACADDRESS /* brandy_0724 [[ */
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-struct task_struct *wilc_mac_thread;
-unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2};
-#endif /* brandy_0724 ]] */
-
 #if defined(CUSTOMER_PLATFORM)
 /*
  TODO : Write power control functions as customer platform.
@@ -114,24 +101,6 @@ static struct notifier_block g_dev_notifier = {
 		if (g_linux_wlan->oup.wlan_cleanup != NULL) \
 			g_linux_wlan->oup.wlan_cleanup(); }
 
-#ifndef STA_FIRMWARE
-#define STA_FIRMWARE	"wifi_firmware.bin"
-#endif
-
-#ifndef AP_FIRMWARE
-#define AP_FIRMWARE		"wifi_firmware_ap.bin"
-#endif
-
-#ifndef P2P_CONCURRENCY_FIRMWARE
-#define P2P_CONCURRENCY_FIRMWARE	"wifi_firmware_p2p_concurrency.bin"
-#endif
-
-typedef struct android_wifi_priv_cmd {
-	char *buf;
-	int used_len;
-	int total_len;
-} android_wifi_priv_cmd;
-
 #define IRQ_WAIT	1
 #define IRQ_NO_WAIT	0
 /*
@@ -141,18 +110,12 @@ typedef struct android_wifi_priv_cmd {
  *      deinitialized from mdoule_exit
  */
 static struct semaphore close_exit_sync;
-unsigned int int_rcvdU;
-unsigned int int_rcvdB;
-unsigned int int_clrd;
 
 static int wlan_deinit_locks(linux_wlan_t *nic);
 static void wlan_deinitialize_threads(linux_wlan_t *nic);
-static void linux_wlan_lock(void *vp);
-void linux_wlan_unlock(void *vp);
 extern void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size);
 extern void WILC_WFI_p2p_rx(struct net_device *dev, uint8_t *buff, uint32_t size);
 
-static void *internal_alloc(uint32_t size, uint32_t flag);
 static void linux_wlan_tx_complete(void *priv, int status);
 void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset);
 static int  mac_init_fn(struct net_device *ndev);
@@ -194,6 +157,7 @@ static char *ps8current = DebugBuffer;
 void printk_later(const char *format, ...)
 {
 	va_list args;
+
 	va_start(args, format);
 	ps8current += vsprintf(ps8current, format, args);
 	va_end(args);
@@ -367,7 +331,6 @@ void linux_wlan_disable_irq(int wait)
 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
 static irqreturn_t isr_uh_routine(int irq, void *user_data)
 {
-	int_rcvdU++;
 #if (RX_BH_TYPE != RX_BH_THREADED_IRQ)
 	linux_wlan_disable_irq(IRQ_NO_WAIT);
 #endif
@@ -387,7 +350,7 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data)
 	schedule_work(&g_linux_wlan->rx_work_queue);
 	return IRQ_HANDLED;
 #elif (RX_BH_TYPE == RX_BH_KTHREAD)
-	linux_wlan_unlock(&g_linux_wlan->rx_sem);
+	up(&g_linux_wlan->rx_sem);
 	return IRQ_HANDLED;
 #elif (RX_BH_TYPE == RX_BH_THREADED_IRQ)
 	return IRQ_WAKE_THREAD;
@@ -402,11 +365,13 @@ static irqreturn_t isr_uh_routine(int irq, void *user_data)
 irqreturn_t isr_bh_routine(int irq, void *userdata)
 {
 	linux_wlan_t *nic;
+
 	nic = (linux_wlan_t *)userdata;
 #else
 static void isr_bh_routine(struct work_struct *work)
 {
 	perInterface_wlan_t *nic;
+
 	nic = (perInterface_wlan_t *)container_of(work, linux_wlan_t, rx_work_queue);
 #endif
 
@@ -420,7 +385,6 @@ static void isr_bh_routine(struct work_struct *work)
 	#endif
 	}
 
-	int_rcvdB++;
 	PRINT_D(INT_DBG, "Interrupt received BH\n");
 	if (g_linux_wlan->oup.wlan_handle_rx_isr != 0)
 		g_linux_wlan->oup.wlan_handle_rx_isr();
@@ -439,7 +403,7 @@ static int isr_bh_routine(void *vp)
 	nic = (linux_wlan_t *)vp;
 
 	while (1) {
-		linux_wlan_lock(&nic->rx_sem);
+		down(&nic->rx_sem);
 		if (g_linux_wlan->close) {
 
 			while (!kthread_should_stop())
@@ -447,7 +411,6 @@ static int isr_bh_routine(void *vp)
 
 			break;
 		}
-		int_rcvdB++;
 		PRINT_D(INT_DBG, "Interrupt received BH\n");
 		if (g_linux_wlan->oup.wlan_handle_rx_isr != 0)
 			g_linux_wlan->oup.wlan_handle_rx_isr();
@@ -475,8 +438,6 @@ static int init_irq(linux_wlan_t *p_nic)
  *
  * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
  */
-#elif defined(NM73131_0_BOARD)
-		nic->dev_irq_num = IRQ_WILC1000;
 #elif defined(PANDA_BOARD)
 		gpio_export(GPIO_NUM, 1);
 		nic->dev_irq_num = OMAP_GPIO_IRQ(GPIO_NUM);
@@ -527,83 +488,15 @@ static void deinit_irq(linux_wlan_t *nic)
 /*
  *      OS functions
  */
-static void linux_wlan_msleep(uint32_t msc)
-{
-	if (msc <= 4000000) {
-		u32 u32Temp = msc * 1000;
-		usleep_range(u32Temp, u32Temp);
-	} else {
-		msleep(msc);
-	}
-}
-
-static void linux_wlan_atomic_msleep(uint32_t msc)
-{
-	mdelay(msc);
-}
 static void linux_wlan_dbg(uint8_t *buff)
 {
 	PRINT_D(INIT_DBG, "%d\n", *buff);
 }
 
-static void *linux_wlan_malloc_atomic(uint32_t sz)
-{
-	char *pntr = NULL;
-	pntr = kmalloc(sz, GFP_ATOMIC);
-	PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr);
-	return (void *)pntr;
-
-}
-static void *linux_wlan_malloc(uint32_t sz)
-{
-	char *pntr = NULL;
-	pntr = kmalloc(sz, GFP_KERNEL);
-	PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", sz, pntr);
-	return (void *)pntr;
-}
-
-void linux_wlan_free(void *vp)
-{
-	if (vp != NULL) {
-		PRINT_D(MEM_DBG, "Freeing %p\n", vp);
-		kfree(vp);
-	}
-}
-
-static void *internal_alloc(uint32_t size, uint32_t flag)
-{
-	char *pntr = NULL;
-	pntr = kmalloc(size, flag);
-	PRINT_D(MEM_DBG, "Allocating %d bytes at address %p\n", size, pntr);
-	return (void *)pntr;
-}
-
-static void linux_wlan_init_lock(char *lockName, void *plock, int count)
-{
-	sema_init((struct semaphore *)plock, count);
-	PRINT_D(LOCK_DBG, "Initializing [%s][%p]\n", lockName, plock);
-
-}
-
-static void linux_wlan_deinit_lock(void *plock)
-{
-	/* mutex_destroy((struct mutex*)plock); */
-}
-
-static void linux_wlan_lock(void *vp)
-{
-	PRINT_D(LOCK_DBG, "Locking %p\n", vp);
-	if (vp != NULL) {
-		while (down_interruptible((struct semaphore *) vp))
-			;
-	} else {
-		PRINT_ER("Failed, mutex is NULL\n");
-	}
-}
-
 static int linux_wlan_lock_timeout(void *vp, u32 timeout)
 {
 	int error = -1;
+
 	PRINT_D(LOCK_DBG, "Locking %p\n", vp);
 	if (vp != NULL)
 		error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout));
@@ -612,95 +505,6 @@ static int linux_wlan_lock_timeout(void *vp, u32 timeout)
 	return error;
 }
 
-void linux_wlan_unlock(void *vp)
-{
-	PRINT_D(LOCK_DBG, "Unlocking %p\n", vp);
-	if (vp != NULL)
-		up((struct semaphore *)vp);
-	else
-		PRINT_ER("Failed, mutex is NULL\n");
-}
-
-static void linux_wlan_init_mutex(char *lockName, void *plock, int count)
-{
-	mutex_init((struct mutex *)plock);
-	PRINT_D(LOCK_DBG, "Initializing mutex [%s][%p]\n", lockName, plock);
-
-}
-
-static void linux_wlan_deinit_mutex(void *plock)
-{
-	mutex_destroy((struct mutex *)plock);
-}
-
-static void linux_wlan_lock_mutex(void *vp)
-{
-	PRINT_D(LOCK_DBG, "Locking mutex %p\n", vp);
-	if (vp != NULL)	{
-		/*
-		 *      if(mutex_is_locked((struct mutex*)vp))
-		 *      {
-		 *              //PRINT_ER("Mutex already locked - %p \n",vp);
-		 *      }
-		 */
-		mutex_lock((struct mutex *)vp);
-
-	} else {
-		PRINT_ER("Failed, mutex is NULL\n");
-	}
-}
-
-static void linux_wlan_unlock_mutex(void *vp)
-{
-	PRINT_D(LOCK_DBG, "Unlocking mutex %p\n", vp);
-	if (vp != NULL) {
-
-		if (mutex_is_locked((struct mutex *)vp)) {
-			mutex_unlock((struct mutex *)vp);
-		} else {
-			/* PRINT_ER("Mutex already unlocked  - %p\n",vp); */
-		}
-
-	} else {
-		PRINT_ER("Failed, mutex is NULL\n");
-	}
-}
-
-/*Added by Amr - BugID_4720*/
-static void linux_wlan_init_spin_lock(char *lockName, void *plock, int count)
-{
-	spin_lock_init((spinlock_t *)plock);
-	PRINT_D(SPIN_DEBUG, "Initializing mutex [%s][%p]\n", lockName, plock);
-
-}
-
-static void linux_wlan_deinit_spin_lock(void *plock)
-{
-
-}
-static void linux_wlan_spin_lock(void *vp, unsigned long *flags)
-{
-	unsigned long lflags;
-	PRINT_D(SPIN_DEBUG, "Lock spin %p\n", vp);
-	if (vp != NULL) {
-		spin_lock_irqsave((spinlock_t *)vp, lflags);
-		*flags = lflags;
-	} else {
-		PRINT_ER("Failed, spin lock is NULL\n");
-	}
-}
-static void linux_wlan_spin_unlock(void *vp, unsigned long *flags)
-{
-	unsigned long lflags = *flags;
-	PRINT_D(SPIN_DEBUG, "Unlock spin %p\n", vp);
-	if (vp != NULL) {
-		spin_unlock_irqrestore((spinlock_t *)vp, lflags);
-		*flags = lflags;
-	} else {
-		PRINT_ER("Failed, spin lock is NULL\n");
-	}
-}
-
 static void linux_wlan_mac_indicate(int flag)
 {
 	/*I have to do it that way becuase there is no mean to encapsulate device pointer
@@ -713,7 +517,7 @@ static void linux_wlan_mac_indicate(int flag)
 		pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char *)&status, 4);
 		if (pd->mac_status == WILC_MAC_STATUS_INIT) {
 			pd->mac_status = status;
-			linux_wlan_unlock(&pd->sync_event);
+			up(&pd->sync_event);
 		} else {
 			pd->mac_status = status;
 		}
@@ -794,14 +598,14 @@ static int linux_wlan_rxq_task(void *vp)
 {
 
 	/* inform wilc1000_wlan_init that RXQ task is started. */
-	linux_wlan_unlock(&g_linux_wlan->rxq_thread_started);
+	up(&g_linux_wlan->rxq_thread_started);
 	while (1) {
-		linux_wlan_lock(&g_linux_wlan->rxq_event);
+		down(&g_linux_wlan->rxq_event);
 		/* wait_for_completion(&g_linux_wlan->rxq_event); */
 
 		if (g_linux_wlan->close) {
 			/*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */
-			linux_wlan_unlock(&g_linux_wlan->rxq_thread_started);
+			up(&g_linux_wlan->rxq_thread_started);
 
 			while (!kthread_should_stop())
 				schedule();
@@ -832,17 +636,17 @@ static int linux_wlan_txq_task(void *vp)
 #endif
 
 	/* inform wilc1000_wlan_init that TXQ task is started. */
-	linux_wlan_unlock(&g_linux_wlan->txq_thread_started);
+	up(&g_linux_wlan->txq_thread_started);
 	while (1) {
 
 		PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
-		linux_wlan_lock(&g_linux_wlan->txq_event);
+		down(&g_linux_wlan->txq_event);
 		/* wait_for_completion(&pd->txq_event); */
 		PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
 
 		if (g_linux_wlan->close) {
 			/*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
-			linux_wlan_unlock(&g_linux_wlan->txq_thread_started);
+			up(&g_linux_wlan->txq_thread_started);
 
 			while (!kthread_should_stop())
 				schedule();
@@ -1027,19 +831,15 @@ static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_n
 {
 
 	unsigned char c_val[64];
-	#ifndef STATIC_MACADDRESS
 	unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
-	#endif
 
 	/*BugID_5077*/
 	struct WILC_WFI_priv *priv;
 	tstrWILC_WFIDrv *pstrWFIDrv;
 
 	PRINT_D(TX_DBG, "Start configuring Firmware\n");
-	#ifndef STATIC_MACADDRESS
 	get_random_bytes(&mac_add[5], 1);
 	get_random_bytes(&mac_add[4], 1);
-	#endif
 	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
 	pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
 	PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv);
@@ -1052,7 +852,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_n
 		goto _fail_;
 	}
 
-	*(int *)c_val = (u32)pstrWFIDrv;
+	*(int *)c_val = 1;
 
 	if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
 		goto _fail_;
@@ -1087,12 +887,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_n
 	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
 		goto _fail_;
 
-#ifdef SWITCH_LOG_TERMINAL
-	c_val[0] = AUTO_PROT;
-	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0, 0))
-		goto _fail_;
-#endif
-
 	c_val[0] = ACTIVE_SCAN;
 	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
 		goto _fail_;
@@ -1116,12 +910,6 @@ static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_n
 	/*                    ( In BSS Station Set SSID to "" (null string)      */
 	/*                      to enable Broadcast SSID suppport )              */
 	/*  --------------------------------------------------------------       */
-#ifndef USE_WIRELESS
-	strcpy(c_val, "nwifi");
-	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val) + 1), 0, 0))
-		goto _fail_;
-#endif
-
 	c_val[0] = 0;
 	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
 		goto _fail_;
@@ -1291,7 +1079,7 @@ static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_n
 		goto _fail_;
 
 	c_val[0] = 1; /* Enable N with immediate block ack. */
-	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, (u32)pstrWFIDrv))
+	if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
 		goto _fail_;
 
 	return 0;
@@ -1327,18 +1115,18 @@ void wilc1000_wlan_deinit(linux_wlan_t *nic)
 		  #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
 
 		  #else
-		linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs);
+		mutex_lock(&g_linux_wlan->hif_cs);
 		disable_sdio_interrupt();
-		linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs);
+		mutex_unlock(&g_linux_wlan->hif_cs);
 		  #endif
 		#endif
 
 		/* not sure if the following unlocks are needed or not*/
 		if (&g_linux_wlan->rxq_event != NULL)
-			linux_wlan_unlock(&g_linux_wlan->rxq_event);
+			up(&g_linux_wlan->rxq_event);
 
 		if (&g_linux_wlan->txq_event != NULL)
-			linux_wlan_unlock(&g_linux_wlan->txq_event);
+			up(&g_linux_wlan->txq_event);
 
 	#if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
 		/*Removing the work struct from the linux kernel workqueue*/
@@ -1347,7 +1135,7 @@ void wilc1000_wlan_deinit(linux_wlan_t *nic)
 
 	#elif (RX_BH_TYPE == RX_BH_KTHREAD)
 		/* if(&nic->rx_sem != NULL) */
-		/* linux_wlan_unlock(&nic->rx_sem); */
+		/* up(&nic->rx_sem); */
 	#endif
 
 		PRINT_D(INIT_DBG, "Deinitializing Threads\n");
@@ -1367,9 +1155,9 @@ void wilc1000_wlan_deinit(linux_wlan_t *nic)
   #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
 		PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
 
-		linux_wlan_lock_mutex((void *)&g_linux_wlan->hif_cs);
+		mutex_lock(&g_linux_wlan->hif_cs);
 		disable_sdio_interrupt();
-		linux_wlan_unlock_mutex((void *)&g_linux_wlan->hif_cs);
+		mutex_unlock(&g_linux_wlan->hif_cs);
   #endif
 #endif
 
@@ -1392,28 +1180,25 @@ int wlan_init_locks(linux_wlan_t *p_nic)
 
 	PRINT_D(INIT_DBG, "Initializing Locks ...\n");
 
-	/*initialize mutexes*/
-	linux_wlan_init_mutex("hif_lock/hif_cs", &g_linux_wlan->hif_cs, 1);
-	linux_wlan_init_mutex("rxq_lock/rxq_cs", &g_linux_wlan->rxq_cs, 1);
-	linux_wlan_init_mutex("txq_lock/txq_cs", &g_linux_wlan->txq_cs, 1);
-
-	/*Added by Amr - BugID_4720*/
-	linux_wlan_init_spin_lock("txq_spin_lock/txq_cs", &g_linux_wlan->txq_spinlock, 1);
+	mutex_init(&g_linux_wlan->hif_cs);
+	mutex_init(&g_linux_wlan->rxq_cs);
+	mutex_init(&g_linux_wlan->txq_cs);
 
 	/*Added by Amr - BugID_4720*/
-	linux_wlan_init_lock("txq_add_to_head_lock/txq_cs", &g_linux_wlan->txq_add_to_head_cs, 1);
+	spin_lock_init(&g_linux_wlan->txq_spinlock);
+	sema_init(&g_linux_wlan->txq_add_to_head_cs, 1);
 
-	linux_wlan_init_lock("txq_wait/txq_event", &g_linux_wlan->txq_event, 0);
-	linux_wlan_init_lock("rxq_wait/rxq_event", &g_linux_wlan->rxq_event, 0);
+	sema_init(&g_linux_wlan->txq_event, 0);
+	sema_init(&g_linux_wlan->rxq_event, 0);
 
-	linux_wlan_init_lock("cfg_wait/cfg_event", &g_linux_wlan->cfg_event, 0);
-	linux_wlan_init_lock("sync_event", &g_linux_wlan->sync_event, 0);
+	sema_init(&g_linux_wlan->cfg_event, 0);
+	sema_init(&g_linux_wlan->sync_event, 0);
 
-	linux_wlan_init_lock("rxq_lock/rxq_started", &g_linux_wlan->rxq_thread_started, 0);
-	linux_wlan_init_lock("rxq_lock/txq_started", &g_linux_wlan->txq_thread_started, 0);
+	sema_init(&g_linux_wlan->rxq_thread_started, 0);
+	sema_init(&g_linux_wlan->txq_thread_started, 0);
 
 	#if (RX_BH_TYPE == RX_BH_KTHREAD)
-	linux_wlan_init_lock("BH_SEM", &g_linux_wlan->rx_sem, 0);
+	sema_init(&g_linux_wlan->rx_sem, 0);
 	#endif
 
 	return 0;
@@ -1424,39 +1209,13 @@ static int wlan_deinit_locks(linux_wlan_t *nic)
 	PRINT_D(INIT_DBG, "De-Initializing Locks\n");
 
 	if (&g_linux_wlan->hif_cs != NULL)
-		linux_wlan_deinit_mutex(&g_linux_wlan->hif_cs);
+		mutex_destroy(&g_linux_wlan->hif_cs);
 
 	if (&g_linux_wlan->rxq_cs != NULL)
-		linux_wlan_deinit_mutex(&g_linux_wlan->rxq_cs);
+		mutex_destroy(&g_linux_wlan->rxq_cs);
 
 	if (&g_linux_wlan->txq_cs != NULL)
-		linux_wlan_deinit_mutex(&g_linux_wlan->txq_cs);
-
-	/*Added by Amr - BugID_4720*/
-	if (&g_linux_wlan->txq_spinlock != NULL)
-		linux_wlan_deinit_spin_lock(&g_linux_wlan->txq_spinlock);
-
-	if (&g_linux_wlan->rxq_event != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->rxq_event);
-
-	if (&g_linux_wlan->txq_event != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->txq_event);
-
-	/*Added by Amr - BugID_4720*/
-	if (&g_linux_wlan->txq_add_to_head_cs != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->txq_add_to_head_cs);
-
-	if (&g_linux_wlan->rxq_thread_started != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->rxq_thread_started);
-
-	if (&g_linux_wlan->txq_thread_started != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->txq_thread_started);
-
-	if (&g_linux_wlan->cfg_event != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->cfg_event);
-
-	if (&g_linux_wlan->sync_event != NULL)
-		linux_wlan_deinit_lock(&g_linux_wlan->sync_event);
+		mutex_destroy(&g_linux_wlan->txq_cs);
 
 	return 0;
 }
@@ -1485,22 +1244,8 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic)
 	nwi->os_context.rxq_wait_event = (void *)&g_linux_wlan->rxq_event;
 	nwi->os_context.cfg_wait_event = (void *)&g_linux_wlan->cfg_event;
 
-	nwi->os_func.os_sleep = linux_wlan_msleep;
-	nwi->os_func.os_atomic_sleep = linux_wlan_atomic_msleep;
 	nwi->os_func.os_debug = linux_wlan_dbg;
-	nwi->os_func.os_malloc = linux_wlan_malloc;
-	nwi->os_func.os_malloc_atomic = linux_wlan_malloc_atomic;
-	nwi->os_func.os_free = linux_wlan_free;
-	nwi->os_func.os_lock = linux_wlan_lock;
-	nwi->os_func.os_unlock = linux_wlan_unlock;
 	nwi->os_func.os_wait = linux_wlan_lock_timeout;
-	nwi->os_func.os_signal = linux_wlan_unlock;
-	nwi->os_func.os_enter_cs = linux_wlan_lock_mutex;
-	nwi->os_func.os_leave_cs = linux_wlan_unlock_mutex;
-
-	/*Added by Amr - BugID_4720*/
-	nwi->os_func.os_spin_lock = linux_wlan_spin_lock;
-	nwi->os_func.os_spin_unlock = linux_wlan_spin_unlock;
 
 #ifdef WILC_SDIO
 	nwi->io_func.io_type = HIF_SDIO;
@@ -1521,12 +1266,7 @@ void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic)
 #endif
 
 	/*for now - to be revised*/
-	#ifdef WILC_FULLY_HOSTING_AP
-	/* incase of Fully hosted AP, all non cfg pkts are processed here*/
-	nwi->net_func.rx_indicate = WILC_Process_rx_frame;
-	#else
 	nwi->net_func.rx_indicate = frmw_to_linux;
-	#endif
 	nwi->net_func.rx_complete = linux_wlan_rx_complete;
 	nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate;
 }
@@ -1535,6 +1275,7 @@ int wlan_initialize_threads(perInterface_wlan_t *nic)
 {
 
 	int ret = 0;
+
 	PRINT_D(INIT_DBG, "Initializing Threads ...\n");
 
 #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
@@ -1561,7 +1302,7 @@ int wlan_initialize_threads(perInterface_wlan_t *nic)
 	}
 
 	/* wait for RXQ task to start. */
-	linux_wlan_lock(&g_linux_wlan->rxq_thread_started);
+	down(&g_linux_wlan->rxq_thread_started);
 
 #endif
 
@@ -1583,14 +1324,14 @@ int wlan_initialize_threads(perInterface_wlan_t *nic)
 	}
 #endif
 	/* wait for TXQ task to start. */
-	linux_wlan_lock(&g_linux_wlan->txq_thread_started);
+	down(&g_linux_wlan->txq_thread_started);
 
 	return 0;
 
 _fail_2:
 	/*De-Initialize 2nd thread*/
 	g_linux_wlan->close = 1;
-	linux_wlan_unlock(&g_linux_wlan->rxq_event);
+	up(&g_linux_wlan->rxq_event);
 	kthread_stop(g_linux_wlan->rxq_thread);
 
 #ifndef TCP_ENHANCEMENTS
@@ -1599,7 +1340,7 @@ _fail_1:
 	#if (RX_BH_TYPE == RX_BH_KTHREAD)
 	/*De-Initialize 1st thread*/
 	g_linux_wlan->close = 1;
-	linux_wlan_unlock(&g_linux_wlan->rx_sem);
+	up(&g_linux_wlan->rx_sem);
 	kthread_stop(g_linux_wlan->rx_bh_thread);
 _fail_:
 	#endif
@@ -1613,7 +1354,7 @@ static void wlan_deinitialize_threads(linux_wlan_t *nic)
 	g_linux_wlan->close = 1;
 	PRINT_D(INIT_DBG, "Deinitializing Threads\n");
 	if (&g_linux_wlan->rxq_event != NULL)
-		linux_wlan_unlock(&g_linux_wlan->rxq_event);
+		up(&g_linux_wlan->rxq_event);
 
 	if (g_linux_wlan->rxq_thread != NULL) {
 		kthread_stop(g_linux_wlan->rxq_thread);
@@ -1621,7 +1362,7 @@ static void wlan_deinitialize_threads(linux_wlan_t *nic)
 	}
 
 	if (&g_linux_wlan->txq_event != NULL)
-		linux_wlan_unlock(&g_linux_wlan->txq_event);
+		up(&g_linux_wlan->txq_event);
 
 	if (g_linux_wlan->txq_thread != NULL) {
 		kthread_stop(g_linux_wlan->txq_thread);
@@ -1630,7 +1371,7 @@ static void wlan_deinitialize_threads(linux_wlan_t *nic)
 
 	#if (RX_BH_TYPE == RX_BH_KTHREAD)
 	if (&g_linux_wlan->rx_sem != NULL)
-		linux_wlan_unlock(&g_linux_wlan->rx_sem);
+		up(&g_linux_wlan->rx_sem);
 
 	if (g_linux_wlan->rx_bh_thread != NULL) {
 		kthread_stop(g_linux_wlan->rx_bh_thread);
@@ -1639,66 +1380,6 @@ static void wlan_deinitialize_threads(linux_wlan_t *nic)
 	#endif
 }
 
-#ifdef STATIC_MACADDRESS
-const char *path_string[] = {
-	"/etc/wlan",
-	"/data/wlan",
-};
-
-static int linux_wlan_read_mac_addr(void *vp)
-{
-	int ret = 0;
-	struct file *fp = (struct file *)-ENOENT;
-	mm_segment_t old_fs;
-	loff_t pos = 0;
-	int index;
-	int array_size = ARRAY_SIZE(path_string);
-
-	/* change to KERNEL_DS address limit */
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-
-	for (index = 0; index < array_size; index++) {
-		fp = filp_open(path_string[index], O_WRONLY, 0640);
-		if (!fp) {
-			ret = -1;
-			goto exit;
-		}
-
-		/*No such file or directory */
-		if (IS_ERR(fp) || !fp->f_op) {
-			get_random_bytes(&mac_add[3], 3);
-			/* open file to write */
-			fp = filp_open(path_string[index], O_WRONLY | O_CREAT, 0640);
-
-			if (!fp || IS_ERR(fp)) {
-				ret = -1;
-				continue;
-			} else {
-				/* write buf to file */
-				fp->f_op->write(fp, mac_add, 6, &pos);
-				break;
-			}
-		} else {
-			/* read file to buf */
-			fp->f_op->read(fp, mac_add, 6, &pos);
-			break;
-		}
-	}
-
-	if (index == array_size)
-		PRINT_ER("random MAC\n");
-
-exit:
-	if (fp && !IS_ERR(fp))
-		filp_close(fp, NULL);
-
-	set_fs(old_fs);
-
-	return ret;
-}
-#endif
-
 #ifdef COMPLEMENT_BOOT
 
 extern volatile int probe;
@@ -1709,6 +1390,7 @@ extern void wilc_wlan_global_reset(void);
 uint8_t wilc1000_prepare_11b_core(wilc_wlan_inp_t *nwi,	wilc_wlan_oup_t *nwo, linux_wlan_t *nic)
 {
 	uint8_t trials = 0;
+
 	while ((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++)))) {
 		PRINT_D(INIT_DBG, "11b core not ready yet: %u\n", trials);
 		wilc_wlan_deinit(nic);
@@ -1743,6 +1425,7 @@ int repeat_power_cycle(perInterface_wlan_t *nic)
 	int ret = 0;
 	wilc_wlan_inp_t nwi;
 	wilc_wlan_oup_t nwo;
+
 	sdio_unregister_driver(&wilc_bus);
 
 	linux_wlan_device_detection(0);
@@ -1803,12 +1486,6 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
 
 		wlan_init_locks(g_linux_wlan);
 
-#ifdef STATIC_MACADDRESS
-		wilc_mac_thread = kthread_run(linux_wlan_read_mac_addr, NULL, "wilc_mac_thread");
-		if (wilc_mac_thread < 0)
-			PRINT_ER("couldn't create Mac addr thread\n");
-#endif
-
 		linux_to_wlan(&nwi, g_linux_wlan);
 
 		ret = wilc_wlan_init(&nwi, &nwo);
@@ -1880,6 +1557,7 @@ int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
 		if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
 			int size;
 			char Firmware_ver[20];
+
 			size = g_linux_wlan->oup.wlan_cfg_get_value(
 					WID_FIRMWARE_VERSION,
 					Firmware_ver, sizeof(Firmware_ver));
@@ -1930,7 +1608,6 @@ _fail_locks_:
  *      - this function will be called automatically by OS when module inserted.
  */
 
-#if !defined(NM73131_0_BOARD)
 int mac_init_fn(struct net_device *ndev)
 {
 
@@ -1940,28 +1617,11 @@ int mac_init_fn(struct net_device *ndev)
 
 	return 0;
 }
-#else
-int mac_init_fn(struct net_device *ndev)
-{
-
-	unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x00};
-	/* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
-	memcpy(ndev->dev_addr, mac_add, 6);
-
-	if (!is_valid_ether_addr(ndev->dev_addr)) {
-		PRINT_ER("Error: Wrong MAC address\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-#endif
 
 void    WILC_WFI_frame_register(struct wiphy *wiphy, struct net_device *dev,
 				u16 frame_type, bool reg);
 
 /* This fn is called, when this device is setup using ifconfig */
-#if !defined(NM73131_0_BOARD)
 int mac_open(struct net_device *ndev)
 {
 	perInterface_wlan_t *nic;
@@ -1978,14 +1638,12 @@ int mac_open(struct net_device *ndev)
 	priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
 	PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
 
-	#ifdef USE_WIRELESS
 	ret = WILC_WFI_InitHostInt(ndev);
 	if (ret < 0) {
 		PRINT_ER("Failed to initialize host interface\n");
 
 		return ret;
 	}
-	#endif
 
 	/*initialize platform*/
 	PRINT_D(INIT_DBG, "*** re-init ***\n");
@@ -1999,8 +1657,7 @@ int mac_open(struct net_device *ndev)
 	Set_machw_change_vir_if(false);
 
 	host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add);
-	PRINT_D(INIT_DBG, "Mac address: %x:%x:%x:%x:%x:%x\n", mac_add[0], mac_add[1], mac_add[2],
-		mac_add[3], mac_add[4], mac_add[5]);
+	PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
 
 	/* loop through the NUM of supported devices and set the MAC address */
 	for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
@@ -2034,25 +1691,6 @@ _err_:
 	wilc1000_wlan_deinit(g_linux_wlan);
 	return ret;
 }
-#else
-int mac_open(struct net_device *ndev)
-{
-
-	linux_wlan_t *nic;
-	nic = netdev_priv(ndev);
-
-	/*initialize platform*/
-	if (wilc1000_wlan_init(nic)) {
-		PRINT_ER("Failed to initialize platform\n");
-		return 1;
-	}
-	/* Start the network interface queue for this device */
-	PRINT_D(INIT_DBG, "Starting netifQ\n");
-	netif_start_queue(ndev);
-/*	linux_wlan_lock(&close_exit_sync); */
-	return 0;
-}
-#endif
 
 struct net_device_stats *mac_stats(struct net_device *dev)
 {
@@ -2069,6 +1707,7 @@ static void wilc_set_multicast_list(struct net_device *dev)
 	struct WILC_WFI_priv *priv;
 	tstrWILC_WFIDrv *pstrWFIDrv;
 	int i = 0;
+
 	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
 	pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
 
@@ -2120,13 +1759,14 @@ static void linux_wlan_tx_complete(void *priv, int status)
 {
 
 	struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
+
 	if (status == 1)
 		PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
 	else
 		PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
 	/* Free the SK Buffer, its work is done */
 	dev_kfree_skb(pv_data->skb);
-	linux_wlan_free(pv_data);
+	kfree(pv_data);
 }
 
 int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
@@ -2137,9 +1777,9 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 	char *pu8UdpBuffer;
 	struct iphdr *ih;
 	struct ethhdr *eth_h;
+
 	nic = netdev_priv(ndev);
 
-	PRINT_D(INT_DBG, "\n========\n IntUH: %d - IntBH: %d - IntCld: %d\n========\n", int_rcvdU, int_rcvdB, int_clrd);
 	PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
 
 	/* Stop the network interface queue */
@@ -2148,7 +1788,7 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 		return 0;
 	}
 
-	tx_data = (struct tx_complete_data *)internal_alloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
+	tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
 	if (tx_data == NULL) {
 		PRINT_ER("Failed to allocate memory for tx_data structure\n");
 		dev_kfree_skb(skb);
@@ -2182,14 +1822,10 @@ int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 	nic->netstats.tx_packets++;
 	nic->netstats.tx_bytes += tx_data->size;
 	tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID;
-	#ifndef WILC_FULLY_HOSTING_AP
 	QueueCount = g_linux_wlan->oup.wlan_add_to_tx_que((void *)tx_data,
 							  tx_data->buff,
 							  tx_data->size,
 							  linux_wlan_tx_complete);
-	#else
-	QueueCount = WILC_Xmit_data((void *)tx_data, HOST_TO_WLAN);
-	#endif /* WILC_FULLY_HOSTING_AP */
 
 	if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) {
 		netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev);
@@ -2244,23 +1880,19 @@ int mac_close(struct net_device *ndev)
 		/* Stop the network interface queue */
 		netif_stop_queue(nic->wilc_netdev);
 
-		#ifdef USE_WIRELESS
 		WILC_WFI_DeInitHostInt(nic->wilc_netdev);
-		#endif
 	}
 
 	if (g_linux_wlan->open_ifcs == 0) {
 		PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
 		g_linux_wlan->close = 1;
 		wilc1000_wlan_deinit(g_linux_wlan);
-		#ifdef USE_WIRELESS
 		#ifdef WILC_AP_EXTERNAL_MLME
 		WILC_WFI_deinit_mon_interface();
 		#endif
-		#endif
 	}
 
-	linux_wlan_unlock(&close_exit_sync);
+	up(&close_exit_sync);
 	nic->mac_opened = 0;
 
 	return 0;
@@ -2277,14 +1909,11 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
 	s32 s32Error = WILC_SUCCESS;
 
 	/* struct iwreq *wrq = (struct iwreq *) req;	// tony moved to case SIOCSIWPRIV */
-	#ifdef USE_WIRELESS
 	nic = netdev_priv(ndev);
 
 	if (!g_linux_wlan->wilc1000_initialized)
 		return 0;
 
-	#endif
-
 	switch (cmd) {
 
 	/* ]] 2013-06-24 */
@@ -2297,19 +1926,14 @@ int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
 		if (size && wrq->u.data.pointer) {
 
 			buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length);
-			if (IS_ERR(buff)) {
-				s32Error = PTR_ERR(buff);
-				goto done;
-			}
+			if (IS_ERR(buff))
+				return PTR_ERR(buff);
 
 			if (strncasecmp(buff, "RSSI", length) == 0) {
-
-					#ifdef USE_WIRELESS
 				priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
 				s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi));
 				if (s32Error)
 					PRINT_ER("Failed to send get rssi param's message queue ");
-					#endif
 				PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
 
 				/*Rounding up the rssi negative value*/
@@ -2375,8 +1999,6 @@ void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset)
 			return;
 		}
 
-		skb_reserve(skb, (unsigned int)skb->data & 0x3);
-
 		if (g_linux_wlan == NULL || wilc_netdev == NULL)
 			PRINT_ER("wilc_netdev in g_linux_wlan is NULL");
 		skb->dev = wilc_netdev;
@@ -2399,13 +2021,6 @@ void frmw_to_linux(uint8_t *buff, uint32_t size, uint32_t pkt_offset)
 
 		/* nic = netdev_priv(wilc_netdev); */
 
-#ifdef USE_WIRELESS
-		/*	if(nic->monitor_flag)
-		 *      {
-		 *              WILC_WFI_monitor_rx(nic->wilc_netdev,skb);
-		 *              return;
-		 *      }*/
-#endif
 		skb->protocol = eth_type_trans(skb, wilc_netdev);
 			#ifndef TCP_ENHANCEMENTS
 		/*get source and dest ip addresses*/
@@ -2461,16 +2076,13 @@ int wilc_netdev_init(void)
 	perInterface_wlan_t *nic;
 	struct net_device *ndev;
 
-	linux_wlan_init_lock("close_exit_sync", &close_exit_sync, 0);
+	sema_init(&close_exit_sync, 0);
 
 	/*create the common structure*/
-	g_linux_wlan = WILC_MALLOC(sizeof(linux_wlan_t));
-	memset(g_linux_wlan, 0, sizeof(linux_wlan_t));
+	g_linux_wlan = kzalloc(sizeof(linux_wlan_t), GFP_KERNEL);
+	if (!g_linux_wlan)
+		return -ENOMEM;
 
-	/*Reset interrupt count debug*/
-	int_rcvdU = 0;
-	int_rcvdB = 0;
-	int_clrd = 0;
 	#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
 	register_inetaddr_notifier(&g_dev_notifier);
 	#endif
@@ -2504,7 +2116,6 @@ int wilc_netdev_init(void)
 		g_linux_wlan->u8NoIfcs++;
 		ndev->netdev_ops = &wilc_netdev_ops;
 
-		#ifdef USE_WIRELESS
 		{
 			struct wireless_dev *wdev;
 			/*Register WiFi*/
@@ -2530,7 +2141,6 @@ int wilc_netdev_init(void)
 			nic->netstats.tx_bytes = 0;
 
 		}
-		#endif
 
 		if (register_netdev(ndev)) {
 			PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
@@ -2631,21 +2241,17 @@ static void __exit exit_wilc_driver(void)
 		for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
 			PRINT_D(INIT_DBG, "Unregistering netdev %p\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
 			unregister_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
-			#ifdef USE_WIRELESS
 			PRINT_D(INIT_DBG, "Freeing Wiphy...\n");
 			WILC_WFI_WiphyFree(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
-			#endif
 			PRINT_D(INIT_DBG, "Freeing netdev...\n");
 			free_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
 		}
 	}
 
-#ifdef USE_WIRELESS
 #ifdef WILC_AP_EXTERNAL_MLME
 	/* Bug 4600 : WILC_WFI_deinit_mon_interface was already called at mac_close */
 	/* WILC_WFI_deinit_mon_interface(); */
 #endif
-#endif
 
 	/* if(g_linux_wlan->open_ifcs==0) */
 	{
@@ -2657,7 +2263,6 @@ static void __exit exit_wilc_driver(void)
 		sdio_unregister_driver(&wilc_bus);
 	#endif
 
-		linux_wlan_deinit_lock(&close_exit_sync);
 		if (g_linux_wlan != NULL) {
 			kfree(g_linux_wlan);
 			g_linux_wlan = NULL;
diff --git a/drivers/staging/wilc1000/linux_wlan_common.h b/drivers/staging/wilc1000/linux_wlan_common.h
index e6ebf3e89129..ea121f9b7fb0 100644
--- a/drivers/staging/wilc1000/linux_wlan_common.h
+++ b/drivers/staging/wilc1000/linux_wlan_common.h
@@ -135,12 +135,7 @@ extern atomic_t DEBUG_LEVEL;
 
 #define WILC_MULTICAST_TABLE_SIZE	8
 
-#if defined (NM73131_0_BOARD)
-
-#define MODALIAS "wilc_spi"
-#define GPIO_NUM	IRQ_WILC1000_GPIO
-
-#elif defined (BEAGLE_BOARD)
+#if defined (BEAGLE_BOARD)
 	#define SPI_CHANNEL	4
 
 	#if SPI_CHANNEL == 4
diff --git a/drivers/staging/wilc1000/linux_wlan_sdio.c b/drivers/staging/wilc1000/linux_wlan_sdio.c
index 37f31f4558b5..1120a0f595d4 100644
--- a/drivers/staging/wilc1000/linux_wlan_sdio.c
+++ b/drivers/staging/wilc1000/linux_wlan_sdio.c
@@ -8,15 +8,9 @@
 
 
 
-#if defined (NM73131_0_BOARD)
-#define SDIO_MODALIAS "wilc_sdio"
-#else
 #define SDIO_MODALIAS "wilc1000_sdio"
-#endif
 
-#if defined (NM73131_0_BOARD)
- #define MAX_SPEED 50000000
-#elif defined(CUSTOMER_PLATFORM)
+#if defined(CUSTOMER_PLATFORM)
 /* TODO : User have to stable bus clock as user's environment. */
  #ifdef MAX_BUS_SPEED
  #define MAX_SPEED MAX_BUS_SPEED
@@ -194,6 +188,7 @@ void disable_sdio_interrupt(void)
 static int linux_sdio_set_speed(int speed)
 {
 	struct mmc_ios ios;
+
 	sdio_claim_host(local_sdio_func);
 
 	memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios));
diff --git a/drivers/staging/wilc1000/linux_wlan_spi.c b/drivers/staging/wilc1000/linux_wlan_spi.c
index 236669cfcd3a..3b3ba8a1c79e 100644
--- a/drivers/staging/wilc1000/linux_wlan_spi.c
+++ b/drivers/staging/wilc1000/linux_wlan_spi.c
@@ -5,7 +5,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/cdev.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 
@@ -113,54 +113,19 @@ int linux_spi_init(void *vp)
 #define TXRX_PHASE_SIZE (4096)
 #endif
 
-#if defined (NM73131_0_BOARD)
+#if defined(TXRX_PHASE_SIZE)
 
 int linux_spi_write(uint8_t *b, uint32_t len)
 {
-
 	int ret;
 
 	if (len > 0 && b != NULL) {
-		struct spi_message msg;
-		PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
-		struct spi_transfer tr = {
-			.tx_buf = b,
-			.len = len,
-			.speed_hz = SPEED,
-			.delay_usecs = 0,
-		};
-
-		spi_message_init(&msg);
-		spi_message_add_tail(&tr, &msg);
-		ret = spi_sync(wilc_spi_dev, &msg);
-		if (ret < 0) {
-			PRINT_ER("SPI transaction failed\n");
-		}
-
-	} else {
-		PRINT_ER("can't write data with the following length: %d\n", len);
-		PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
-		ret = -1;
-	}
-
-	/* change return value to match WILC interface */
-	(ret < 0) ? (ret = 0) : (ret = 1);
-
-
-	return ret;
-}
-
-#elif defined(TXRX_PHASE_SIZE)
-
-int linux_spi_write(uint8_t *b, uint32_t len)
-{
-	int ret;
-	if (len > 0 && b != NULL) {
 		int i = 0;
 		int blk = len / TXRX_PHASE_SIZE;
 		int remainder = len % TXRX_PHASE_SIZE;
 
 		char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
+
 		if (!r_buffer) {
 			PRINT_ER("Failed to allocate memory for r_buffer\n");
 		}
@@ -243,6 +208,7 @@ int linux_spi_write(uint8_t *b, uint32_t len)
 			.delay_usecs = 0,
 		};
 		char *r_buffer = kzalloc(len, GFP_KERNEL);
+
 		if (!r_buffer) {
 			PRINT_ER("Failed to allocate memory for r_buffer\n");
 		}
@@ -278,40 +244,7 @@ int linux_spi_write(uint8_t *b, uint32_t len)
 
 #endif
 
-#if defined (NM73131_0_BOARD)
-
-int linux_spi_read(unsigned char *rb, unsigned long rlen)
-{
-
-	int ret;
-
-	if (rlen > 0) {
-		struct spi_message msg;
-		struct spi_transfer tr = {
-			.rx_buf = rb,
-			.len = rlen,
-			.speed_hz = SPEED,
-			.delay_usecs = 0,
-
-		};
-
-		spi_message_init(&msg);
-		spi_message_add_tail(&tr, &msg);
-		ret = spi_sync(wilc_spi_dev, &msg);
-		if (ret < 0) {
-			PRINT_ER("SPI transaction failed\n");
-		}
-	} else {
-		PRINT_ER("can't read data with the following length: %ld\n", rlen);
-		ret = -1;
-	}
-	/* change return value to match WILC interface */
-	(ret < 0) ? (ret = 0) : (ret = 1);
-
-	return ret;
-}
-
-#elif defined(TXRX_PHASE_SIZE)
+#if defined(TXRX_PHASE_SIZE)
 
 int linux_spi_read(unsigned char *rb, unsigned long rlen)
 {
@@ -324,6 +257,7 @@ int linux_spi_read(unsigned char *rb, unsigned long rlen)
 		int remainder = rlen % TXRX_PHASE_SIZE;
 
 		char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
+
 		if (!t_buffer) {
 			PRINT_ER("Failed to allocate memory for t_buffer\n");
 		}
@@ -403,6 +337,7 @@ int linux_spi_read(unsigned char *rb, unsigned long rlen)
 
 		};
 		char *t_buffer = kzalloc(rlen, GFP_KERNEL);
+
 		if (!t_buffer) {
 			PRINT_ER("Failed to allocate memory for t_buffer\n");
 		}
diff --git a/drivers/staging/wilc1000/wilc_errorsupport.h b/drivers/staging/wilc1000/wilc_errorsupport.h
index b9517dc7f661..6012ec4dfce0 100644
--- a/drivers/staging/wilc1000/wilc_errorsupport.h
+++ b/drivers/staging/wilc1000/wilc_errorsupport.h
@@ -36,8 +36,6 @@
 #define WILC_FILE_EOF			-116
 
 
-/* Error type */
-typedef s32 WILC_ErrNo;
 
 #define WILC_IS_ERR(__status__) (__status__ < WILC_SUCCESS)
 
diff --git a/drivers/staging/wilc1000/wilc_exported_buf.c b/drivers/staging/wilc1000/wilc_exported_buf.c
deleted file mode 100644
index c3f6a0a1c9ad..000000000000
--- a/drivers/staging/wilc1000/wilc_exported_buf.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#define LINUX_RX_SIZE	(96 * 1024)
-#define LINUX_TX_SIZE	(64 * 1024)
-#define WILC1000_FW_SIZE (4 * 1024)
-
-#define MALLOC_WILC_BUFFER(name, size)	\
-	exported_ ## name = kmalloc(size, GFP_KERNEL);	  \
-	if (!exported_ ## name) {   \
-		printk("fail to alloc: %s memory\n", exported_ ## name);  \
-		return -ENOBUFS;	\
-	}
-
-#define FREE_WILC_BUFFER(name)	\
-	kfree(exported_ ## name);
-
-/*
- * Add necessary buffer pointers
- */
-void *exported_g_tx_buf;
-void *exported_g_rx_buf;
-void *exported_g_fw_buf;
-
-void *get_tx_buffer(void)
-{
-	return exported_g_tx_buf;
-}
-EXPORT_SYMBOL(get_tx_buffer);
-
-void *get_rx_buffer(void)
-{
-	return exported_g_rx_buf;
-}
-EXPORT_SYMBOL(get_rx_buffer);
-
-void *get_fw_buffer(void)
-{
-	return exported_g_fw_buf;
-}
-EXPORT_SYMBOL(get_fw_buffer);
-
-static int __init wilc_module_init(void)
-{
-	printk("wilc_module_init\n");
-	/*
-	 * alloc necessary memory
-	 */
-	MALLOC_WILC_BUFFER(g_tx_buf, LINUX_TX_SIZE)
-	MALLOC_WILC_BUFFER(g_rx_buf, LINUX_RX_SIZE)
-	MALLOC_WILC_BUFFER(g_fw_buf, WILC1000_FW_SIZE)
-
-	return 0;
-}
-
-static void __exit wilc_module_deinit(void)
-{
-	printk("wilc_module_deinit\n");
-	FREE_WILC_BUFFER(g_tx_buf)
-	FREE_WILC_BUFFER(g_rx_buf)
-	FREE_WILC_BUFFER(g_fw_buf)
-}
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Tony Cho");
-MODULE_DESCRIPTION("WILC1xxx Memory Manager");
-pure_initcall(wilc_module_init);
-module_exit(wilc_module_deinit);
diff --git a/drivers/staging/wilc1000/wilc_memory.c b/drivers/staging/wilc1000/wilc_memory.c
deleted file mode 100644
index e90a95705a7d..000000000000
--- a/drivers/staging/wilc1000/wilc_memory.c
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#include "wilc_memory.h"
-
-/*!
- *  @author	syounan
- *  @date	18 Aug 2010
- *  @version	1.0
- */
-void *WILC_MemoryAlloc(u32 u32Size, tstrWILC_MemoryAttrs *strAttrs,
-		       char *pcFileName, u32 u32LineNo)
-{
-	if (u32Size > 0)
-		return kmalloc(u32Size, GFP_ATOMIC);
-	else
-		return NULL;
-}
diff --git a/drivers/staging/wilc1000/wilc_memory.h b/drivers/staging/wilc1000/wilc_memory.h
deleted file mode 100644
index f19cec11a69a..000000000000
--- a/drivers/staging/wilc1000/wilc_memory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef __WILC_MEMORY_H__
-#define __WILC_MEMORY_H__
-
-/*!
- *  @file	wilc_memory.h
- *  @brief	Memory OS wrapper functionality
- *  @author	syounan
- *  @sa		wilc_oswrapper.h top level OS wrapper file
- *  @date	16 Aug 2010
- *  @version	1.0
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-
-/*!
- *  @struct             tstrWILC_MemoryAttrs
- *  @brief		Memory API options
- *  @author		syounan
- *  @date		16 Aug 2010
- *  @version		1.0
- */
-typedef struct {
-} tstrWILC_MemoryAttrs;
-
-/*!
- *  @brief	Allocates a given size of bytes
- *  @param[in]	u32Size size of memory in bytes to be allocated
- *  @param[in]	strAttrs Optional attributes, NULL for default
- *              if not NULL, pAllocationPool should point to the pool to use for
- *              this allocation. if NULL memory will be allocated directly from
- *              the system
- *  @param[in]	pcFileName file name of the calling code for debugging
- *  @param[in]	u32LineNo line number of the calling code for debugging
- *  @return	The new allocated block, NULL if allocation fails
- *  @note	It is recommended to use of of the wrapper macros instead of
- *              calling this function directly
- *  @sa		sttrWILC_MemoryAttrs
- *  @sa		WILC_MALLOC
- *  @sa		WILC_MALLOC_EX
- *  @author	syounan
- *  @date	16 Aug 2010
- *  @version	1.0
- */
-void *WILC_MemoryAlloc(u32 u32Size, tstrWILC_MemoryAttrs *strAttrs,
-		       char *pcFileName, u32 u32LineNo);
-
-/*!
- * @brief	standrad malloc wrapper with custom attributes
- */
-	#define WILC_MALLOC_EX(__size__, __attrs__) \
-	(WILC_MemoryAlloc( \
-		 (__size__), __attrs__, NULL, 0))
-
-
-/*!
- * @brief	standrad malloc wrapper with default attributes
- */
-#define WILC_MALLOC(__size__) \
-	WILC_MALLOC_EX(__size__, NULL)
-
-
-
-
-
-#endif
diff --git a/drivers/staging/wilc1000/wilc_msgqueue.c b/drivers/staging/wilc1000/wilc_msgqueue.c
index 70e4fa6a07a6..41244ce942ba 100644
--- a/drivers/staging/wilc1000/wilc_msgqueue.c
+++ b/drivers/staging/wilc1000/wilc_msgqueue.c
@@ -8,7 +8,7 @@
  *  @note		copied from FLO glue implementatuion
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle)
+int wilc_mq_create(WILC_MsgQueueHandle *pHandle)
 {
 	spin_lock_init(&pHandle->strCriticalSection);
 	sema_init(&pHandle->hSem, 0);
@@ -24,19 +24,19 @@ WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle)
  *  @note		copied from FLO glue implementatuion
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle)
+int wilc_mq_destroy(WILC_MsgQueueHandle *pHandle)
 {
-
 	pHandle->bExiting = true;
 
 	/* Release any waiting receiver thread. */
 	while (pHandle->u32ReceiversCount > 0) {
-		up(&(pHandle->hSem));
+		up(&pHandle->hSem);
 		pHandle->u32ReceiversCount--;
 	}
 
-	while (pHandle->pstrMessageList != NULL) {
+	while (pHandle->pstrMessageList) {
 		Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
+
 		kfree(pHandle->pstrMessageList);
 		pHandle->pstrMessageList = pstrMessge;
 	}
@@ -50,18 +50,18 @@ WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle)
  *  @note		copied from FLO glue implementatuion
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
+int wilc_mq_send(WILC_MsgQueueHandle *pHandle,
 			     const void *pvSendBuffer, u32 u32SendBufferSize)
 {
-	WILC_ErrNo s32RetStatus = WILC_SUCCESS;
+	int s32RetStatus = WILC_SUCCESS;
 	unsigned long flags;
 	Message *pstrMessage = NULL;
 
-	if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) {
+	if ((!pHandle) || (u32SendBufferSize == 0) || (!pvSendBuffer)) {
 		WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
 	}
 
-	if (pHandle->bExiting == true) {
+	if (pHandle->bExiting) {
 		WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
 	}
 
@@ -72,19 +72,19 @@ WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
 	WILC_NULLCHECK(s32RetStatus, pstrMessage);
 	pstrMessage->u32Length = u32SendBufferSize;
 	pstrMessage->pstrNext = NULL;
-	pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize);
+	pstrMessage->pvBuffer = kmalloc(u32SendBufferSize, GFP_ATOMIC);
 	WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
 	memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
 
-
 	/* add it to the message queue */
-	if (pHandle->pstrMessageList == NULL) {
+	if (!pHandle->pstrMessageList) {
 		pHandle->pstrMessageList  = pstrMessage;
 	} else {
 		Message *pstrTailMsg = pHandle->pstrMessageList;
-		while (pstrTailMsg->pstrNext != NULL) {
+
+		while (pstrTailMsg->pstrNext)
 			pstrTailMsg = pstrTailMsg->pstrNext;
-		}
+
 		pstrTailMsg->pstrNext = pstrMessage;
 	}
 
@@ -95,10 +95,8 @@ WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
 	WILC_CATCH(s32RetStatus)
 	{
 		/* error occured, free any allocations */
-		if (pstrMessage != NULL) {
-			if (pstrMessage->pvBuffer != NULL) {
-				kfree(pstrMessage->pvBuffer);
-			}
+		if (pstrMessage) {
+			kfree(pstrMessage->pvBuffer);
 			kfree(pstrMessage);
 		}
 	}
@@ -106,28 +104,26 @@ WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
 	return s32RetStatus;
 }
 
-
-
 /*!
  *  @author		syounan
  *  @date		1 Sep 2010
  *  @note		copied from FLO glue implementatuion
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
+int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
 			     void *pvRecvBuffer, u32 u32RecvBufferSize,
 			     u32 *pu32ReceivedLength)
 {
-
 	Message *pstrMessage;
-	WILC_ErrNo s32RetStatus = WILC_SUCCESS;
+	int s32RetStatus = WILC_SUCCESS;
 	unsigned long flags;
-	if ((pHandle == NULL) || (u32RecvBufferSize == 0)
-	    || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) {
+
+	if ((!pHandle) || (u32RecvBufferSize == 0)
+	    || (!pvRecvBuffer) || (!pu32ReceivedLength)) {
 		WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
 	}
 
-	if (pHandle->bExiting == true) {
+	if (pHandle->bExiting) {
 		WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
 	}
 
@@ -135,7 +131,7 @@ WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
 	pHandle->u32ReceiversCount++;
 	spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
 
-	down(&(pHandle->hSem));
+	down(&pHandle->hSem);
 
 	if (s32RetStatus == WILC_TIMEOUT) {
 		/* timed out, just exit without consumeing the message */
@@ -153,7 +149,7 @@ WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
 		spin_lock_irqsave(&pHandle->strCriticalSection, flags);
 
 		pstrMessage = pHandle->pstrMessageList;
-		if (pstrMessage == NULL) {
+		if (!pstrMessage) {
 			spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
 			WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
 		}
@@ -175,7 +171,6 @@ WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
 		kfree(pstrMessage);
 
 		spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
-
 	}
 
 	WILC_CATCH(s32RetStatus)
diff --git a/drivers/staging/wilc1000/wilc_msgqueue.h b/drivers/staging/wilc1000/wilc_msgqueue.h
index ef1d2fa20c50..fb26463a001c 100644
--- a/drivers/staging/wilc1000/wilc_msgqueue.h
+++ b/drivers/staging/wilc1000/wilc_msgqueue.h
@@ -12,7 +12,6 @@
 
 #include "wilc_platform.h"
 #include "wilc_errorsupport.h"
-#include "wilc_memory.h"
 
 /*!
  *  @brief		Creates a new Message queue
@@ -27,7 +26,7 @@
  *  @date		30 Aug 2010
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle);
+int wilc_mq_create(WILC_MsgQueueHandle *pHandle);
 
 /*!
  *  @brief		Sends a message
@@ -44,7 +43,7 @@ WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle);
  *  @date		30 Aug 2010
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
+int wilc_mq_send(WILC_MsgQueueHandle *pHandle,
 			     const void *pvSendBuffer, u32 u32SendBufferSize);
 
 /*!
@@ -63,7 +62,7 @@ WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
  *  @date		30 Aug 2010
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
+int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
 			     void *pvRecvBuffer, u32 u32RecvBufferSize,
 			     u32 *pu32ReceivedLength);
 
@@ -76,6 +75,6 @@ WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
  *  @date		30 Aug 2010
  *  @version		1.0
  */
-WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle);
+int wilc_mq_destroy(WILC_MsgQueueHandle *pHandle);
 
 #endif
diff --git a/drivers/staging/wilc1000/wilc_oswrapper.h b/drivers/staging/wilc1000/wilc_oswrapper.h
index cb483253e788..68f6efebc00c 100644
--- a/drivers/staging/wilc1000/wilc_oswrapper.h
+++ b/drivers/staging/wilc1000/wilc_oswrapper.h
@@ -19,10 +19,6 @@
 /* Error reporting and handling support */
 #include "wilc_errorsupport.h"
 
-/* Memory support */
-#include "wilc_memory.h"
-
-
 /* Message Queue */
 #include "wilc_msgqueue.h"
 
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
index 5a18148a593e..79aa4a1b8f9f 100644
--- a/drivers/staging/wilc1000/wilc_sdio.c
+++ b/drivers/staging/wilc1000/wilc_sdio.c
@@ -32,7 +32,6 @@ static wilc_sdio_t g_sdio;
 static int sdio_write_reg(uint32_t addr, uint32_t data);
 static int sdio_read_reg(uint32_t addr, uint32_t *data);
 #endif
-extern unsigned int int_clrd;
 
 /********************************************
  *
@@ -167,7 +166,6 @@ static int sdio_clear_int(void)
 	cmd.address = 0x4;
 	cmd.data = 0;
 	g_sdio.sdio_cmd52(&cmd);
-	int_clrd++;
 
 	return cmd.data;
 #else
@@ -179,7 +177,6 @@ static int sdio_clear_int(void)
 	}
 	reg &= ~0x1;
 	sdio_write_reg(WILC_HOST_RX_CTRL_0, reg);
-	int_clrd++;
 	return 1;
 #endif
 
diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index 1bf7d314ae34..d9ccca916517 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -10,8 +10,6 @@
 #include "wilc_wlan_if.h"
 #include "wilc_wlan.h"
 
-extern unsigned int int_clrd;
-
 /*
  * #include <linux/kernel.h>
  * #include <linux/string.h>
@@ -1023,13 +1021,13 @@ static int spi_read(uint32_t addr, uint8_t *buf, uint32_t size)
 static int spi_clear_int(void)
 {
 	uint32_t reg;
+
 	if (!spi_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
 		return 0;
 	}
 	reg &= ~0x1;
 	spi_write_reg(WILC_HOST_RX_CTRL_0, reg);
-	int_clrd++;
 	return 1;
 }
 
@@ -1170,6 +1168,7 @@ static void spi_default_bus_speed(void)
 static int spi_read_size(uint32_t *size)
 {
 	int ret;
+
 	if (g_spi.has_thrpt_enh) {
 		ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size);
 		*size = *size  & IRQ_DMA_WD_CNT_MASK;
@@ -1197,6 +1196,7 @@ _fail_:
 static int spi_read_int(uint32_t *int_status)
 {
 	int ret;
+
 	if (g_spi.has_thrpt_enh) {
 		ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status);
 	} else {
@@ -1257,6 +1257,7 @@ static int spi_clear_int_ext(uint32_t val)
 		ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val);
 	} else {
 		uint32_t flags;
+
 		flags = val & ((1 << MAX_NUM_INT) - 1);
 		if (flags) {
 			int i;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index a6edc973f636..26412a597489 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -23,7 +23,6 @@
 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
 
 extern int linux_wlan_get_firmware(perInterface_wlan_t *p_nic);
-extern void linux_wlan_unlock(void *vp);
 extern u16 Set_machw_change_vir_if(bool bValue);
 
 extern int mac_open(struct net_device *ndev);
@@ -144,6 +143,7 @@ bool g_wep_keys_saved;
 void clear_shadow_scan(void *pUserVoid)
 {
 	int i;
+
 	if (op_ifcs == 0) {
 		del_timer_sync(&hAgingTimer);
 		PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
@@ -188,6 +188,7 @@ void refresh_scan(void *pUserVoid, uint8_t all, bool bDirectScan)
 
 	for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
 		tstrNetworkInfo *pstrNetworkInfo;
+
 		pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
 
 
@@ -217,6 +218,7 @@ void refresh_scan(void *pUserVoid, uint8_t all, bool bDirectScan)
 void reset_shadow_found(void *pUserVoid)
 {
 	int i;
+
 	for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
 		astrLastScannedNtwrksShadow[i].u8Found = 0;
 
@@ -226,6 +228,7 @@ void reset_shadow_found(void *pUserVoid)
 void update_scan_time(void *pUserVoid)
 {
 	int i;
+
 	for (i = 0; i < u32LastScannedNtwrksCountShadow; i++) {
 		astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
 	}
@@ -339,7 +342,7 @@ void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, vo
 	if (ap_found != -1)
 		kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
 	astrLastScannedNtwrksShadow[ap_index].pu8IEs =
-		WILC_MALLOC(pstrNetworkInfo->u16IEsLen);        /* will be deallocated by the WILC_WFI_CfgScan() function */
+		kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);        /* will be deallocated by the WILC_WFI_CfgScan() function */
 	memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
 		    pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
 
@@ -553,6 +556,7 @@ static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent,
 	tstrWILC_WFIDrv *pstrWFIDrv;
 	#endif
 	u8 NullBssid[ETH_ALEN] = {0};
+
 	connecting = 0;
 
 	priv = (struct WILC_WFI_priv *)pUserVoid;
@@ -692,6 +696,7 @@ static int WILC_WFI_CfgSetChannel(struct wiphy *wiphy,
 	u32 channelnum = 0;
 	struct WILC_WFI_priv *priv;
 	s32 s32Error = WILC_SUCCESS;
+
 	priv = wiphy_priv(wiphy);
 
 	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
@@ -758,7 +763,7 @@ static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *r
 		if (request->n_ssids >= 1) {
 
 
-			strHiddenNetwork.pstrHiddenNetworkInfo = WILC_MALLOC(request->n_ssids * sizeof(tstrHiddenNetwork));
+			strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(tstrHiddenNetwork), GFP_KERNEL);
 			strHiddenNetwork.u8ssidnum = request->n_ssids;
 
 
@@ -766,7 +771,7 @@ static int WILC_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *r
 			for (i = 0; i < request->n_ssids; i++) {
 
 				if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
-					strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = WILC_MALLOC(request->ssids[i].ssid_len);
+					strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
 					memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
 					strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
 				} else {
@@ -922,7 +927,7 @@ static int WILC_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev,
 
 			/*BugID_5137*/
 			g_key_wep_params.key_len = sme->key_len;
-			g_key_wep_params.key = WILC_MALLOC(sme->key_len);
+			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
 			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
 			g_key_wep_params.key_idx = sme->key_idx;
 			g_wep_keys_saved = true;
@@ -940,7 +945,7 @@ static int WILC_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev,
 
 			/*BugID_5137*/
 			g_key_wep_params.key_len = sme->key_len;
-			g_key_wep_params.key = WILC_MALLOC(sme->key_len);
+			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
 			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
 			g_key_wep_params.key_idx = sme->key_idx;
 			g_wep_keys_saved = true;
@@ -1075,6 +1080,7 @@ static int WILC_WFI_disconnect(struct wiphy *wiphy, struct net_device *dev, u16
 	tstrWILC_WFIDrv *pstrWFIDrv;
 	#endif
 	uint8_t NullBssid[ETH_ALEN] = {0};
+
 	connecting = 0;
 	priv = wiphy_priv(wiphy);
 
@@ -1193,13 +1199,13 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 		if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
 
 			if (priv->wilc_gtk[key_index] == NULL) {
-				priv->wilc_gtk[key_index] = WILC_MALLOC(sizeof(struct wilc_wfi_key));
+				priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
 				priv->wilc_gtk[key_index]->key = NULL;
 				priv->wilc_gtk[key_index]->seq = NULL;
 
 			}
 			if (priv->wilc_ptk[key_index] == NULL) {
-				priv->wilc_ptk[key_index] = WILC_MALLOC(sizeof(struct wilc_wfi_key));
+				priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
 				priv->wilc_ptk[key_index]->key = NULL;
 				priv->wilc_ptk[key_index]->seq = NULL;
 			}
@@ -1224,7 +1230,7 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 				if (priv->wilc_gtk[key_index]->key)
 					kfree(priv->wilc_gtk[key_index]->key);
 
-				priv->wilc_gtk[key_index]->key = WILC_MALLOC(params->key_len);
+				priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
 				memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
 
 				/* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
@@ -1232,7 +1238,7 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 					kfree(priv->wilc_gtk[key_index]->seq);
 
 				if ((params->seq_len) > 0) {
-					priv->wilc_gtk[key_index]->seq = WILC_MALLOC(params->seq_len);
+					priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
 					memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
 				}
 
@@ -1270,13 +1276,13 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 				if (priv->wilc_ptk[key_index]->key)
 					kfree(priv->wilc_ptk[key_index]->key);
 
-				priv->wilc_ptk[key_index]->key = WILC_MALLOC(params->key_len);
+				priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
 
 				if (priv->wilc_ptk[key_index]->seq)
 					kfree(priv->wilc_ptk[key_index]->seq);
 
 				if ((params->seq_len) > 0)
-					priv->wilc_ptk[key_index]->seq = WILC_MALLOC(params->seq_len);
+					priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
 
 				if (INFO) {
 					for (i = 0; i < params->key_len; i++)
@@ -1320,15 +1326,15 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 					if (!mac_addr) {
 						g_add_gtk_key_params.mac_addr = NULL;
 					} else {
-						g_add_gtk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
+						g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
 						memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
 					}
 					g_key_gtk_params.key_len = params->key_len;
 					g_key_gtk_params.seq_len = params->seq_len;
-					g_key_gtk_params.key =  WILC_MALLOC(params->key_len);
+					g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
 					memcpy(g_key_gtk_params.key, params->key, params->key_len);
 					if (params->seq_len > 0) {
-						g_key_gtk_params.seq =  WILC_MALLOC(params->seq_len);
+						g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
 						memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
 					}
 					g_key_gtk_params.cipher = params->cipher;
@@ -1357,15 +1363,15 @@ static int WILC_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 					if (!mac_addr) {
 						g_add_ptk_key_params.mac_addr = NULL;
 					} else {
-						g_add_ptk_key_params.mac_addr = WILC_MALLOC(ETH_ALEN);
+						g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
 						memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
 					}
 					g_key_ptk_params.key_len = params->key_len;
 					g_key_ptk_params.seq_len = params->seq_len;
-					g_key_ptk_params.key =  WILC_MALLOC(params->key_len);
+					g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
 					memcpy(g_key_ptk_params.key, params->key, params->key_len);
 					if (params->seq_len > 0) {
-						g_key_ptk_params.seq =  WILC_MALLOC(params->seq_len);
+						g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
 						memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
 					}
 					g_key_ptk_params.cipher = params->cipher;
@@ -1527,6 +1533,7 @@ static int WILC_WFI_get_key(struct wiphy *wiphy, struct net_device *netdev, u8 k
 	struct WILC_WFI_priv *priv;
 	struct  key_params key_params;
 	u32 i;
+
 	priv = wiphy_priv(wiphy);
 
 
@@ -1668,6 +1675,7 @@ static int WILC_WFI_get_station(struct wiphy *wiphy, struct net_device *dev,
 
 	if (nic->iftype == STATION_MODE) {
 		tstrStatistics strStatistics;
+
 		host_int_get_statistics(priv->hWILCWFIDrv, &strStatistics);
 
 		/*
@@ -2198,6 +2206,7 @@ void WILC_WFI_p2p_rx (struct net_device *dev, uint8_t *buff, uint32_t size)
 	tstrWILC_WFIDrv *pstrWFIDrv;
 	u32 i = 0;
 	s32 s32Freq;
+
 	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
 	pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
 
@@ -2333,6 +2342,7 @@ static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
 {
 	struct WILC_WFI_priv *priv;
+
 	priv = (struct WILC_WFI_priv *)pUserVoid;
 
 	PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
@@ -2359,6 +2369,7 @@ static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
 {
 	struct WILC_WFI_priv *priv;
+
 	priv = (struct WILC_WFI_priv *)pUserVoid;
 
 	/*BugID_5477*/
@@ -2399,6 +2410,7 @@ static int  WILC_WFI_remain_on_channel(struct wiphy *wiphy,
 {
 	s32 s32Error = WILC_SUCCESS;
 	struct WILC_WFI_priv *priv;
+
 	priv = wiphy_priv(wiphy);
 
 	PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
@@ -2450,6 +2462,7 @@ static int   WILC_WFI_cancel_remain_on_channel(struct wiphy *wiphy,
 {
 	s32 s32Error = WILC_SUCCESS;
 	struct WILC_WFI_priv *priv;
+
 	priv = wiphy_priv(wiphy);
 
 	PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
@@ -2512,14 +2525,15 @@ int WILC_WFI_mgmt_tx(struct wiphy *wiphy,
 	if (ieee80211_is_mgmt(mgmt->frame_control)) {
 
 		/*mgmt frame allocation*/
-		mgmt_tx = WILC_MALLOC(sizeof(struct p2p_mgmt_data));
+		mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
 		if (mgmt_tx == NULL) {
 			PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
 			return WILC_FAIL;
 		}
-		mgmt_tx->buff = WILC_MALLOC(buf_len);
+		mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
 		if (mgmt_tx->buff == NULL) {
 			PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
+			kfree(mgmt_tx);
 			return WILC_FAIL;
 		}
 		memcpy(mgmt_tx->buff, buf, len);
@@ -2644,6 +2658,7 @@ int   WILC_WFI_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 {
 	struct WILC_WFI_priv *priv;
 	tstrWILC_WFIDrv *pstrWFIDrv;
+
 	priv = wiphy_priv(wiphy);
 	pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
 
@@ -2761,6 +2776,7 @@ static int WILC_WFI_dump_station(struct wiphy *wiphy, struct net_device *dev,
 				 int idx, u8 *mac, struct station_info *sinfo)
 {
 	struct WILC_WFI_priv *priv;
+
 	PRINT_D(CFG80211_DBG, "Dumping station information\n");
 
 	if (idx != 0)
@@ -2790,6 +2806,7 @@ int WILC_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 			    bool enabled, int timeout)
 {
 	struct WILC_WFI_priv *priv;
+
 	PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
 
 	if (wiphy == NULL)
@@ -2881,7 +2898,7 @@ static int WILC_WFI_change_virt_intf(struct wiphy *wiphy, struct net_device *dev
 
 			/*BugID_5213*/
 			/*Eliminate host interface blocking state*/
-			linux_wlan_unlock((void *)&g_linux_wlan->cfg_event);
+			up(&g_linux_wlan->cfg_event);
 
 			wilc1000_wlan_deinit(g_linux_wlan);
 			wilc1000_wlan_init(dev, nic);
@@ -3220,19 +3237,11 @@ static int WILC_WFI_start_ap(struct wiphy *wiphy, struct net_device *dev,
 
 	linux_wlan_set_bssid(dev, g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
 
-	#ifndef WILC_FULLY_HOSTING_AP
 	s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
 					settings->beacon_interval,
 					settings->dtim_period,
 					beacon->head_len, (u8 *)beacon->head,
 					beacon->tail_len, (u8 *)beacon->tail);
-	#else
-	s32Error = host_add_beacon(priv->hWILCWFIDrv,
-					settings->beacon_interval,
-					settings->dtim_period,
-					beacon->head_len, (u8 *)beacon->head,
-					beacon->tail_len, (u8 *)beacon->tail);
-	#endif
 
 	return s32Error;
 }
@@ -3259,19 +3268,11 @@ static int  WILC_WFI_change_beacon(struct wiphy *wiphy, struct net_device *dev,
 	PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
 
 
-#ifndef WILC_FULLY_HOSTING_AP
 	s32Error = host_int_add_beacon(priv->hWILCWFIDrv,
 					0,
 					0,
 					beacon->head_len, (u8 *)beacon->head,
 					beacon->tail_len, (u8 *)beacon->tail);
-#else
-	s32Error = host_add_beacon(priv->hWILCWFIDrv,
-					0,
-					0,
-					beacon->head_len, (u8 *)beacon->head,
-					beacon->tail_len, (u8 *)beacon->tail);
-#endif
 
 	return s32Error;
 }
@@ -3301,11 +3302,7 @@ static int  WILC_WFI_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 	/*BugID_5188*/
 	linux_wlan_set_bssid(dev, NullBssid);
 
-	#ifndef WILC_FULLY_HOSTING_AP
 	s32Error = host_int_del_beacon(priv->hWILCWFIDrv);
-	#else
-	s32Error = host_del_beacon(priv->hWILCWFIDrv);
-	#endif
 
 	WILC_ERRORCHECK(s32Error);
 
@@ -3339,8 +3336,6 @@ static int  WILC_WFI_add_station(struct wiphy *wiphy, struct net_device *dev,
 	nic = netdev_priv(dev);
 
 	if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
-		#ifndef WILC_FULLY_HOSTING_AP
-
 		memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
 		memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
 		strStaParams.u16AssocID = params->aid;
@@ -3380,18 +3375,6 @@ static int  WILC_WFI_add_station(struct wiphy *wiphy, struct net_device *dev,
 
 		s32Error = host_int_add_station(priv->hWILCWFIDrv, &strStaParams);
 		WILC_ERRORCHECK(s32Error);
-
-		#else
-		PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
-		memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
-
-		PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
-			priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
-
-		WILC_AP_AddSta(mac, params);
-		WILC_ERRORCHECK(s32Error);
-		#endif /* WILC_FULLY_HOSTING_AP */
-
 	}
 
 	WILC_CATCH(s32Error)
@@ -3416,6 +3399,7 @@ static int WILC_WFI_del_station(struct wiphy *wiphy, struct net_device *dev,
 	s32 s32Error = WILC_SUCCESS;
 	struct WILC_WFI_priv *priv;
 	perInterface_wlan_t *nic;
+
 	WILC_NULLCHECK(s32Error, wiphy);
 
 	priv = wiphy_priv(wiphy);
@@ -3432,11 +3416,7 @@ static int WILC_WFI_del_station(struct wiphy *wiphy, struct net_device *dev,
 			PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 		}
 
-		#ifndef WILC_FULLY_HOSTING_AP
 		s32Error = host_int_del_station(priv->hWILCWFIDrv, mac);
-		#else
-		WILC_AP_RemoveSta(mac);
-		#endif /* WILC_FULLY_HOSTING_AP */
 
 		WILC_ERRORCHECK(s32Error);
 	}
@@ -3472,8 +3452,6 @@ static int WILC_WFI_change_station(struct wiphy *wiphy, struct net_device *dev,
 	nic = netdev_priv(dev);
 
 	if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
-		#ifndef WILC_FULLY_HOSTING_AP
-
 		memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
 		strStaParams.u16AssocID = params->aid;
 		strStaParams.u8NumRates = params->supported_rates_len;
@@ -3511,12 +3489,6 @@ static int WILC_WFI_change_station(struct wiphy *wiphy, struct net_device *dev,
 
 		s32Error = host_int_edit_station(priv->hWILCWFIDrv, &strStaParams);
 		WILC_ERRORCHECK(s32Error);
-
-		#else
-		WILC_AP_EditSta(mac, params);
-		WILC_ERRORCHECK(s32Error);
-		#endif /* WILC_FULLY_HOSTING_AP */
-
 	}
 	WILC_CATCH(s32Error)
 	{
@@ -3542,6 +3514,7 @@ struct wireless_dev *WILC_WFI_add_virt_intf(struct wiphy *wiphy, const char *nam
 	perInterface_wlan_t *nic;
 	struct WILC_WFI_priv *priv;
 	struct net_device *new_ifc = NULL;
+
 	priv = wiphy_priv(wiphy);
 
 
@@ -3605,9 +3578,7 @@ static struct cfg80211_ops WILC_WFI_cfg80211_ops = {
 	.del_station = WILC_WFI_del_station,
 	.change_station = WILC_WFI_change_station,
 	#endif /* WILC_AP_EXTERNAL_MLME*/
-	#ifndef WILC_FULLY_HOSTING_AP
 	.get_station = WILC_WFI_get_station,
-	#endif
 	.dump_station = WILC_WFI_dump_station,
 	.change_bss = WILC_WFI_change_bss,
 	.set_wiphy_params = WILC_WFI_set_wiphy_params,
@@ -3864,6 +3835,7 @@ int WILC_WFI_DeInitHostInt(struct net_device *net)
 	s32 s32Error = WILC_SUCCESS;
 
 	struct WILC_WFI_priv *priv;
+
 	priv = wdev_priv(net->ieee80211_ptr);
 
 	priv->gbAutoRateAdjusted = false;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
index 97b663b7fd14..3c3571d8a369 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
@@ -10,11 +10,6 @@
 #define NM_WFI_CFGOPERATIONS
 #include "wilc_wfi_netdevice.h"
 
-#ifdef WILC_FULLY_HOSTING_AP
-#include "wilc_host_ap.h"
-#endif
-
-
 /* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
 #define NO_ENCRYPT			0
 #define ENCRYPT_ENABLED	(1 << 0)
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 77f320d125e8..e1caea9630af 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -80,9 +80,7 @@ struct WILC_WFI_stats {
  * LPC3131 which is important to get the MAC start status when you are blocked
  * inside linux_wlan_firmware_download() which blocks mac_open().
  */
-#if defined(NM73131_0_BOARD)
- #define RX_BH_TYPE  RX_BH_KTHREAD
-#elif defined(PANDA_BOARD)
+#if defined(PANDA_BOARD)
  #define RX_BH_TYPE  RX_BH_THREADED_IRQ
 #else
  #define RX_BH_TYPE  RX_BH_KTHREAD
@@ -172,7 +170,6 @@ typedef struct {
 
 } struct_frame_reg;
 
-#define NUM_CONCURRENT_IFC 2
 typedef struct {
 	uint8_t aSrcAddress[ETH_ALEN];
 	uint8_t aBSSID[ETH_ALEN];
@@ -193,19 +190,16 @@ typedef struct {
 	struct mutex txq_cs;
 
 	/*Added by Amr - BugID_4720*/
-	struct mutex txq_add_to_head_cs;
+	struct semaphore txq_add_to_head_cs;
 	spinlock_t txq_spinlock;
 
 	struct mutex rxq_cs;
 	struct mutex hif_cs;
 
-	/* struct mutex txq_event; */
 	struct semaphore rxq_event;
 	struct semaphore cfg_event;
 	struct semaphore sync_event;
-
 	struct semaphore txq_event;
-	/* struct completion txq_event; */
 
 #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
 	struct work_struct rx_work_queue;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index 7c53a2bd0381..39716babf606 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -19,9 +19,6 @@
 extern wilc_hif_func_t hif_sdio;
 extern wilc_hif_func_t hif_spi;
 extern wilc_cfg_func_t mac_cfg;
-#if defined(PLAT_RK3026_TCHIP)
-extern u8 g_wilc_initialized; /* AMR : 0422 RK3026 Crash issue */
-#endif
 extern void WILC_WFI_mgmt_rx(uint8_t *buff, uint32_t size);
 uint32_t wilc_get_chipid(uint8_t update);
 u16 Set_machw_change_vir_if(bool bValue);
@@ -43,7 +40,7 @@ typedef struct {
 	 *      host interface functions
 	 **/
 	wilc_hif_func_t hif_func;
-	void *hif_lock;
+	struct mutex *hif_lock;
 
 	/**
 	 *      configuration interface functions
@@ -76,7 +73,7 @@ typedef struct {
 	void *txq_lock;
 
 	/*Added by Amr - BugID_4720*/
-	void *txq_add_to_head_lock;
+	struct semaphore *txq_add_to_head_lock;
 	void *txq_spinlock;
 	unsigned long txq_spinlock_flags;
 
@@ -89,7 +86,7 @@ typedef struct {
 	/**
 	 *      RX queue
 	 **/
-	void *rxq_lock;
+	struct mutex *rxq_lock;
 	struct rxq_entry_t *rxq_head;
 	struct rxq_entry_t *rxq_tail;
 	int rxq_entries;
@@ -135,7 +132,7 @@ static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP;
 INLINE void acquire_bus(BUS_ACQUIRE_T acquire)
 {
 
-	g_wlan.os_func.os_enter_cs(g_wlan.hif_lock);
+	mutex_lock(g_wlan.hif_lock);
 	#ifndef WILC_OPTIMIZE_SLEEP_INT
 	if (genuChipPSstate != CHIP_WAKEDUP)
 	#endif
@@ -151,7 +148,7 @@ INLINE void release_bus(BUS_RELEASE_T release)
 	if (release == RELEASE_ALLOW_SLEEP)
 		chip_allow_sleep();
 	#endif
-	g_wlan.os_func.os_leave_cs(g_wlan.hif_lock);
+	mutex_unlock(g_wlan.hif_lock);
 }
 /********************************************
  *
@@ -188,7 +185,8 @@ static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void)
 	struct txq_entry_t *tqe;
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 	unsigned long flags;
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+	spin_lock_irqsave(p->txq_spinlock, flags);
 	if (p->txq_head) {
 		tqe = p->txq_head;
 		p->txq_head = tqe->next;
@@ -204,7 +202,7 @@ static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void)
 	} else {
 		tqe = NULL;
 	}
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 	return tqe;
 }
 
@@ -213,7 +211,7 @@ static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe)
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 	unsigned long flags;
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+	spin_lock_irqsave(p->txq_spinlock, flags);
 
 	if (p->txq_head == NULL) {
 		tqe->next = NULL;
@@ -230,16 +228,14 @@ static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe)
 	PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
 
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 
 	/**
 	 *      wake up TX queue
 	 **/
 	PRINT_D(TX_DBG, "Wake the txq_handling\n");
 
-	p->os_func.os_signal(p->txq_wait);
-
-
+	up(p->txq_wait);
 }
 
 static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe)
@@ -250,7 +246,7 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe)
 	if (p->os_func.os_wait(p->txq_add_to_head_lock, CFG_PKTS_TIMEOUT))
 		return -1;
 
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+	spin_lock_irqsave(p->txq_spinlock, flags);
 
 	if (p->txq_head == NULL) {
 		tqe->next = NULL;
@@ -267,14 +263,14 @@ static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe)
 	PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
 
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
-	p->os_func.os_signal(p->txq_add_to_head_lock);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
+	up(p->txq_add_to_head_lock);
 
 
 	/**
 	 *      wake up TX queue
 	 **/
-	p->os_func.os_signal(p->txq_wait);
+	up(p->txq_wait);
 	PRINT_D(TX_DBG, "Wake up the txq_handler\n");
 
 	/*Added by Amr - BugID_4720*/
@@ -368,9 +364,10 @@ static __inline int remove_TCP_related(void)
 {
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 	unsigned long flags;
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
 
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_lock_irqsave(p->txq_spinlock, flags);
+
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 	return 0;
 }
 
@@ -383,7 +380,8 @@ static __inline int tcp_process(struct txq_entry_t *tqe)
 	int i;
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 	unsigned long flags;
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+	spin_lock_irqsave(p->txq_spinlock, flags);
 
 	eth_hdr_ptr = &buffer[0];
 	h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
@@ -398,12 +396,14 @@ static __inline int tcp_process(struct txq_entry_t *tqe)
 		if (protocol == 0x06) {
 			uint8_t *tcp_hdr_ptr;
 			uint32_t IHL, Total_Length, Data_offset;
+
 			tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
 			IHL = (ip_hdr_ptr[0] & 0xf) << 2;
 			Total_Length = (((uint32_t)ip_hdr_ptr[2]) << 8) + ((uint32_t)ip_hdr_ptr[3]);
 			Data_offset = (((uint32_t)tcp_hdr_ptr[12] & 0xf0) >> 2);
 			if (Total_Length == (IHL + Data_offset)) { /*we want to recognize the clear Acks(packet only carry Ack infos not with data) so data size must be equal zero*/
 				uint32_t seq_no, Ack_no;
+
 				seq_no	= (((uint32_t)tcp_hdr_ptr[4]) << 24) + (((uint32_t)tcp_hdr_ptr[5]) << 16) + (((uint32_t)tcp_hdr_ptr[6]) << 8) + ((uint32_t)tcp_hdr_ptr[7]);
 
 				Ack_no	= (((uint32_t)tcp_hdr_ptr[8]) << 24) + (((uint32_t)tcp_hdr_ptr[9]) << 16) + (((uint32_t)tcp_hdr_ptr[10]) << 8) + ((uint32_t)tcp_hdr_ptr[11]);
@@ -429,7 +429,7 @@ static __inline int tcp_process(struct txq_entry_t *tqe)
 	} else {
 		ret = 0;
 	}
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 	return ret;
 }
 
@@ -441,10 +441,11 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(void)
 	uint32_t Dropped = 0;
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 
-	p->os_func.os_spin_lock(p->txq_spinlock, &p->txq_spinlock_flags);
+	spin_lock_irqsave(p->txq_spinlock, p->txq_spinlock_flags);
 	for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) {
 		if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].Bigger_Ack_num) {
 			struct txq_entry_t *tqe;
+
 			PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num);
 			tqe = Pending_Acks_info[i].txqe;
 			if (tqe) {
@@ -453,7 +454,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(void)
 				tqe->status = 1;                                /* mark the packet send */
 				if (tqe->tx_complete_func)
 					tqe->tx_complete_func(tqe->priv, tqe->status);
-				p->os_func.os_free(tqe);
+				kfree(tqe);
 				Dropped++;
 			}
 		}
@@ -467,7 +468,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(void)
 		PendingAcks_arrBase = 0;
 
 
-	p->os_func.os_spin_unlock(p->txq_spinlock, &p->txq_spinlock_flags);
+	spin_unlock_irqrestore(p->txq_spinlock, p->txq_spinlock_flags);
 
 	while (Dropped > 0) {
 		/*consume the semaphore count of the removed packet*/
@@ -501,11 +502,11 @@ static int wilc_wlan_txq_add_cfg_pkt(uint8_t *buffer, uint32_t buffer_size)
 	PRINT_D(TX_DBG, "Adding config packet ...\n");
 	if (p->quit) {
 		PRINT_D(TX_DBG, "Return due to clear function\n");
-		p->os_func.os_signal(p->cfg_wait);
+		up(p->cfg_wait);
 		return 0;
 	}
 
-	tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+	tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC);
 	if (tqe == NULL) {
 		PRINT_ER("Failed to allocate memory\n");
 		return 0;
@@ -538,7 +539,7 @@ static int wilc_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffe
 	if (p->quit)
 		return 0;
 
-	tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+	tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC);
 
 	if (tqe == NULL)
 		return 0;
@@ -571,7 +572,7 @@ int wilc_wlan_txq_add_mgmt_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size
 	if (p->quit)
 		return 0;
 
-	tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+	tqe = kmalloc(sizeof(struct txq_entry_t), GFP_KERNEL);
 
 	if (tqe == NULL)
 		return 0;
@@ -587,31 +588,6 @@ int wilc_wlan_txq_add_mgmt_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size
 	wilc_wlan_txq_add_to_tail(tqe);
 	return 1;
 }
-
-#ifdef WILC_FULLY_HOSTING_AP
-int wilc_FH_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, wilc_tx_complete_func_t func)
-{
-	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
-	struct txq_entry_t *tqe;
-
-	if (p->quit)
-		return 0;
-
-	tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
-
-	if (tqe == NULL)
-		return 0;
-	tqe->type = WILC_FH_DATA_PKT;
-	tqe->buffer = buffer;
-	tqe->buffer_size = buffer_size;
-	tqe->tx_complete_func = func;
-	tqe->priv = priv;
-	PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n");
-	wilc_wlan_txq_add_to_tail(tqe);
-	/*return number of itemes in the queue*/
-	return p->txq_entries;
-}
-#endif  /* WILC_FULLY_HOSTING_AP*/
 #endif /*WILC_AP_EXTERNAL_MLME*/
 static struct txq_entry_t *wilc_wlan_txq_get_first(void)
 {
@@ -620,12 +596,12 @@ static struct txq_entry_t *wilc_wlan_txq_get_first(void)
 	unsigned long flags;
 
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+	spin_lock_irqsave(p->txq_spinlock, flags);
 
 	tqe = p->txq_head;
 
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 
 
 	return tqe;
@@ -636,11 +612,11 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct txq_entry_t *tqe)
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
 	unsigned long flags;
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+	spin_lock_irqsave(p->txq_spinlock, flags);
 
 	tqe = tqe->next;
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+	spin_unlock_irqrestore(p->txq_spinlock, flags);
 
 
 	return tqe;
@@ -653,7 +629,7 @@ static int wilc_wlan_rxq_add(struct rxq_entry_t *rqe)
 	if (p->quit)
 		return 0;
 
-	p->os_func.os_enter_cs(p->rxq_lock);
+	mutex_lock(p->rxq_lock);
 	if (p->rxq_head == NULL) {
 		PRINT_D(RX_DBG, "Add to Queue head\n");
 		rqe->next = NULL;
@@ -667,7 +643,7 @@ static int wilc_wlan_rxq_add(struct rxq_entry_t *rqe)
 	}
 	p->rxq_entries += 1;
 	PRINT_D(RX_DBG, "Number of queue entries: %d\n", p->rxq_entries);
-	p->os_func.os_leave_cs(p->rxq_lock);
+	mutex_unlock(p->rxq_lock);
 	return p->rxq_entries;
 }
 
@@ -679,12 +655,12 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(void)
 	if (p->rxq_head) {
 		struct rxq_entry_t *rqe;
 
-		p->os_func.os_enter_cs(p->rxq_lock);
+		mutex_lock(p->rxq_lock);
 		rqe = p->rxq_head;
 		p->rxq_head = p->rxq_head->next;
 		p->rxq_entries -= 1;
 		PRINT_D(RX_DBG, "RXQ entries decreased\n");
-		p->os_func.os_leave_cs(p->rxq_lock);
+		mutex_unlock(p->rxq_lock);
 		return rqe;
 	}
 	PRINT_D(RX_DBG, "Nothing to get from Q\n");
@@ -778,6 +754,7 @@ INLINE void chip_wakeup(void)
 		if (wilc_get_chipid(false) >= 0x1002b0) {
 			/* Enable PALDO back right after wakeup */
 			uint32_t val32;
+
 			g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
 			val32 |= (1 << 6);
 			g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
@@ -793,6 +770,7 @@ INLINE void chip_wakeup(void)
 INLINE void chip_wakeup(void)
 {
 	uint32_t reg, trials = 0;
+
 	do {
 		if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) {
 			g_wlan.hif_func.hif_read_reg(1, &reg);
@@ -833,6 +811,7 @@ INLINE void chip_wakeup(void)
 		if (wilc_get_chipid(false) >= 0x1002b0) {
 			/* Enable PALDO back right after wakeup */
 			uint32_t val32;
+
 			g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
 			val32 |= (1 << 6);
 			g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
@@ -885,6 +864,7 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 	int counter;
 	int timeout;
 	uint32_t vmm_table[WILC_VMM_TBL_SIZE];
+
 	p->txq_exit = 0;
 	do {
 		if (p->quit)
@@ -916,11 +896,6 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 				else if (tqe->type == WILC_NET_PKT) {
 					vmm_sz = ETH_ETHERNET_HDR_OFFSET;
 				}
-#ifdef WILC_FULLY_HOSTING_AP
-				else if (tqe->type == WILC_FH_DATA_PKT)	{
-					vmm_sz = FH_TX_HOST_HDR_OFFSET;
-				}
-#endif
 #ifdef WILC_AP_EXTERNAL_MLME
 				else {
 					vmm_sz = HOST_HDR_OFFSET;
@@ -991,7 +966,7 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 				 **/
 				PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n");
 				release_bus(RELEASE_ALLOW_SLEEP);
-				p->os_func.os_sleep(3); /* wait 3 ms */
+				usleep_range(3000, 3000);
 				acquire_bus(ACQUIRE_AND_WAKEUP);
 			}
 		} while (!p->quit);
@@ -1041,7 +1016,7 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 					break;
 				} else {
 					release_bus(RELEASE_ALLOW_SLEEP);
-					p->os_func.os_sleep(3); /* wait 3 ms */
+					usleep_range(3000, 3000);
 					acquire_bus(ACQUIRE_AND_WAKEUP);
 					PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg);
 				}
@@ -1125,15 +1100,11 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 				/* and WILC_DATA_PKT_MAC_HDR*/
 				else if (tqe->type == WILC_NET_PKT) {
 					char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid;
+
 					buffer_offset = ETH_ETHERNET_HDR_OFFSET;
 					/* copy the bssid at the sart of the buffer */
 					memcpy(&txb[offset + 4], pBSSID, 6);
 				}
-#ifdef WILC_FULLY_HOSTING_AP
-				else if (tqe->type == WILC_FH_DATA_PKT)	{
-					buffer_offset = FH_TX_HOST_HDR_OFFSET;
-				}
-#endif
 				else {
 					buffer_offset = HOST_HDR_OFFSET;
 				}
@@ -1149,7 +1120,7 @@ static int wilc_wlan_handle_txq(uint32_t *pu32TxqCount)
 					Pending_Acks_info[tqe->tcp_PendingAck_index].txqe = NULL;
 				}
 				#endif
-				p->os_func.os_free(tqe);
+				kfree(tqe);
 			} else {
 				break;
 			}
@@ -1182,7 +1153,7 @@ _end_:
 			break;
 	} while (0);
 	/*Added by Amr - BugID_4720*/
-	p->os_func.os_signal(p->txq_add_to_head_lock);
+	up(p->txq_add_to_head_lock);
 
 	p->txq_exit = 1;
 	PRINT_D(TX_DBG, "THREAD: Exiting txq\n");
@@ -1206,7 +1177,7 @@ static void wilc_wlan_handle_rxq(void)
 	do {
 		if (p->quit) {
 			PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n");
-			p->os_func.os_signal(p->cfg_wait);
+			up(p->cfg_wait);
 			break;
 		}
 		rqe = wilc_wlan_rxq_remove();
@@ -1225,6 +1196,7 @@ static void wilc_wlan_handle_rxq(void)
 			uint32_t header;
 			uint32_t pkt_len, pkt_offset, tp_len;
 			int is_cfg_packet;
+
 			PRINT_D(RX_DBG, "In the 2nd do-while\n");
 			memcpy(&header, &buffer[offset], 4);
 #ifdef BIG_ENDIAN
@@ -1255,11 +1227,7 @@ static void wilc_wlan_handle_rxq(void)
 				/* reset mgmt indicator bit, to use pkt_offeset in furthur calculations */
 				pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES);
 
-#ifdef USE_WIRELESS
 				WILC_WFI_mgmt_rx(&buffer[offset + HOST_HDR_OFFSET], pkt_len);
-
-#endif
-
 			}
 			/* BUG4530 fix */
 			else
@@ -1286,7 +1254,7 @@ static void wilc_wlan_handle_rxq(void)
 						 **/
 						PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no);
 						if (p->cfg_seq_no == rsp.seq_no) {
-							p->os_func.os_signal(p->cfg_wait);
+							up(p->cfg_wait);
 						}
 					} else if (rsp.type == WILC_CFG_RSP_STATUS) {
 						/**
@@ -1309,11 +1277,9 @@ static void wilc_wlan_handle_rxq(void)
 
 
 #ifndef MEMORY_STATIC
-		if (buffer != NULL)
-			p->os_func.os_free((void *)buffer);
+		kfree(buffer);
 #endif
-		if (rqe != NULL)
-			p->os_func.os_free((void *)rqe);
+		kfree(rqe);
 
 		if (has_packet) {
 			if (p->net_func.rx_complete)
@@ -1342,12 +1308,12 @@ static void wilc_pllupdate_isr_ext(uint32_t int_stats)
 	g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR);
 
 	/* Waiting for PLL */
-	g_wlan.os_func.os_atomic_sleep(WILC_PLL_TO);
+	mdelay(WILC_PLL_TO);
 
 	/* poll till read a valid data */
 	while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) {
 		PRINT_D(TX_DBG, "PLL update retrying\n");
-		g_wlan.os_func.os_atomic_sleep(1);
+		mdelay(1);
 	}
 }
 
@@ -1402,7 +1368,7 @@ static void wilc_wlan_handle_isr_ext(uint32_t int_status)
 		}
 
 #else
-		buffer = p->os_func.os_malloc(size);
+		buffer = kmalloc(size, GFP_KERNEL);
 		if (buffer == NULL) {
 			wilc_debug(N_ERR, "[wilc isr]: fail alloc host memory...drop the packets (%d)\n", size);
 			usleep_range(100 * 1000, 100 * 1000);
@@ -1436,18 +1402,17 @@ _end_:
 			/**
 			 *      add to rx queue
 			 **/
-			rqe = (struct rxq_entry_t *)p->os_func.os_malloc(sizeof(struct rxq_entry_t));
+			rqe = kmalloc(sizeof(struct rxq_entry_t), GFP_KERNEL);
 			if (rqe != NULL) {
 				rqe->buffer = buffer;
 				rqe->buffer_size = size;
 				PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer);
 				wilc_wlan_rxq_add(rqe);
-				p->os_func.os_signal(p->rxq_wait);
+				up(p->rxq_wait);
 			}
 		} else {
 #ifndef MEMORY_STATIC
-			if (buffer != NULL)
-				p->os_func.os_free(buffer);
+			kfree(buffer);
 #endif
 		}
 	}
@@ -1505,15 +1470,7 @@ static int wilc_wlan_firmware_download(const uint8_t *buffer, uint32_t buffer_si
 	blksz = (1ul << 12); /* Bug 4703: 4KB Good enough size for most platforms = PAGE_SIZE. */
 	/* Allocate a DMA coherent  buffer. */
 
-#if (defined WILC_PREALLOC_AT_BOOT)
-	{
-		extern void *get_fw_buffer(void);
-		dma_buffer = (uint8_t *)get_fw_buffer();
-		PRINT_D(TX_DBG, "fw_buffer = 0x%x\n", dma_buffer);
-	}
-#else
-	dma_buffer = (uint8_t *)g_wlan.os_func.os_malloc(blksz);
-#endif
+	dma_buffer = kmalloc(blksz, GFP_KERNEL);
 	if (dma_buffer == NULL) {
 		/*EIO	5*/
 		ret = -5;
@@ -1563,12 +1520,7 @@ static int wilc_wlan_firmware_download(const uint8_t *buffer, uint32_t buffer_si
 
 _fail_:
 
-#if (defined WILC_PREALLOC_AT_BOOT)
-
-#else
-	if (dma_buffer)
-		g_wlan.os_func.os_free(dma_buffer);
-#endif
+	kfree(dma_buffer);
 
 _fail_1:
 
@@ -1705,6 +1657,7 @@ void wilc_wlan_global_reset(void)
 {
 
 	wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
+
 	acquire_bus(ACQUIRE_AND_WAKEUP);
 	p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0);
 	release_bus(RELEASE_ONLY);
@@ -1799,7 +1752,7 @@ static void wilc_wlan_cleanup(void)
 			break;
 		if (tqe->tx_complete_func)
 			tqe->tx_complete_func(tqe->priv, 0);
-		p->os_func.os_free((void *)tqe);
+		kfree(tqe);
 	} while (1);
 
 	do {
@@ -1807,29 +1760,20 @@ static void wilc_wlan_cleanup(void)
 		if (rqe == NULL)
 			break;
 #ifdef MEMORY_DYNAMIC
-		p->os_func.os_free((void *)tqe->buffer);
+		kfree(tqe->buffer);
 #endif
-		p->os_func.os_free((void *)rqe);
+		kfree(rqe);
 	} while (1);
 
 	/**
 	 *      clean up buffer
 	 **/
 
-#if (defined WILC_PREALLOC_AT_BOOT)
-
-#else
 	#ifdef MEMORY_STATIC
-	if (p->rx_buffer) {
-		p->os_func.os_free(p->rx_buffer);
-		p->rx_buffer = NULL;
-	}
+	kfree(p->rx_buffer);
+	p->rx_buffer = NULL;
 	#endif
-	if (p->tx_buffer) {
-		p->os_func.os_free(p->tx_buffer);
-		p->tx_buffer = NULL;
-	}
-#endif
+	kfree(p->tx_buffer);
 
 	acquire_bus(ACQUIRE_AND_WAKEUP);
 
@@ -1996,11 +1940,7 @@ uint32_t init_chip(void)
 	uint32_t chipid;
 	uint32_t reg, ret = 0;
 
-#if defined(PLAT_RK3026_TCHIP)
-	acquire_bus(ACQUIRE_AND_WAKEUP); /* AMR : 0422 RK3026 Crash issue */
-#else
 	acquire_bus(ACQUIRE_ONLY);
-#endif
 
 	chipid = wilc_get_chipid(true);
 
@@ -2130,13 +2070,6 @@ int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
 	/***
 	 *      host interface init
 	 **/
-#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */
-	if (!g_wilc_initialized) {
-		custom_lock_bus(g_mac_open);
-		custom_wakeup(g_mac_open);
-	}
-#endif
-
 	if ((inp->io_func.io_type & 0x1) == HIF_SDIO) {
 		if (!hif_sdio.hif_init(inp, wilc_debug)) {
 			/* EIO	5 */
@@ -2176,21 +2109,8 @@ int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
 	/**
 	 *      alloc tx, rx buffer
 	 **/
-#if (defined WILC_PREALLOC_AT_BOOT)
-	extern void *get_tx_buffer(void);
-	extern void *get_rx_buffer(void);
-
-	PRINT_D(TX_DBG, "malloc before, g_wlan.tx_buffer = 0x%x, g_wlan.rx_buffer = 0x%x\n", g_wlan.tx_buffer, g_wlan.rx_buffer);
-#endif
-
-
-
 	if (g_wlan.tx_buffer == NULL)
-#if (defined WILC_PREALLOC_AT_BOOT)
-		g_wlan.tx_buffer = (uint8_t *)get_tx_buffer();
-#else
-		g_wlan.tx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.tx_buffer_size);
-#endif
+		g_wlan.tx_buffer = kmalloc(g_wlan.tx_buffer_size, GFP_KERNEL);
 	PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer);
 
 	if (g_wlan.tx_buffer == NULL) {
@@ -2203,11 +2123,7 @@ int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
 /* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/
 #if defined (MEMORY_STATIC)
 	if (g_wlan.rx_buffer == NULL)
-  #if (defined WILC_PREALLOC_AT_BOOT)
-		g_wlan.rx_buffer = (uint8_t *)get_rx_buffer();
-  #else
-		g_wlan.rx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.rx_buffer_size);
-  #endif
+		g_wlan.rx_buffer = kmalloc(g_wlan.rx_buffer_size, GFP_KERNEL);
 	PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer);
 	if (g_wlan.rx_buffer == NULL) {
 		/* ENOBUFS	105 */
@@ -2235,10 +2151,6 @@ int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
 	/*Bug3959: transmitting mgmt frames received from host*/
 	#if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P)
 	oup->wlan_add_mgmt_to_tx_que = wilc_wlan_txq_add_mgmt_pkt;
-
-	#ifdef WILC_FULLY_HOSTING_AP
-	oup->wlan_add_data_to_tx_que = wilc_FH_wlan_txq_add_net_pkt;
-	#endif
 	#endif
 
 	if (!init_chip()) {
@@ -2250,34 +2162,16 @@ int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
 	Init_TCP_tracking();
 #endif
 
-#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */
-	if (!g_wilc_initialized)
-		custom_unlock_bus(g_mac_open);
-#endif
-
 	return 1;
 
 _fail_:
 
-#if (defined WILC_PREALLOC_AT_BOOT)
-
-#else
   #ifdef MEMORY_STATIC
-	if (g_wlan.rx_buffer) {
-		g_wlan.os_func.os_free(g_wlan.rx_buffer);
-		g_wlan.rx_buffer = NULL;
-	}
+	kfree(g_wlan.rx_buffer);
+	g_wlan.rx_buffer = NULL;
   #endif
-	if (g_wlan.tx_buffer) {
-		g_wlan.os_func.os_free(g_wlan.tx_buffer);
-		g_wlan.tx_buffer = NULL;
-	}
-#endif
-
-#if defined(PLAT_RK3026_TCHIP) /* AMR : 0422 RK3026 Crash issue */
-	if (!g_wilc_initialized)
-		custom_unlock_bus(g_mac_open);
-#endif
+	kfree(g_wlan.tx_buffer);
+	g_wlan.tx_buffer = NULL;
 
 	return ret;
 
@@ -2290,7 +2184,7 @@ u16 Set_machw_change_vir_if(bool bValue)
 	u32 reg;
 
 	/*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
-	(&g_wlan)->os_func.os_enter_cs((&g_wlan)->hif_lock);
+	mutex_lock((&g_wlan)->hif_lock);
 	ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, &reg);
 	if (!ret) {
 		PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n");
@@ -2306,16 +2200,7 @@ u16 Set_machw_change_vir_if(bool bValue)
 	if (!ret) {
 		PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n");
 	}
-	(&g_wlan)->os_func.os_leave_cs((&g_wlan)->hif_lock);
+	mutex_unlock((&g_wlan)->hif_lock);
 
 	return ret;
 }
-
-#ifdef WILC_FULLY_HOSTING_AP
-wilc_wlan_dev_t *Get_wlan_context(u16 *pu16size)
-{
-	*pu16size = sizeof(wilc_wlan_dev_t);
-	return &g_wlan;
-}
-#endif
-
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 244f7108ae92..99e07de2d3ed 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -36,9 +36,6 @@
 				   ETH_CONFIG_PKT_HDR_LEN)
 #define   ACTION         0xD0
 #define   PROBE_REQ   0x40
-#ifdef WILC_FULLY_HOSTING_AP
-#define	FH_TX_HOST_HDR_OFFSET	24
-#endif
 
 /********************************************
  *
@@ -145,10 +142,6 @@
 #ifdef WILC_AP_EXTERNAL_MLME
 #define WILC_MGMT_PKT 2
 
-#ifdef WILC_FULLY_HOSTING_AP
-#define WILC_FH_DATA_PKT 4
-#endif
-
 #endif /*WILC_AP_EXTERNAL_MLME*/
 #define WILC_CFG_SET 1
 #define WILC_CFG_QUERY 0
diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c
index e2842d37b078..21ed14d8bfe0 100644
--- a/drivers/staging/wilc1000/wilc_wlan_cfg.c
+++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c
@@ -12,11 +12,6 @@
 #include "wilc_wlan_cfg.h"
 #include "coreconfigurator.h"
 
-#ifdef WILC_FULLY_HOSTING_AP
-#include "wilc_host_ap.h"
-void WILC_mgm_HOSTAPD_ACK(void *priv, bool bStatus);
-#endif
-
 /********************************************
  *
  *      Global Data
@@ -342,6 +337,7 @@ static void wilc_wlan_parse_response_frame(uint8_t *info, int size)
 				if (g_cfg_str[i].id == wid) {
 					if (wid == WID_SITE_SURVEY_RESULTS) {
 						static int toggle;
+
 						PRINT_INFO(GENERIC_DBG, "Site survey results received[%d]\n",
 							   size);
 
@@ -483,9 +479,11 @@ static int wilc_wlan_cfg_get_wid_value(uint16_t wid, uint8_t *buffer, uint32_t b
 
 			if (g_cfg_str[i].id == wid) {
 				uint32_t size =  g_cfg_str[i].str[0];
+
 				if (buffer_size >= size) {
 					if (g_cfg_str[i].id == WID_SITE_SURVEY_RESULTS)	{
 						static int toggle;
+
 						PRINT_INFO(GENERIC_DBG, "Site survey results value[%d]\n",
 							   size);
 						i += toggle;
@@ -511,17 +509,6 @@ static int wilc_wlan_cfg_indicate_rx(uint8_t *frame, int size, wilc_cfg_rsp_t *r
 	int ret = 1;
 	uint8_t msg_type;
 	uint8_t msg_id;
-	#ifdef WILC_FULLY_HOSTING_AP
-	u32 *ptru32Frame;
-	bool bStatus = frame[2];
-
-	#ifdef BIG_ENDIAN
-	ptru32Frame = (frame[4] << 24) | (frame[5] << 16) | (frame[6] << 8) | frame[7];
-	#else
-	ptru32Frame = (frame[7] << 24) | (frame[6] << 16) | (frame[5] << 8) | frame[4];
-	#endif  /* BIG_ENDIAN */
-
-	#endif  /* WILC_FULLY_HOSTING_AP */
 
 	msg_type = frame[0];
 	msg_id = frame[1];      /* seq no */
@@ -547,14 +534,6 @@ static int wilc_wlan_cfg_indicate_rx(uint8_t *frame, int size, wilc_cfg_rsp_t *r
 		GnrlAsyncInfoReceived(frame - 4, size + 4);
 		break;
 
-	case 'L':
-#ifndef SWITCH_LOG_TERMINAL
-		PRINT_ER("Unexpected firmware log message received\n");
-#else
-		PRINT_D(FIRM_DBG, "\nFIRMWARE LOGS :\n<<\n%s\n>>\n", frame);
-		break;
-
-#endif
 #if 1
 	case 'N':
 		NetworkInfoReceived(frame - 4, size + 4);
@@ -568,18 +547,6 @@ static int wilc_wlan_cfg_indicate_rx(uint8_t *frame, int size, wilc_cfg_rsp_t *r
 		host_int_ScanCompleteReceived(frame - 4, size + 4);
 		break;
 
-#ifdef WILC_FULLY_HOSTING_AP
-	case 'T':
-		PRINT_INFO(RX_DBG, "TBTT Notification Received\n");
-		process_tbtt_isr();
-		break;
-
-	case 'A':
-		PRINT_INFO(RX_DBG, "HOSTAPD ACK Notification Received\n");
-		WILC_mgm_HOSTAPD_ACK(ptru32Frame, bStatus);
-		break;
-#endif
-
 	default:
 		PRINT_INFO(RX_DBG, "Receive unknown message type[%d-%d-%d-%d-%d-%d-%d-%d]\n",
 			   frame[0], frame[1], frame[2], frame[3], frame[4],
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h
index 5cf74e4c4a70..9f9f4a97fa99 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -16,7 +16,6 @@
 #define WILC_P2P
 #define TCP_ENHANCEMENTS
 /* #define MEMORY_STATIC */
-/* #define WILC_FULLY_HOSTING_AP */
 /* #define USE_OLD_SPI_SW */
 
 
@@ -84,23 +83,8 @@ typedef struct {
 } sdio_cmd53_t;
 
 typedef struct {
-	void (*os_sleep)(uint32_t);
-	void (*os_atomic_sleep)(uint32_t);
 	void (*os_debug)(uint8_t *);
-	void *(*os_malloc)(uint32_t);
-	void *(*os_malloc_atomic)(uint32_t);
-	void (*os_free)(void *);
-	void (*os_lock)(void *);
-	void (*os_unlock)(void *);
 	int (*os_wait)(void *, u32);
-	void (*os_signal)(void *);
-	void (*os_enter_cs)(void *);
-	void (*os_leave_cs)(void *);
-
-	/*Added by Amr - BugID_4720*/
-	void (*os_spin_lock)(void *, unsigned long *);
-	void (*os_spin_unlock)(void *, unsigned long *);
-
 } wilc_wlan_os_func_t;
 
 typedef struct {
@@ -141,7 +125,7 @@ typedef struct {
 typedef struct {
 	void *os_private;
 
-	void *hif_critical_section;
+	struct mutex *hif_critical_section;
 
 	uint32_t tx_buffer_size;
 	void *txq_critical_section;
@@ -158,7 +142,7 @@ typedef struct {
 	void *rxq_critical_section;
 	void *rxq_wait_event;
 
-	void *cfg_wait_event;
+	struct semaphore *cfg_wait_event;
 } wilc_wlan_os_context_t;
 
 typedef struct {
@@ -170,9 +154,6 @@ typedef struct {
 } wilc_wlan_inp_t;
 
 struct tx_complete_data {
-	#ifdef WILC_FULLY_HOSTING_AP
-	struct tx_complete_data *next;
-	#endif
 	int size;
 	void *buff;
 	uint8_t *pBssid;
@@ -199,11 +180,6 @@ typedef struct {
 	/*Bug3959: transmitting mgmt frames received from host*/
 	#if defined(WILC_AP_EXTERNAL_MLME) || defined(WILC_P2P)
 	int (*wlan_add_mgmt_to_tx_que)(void *, uint8_t *, uint32_t, wilc_tx_complete_func_t);
-
-	#ifdef WILC_FULLY_HOSTING_AP
-	int (*wlan_add_data_to_tx_que)(void *, uint8_t *, uint32_t, wilc_tx_complete_func_t);
-	#endif
-
 	#endif
 } wilc_wlan_oup_t;
 
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 49f2ef88929d..1b02cdf9d1fa 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -135,7 +135,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
 			/* it's 802.3, pass ether payload unchanged,  */
 
 			/* trim off ethernet header */
-			skb_pull(skb, WLAN_ETHHDR_LEN);
+			skb_pull(skb, ETH_HLEN);
 
 			/*   leave off any PAD octets.  */
 			skb_trim(skb, proto);
@@ -144,7 +144,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
 			/* it's DIXII, time for some conversion */
 
 			/* trim off ethernet header */
-			skb_pull(skb, WLAN_ETHHDR_LEN);
+			skb_pull(skb, ETH_HLEN);
 
 			/* tack on SNAP */
 			e_snap =
@@ -281,8 +281,8 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 	u16 fc;
 	unsigned int payload_length;
 	unsigned int payload_offset;
-	u8 daddr[WLAN_ETHADDR_LEN];
-	u8 saddr[WLAN_ETHADDR_LEN];
+	u8 daddr[ETH_ALEN];
+	u8 saddr[ETH_ALEN];
 	union p80211_hdr *w_hdr;
 	struct wlan_ethhdr *e_hdr;
 	struct wlan_llc *e_llc;
@@ -298,16 +298,16 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 	/* setup some vars for convenience */
 	fc = le16_to_cpu(w_hdr->a3.fc);
 	if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
-		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
-		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+		ether_addr_copy(daddr, w_hdr->a3.a1);
+		ether_addr_copy(saddr, w_hdr->a3.a2);
 	} else if ((WLAN_GET_FC_TODS(fc) == 0)
 			&& (WLAN_GET_FC_FROMDS(fc) == 1)) {
-		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
-		memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
+		ether_addr_copy(daddr, w_hdr->a3.a1);
+		ether_addr_copy(saddr, w_hdr->a3.a3);
 	} else if ((WLAN_GET_FC_TODS(fc) == 1)
 			&& (WLAN_GET_FC_FROMDS(fc) == 0)) {
-		memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
-		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+		ether_addr_copy(daddr, w_hdr->a3.a3);
+		ether_addr_copy(saddr, w_hdr->a3.a2);
 	} else {
 		payload_offset = WLAN_HDR_A4_LEN;
 		if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) {
@@ -315,8 +315,8 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 			return 1;
 		}
 		payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
-		memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN);
-		memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN);
+		ether_addr_copy(daddr, w_hdr->a4.a3);
+		ether_addr_copy(saddr, w_hdr->a4.a4);
 	}
 
 	/* perform de-wep if necessary.. */
@@ -360,16 +360,16 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 	/* Test for the various encodings */
 	if ((payload_length >= sizeof(struct wlan_ethhdr)) &&
 	    (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) &&
-	    ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
-	     (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
+	    ((!ether_addr_equal_unaligned(daddr, e_hdr->daddr)) ||
+	     (!ether_addr_equal_unaligned(saddr, e_hdr->saddr)))) {
 		pr_debug("802.3 ENCAP len: %d\n", payload_length);
 		/* 802.3 Encapsulated */
 		/* Test for an overlength frame */
-		if (payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+		if (payload_length > (netdev->mtu + ETH_HLEN)) {
 			/* A bogus length ethfrm has been encap'd. */
 			/* Is someone trying an oflow attack? */
 			netdev_err(netdev, "ENCAP frame too large (%d > %d)\n",
-			       payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
+			       payload_length, netdev->mtu + ETH_HLEN);
 			return 1;
 		}
 
@@ -406,9 +406,9 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 		skb_pull(skb, payload_offset);
 
 		/* create 802.3 header at beginning of skb. */
-		e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
-		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
-		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+		e_hdr = (struct wlan_ethhdr *)skb_push(skb, ETH_HLEN);
+		ether_addr_copy(e_hdr->daddr, daddr);
+		ether_addr_copy(e_hdr->saddr, saddr);
 		e_hdr->type = htons(payload_length);
 
 		/* chop off the 802.11 CRC */
@@ -446,10 +446,10 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 		skb_pull(skb, sizeof(struct wlan_snap));
 
 		/* create 802.3 header at beginning of skb. */
-		e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
+		e_hdr = (struct wlan_ethhdr *)skb_push(skb, ETH_HLEN);
 		e_hdr->type = e_snap->type;
-		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
-		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+		ether_addr_copy(e_hdr->daddr, daddr);
+		ether_addr_copy(e_hdr->saddr, saddr);
 
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
@@ -473,9 +473,9 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 		skb_pull(skb, payload_offset);
 
 		/* create 802.3 header at beginning of skb. */
-		e_hdr = (struct wlan_ethhdr *) skb_push(skb, WLAN_ETHHDR_LEN);
-		memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
-		memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+		e_hdr = (struct wlan_ethhdr *)skb_push(skb, ETH_HLEN);
+		ether_addr_copy(e_hdr->daddr, daddr);
+		ether_addr_copy(e_hdr->saddr, saddr);
 		e_hdr->type = htons(payload_length);
 
 		/* chop off the 802.11 CRC */
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index e031a74d2ad4..8c10357bedf0 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -53,14 +53,11 @@
 #ifndef _LINUX_P80211CONV_H
 #define _LINUX_P80211CONV_H
 
-#define WLAN_ETHADDR_LEN	6
 #define WLAN_IEEE_OUI_LEN	3
 
 #define WLAN_ETHCONV_ENCAP	1
 #define WLAN_ETHCONV_8021h	3
 
-#define WLAN_ETHHDR_LEN		14
-
 #define P80211CAPTURE_VERSION	0x80211001
 
 #define	P80211_FRMMETA_MAGIC	0x802110
@@ -131,8 +128,8 @@ struct p80211_metawep {
 
 /* local ether header type */
 struct wlan_ethhdr {
-	u8 daddr[WLAN_ETHADDR_LEN];
-	u8 saddr[WLAN_ETHADDR_LEN];
+	u8 daddr[ETH_ALEN];
+	u8 saddr[ETH_ALEN];
 	u16 type;
 } __packed;
 
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 47249a30eae3..20f766afa4c7 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -91,8 +91,7 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
 	err = device_register(&dev->dev);
 	if (err) {
 		pr_err("Failed to register master device. err=%d\n", err);
-		memset(dev, 0, sizeof(struct w1_master));
-		kfree(dev);
+		put_device(&dev->dev);
 		dev = NULL;
 	}
 
diff --git a/fs/Kconfig b/fs/Kconfig
index da3f32f1a4e4..7d1bef1999af 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -190,6 +190,7 @@ menuconfig MISC_FILESYSTEMS
 
 if MISC_FILESYSTEMS
 
+source "fs/orangefs/Kconfig"
 source "fs/adfs/Kconfig"
 source "fs/affs/Kconfig"
 source "fs/ecryptfs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index f79cf4043e60..b4406d6f7da1 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_AUTOFS4_FS)	+= autofs4/
 obj-$(CONFIG_ADFS_FS)		+= adfs/
 obj-$(CONFIG_FUSE_FS)		+= fuse/
 obj-$(CONFIG_OVERLAY_FS)	+= overlayfs/
+obj-$(CONFIG_ORANGEFS_FS)       += orangefs/
 obj-$(CONFIG_UDF_FS)		+= udf/
 obj-$(CONFIG_SUN_OPENPROMFS)	+= openpromfs/
 obj-$(CONFIG_OMFS_FS)		+= omfs/
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 6a1119e87fbb..e739950ca084 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -325,8 +325,11 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
 static void
 cifs_show_security(struct seq_file *s, struct cifs_ses *ses)
 {
-	if (ses->sectype == Unspecified)
+	if (ses->sectype == Unspecified) {
+		if (ses->user_name == NULL)
+			seq_puts(s, ",sec=none");
 		return;
+	}
 
 	seq_puts(s, ",sec=");
 
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index c63f5227b681..28a77bf1d559 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -67,6 +67,12 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
 		goto out_drop_write;
 	}
 
+	if (src_file.file->f_op->unlocked_ioctl != cifs_ioctl) {
+		rc = -EBADF;
+		cifs_dbg(VFS, "src file seems to be from a different filesystem type\n");
+		goto out_fput;
+	}
+
 	if ((!src_file.file->private_data) || (!dst_file->private_data)) {
 		rc = -EBADF;
 		cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
diff --git a/fs/coredump.c b/fs/coredump.c
index a8f75640ac86..53d7d46c55c8 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -32,6 +32,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
 #include <linux/compat.h>
+#include <linux/timekeeping.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -232,9 +233,10 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
 				break;
 			/* UNIX time of coredump */
 			case 't': {
-				struct timeval tv;
-				do_gettimeofday(&tv);
-				err = cn_printf(cn, "%lu", tv.tv_sec);
+				time64_t time;
+
+				time = ktime_get_real_seconds();
+				err = cn_printf(cn, "%lld", time);
 				break;
 			}
 			/* hostname */
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
index 6d941f56faf4..9b28649df3a1 100644
--- a/fs/fscache/netfs.c
+++ b/fs/fscache/netfs.c
@@ -22,6 +22,7 @@ static LIST_HEAD(fscache_netfs_list);
 int __fscache_register_netfs(struct fscache_netfs *netfs)
 {
 	struct fscache_netfs *ptr;
+	struct fscache_cookie *cookie;
 	int ret;
 
 	_enter("{%s}", netfs->name);
@@ -29,29 +30,25 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
 	INIT_LIST_HEAD(&netfs->link);
 
 	/* allocate a cookie for the primary index */
-	netfs->primary_index =
-		kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
+	cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
 
-	if (!netfs->primary_index) {
+	if (!cookie) {
 		_leave(" = -ENOMEM");
 		return -ENOMEM;
 	}
 
 	/* initialise the primary index cookie */
-	atomic_set(&netfs->primary_index->usage, 1);
-	atomic_set(&netfs->primary_index->n_children, 0);
-	atomic_set(&netfs->primary_index->n_active, 1);
+	atomic_set(&cookie->usage, 1);
+	atomic_set(&cookie->n_children, 0);
+	atomic_set(&cookie->n_active, 1);
 
-	netfs->primary_index->def		= &fscache_fsdef_netfs_def;
-	netfs->primary_index->parent		= &fscache_fsdef_index;
-	netfs->primary_index->netfs_data	= netfs;
-	netfs->primary_index->flags		= 1 << FSCACHE_COOKIE_ENABLED;
+	cookie->def		= &fscache_fsdef_netfs_def;
+	cookie->parent		= &fscache_fsdef_index;
+	cookie->netfs_data	= netfs;
+	cookie->flags		= 1 << FSCACHE_COOKIE_ENABLED;
 
-	atomic_inc(&netfs->primary_index->parent->usage);
-	atomic_inc(&netfs->primary_index->parent->n_children);
-
-	spin_lock_init(&netfs->primary_index->lock);
-	INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+	spin_lock_init(&cookie->lock);
+	INIT_HLIST_HEAD(&cookie->backing_objects);
 
 	/* check the netfs type is not already present */
 	down_write(&fscache_addremove_sem);
@@ -62,6 +59,10 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
 			goto already_registered;
 	}
 
+	atomic_inc(&cookie->parent->usage);
+	atomic_inc(&cookie->parent->n_children);
+
+	netfs->primary_index = cookie;
 	list_add(&netfs->link, &fscache_netfs_list);
 	ret = 0;
 
@@ -70,11 +71,8 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
 already_registered:
 	up_write(&fscache_addremove_sem);
 
-	if (ret < 0) {
-		netfs->primary_index->parent = NULL;
-		__fscache_cookie_put(netfs->primary_index);
-		netfs->primary_index = NULL;
-	}
+	if (ret < 0)
+		kmem_cache_free(fscache_cookie_jar, cookie);
 
 	_leave(" = %d", ret);
 	return ret;
diff --git a/fs/namei.c b/fs/namei.c
index 726d211db484..d68c21fe4598 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2278,6 +2278,8 @@ EXPORT_SYMBOL(vfs_path_lookup);
  *
  * Note that this routine is purely a helper for filesystem usage and should
  * not be called by generic code.
+ *
+ * The caller must hold base->i_mutex.
  */
 struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 {
@@ -2321,6 +2323,78 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 }
 EXPORT_SYMBOL(lookup_one_len);
 
+/**
+ * lookup_one_len_unlocked - filesystem helper to lookup single pathname component
+ * @name:	pathname component to lookup
+ * @base:	base directory to lookup from
+ * @len:	maximum length @len should be interpreted to
+ *
+ * Note that this routine is purely a helper for filesystem usage and should
+ * not be called by generic code.
+ *
+ * Unlike lookup_one_len, it should be called without the parent
+ * i_mutex held, and will take the i_mutex itself if necessary.
+ */
+struct dentry *lookup_one_len_unlocked(const char *name,
+				       struct dentry *base, int len)
+{
+	struct qstr this;
+	unsigned int c;
+	int err;
+	struct dentry *ret;
+
+	this.name = name;
+	this.len = len;
+	this.hash = full_name_hash(name, len);
+	if (!len)
+		return ERR_PTR(-EACCES);
+
+	if (unlikely(name[0] == '.')) {
+		if (len < 2 || (len == 2 && name[1] == '.'))
+			return ERR_PTR(-EACCES);
+	}
+
+	while (len--) {
+		c = *(const unsigned char *)name++;
+		if (c == '/' || c == '\0')
+			return ERR_PTR(-EACCES);
+	}
+	/*
+	 * See if the low-level filesystem might want
+	 * to use its own hash..
+	 */
+	if (base->d_flags & DCACHE_OP_HASH) {
+		int err = base->d_op->d_hash(base, &this);
+		if (err < 0)
+			return ERR_PTR(err);
+	}
+
+	err = inode_permission(base->d_inode, MAY_EXEC);
+	if (err)
+		return ERR_PTR(err);
+
+	ret = __d_lookup(base, &this);
+	if (ret)
+		return ret;
+	/*
+	 * __d_lookup() is used to try to get a quick answer and avoid the
+	 * mutex.  A false-negative does no harm.
+	 */
+	ret = __d_lookup(base, &this);
+	if (ret && ret->d_flags & DCACHE_OP_REVALIDATE) {
+		dput(ret);
+		ret = NULL;
+	}
+	if (ret)
+		return ret;
+
+	mutex_lock(&base->d_inode->i_mutex);
+	ret =  __lookup_hash(&this, base, 0);
+	mutex_unlock(&base->d_inode->i_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(lookup_one_len_unlocked);
+
 int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
 		 struct path *path, int *empty)
 {
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index f6e7cbabac5a..01dcd494f781 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -823,7 +823,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
 		} else
 			dchild = dget(dparent);
 	} else
-		dchild = lookup_one_len(name, dparent, namlen);
+		dchild = lookup_one_len_unlocked(name, dparent, namlen);
 	if (IS_ERR(dchild))
 		return rv;
 	if (d_mountpoint(dchild))
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 51c9e9ca39a4..325521ce389a 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2838,14 +2838,14 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
 	__be32 nfserr;
 	int ignore_crossmnt = 0;
 
-	dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
+	dentry = lookup_one_len_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
 	if (IS_ERR(dentry))
 		return nfserrno(PTR_ERR(dentry));
 	if (d_really_is_negative(dentry)) {
 		/*
-		 * nfsd_buffered_readdir drops the i_mutex between
-		 * readdir and calling this callback, leaving a window
-		 * where this directory entry could have gone away.
+		 * we're not holding the i_mutex here, so there's
+		 * a window where this directory entry could have gone
+		 * away.
 		 */
 		dput(dentry);
 		return nfserr_noent;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 45c04979e7b3..2ea6c6a37364 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -217,10 +217,16 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		host_err = PTR_ERR(dentry);
 		if (IS_ERR(dentry))
 			goto out_nfserr;
-		/*
-		 * check if we have crossed a mount point ...
-		 */
 		if (nfsd_mountpoint(dentry, exp)) {
+			/*
+			 * We don't need the i_mutex after all.  It's
+			 * still possible we could open this (regular
+			 * files can be mountpoints too), but the
+			 * i_mutex is just there to prevent renames of
+			 * something that we might be about to delegate,
+			 * and a mountpoint won't be renamed:
+			 */
+			fh_unlock(fhp);
 			if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
 				dput(dentry);
 				goto out_nfserr;
@@ -1809,7 +1815,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
 	offset = *offsetp;
 
 	while (1) {
-		struct inode *dir_inode = file_inode(file);
 		unsigned int reclen;
 
 		cdp->err = nfserr_eof; /* will be cleared on successful read */
@@ -1828,15 +1833,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
 		if (!size)
 			break;
 
-		/*
-		 * Various filldir functions may end up calling back into
-		 * lookup_one_len() and the file system's ->lookup() method.
-		 * These expect i_mutex to be held, as it would within readdir.
-		 */
-		host_err = mutex_lock_killable(&dir_inode->i_mutex);
-		if (host_err)
-			break;
-
 		de = (struct buffered_dirent *)buf.dirent;
 		while (size > 0) {
 			offset = de->offset;
@@ -1853,7 +1849,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
 			size -= reclen;
 			de = (struct buffered_dirent *)((char *)de + reclen);
 		}
-		mutex_unlock(&dir_inode->i_mutex);
 		if (size > 0) /* We bailed out early */
 			break;
 
diff --git a/fs/orangefs/Kconfig b/fs/orangefs/Kconfig
new file mode 100644
index 000000000000..1554c02489de
--- /dev/null
+++ b/fs/orangefs/Kconfig
@@ -0,0 +1,6 @@
+config ORANGEFS_FS
+	tristate "ORANGEFS (Powered by PVFS) support"
+	select FS_POSIX_ACL
+	help
+	   Orange is a parallel file system designed for use on high end
+	   computing (HEC) systems.
diff --git a/fs/orangefs/Makefile b/fs/orangefs/Makefile
new file mode 100644
index 000000000000..828b36a6916d
--- /dev/null
+++ b/fs/orangefs/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the ORANGEFS filesystem.
+#
+
+obj-$(CONFIG_ORANGEFS_FS) += orangefs.o
+
+orangefs-objs := acl.o file.o pvfs2-cache.o pvfs2-utils.o xattr.o dcache.o \
+		 inode.o pvfs2-sysfs.o pvfs2-mod.o super.o devpvfs2-req.o \
+		 namei.o symlink.o dir.o pvfs2-bufmap.o \
+		 pvfs2-debugfs.o waitqueue.o
diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c
new file mode 100644
index 000000000000..e462b81a3ba1
--- /dev/null
+++ b/fs/orangefs/acl.c
@@ -0,0 +1,175 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+#include <linux/posix_acl_xattr.h>
+#include <linux/fs_struct.h>
+
+struct posix_acl *pvfs2_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl;
+	int ret;
+	char *key = NULL, *value = NULL;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		key = PVFS2_XATTR_NAME_ACL_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		key = PVFS2_XATTR_NAME_ACL_DEFAULT;
+		break;
+	default:
+		gossip_err("pvfs2_get_acl: bogus value of type %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+	/*
+	 * Rather than incurring a network call just to determine the exact
+	 * length of the attribute, I just allocate a max length to save on
+	 * the network call. Conceivably, we could pass NULL to
+	 * pvfs2_inode_getxattr() to probe the length of the value, but
+	 * I don't do that for now.
+	 */
+	value = kmalloc(PVFS_MAX_XATTR_VALUELEN, GFP_KERNEL);
+	if (value == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	gossip_debug(GOSSIP_ACL_DEBUG,
+		     "inode %pU, key %s, type %d\n",
+		     get_khandle_from_ino(inode),
+		     key,
+		     type);
+	ret = pvfs2_inode_getxattr(inode,
+				   "",
+				   key,
+				   value,
+				   PVFS_MAX_XATTR_VALUELEN);
+	/* if the key exists, convert it to an in-memory rep */
+	if (ret > 0) {
+		acl = posix_acl_from_xattr(&init_user_ns, value, ret);
+	} else if (ret == -ENODATA || ret == -ENOSYS) {
+		acl = NULL;
+	} else {
+		gossip_err("inode %pU retrieving acl's failed with error %d\n",
+			   get_khandle_from_ino(inode),
+			   ret);
+		acl = ERR_PTR(ret);
+	}
+	/* kfree(NULL) is safe, so don't worry if value ever got used */
+	kfree(value);
+	return acl;
+}
+
+int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	int error = 0;
+	void *value = NULL;
+	size_t size = 0;
+	const char *name = NULL;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = PVFS2_XATTR_NAME_ACL_ACCESS;
+		if (acl) {
+			umode_t mode = inode->i_mode;
+			/*
+			 * can we represent this with the traditional file
+			 * mode permission bits?
+			 */
+			error = posix_acl_equiv_mode(acl, &mode);
+			if (error < 0) {
+				gossip_err("%s: posix_acl_equiv_mode err: %d\n",
+					   __func__,
+					   error);
+				return error;
+			}
+
+			if (inode->i_mode != mode)
+				SetModeFlag(pvfs2_inode);
+			inode->i_mode = mode;
+			mark_inode_dirty_sync(inode);
+			if (error == 0)
+				acl = NULL;
+		}
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = PVFS2_XATTR_NAME_ACL_DEFAULT;
+		break;
+	default:
+		gossip_err("%s: invalid type %d!\n", __func__, type);
+		return -EINVAL;
+	}
+
+	gossip_debug(GOSSIP_ACL_DEBUG,
+		     "%s: inode %pU, key %s type %d\n",
+		     __func__, get_khandle_from_ino(inode),
+		     name,
+		     type);
+
+	if (acl) {
+		size = posix_acl_xattr_size(acl->a_count);
+		value = kmalloc(size, GFP_KERNEL);
+		if (!value)
+			return -ENOMEM;
+
+		error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
+		if (error < 0)
+			goto out;
+	}
+
+	gossip_debug(GOSSIP_ACL_DEBUG,
+		     "%s: name %s, value %p, size %zd, acl %p\n",
+		     __func__, name, value, size, acl);
+	/*
+	 * Go ahead and set the extended attribute now. NOTE: Suppose acl
+	 * was NULL, then value will be NULL and size will be 0 and that
+	 * will xlate to a removexattr. However, we don't want removexattr
+	 * complain if attributes does not exist.
+	 */
+	error = pvfs2_inode_setxattr(inode, "", name, value, size, 0);
+
+out:
+	kfree(value);
+	if (!error)
+		set_cached_acl(inode, type, acl);
+	return error;
+}
+
+int pvfs2_init_acl(struct inode *inode, struct inode *dir)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct posix_acl *default_acl, *acl;
+	umode_t mode = inode->i_mode;
+	int error = 0;
+
+	ClearModeFlag(pvfs2_inode);
+
+	error = posix_acl_create(dir, &mode, &default_acl, &acl);
+	if (error)
+		return error;
+
+	if (default_acl) {
+		error = pvfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+		posix_acl_release(default_acl);
+	}
+
+	if (acl) {
+		if (!error)
+			error = pvfs2_set_acl(inode, acl, ACL_TYPE_ACCESS);
+		posix_acl_release(acl);
+	}
+
+	/* If mode of the inode was changed, then do a forcible ->setattr */
+	if (mode != inode->i_mode) {
+		SetModeFlag(pvfs2_inode);
+		inode->i_mode = mode;
+		pvfs2_flush_inode(inode);
+	}
+
+	return error;
+}
diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c
new file mode 100644
index 000000000000..9466b179bf24
--- /dev/null
+++ b/fs/orangefs/dcache.c
@@ -0,0 +1,142 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Implementation of dentry (directory cache) functions.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+
+/* Returns 1 if dentry can still be trusted, else 0. */
+static int pvfs2_revalidate_lookup(struct dentry *dentry)
+{
+	struct dentry *parent_dentry = dget_parent(dentry);
+	struct inode *parent_inode = parent_dentry->d_inode;
+	struct pvfs2_inode_s *parent = PVFS2_I(parent_inode);
+	struct inode *inode = dentry->d_inode;
+	struct pvfs2_kernel_op_s *new_op;
+	int ret = 0;
+	int err = 0;
+
+	gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__);
+
+	new_op = op_alloc(PVFS2_VFS_OP_LOOKUP);
+	if (!new_op)
+		goto out_put_parent;
+
+	new_op->upcall.req.lookup.sym_follow = PVFS2_LOOKUP_LINK_NO_FOLLOW;
+	new_op->upcall.req.lookup.parent_refn = parent->refn;
+	strncpy(new_op->upcall.req.lookup.d_name,
+		dentry->d_name.name,
+		PVFS2_NAME_LEN);
+
+	gossip_debug(GOSSIP_DCACHE_DEBUG,
+		     "%s:%s:%d interrupt flag [%d]\n",
+		     __FILE__,
+		     __func__,
+		     __LINE__,
+		     get_interruptible_flag(parent_inode));
+
+	err = service_operation(new_op, "pvfs2_lookup",
+			get_interruptible_flag(parent_inode));
+	if (err)
+		goto out_drop;
+
+	if (new_op->downcall.status != 0 ||
+	    !match_handle(new_op->downcall.resp.lookup.refn.khandle, inode)) {
+		gossip_debug(GOSSIP_DCACHE_DEBUG,
+			"%s:%s:%d "
+			"lookup failure |%s| or no match |%s|.\n",
+			__FILE__,
+			__func__,
+			__LINE__,
+			new_op->downcall.status ? "true" : "false",
+			match_handle(new_op->downcall.resp.lookup.refn.khandle,
+					inode) ? "false" : "true");
+		gossip_debug(GOSSIP_DCACHE_DEBUG,
+			     "%s:%s:%d revalidate failed\n",
+			     __FILE__, __func__, __LINE__);
+		goto out_drop;
+	}
+
+	ret = 1;
+out_release_op:
+	op_release(new_op);
+out_put_parent:
+	dput(parent_dentry);
+	return ret;
+out_drop:
+	d_drop(dentry);
+	goto out_release_op;
+}
+
+/*
+ * Verify that dentry is valid.
+ *
+ * Should return 1 if dentry can still be trusted, else 0
+ */
+static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags)
+{
+	struct inode *inode;
+	int ret = 0;
+
+	if (flags & LOOKUP_RCU)
+		return -ECHILD;
+
+	gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p.\n",
+		     __func__, dentry);
+
+	/* find inode from dentry */
+	if (!dentry->d_inode) {
+		gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n",
+			     __func__);
+		goto invalid_exit;
+	}
+
+	gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: inode valid.\n", __func__);
+	inode = dentry->d_inode;
+
+	/*
+	 * first perform a lookup to make sure that the object not only
+	 * exists, but is still in the expected place in the name space
+	 */
+	if (!is_root_handle(inode)) {
+		if (!pvfs2_revalidate_lookup(dentry))
+			goto invalid_exit;
+	} else {
+		gossip_debug(GOSSIP_DCACHE_DEBUG,
+			     "%s: root handle, lookup skipped.\n",
+			     __func__);
+	}
+
+	/* now perform getattr */
+	gossip_debug(GOSSIP_DCACHE_DEBUG,
+		     "%s: doing getattr: inode: %p, handle: %pU\n",
+		     __func__,
+		     inode,
+		     get_khandle_from_ino(inode));
+	ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
+	gossip_debug(GOSSIP_DCACHE_DEBUG,
+		     "%s: getattr %s (ret = %d), returning %s for dentry i_count=%d\n",
+		     __func__,
+		     (ret == 0 ? "succeeded" : "failed"),
+		     ret,
+		     (ret == 0 ? "valid" : "INVALID"),
+		     atomic_read(&inode->i_count));
+	if (ret != 0)
+		goto invalid_exit;
+
+	/* dentry is valid! */
+	return 1;
+
+invalid_exit:
+	return 0;
+}
+
+const struct dentry_operations pvfs2_dentry_operations = {
+	.d_revalidate = pvfs2_d_revalidate,
+};
diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c
new file mode 100644
index 000000000000..13878cac49ed
--- /dev/null
+++ b/fs/orangefs/devpvfs2-req.c
@@ -0,0 +1,1004 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * Changes by Acxiom Corporation to add protocol version to kernel
+ * communication, Copyright Acxiom Corporation, 2005.
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-dev-proto.h"
+#include "pvfs2-bufmap.h"
+
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+
+/* this file implements the /dev/pvfs2-req device node */
+
+static int open_access_count;
+
+#define DUMP_DEVICE_ERROR()                                                   \
+do {                                                                          \
+	gossip_err("*****************************************************\n");\
+	gossip_err("PVFS2 Device Error:  You cannot open the device file ");  \
+	gossip_err("\n/dev/%s more than once.  Please make sure that\nthere " \
+		   "are no ", PVFS2_REQDEVICE_NAME);                          \
+	gossip_err("instances of a program using this device\ncurrently "     \
+		   "running. (You must verify this!)\n");                     \
+	gossip_err("For example, you can use the lsof program as follows:\n");\
+	gossip_err("'lsof | grep %s' (run this as root)\n",                   \
+		   PVFS2_REQDEVICE_NAME);                                     \
+	gossip_err("  open_access_count = %d\n", open_access_count);          \
+	gossip_err("*****************************************************\n");\
+} while (0)
+
+static int hash_func(__u64 tag, int table_size)
+{
+	return do_div(tag, (unsigned int)table_size);
+}
+
+static void pvfs2_devreq_add_op(struct pvfs2_kernel_op_s *op)
+{
+	int index = hash_func(op->tag, hash_table_size);
+
+	spin_lock(&htable_ops_in_progress_lock);
+	list_add_tail(&op->list, &htable_ops_in_progress[index]);
+	spin_unlock(&htable_ops_in_progress_lock);
+}
+
+static struct pvfs2_kernel_op_s *pvfs2_devreq_remove_op(__u64 tag)
+{
+	struct pvfs2_kernel_op_s *op, *next;
+	int index;
+
+	index = hash_func(tag, hash_table_size);
+
+	spin_lock(&htable_ops_in_progress_lock);
+	list_for_each_entry_safe(op,
+				 next,
+				 &htable_ops_in_progress[index],
+				 list) {
+		if (op->tag == tag) {
+			list_del(&op->list);
+			spin_unlock(&htable_ops_in_progress_lock);
+			return op;
+		}
+	}
+
+	spin_unlock(&htable_ops_in_progress_lock);
+	return NULL;
+}
+
+static int pvfs2_devreq_open(struct inode *inode, struct file *file)
+{
+	int ret = -EINVAL;
+
+	if (!(file->f_flags & O_NONBLOCK)) {
+		gossip_err("pvfs2: device cannot be opened in blocking mode\n");
+		goto out;
+	}
+	ret = -EACCES;
+	gossip_debug(GOSSIP_DEV_DEBUG, "pvfs2-client-core: opening device\n");
+	mutex_lock(&devreq_mutex);
+
+	if (open_access_count == 0) {
+		ret = generic_file_open(inode, file);
+		if (ret == 0)
+			open_access_count++;
+	} else {
+		DUMP_DEVICE_ERROR();
+	}
+	mutex_unlock(&devreq_mutex);
+
+out:
+
+	gossip_debug(GOSSIP_DEV_DEBUG,
+		     "pvfs2-client-core: open device complete (ret = %d)\n",
+		     ret);
+	return ret;
+}
+
+static ssize_t pvfs2_devreq_read(struct file *file,
+				 char __user *buf,
+				 size_t count, loff_t *offset)
+{
+	int ret = 0;
+	ssize_t len = 0;
+	struct pvfs2_kernel_op_s *cur_op = NULL;
+	static __s32 magic = PVFS2_DEVREQ_MAGIC;
+	__s32 proto_ver = PVFS_KERNEL_PROTO_VERSION;
+
+	if (!(file->f_flags & O_NONBLOCK)) {
+		/* We do not support blocking reads/opens any more */
+		gossip_err("pvfs2: blocking reads are not supported! (pvfs2-client-core bug)\n");
+		return -EINVAL;
+	} else {
+		struct pvfs2_kernel_op_s *op = NULL, *temp = NULL;
+		/* get next op (if any) from top of list */
+		spin_lock(&pvfs2_request_list_lock);
+		list_for_each_entry_safe(op, temp, &pvfs2_request_list, list) {
+			__s32 fsid = fsid_of_op(op);
+			/*
+			 * Check if this op's fsid is known and needs
+			 * remounting
+			 */
+			if (fsid != PVFS_FS_ID_NULL &&
+			    fs_mount_pending(fsid) == 1) {
+				gossip_debug(GOSSIP_DEV_DEBUG,
+					     "Skipping op tag %llu %s\n",
+					     llu(op->tag),
+					     get_opname_string(op));
+				continue;
+			} else {
+				/*
+				 * op does not belong to any particular fsid
+				 * or already mounted.. let it through
+				 */
+				cur_op = op;
+				spin_lock(&cur_op->lock);
+				list_del(&cur_op->list);
+				cur_op->op_linger_tmp--;
+				/*
+				 * if there is a trailer, re-add it to
+				 * the request list.
+				 */
+				if (cur_op->op_linger == 2 &&
+				    cur_op->op_linger_tmp == 1) {
+					if (cur_op->upcall.trailer_size <= 0 ||
+					    cur_op->upcall.trailer_buf == NULL)
+						gossip_err("BUG:trailer_size is %ld and trailer buf is %p\n", (long)cur_op->upcall.trailer_size, cur_op->upcall.trailer_buf);
+					/* re-add it to the head of the list */
+					list_add(&cur_op->list,
+						 &pvfs2_request_list);
+				}
+				spin_unlock(&cur_op->lock);
+				break;
+			}
+		}
+		spin_unlock(&pvfs2_request_list_lock);
+	}
+
+	if (cur_op) {
+		spin_lock(&cur_op->lock);
+
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "client-core: reading op tag %llu %s\n",
+			     llu(cur_op->tag), get_opname_string(cur_op));
+		if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
+			if (cur_op->op_linger == 1)
+				gossip_err("WARNING: Current op already queued...skipping\n");
+		} else if (cur_op->op_linger == 1 ||
+			   (cur_op->op_linger == 2 &&
+			    cur_op->op_linger_tmp == 0)) {
+			/*
+			 * atomically move the operation to the
+			 * htable_ops_in_progress
+			 */
+			set_op_state_inprogress(cur_op);
+			pvfs2_devreq_add_op(cur_op);
+		}
+
+		spin_unlock(&cur_op->lock);
+
+		/* 2 cases
+		 * a) OPs with no trailers
+		 * b) OPs with trailers, Stage 1
+		 * Either way push the upcall out
+		 */
+		if (cur_op->op_linger == 1 ||
+		   (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 1)) {
+			len = MAX_ALIGNED_DEV_REQ_UPSIZE;
+			if ((size_t) len <= count) {
+			    ret = copy_to_user(buf,
+					       &proto_ver,
+					       sizeof(__s32));
+			    if (ret == 0) {
+				ret = copy_to_user(buf + sizeof(__s32),
+						   &magic,
+						   sizeof(__s32));
+				if (ret == 0) {
+				    ret = copy_to_user(buf+2 * sizeof(__s32),
+						       &cur_op->tag,
+						       sizeof(__u64));
+				    if (ret == 0) {
+					ret = copy_to_user(
+						buf +
+						  2 *
+						  sizeof(__s32) +
+						  sizeof(__u64),
+						&cur_op->upcall,
+						sizeof(struct pvfs2_upcall_s));
+				    }
+				}
+			    }
+
+			    if (ret) {
+				gossip_err("Failed to copy data to user space\n");
+				len = -EFAULT;
+			    }
+			} else {
+				gossip_err
+				    ("Failed to copy data to user space\n");
+				len = -EIO;
+			}
+		}
+		/* Stage 2: Push the trailer out */
+		else if (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 0) {
+			len = cur_op->upcall.trailer_size;
+			if ((size_t) len <= count) {
+				ret = copy_to_user(buf,
+						   cur_op->upcall.trailer_buf,
+						   len);
+				if (ret) {
+					gossip_err("Failed to copy trailer to user space\n");
+					len = -EFAULT;
+				}
+			} else {
+				gossip_err("Read buffer for trailer is too small (%ld as opposed to %ld)\n",
+					(long)count,
+					(long)len);
+				len = -EIO;
+			}
+		} else {
+			gossip_err("cur_op: %p (op_linger %d), (op_linger_tmp %d), erroneous request list?\n",
+				cur_op,
+				cur_op->op_linger,
+				cur_op->op_linger_tmp);
+			len = 0;
+		}
+	} else if (file->f_flags & O_NONBLOCK) {
+		/*
+		 * if in non-blocking mode, return EAGAIN since no requests are
+		 * ready yet
+		 */
+		len = -EAGAIN;
+	}
+	return len;
+}
+
+/* Function for writev() callers into the device */
+static ssize_t pvfs2_devreq_writev(struct file *file,
+				   const struct iovec *iov,
+				   size_t count,
+				   loff_t *offset)
+{
+	struct pvfs2_kernel_op_s *op = NULL;
+	void *buffer = NULL;
+	void *ptr = NULL;
+	unsigned long i = 0;
+	static int max_downsize = MAX_ALIGNED_DEV_REQ_DOWNSIZE;
+	int ret = 0, num_remaining = max_downsize;
+	int notrailer_count = 4; /* num elements in iovec without trailer */
+	int payload_size = 0;
+	__s32 magic = 0;
+	__s32 proto_ver = 0;
+	__u64 tag = 0;
+	ssize_t total_returned_size = 0;
+
+	/* Either there is a trailer or there isn't */
+	if (count != notrailer_count && count != (notrailer_count + 1)) {
+		gossip_err("Error: Number of iov vectors is (%zu) and notrailer count is %d\n",
+			count,
+			notrailer_count);
+		return -EPROTO;
+	}
+	buffer = dev_req_alloc();
+	if (!buffer)
+		return -ENOMEM;
+	ptr = buffer;
+
+	for (i = 0; i < notrailer_count; i++) {
+		if (iov[i].iov_len > num_remaining) {
+			gossip_err
+			    ("writev error: Freeing buffer and returning\n");
+			dev_req_release(buffer);
+			return -EMSGSIZE;
+		}
+		ret = copy_from_user(ptr, iov[i].iov_base, iov[i].iov_len);
+		if (ret) {
+			gossip_err("Failed to copy data from user space\n");
+			dev_req_release(buffer);
+			return -EIO;
+		}
+		num_remaining -= iov[i].iov_len;
+		ptr += iov[i].iov_len;
+		payload_size += iov[i].iov_len;
+	}
+	total_returned_size = payload_size;
+
+	/* these elements are currently 8 byte aligned (8 bytes for (version +
+	 * magic) 8 bytes for tag).  If you add another element, either
+	 * make it 8 bytes big, or use get_unaligned when asigning.
+	 */
+	ptr = buffer;
+	proto_ver = *((__s32 *) ptr);
+	ptr += sizeof(__s32);
+
+	magic = *((__s32 *) ptr);
+	ptr += sizeof(__s32);
+
+	tag = *((__u64 *) ptr);
+	ptr += sizeof(__u64);
+
+	if (magic != PVFS2_DEVREQ_MAGIC) {
+		gossip_err("Error: Device magic number does not match.\n");
+		dev_req_release(buffer);
+		return -EPROTO;
+	}
+
+	/*
+	 * proto_ver = 20902 for 2.9.2
+	 */
+
+	op = pvfs2_devreq_remove_op(tag);
+	if (op) {
+		/* Increase ref count! */
+		get_op(op);
+		/* cut off magic and tag from payload size */
+		payload_size -= (2 * sizeof(__s32) + sizeof(__u64));
+		if (payload_size <= sizeof(struct pvfs2_downcall_s))
+			/* copy the passed in downcall into the op */
+			memcpy(&op->downcall,
+			       ptr,
+			       sizeof(struct pvfs2_downcall_s));
+		else
+			gossip_debug(GOSSIP_DEV_DEBUG,
+				     "writev: Ignoring %d bytes\n",
+				     payload_size);
+
+		/* Do not allocate needlessly if client-core forgets
+		 * to reset trailer size on op errors.
+		 */
+		if (op->downcall.status == 0 && op->downcall.trailer_size > 0) {
+			gossip_debug(GOSSIP_DEV_DEBUG,
+				     "writev: trailer size %ld\n",
+				     (unsigned long)op->downcall.trailer_size);
+			if (count != (notrailer_count + 1)) {
+				gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)op->downcall.trailer_size, count);
+				dev_req_release(buffer);
+				put_op(op);
+				return -EPROTO;
+			}
+			if (iov[notrailer_count].iov_len >
+			    op->downcall.trailer_size) {
+				gossip_err("writev error: trailer size (%ld) != iov_len (%ld)\n", (unsigned long)op->downcall.trailer_size, (unsigned long)iov[notrailer_count].iov_len);
+				dev_req_release(buffer);
+				put_op(op);
+				return -EMSGSIZE;
+			}
+			/* Allocate a buffer large enough to hold the
+			 * trailer bytes.
+			 */
+			op->downcall.trailer_buf =
+			    vmalloc(op->downcall.trailer_size);
+			if (op->downcall.trailer_buf != NULL) {
+				gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n",
+					     op->downcall.trailer_buf);
+				ret = copy_from_user(op->downcall.trailer_buf,
+						     iov[notrailer_count].
+						     iov_base,
+						     iov[notrailer_count].
+						     iov_len);
+				if (ret) {
+					gossip_err("Failed to copy trailer data from user space\n");
+					dev_req_release(buffer);
+					gossip_debug(GOSSIP_DEV_DEBUG,
+						     "vfree: %p\n",
+						     op->downcall.trailer_buf);
+					vfree(op->downcall.trailer_buf);
+					op->downcall.trailer_buf = NULL;
+					put_op(op);
+					return -EIO;
+				}
+			} else {
+				/* Change downcall status */
+				op->downcall.status = -ENOMEM;
+				gossip_err("writev: could not vmalloc for trailer!\n");
+			}
+		}
+
+		/* if this operation is an I/O operation and if it was
+		 * initiated on behalf of a *synchronous* VFS I/O operation,
+		 * only then we need to wait
+		 * for all data to be copied before we can return to avoid
+		 * buffer corruption and races that can pull the buffers
+		 * out from under us.
+		 *
+		 * Essentially we're synchronizing with other parts of the
+		 * vfs implicitly by not allowing the user space
+		 * application reading/writing this device to return until
+		 * the buffers are done being used.
+		 */
+		if ((op->upcall.type == PVFS2_VFS_OP_FILE_IO &&
+		     op->upcall.req.io.async_vfs_io == PVFS_VFS_SYNC_IO) ||
+		     op->upcall.type == PVFS2_VFS_OP_FILE_IOX) {
+			int timed_out = 0;
+			DECLARE_WAITQUEUE(wait_entry, current);
+
+			/* tell the vfs op waiting on a waitqueue
+			 * that this op is done
+			 */
+			spin_lock(&op->lock);
+			set_op_state_serviced(op);
+			spin_unlock(&op->lock);
+
+			add_wait_queue_exclusive(&op->io_completion_waitq,
+						 &wait_entry);
+			wake_up_interruptible(&op->waitq);
+
+			while (1) {
+				set_current_state(TASK_INTERRUPTIBLE);
+
+				spin_lock(&op->lock);
+				if (op->io_completed) {
+					spin_unlock(&op->lock);
+					break;
+				}
+				spin_unlock(&op->lock);
+
+				if (!signal_pending(current)) {
+					int timeout =
+					    MSECS_TO_JIFFIES(1000 *
+							     op_timeout_secs);
+					if (!schedule_timeout(timeout)) {
+						gossip_debug(GOSSIP_DEV_DEBUG, "*** I/O wait time is up\n");
+						timed_out = 1;
+						break;
+					}
+					continue;
+				}
+
+				gossip_debug(GOSSIP_DEV_DEBUG, "*** signal on I/O wait -- aborting\n");
+				break;
+			}
+
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&op->io_completion_waitq,
+					  &wait_entry);
+
+			/* NOTE: for I/O operations we handle releasing the op
+			 * object except in the case of timeout.  the reason we
+			 * can't free the op in timeout cases is that the op
+			 * service logic in the vfs retries operations using
+			 * the same op ptr, thus it can't be freed.
+			 */
+			if (!timed_out)
+				op_release(op);
+		} else {
+
+			/*
+			 * tell the vfs op waiting on a waitqueue that
+			 * this op is done
+			 */
+			spin_lock(&op->lock);
+			set_op_state_serviced(op);
+			spin_unlock(&op->lock);
+			/*
+			   for every other operation (i.e. non-I/O), we need to
+			   wake up the callers for downcall completion
+			   notification
+			 */
+			wake_up_interruptible(&op->waitq);
+		}
+	} else {
+		/* ignore downcalls that we're not interested in */
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "WARNING: No one's waiting for tag %llu\n",
+			     llu(tag));
+	}
+	dev_req_release(buffer);
+
+	return total_returned_size;
+}
+
+static ssize_t pvfs2_devreq_write_iter(struct kiocb *iocb,
+				      struct iov_iter *iter)
+{
+	return pvfs2_devreq_writev(iocb->ki_filp,
+				   iter->iov,
+				   iter->nr_segs,
+				   &iocb->ki_pos);
+}
+
+/* Returns whether any FS are still pending remounted */
+static int mark_all_pending_mounts(void)
+{
+	int unmounted = 1;
+	struct pvfs2_sb_info_s *pvfs2_sb = NULL;
+
+	spin_lock(&pvfs2_superblocks_lock);
+	list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) {
+		/* All of these file system require a remount */
+		pvfs2_sb->mount_pending = 1;
+		unmounted = 0;
+	}
+	spin_unlock(&pvfs2_superblocks_lock);
+	return unmounted;
+}
+
+/*
+ * Determine if a given file system needs to be remounted or not
+ *  Returns -1 on error
+ *           0 if already mounted
+ *           1 if needs remount
+ */
+int fs_mount_pending(__s32 fsid)
+{
+	int mount_pending = -1;
+	struct pvfs2_sb_info_s *pvfs2_sb = NULL;
+
+	spin_lock(&pvfs2_superblocks_lock);
+	list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) {
+		if (pvfs2_sb->fs_id == fsid) {
+			mount_pending = pvfs2_sb->mount_pending;
+			break;
+		}
+	}
+	spin_unlock(&pvfs2_superblocks_lock);
+	return mount_pending;
+}
+
+/*
+ * NOTE: gets called when the last reference to this device is dropped.
+ * Using the open_access_count variable, we enforce a reference count
+ * on this file so that it can be opened by only one process at a time.
+ * the devreq_mutex is used to make sure all i/o has completed
+ * before we call pvfs_bufmap_finalize, and similar such tricky
+ * situations
+ */
+static int pvfs2_devreq_release(struct inode *inode, struct file *file)
+{
+	int unmounted = 0;
+
+	gossip_debug(GOSSIP_DEV_DEBUG,
+		     "%s:pvfs2-client-core: exiting, closing device\n",
+		     __func__);
+
+	mutex_lock(&devreq_mutex);
+	pvfs_bufmap_finalize();
+
+	open_access_count--;
+
+	unmounted = mark_all_pending_mounts();
+	gossip_debug(GOSSIP_DEV_DEBUG, "PVFS2 Device Close: Filesystem(s) %s\n",
+		     (unmounted ? "UNMOUNTED" : "MOUNTED"));
+	mutex_unlock(&devreq_mutex);
+
+	/*
+	 * Walk through the list of ops in the request list, mark them
+	 * as purged and wake them up.
+	 */
+	purge_waiting_ops();
+	/*
+	 * Walk through the hash table of in progress operations; mark
+	 * them as purged and wake them up
+	 */
+	purge_inprogress_ops();
+	gossip_debug(GOSSIP_DEV_DEBUG,
+		     "pvfs2-client-core: device close complete\n");
+	return 0;
+}
+
+int is_daemon_in_service(void)
+{
+	int in_service;
+
+	/*
+	 * What this function does is checks if client-core is alive
+	 * based on the access count we maintain on the device.
+	 */
+	mutex_lock(&devreq_mutex);
+	in_service = open_access_count == 1 ? 0 : -EIO;
+	mutex_unlock(&devreq_mutex);
+	return in_service;
+}
+
+static inline long check_ioctl_command(unsigned int command)
+{
+	/* Check for valid ioctl codes */
+	if (_IOC_TYPE(command) != PVFS_DEV_MAGIC) {
+		gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
+			command,
+			_IOC_TYPE(command),
+			PVFS_DEV_MAGIC);
+		return -EINVAL;
+	}
+	/* and valid ioctl commands */
+	if (_IOC_NR(command) >= PVFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
+		gossip_err("Invalid ioctl command number [%d >= %d]\n",
+			   _IOC_NR(command), PVFS_DEV_MAXNR);
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
+{
+	static __s32 magic = PVFS2_DEVREQ_MAGIC;
+	static __s32 max_up_size = MAX_ALIGNED_DEV_REQ_UPSIZE;
+	static __s32 max_down_size = MAX_ALIGNED_DEV_REQ_DOWNSIZE;
+	struct PVFS_dev_map_desc user_desc;
+	int ret = 0;
+	struct dev_mask_info_s mask_info = { 0 };
+	struct dev_mask2_info_s mask2_info = { 0, 0 };
+	int upstream_kmod = 1;
+	struct list_head *tmp = NULL;
+	struct pvfs2_sb_info_s *pvfs2_sb = NULL;
+
+	/* mtmoore: add locking here */
+
+	switch (command) {
+	case PVFS_DEV_GET_MAGIC:
+		return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
+			-EIO :
+			0);
+	case PVFS_DEV_GET_MAX_UPSIZE:
+		return ((put_user(max_up_size,
+				  (__s32 __user *) arg) == -EFAULT) ?
+					-EIO :
+					0);
+	case PVFS_DEV_GET_MAX_DOWNSIZE:
+		return ((put_user(max_down_size,
+				  (__s32 __user *) arg) == -EFAULT) ?
+					-EIO :
+					0);
+	case PVFS_DEV_MAP:
+		ret = copy_from_user(&user_desc,
+				     (struct PVFS_dev_map_desc __user *)
+				     arg,
+				     sizeof(struct PVFS_dev_map_desc));
+		return ret ? -EIO : pvfs_bufmap_initialize(&user_desc);
+	case PVFS_DEV_REMOUNT_ALL:
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "pvfs2_devreq_ioctl: got PVFS_DEV_REMOUNT_ALL\n");
+
+		/*
+		 * remount all mounted pvfs2 volumes to regain the lost
+		 * dynamic mount tables (if any) -- NOTE: this is done
+		 * without keeping the superblock list locked due to the
+		 * upcall/downcall waiting.  also, the request semaphore is
+		 * used to ensure that no operations will be serviced until
+		 * all of the remounts are serviced (to avoid ops between
+		 * mounts to fail)
+		 */
+		ret = mutex_lock_interruptible(&request_mutex);
+		if (ret < 0)
+			return ret;
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "pvfs2_devreq_ioctl: priority remount in progress\n");
+		list_for_each(tmp, &pvfs2_superblocks) {
+			pvfs2_sb =
+				list_entry(tmp, struct pvfs2_sb_info_s, list);
+			if (pvfs2_sb && (pvfs2_sb->sb)) {
+				gossip_debug(GOSSIP_DEV_DEBUG,
+					     "Remounting SB %p\n",
+					     pvfs2_sb);
+
+				ret = pvfs2_remount(pvfs2_sb->sb);
+				if (ret) {
+					gossip_debug(GOSSIP_DEV_DEBUG,
+						     "SB %p remount failed\n",
+						     pvfs2_sb);
+						break;
+				}
+			}
+		}
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "pvfs2_devreq_ioctl: priority remount complete\n");
+		mutex_unlock(&request_mutex);
+		return ret;
+
+	case PVFS_DEV_UPSTREAM:
+		ret = copy_to_user((void __user *)arg,
+				    &upstream_kmod,
+				    sizeof(upstream_kmod));
+
+		if (ret != 0)
+			return -EIO;
+		else
+			return ret;
+
+	case PVFS_DEV_CLIENT_MASK:
+		ret = copy_from_user(&mask2_info,
+				     (void __user *)arg,
+				     sizeof(struct dev_mask2_info_s));
+
+		if (ret != 0)
+			return -EIO;
+
+		client_debug_mask.mask1 = mask2_info.mask1_value;
+		client_debug_mask.mask2 = mask2_info.mask2_value;
+
+		pr_info("%s: client debug mask has been been received "
+			":%llx: :%llx:\n",
+			__func__,
+			(unsigned long long)client_debug_mask.mask1,
+			(unsigned long long)client_debug_mask.mask2);
+
+		return ret;
+
+	case PVFS_DEV_CLIENT_STRING:
+		ret = copy_from_user(&client_debug_array_string,
+				     (void __user *)arg,
+				     PVFS2_MAX_DEBUG_STRING_LEN);
+		if (ret != 0) {
+			pr_info("%s: "
+				"PVFS_DEV_CLIENT_STRING: copy_from_user failed"
+				"\n",
+				__func__);
+			return -EIO;
+		}
+
+		pr_info("%s: client debug array string has been been received."
+			"\n",
+			__func__);
+
+		if (!help_string_initialized) {
+
+			/* Free the "we don't know yet" default string... */
+			kfree(debug_help_string);
+
+			/* build a proper debug help string */
+			if (orangefs_prepare_debugfs_help_string(0)) {
+				gossip_err("%s: "
+					   "prepare_debugfs_help_string failed"
+					   "\n",
+					   __func__);
+				return -EIO;
+			}
+
+			/* Replace the boilerplate boot-time debug-help file. */
+			debugfs_remove(help_file_dentry);
+
+			help_file_dentry =
+				debugfs_create_file(
+					ORANGEFS_KMOD_DEBUG_HELP_FILE,
+					0444,
+					debug_dir,
+					debug_help_string,
+					&debug_help_fops);
+
+			if (!help_file_dentry) {
+				gossip_err("%s: debugfs_create_file failed for"
+					   " :%s:!\n",
+					   __func__,
+					   ORANGEFS_KMOD_DEBUG_HELP_FILE);
+				return -EIO;
+			}
+		}
+
+		debug_mask_to_string(&client_debug_mask, 1);
+
+		debugfs_remove(client_debug_dentry);
+
+		pvfs2_client_debug_init();
+
+		help_string_initialized++;
+
+		return ret;
+
+	case PVFS_DEV_DEBUG:
+		ret = copy_from_user(&mask_info,
+				     (void __user *)arg,
+				     sizeof(mask_info));
+
+		if (ret != 0)
+			return -EIO;
+
+		if (mask_info.mask_type == KERNEL_MASK) {
+			if ((mask_info.mask_value == 0)
+			    && (kernel_mask_set_mod_init)) {
+				/*
+				 * the kernel debug mask was set when the
+				 * kernel module was loaded; don't override
+				 * it if the client-core was started without
+				 * a value for PVFS2_KMODMASK.
+				 */
+				return 0;
+			}
+			debug_mask_to_string(&mask_info.mask_value,
+					     mask_info.mask_type);
+			gossip_debug_mask = mask_info.mask_value;
+			pr_info("PVFS: kernel debug mask has been modified to "
+				":%s: :%llx:\n",
+				kernel_debug_string,
+				(unsigned long long)gossip_debug_mask);
+		} else if (mask_info.mask_type == CLIENT_MASK) {
+			debug_mask_to_string(&mask_info.mask_value,
+					     mask_info.mask_type);
+			pr_info("PVFS: client debug mask has been modified to"
+				":%s: :%llx:\n",
+				client_debug_string,
+				llu(mask_info.mask_value));
+		} else {
+			gossip_lerr("Invalid mask type....\n");
+			return -EINVAL;
+		}
+
+		return ret;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return -ENOIOCTLCMD;
+}
+
+static long pvfs2_devreq_ioctl(struct file *file,
+			       unsigned int command, unsigned long arg)
+{
+	long ret;
+
+	/* Check for properly constructed commands */
+	ret = check_ioctl_command(command);
+	if (ret < 0)
+		return (int)ret;
+
+	return (int)dispatch_ioctl_command(command, arg);
+}
+
+#ifdef CONFIG_COMPAT		/* CONFIG_COMPAT is in .config */
+
+/*  Compat structure for the PVFS_DEV_MAP ioctl */
+struct PVFS_dev_map_desc32 {
+	compat_uptr_t ptr;
+	__s32 total_size;
+	__s32 size;
+	__s32 count;
+};
+
+static unsigned long translate_dev_map26(unsigned long args, long *error)
+{
+	struct PVFS_dev_map_desc32 __user *p32 = (void __user *)args;
+	/*
+	 * Depending on the architecture, allocate some space on the
+	 * user-call-stack based on our expected layout.
+	 */
+	struct PVFS_dev_map_desc __user *p =
+	    compat_alloc_user_space(sizeof(*p));
+	compat_uptr_t addr;
+
+	*error = 0;
+	/* get the ptr from the 32 bit user-space */
+	if (get_user(addr, &p32->ptr))
+		goto err;
+	/* try to put that into a 64-bit layout */
+	if (put_user(compat_ptr(addr), &p->ptr))
+		goto err;
+	/* copy the remaining fields */
+	if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32)))
+		goto err;
+	if (copy_in_user(&p->size, &p32->size, sizeof(__s32)))
+		goto err;
+	if (copy_in_user(&p->count, &p32->count, sizeof(__s32)))
+		goto err;
+	return (unsigned long)p;
+err:
+	*error = -EFAULT;
+	return 0;
+}
+
+/*
+ * 32 bit user-space apps' ioctl handlers when kernel modules
+ * is compiled as a 64 bit one
+ */
+static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
+				      unsigned long args)
+{
+	long ret;
+	unsigned long arg = args;
+
+	/* Check for properly constructed commands */
+	ret = check_ioctl_command(cmd);
+	if (ret < 0)
+		return ret;
+	if (cmd == PVFS_DEV_MAP) {
+		/*
+		 * convert the arguments to what we expect internally
+		 * in kernel space
+		 */
+		arg = translate_dev_map26(args, &ret);
+		if (ret < 0) {
+			gossip_err("Could not translate dev map\n");
+			return ret;
+		}
+	}
+	/* no other ioctl requires translation */
+	return dispatch_ioctl_command(cmd, arg);
+}
+
+#endif /* CONFIG_COMPAT is in .config */
+
+/*
+ * The following two ioctl32 functions had been refactored into the above
+ * CONFIG_COMPAT ifdef, but that was an over simplification that was
+ * not noticed until we tried to compile on power pc...
+ */
+#if (defined(CONFIG_COMPAT) && !defined(HAVE_REGISTER_IOCTL32_CONVERSION)) || !defined(CONFIG_COMPAT)
+static int pvfs2_ioctl32_init(void)
+{
+	return 0;
+}
+
+static void pvfs2_ioctl32_cleanup(void)
+{
+	return;
+}
+#endif
+
+/* the assigned character device major number */
+static int pvfs2_dev_major;
+
+/*
+ * Initialize pvfs2 device specific state:
+ * Must be called at module load time only
+ */
+int pvfs2_dev_init(void)
+{
+	int ret;
+
+	/* register the ioctl32 sub-system */
+	ret = pvfs2_ioctl32_init();
+	if (ret < 0)
+		return ret;
+
+	/* register pvfs2-req device  */
+	pvfs2_dev_major = register_chrdev(0,
+					  PVFS2_REQDEVICE_NAME,
+					  &pvfs2_devreq_file_operations);
+	if (pvfs2_dev_major < 0) {
+		gossip_debug(GOSSIP_DEV_DEBUG,
+			     "Failed to register /dev/%s (error %d)\n",
+			     PVFS2_REQDEVICE_NAME, pvfs2_dev_major);
+		pvfs2_ioctl32_cleanup();
+		return pvfs2_dev_major;
+	}
+
+	gossip_debug(GOSSIP_DEV_DEBUG,
+		     "*** /dev/%s character device registered ***\n",
+		     PVFS2_REQDEVICE_NAME);
+	gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
+		     PVFS2_REQDEVICE_NAME, pvfs2_dev_major);
+	return 0;
+}
+
+void pvfs2_dev_cleanup(void)
+{
+	unregister_chrdev(pvfs2_dev_major, PVFS2_REQDEVICE_NAME);
+	gossip_debug(GOSSIP_DEV_DEBUG,
+		     "*** /dev/%s character device unregistered ***\n",
+		     PVFS2_REQDEVICE_NAME);
+	/* unregister the ioctl32 sub-system */
+	pvfs2_ioctl32_cleanup();
+}
+
+static unsigned int pvfs2_devreq_poll(struct file *file,
+				      struct poll_table_struct *poll_table)
+{
+	int poll_revent_mask = 0;
+
+	if (open_access_count == 1) {
+		poll_wait(file, &pvfs2_request_list_waitq, poll_table);
+
+		spin_lock(&pvfs2_request_list_lock);
+		if (!list_empty(&pvfs2_request_list))
+			poll_revent_mask |= POLL_IN;
+		spin_unlock(&pvfs2_request_list_lock);
+	}
+	return poll_revent_mask;
+}
+
+const struct file_operations pvfs2_devreq_file_operations = {
+	.owner = THIS_MODULE,
+	.read = pvfs2_devreq_read,
+	.write_iter = pvfs2_devreq_write_iter,
+	.open = pvfs2_devreq_open,
+	.release = pvfs2_devreq_release,
+	.unlocked_ioctl = pvfs2_devreq_ioctl,
+
+#ifdef CONFIG_COMPAT		/* CONFIG_COMPAT is in .config */
+	.compat_ioctl = pvfs2_devreq_compat_ioctl,
+#endif
+	.poll = pvfs2_devreq_poll
+};
diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c
new file mode 100644
index 000000000000..c126c0fc6e0f
--- /dev/null
+++ b/fs/orangefs/dir.c
@@ -0,0 +1,378 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+struct readdir_handle_s {
+	int buffer_index;
+	struct pvfs2_readdir_response_s readdir_response;
+	void *dents_buf;
+};
+
+/*
+ * decode routine needed by kmod to make sense of the shared page for readdirs.
+ */
+static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir)
+{
+	int i;
+	struct pvfs2_readdir_response_s *rd =
+		(struct pvfs2_readdir_response_s *) ptr;
+	char *buf = ptr;
+	char **pptr = &buf;
+
+	readdir->token = rd->token;
+	readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount;
+	readdir->dirent_array = kmalloc(readdir->pvfs_dirent_outcount *
+					sizeof(*readdir->dirent_array),
+					GFP_KERNEL);
+	if (readdir->dirent_array == NULL)
+		return -ENOMEM;
+	*pptr += offsetof(struct pvfs2_readdir_response_s, dirent_array);
+	for (i = 0; i < readdir->pvfs_dirent_outcount; i++) {
+		dec_string(pptr, &readdir->dirent_array[i].d_name,
+			   &readdir->dirent_array[i].d_length);
+		readdir->dirent_array[i].khandle =
+			*(struct pvfs2_khandle *) *pptr;
+		*pptr += 16;
+	}
+	return (unsigned long)*pptr - (unsigned long)ptr;
+}
+
+static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf,
+				int buffer_index)
+{
+	long ret;
+
+	if (buf == NULL) {
+		gossip_err
+		    ("Invalid NULL buffer specified in readdir_handle_ctor\n");
+		return -ENOMEM;
+	}
+	if (buffer_index < 0) {
+		gossip_err
+		    ("Invalid buffer index specified in readdir_handle_ctor\n");
+		return -EINVAL;
+	}
+	rhandle->buffer_index = buffer_index;
+	rhandle->dents_buf = buf;
+	ret = decode_dirents(buf, &rhandle->readdir_response);
+	if (ret < 0) {
+		gossip_err("Could not decode readdir from buffer %ld\n", ret);
+		rhandle->buffer_index = -1;
+		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n", buf);
+		vfree(buf);
+		rhandle->dents_buf = NULL;
+	}
+	return ret;
+}
+
+static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap,
+		struct readdir_handle_s *rhandle)
+{
+	if (rhandle == NULL)
+		return;
+
+	/* kfree(NULL) is safe */
+	kfree(rhandle->readdir_response.dirent_array);
+	rhandle->readdir_response.dirent_array = NULL;
+
+	if (rhandle->buffer_index >= 0) {
+		readdir_index_put(bufmap, rhandle->buffer_index);
+		rhandle->buffer_index = -1;
+	}
+	if (rhandle->dents_buf) {
+		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n",
+			     rhandle->dents_buf);
+		vfree(rhandle->dents_buf);
+		rhandle->dents_buf = NULL;
+	}
+}
+
+/*
+ * Read directory entries from an instance of an open directory.
+ *
+ * \note This routine was converted for the readdir to iterate change
+ *       in "struct file_operations". "converted" mostly amounts to
+ *       changing occurrences of "readdir" and "filldir" in the
+ *       comments to "iterate" and "dir_emit". Also filldir calls
+ *       were changed to dir_emit calls.
+ *
+ * \param dir_emit callback function called for each entry read.
+ *
+ * \retval 0  when directory has been completely traversed
+ * \retval >0 if we don't call dir_emit for all entries
+ *
+ * \note If the dir_emit call-back returns non-zero, then iterate should
+ *       assume that it has had enough, and should return as well.
+ */
+static int pvfs2_readdir(struct file *file, struct dir_context *ctx)
+{
+	struct pvfs2_bufmap *bufmap = NULL;
+	int ret = 0;
+	int buffer_index;
+	__u64 *ptoken = file->private_data;
+	__u64 pos = 0;
+	ino_t ino = 0;
+	struct dentry *dentry = file->f_path.dentry;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(dentry->d_inode);
+	int buffer_full = 0;
+	struct readdir_handle_s rhandle;
+	int i = 0;
+	int len = 0;
+	ino_t current_ino = 0;
+	char *current_entry = NULL;
+	long bytes_decoded;
+
+	gossip_ldebug(GOSSIP_DIR_DEBUG,
+		      "%s: ctx->pos:%lld, token = %llu\n",
+		      __func__,
+		      lld(ctx->pos),
+		      llu(*ptoken));
+
+	pos = (__u64) ctx->pos;
+
+	/* are we done? */
+	if (pos == PVFS_READDIR_END) {
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			     "Skipping to termination path\n");
+		return 0;
+	}
+
+	gossip_debug(GOSSIP_DIR_DEBUG,
+		     "pvfs2_readdir called on %s (pos=%llu)\n",
+		     dentry->d_name.name, llu(pos));
+
+	rhandle.buffer_index = -1;
+	rhandle.dents_buf = NULL;
+	memset(&rhandle.readdir_response, 0, sizeof(rhandle.readdir_response));
+
+	new_op = op_alloc(PVFS2_VFS_OP_READDIR);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->uses_shared_memory = 1;
+	new_op->upcall.req.readdir.refn = pvfs2_inode->refn;
+	new_op->upcall.req.readdir.max_dirent_count = MAX_DIRENT_COUNT_READDIR;
+
+	gossip_debug(GOSSIP_DIR_DEBUG,
+		     "%s: upcall.req.readdir.refn.khandle: %pU\n",
+		     __func__,
+		     &new_op->upcall.req.readdir.refn.khandle);
+
+	/*
+	 * NOTE: the position we send to the readdir upcall is out of
+	 * sync with ctx->pos since:
+	 * 1. pvfs2 doesn't include the "." and ".." entries that are
+	 *    added below.
+	 * 2. the introduction of distributed directory logic makes token no
+	 *    longer be related to f_pos and pos. Instead an independent
+	 *    variable is used inside the function and stored in the
+	 *    private_data of the file structure.
+	 */
+	new_op->upcall.req.readdir.token = *ptoken;
+
+get_new_buffer_index:
+	ret = readdir_index_get(&bufmap, &buffer_index);
+	if (ret < 0) {
+		gossip_lerr("pvfs2_readdir: readdir_index_get() failure (%d)\n",
+			    ret);
+		goto out_free_op;
+	}
+	new_op->upcall.req.readdir.buf_index = buffer_index;
+
+	ret = service_operation(new_op,
+				"pvfs2_readdir",
+				get_interruptible_flag(dentry->d_inode));
+
+	gossip_debug(GOSSIP_DIR_DEBUG,
+		     "Readdir downcall status is %d.  ret:%d\n",
+		     new_op->downcall.status,
+		     ret);
+
+	if (ret == -EAGAIN && op_state_purged(new_op)) {
+		/*
+		 * readdir shared memory aread has been wiped due to
+		 * pvfs2-client-core restarting, so we must get a new
+		 * index into the shared memory.
+		 */
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			"%s: Getting new buffer_index for retry of readdir..\n",
+			 __func__);
+		readdir_index_put(bufmap, buffer_index);
+		goto get_new_buffer_index;
+	}
+
+	if (ret == -EIO && op_state_purged(new_op)) {
+		gossip_err("%s: Client is down. Aborting readdir call.\n",
+			__func__);
+		readdir_index_put(bufmap, buffer_index);
+		goto out_free_op;
+	}
+
+	if (ret < 0 || new_op->downcall.status != 0) {
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			     "Readdir request failed.  Status:%d\n",
+			     new_op->downcall.status);
+		readdir_index_put(bufmap, buffer_index);
+		if (ret >= 0)
+			ret = new_op->downcall.status;
+		goto out_free_op;
+	}
+
+	bytes_decoded =
+		readdir_handle_ctor(&rhandle,
+				    new_op->downcall.trailer_buf,
+				    buffer_index);
+	if (bytes_decoded < 0) {
+		gossip_err("pvfs2_readdir: Could not decode trailer buffer into a readdir response %d\n",
+			ret);
+		ret = bytes_decoded;
+		readdir_index_put(bufmap, buffer_index);
+		goto out_free_op;
+	}
+
+	if (bytes_decoded != new_op->downcall.trailer_size) {
+		gossip_err("pvfs2_readdir: # bytes decoded (%ld) != trailer size (%ld)\n",
+			bytes_decoded,
+			(long)new_op->downcall.trailer_size);
+		ret = -EINVAL;
+		goto out_destroy_handle;
+	}
+
+	if (pos == 0) {
+		ino = get_ino_from_khandle(dentry->d_inode);
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			     "%s: calling dir_emit of \".\" with pos = %llu\n",
+			     __func__,
+			     llu(pos));
+		ret = dir_emit(ctx, ".", 1, ino, DT_DIR);
+		ctx->pos++;
+		gossip_ldebug(GOSSIP_DIR_DEBUG,
+			      "%s: ctx->pos:%lld\n",
+			      __func__,
+			      lld(ctx->pos));
+		pos++;
+	}
+
+	if (pos == 1) {
+		ino = get_parent_ino_from_dentry(dentry);
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			     "%s: calling dir_emit of \"..\" with pos = %llu\n",
+			     __func__,
+			     llu(pos));
+		ret = dir_emit(ctx, "..", 2, ino, DT_DIR);
+		ctx->pos++;
+		gossip_ldebug(GOSSIP_DIR_DEBUG,
+			      "%s: ctx->pos:%lld\n",
+			      __func__,
+			      lld(ctx->pos));
+		pos++;
+	}
+
+	for (i = 0; i < rhandle.readdir_response.pvfs_dirent_outcount; i++) {
+		len = rhandle.readdir_response.dirent_array[i].d_length;
+		current_entry = rhandle.readdir_response.dirent_array[i].d_name;
+		current_ino = pvfs2_khandle_to_ino(
+			&(rhandle.readdir_response.dirent_array[i].khandle));
+
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			     "calling dir_emit for %s with len %d, pos %ld\n",
+			     current_entry,
+			     len,
+			     (unsigned long)pos);
+		ret =
+		    dir_emit(ctx, current_entry, len, current_ino, DT_UNKNOWN);
+		ctx->pos++;
+		gossip_ldebug(GOSSIP_DIR_DEBUG,
+			      "%s: ctx->pos:%lld\n",
+			      __func__,
+			      lld(ctx->pos));
+
+		pos++;
+	}
+
+	/* this means that all of the dir_emit calls succeeded */
+	if (i == rhandle.readdir_response.pvfs_dirent_outcount) {
+		/* update token */
+		*ptoken = rhandle.readdir_response.token;
+	} else {
+		/* this means a dir_emit call failed */
+		if (rhandle.readdir_response.token == PVFS_READDIR_END) {
+			/*
+			 * If PVFS hit end of directory, then there
+			 * is no way to do math on the token that it
+			 * returned. Instead we go by ctx->pos but
+			 * back up to account for the artificial .
+			 * and .. entries.
+			 */
+			ctx->pos -= 3;
+		} else {
+			/*
+			 * this means a dir_emit call failed. !!! need to set
+			 * back to previous ctx->pos, no middle value allowed
+			 */
+			pos -= (i - 1);
+			ctx->pos -= (i - 1);
+		}
+		gossip_debug(GOSSIP_DIR_DEBUG,
+			"at least one dir_emit call failed. Setting ctx->pos to: %lld\n",
+			lld(ctx->pos));
+	}
+
+	/*
+	 * Did we hit the end of the directory?
+	 */
+	if (rhandle.readdir_response.token == PVFS_READDIR_END &&
+	    !buffer_full) {
+		gossip_debug(GOSSIP_DIR_DEBUG, "End of dir detected; setting ctx->pos to PVFS_READDIR_END.\n");
+		ctx->pos = PVFS_READDIR_END;
+	}
+
+	gossip_debug(GOSSIP_DIR_DEBUG,
+		     "pos = %llu, token = %llu"
+		     ", ctx->pos should have been %lld\n",
+		     llu(pos),
+		     llu(*ptoken),
+		     lld(ctx->pos));
+
+out_destroy_handle:
+	readdir_handle_dtor(bufmap, &rhandle);
+out_free_op:
+	op_release(new_op);
+	gossip_debug(GOSSIP_DIR_DEBUG, "pvfs2_readdir returning %d\n", ret);
+	return ret;
+}
+
+static int pvfs2_dir_open(struct inode *inode, struct file *file)
+{
+	__u64 *ptoken;
+
+	file->private_data = kmalloc(sizeof(__u64), GFP_KERNEL);
+	if (!file->private_data)
+		return -ENOMEM;
+
+	ptoken = file->private_data;
+	*ptoken = PVFS_READDIR_START;
+	return 0;
+}
+
+static int pvfs2_dir_release(struct inode *inode, struct file *file)
+{
+	pvfs2_flush_inode(inode);
+	kfree(file->private_data);
+	return 0;
+}
+
+/** PVFS2 implementation of VFS directory operations */
+const struct file_operations pvfs2_dir_operations = {
+	.read = generic_read_dir,
+	.iterate = pvfs2_readdir,
+	.open = pvfs2_dir_open,
+	.release = pvfs2_dir_release,
+};
diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h
new file mode 100644
index 000000000000..a79129f875f3
--- /dev/null
+++ b/fs/orangefs/downcall.h
@@ -0,0 +1,138 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Definitions of downcalls used in Linux kernel module.
+ */
+
+#ifndef __DOWNCALL_H
+#define __DOWNCALL_H
+
+/*
+ * Sanitized the device-client core interaction
+ * for clean 32-64 bit usage
+ */
+struct pvfs2_io_response {
+	__s64 amt_complete;
+};
+
+struct pvfs2_iox_response {
+	__s64 amt_complete;
+};
+
+struct pvfs2_lookup_response {
+	struct pvfs2_object_kref refn;
+};
+
+struct pvfs2_create_response {
+	struct pvfs2_object_kref refn;
+};
+
+struct pvfs2_symlink_response {
+	struct pvfs2_object_kref refn;
+};
+
+struct pvfs2_getattr_response {
+	struct PVFS_sys_attr_s attributes;
+	char link_target[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_mkdir_response {
+	struct pvfs2_object_kref refn;
+};
+
+/*
+ * duplication of some system interface structures so that I don't have
+ * to allocate extra memory
+ */
+struct pvfs2_dirent {
+	char *d_name;
+	int d_length;
+	struct pvfs2_khandle khandle;
+};
+
+struct pvfs2_statfs_response {
+	__s64 block_size;
+	__s64 blocks_total;
+	__s64 blocks_avail;
+	__s64 files_total;
+	__s64 files_avail;
+};
+
+struct pvfs2_fs_mount_response {
+	__s32 fs_id;
+	__s32 id;
+	struct pvfs2_khandle root_khandle;
+};
+
+/* the getxattr response is the attribute value */
+struct pvfs2_getxattr_response {
+	__s32 val_sz;
+	__s32 __pad1;
+	char val[PVFS_MAX_XATTR_VALUELEN];
+};
+
+/* the listxattr response is an array of attribute names */
+struct pvfs2_listxattr_response {
+	__s32 returned_count;
+	__s32 __pad1;
+	__u64 token;
+	char key[PVFS_MAX_XATTR_LISTLEN * PVFS_MAX_XATTR_NAMELEN];
+	__s32 keylen;
+	__s32 __pad2;
+	__s32 lengths[PVFS_MAX_XATTR_LISTLEN];
+};
+
+struct pvfs2_param_response {
+	__s64 value;
+};
+
+#define PERF_COUNT_BUF_SIZE 4096
+struct pvfs2_perf_count_response {
+	char buffer[PERF_COUNT_BUF_SIZE];
+};
+
+#define FS_KEY_BUF_SIZE 4096
+struct pvfs2_fs_key_response {
+	__s32 fs_keylen;
+	__s32 __pad1;
+	char fs_key[FS_KEY_BUF_SIZE];
+};
+
+struct pvfs2_downcall_s {
+	__s32 type;
+	__s32 status;
+	/* currently trailer is used only by readdir */
+	__s64 trailer_size;
+	char * trailer_buf;
+
+	union {
+		struct pvfs2_io_response io;
+		struct pvfs2_iox_response iox;
+		struct pvfs2_lookup_response lookup;
+		struct pvfs2_create_response create;
+		struct pvfs2_symlink_response sym;
+		struct pvfs2_getattr_response getattr;
+		struct pvfs2_mkdir_response mkdir;
+		struct pvfs2_statfs_response statfs;
+		struct pvfs2_fs_mount_response fs_mount;
+		struct pvfs2_getxattr_response getxattr;
+		struct pvfs2_listxattr_response listxattr;
+		struct pvfs2_param_response param;
+		struct pvfs2_perf_count_response perf_count;
+		struct pvfs2_fs_key_response fs_key;
+	} resp;
+};
+
+struct pvfs2_readdir_response_s {
+	__u64 token;
+	__u64 directory_version;
+	__u32 __pad2;
+	__u32 pvfs_dirent_outcount;
+	struct pvfs2_dirent *dirent_array;
+};
+
+#endif /* __DOWNCALL_H */
diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c
new file mode 100644
index 000000000000..013a07c8bdfd
--- /dev/null
+++ b/fs/orangefs/file.c
@@ -0,0 +1,1016 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Linux VFS file operations.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+
+#define wake_up_daemon_for_return(op)			\
+do {							\
+	spin_lock(&op->lock);                           \
+	op->io_completed = 1;                           \
+	spin_unlock(&op->lock);                         \
+	wake_up_interruptible(&op->io_completion_waitq);\
+} while (0)
+
+/*
+ * Copy to client-core's address space from the buffers specified
+ * by the iovec upto total_size bytes.
+ * NOTE: the iovector can either contain addresses which
+ *       can futher be kernel-space or user-space addresses.
+ *       or it can pointers to struct page's
+ */
+static int precopy_buffers(struct pvfs2_bufmap *bufmap,
+			   int buffer_index,
+			   const struct iovec *vec,
+			   unsigned long nr_segs,
+			   size_t total_size,
+			   int from_user)
+{
+	int ret = 0;
+
+	/*
+	 * copy data from application/kernel by pulling it out
+	 * of the iovec.
+	 */
+	/* Are we copying from User Virtual Addresses? */
+	if (from_user)
+		ret = pvfs_bufmap_copy_iovec_from_user(
+			bufmap,
+			buffer_index,
+			vec,
+			nr_segs,
+			total_size);
+	/* Are we copying from Kernel Virtual Addresses? */
+	else
+		ret = pvfs_bufmap_copy_iovec_from_kernel(
+			bufmap,
+			buffer_index,
+			vec,
+			nr_segs,
+			total_size);
+	if (ret < 0)
+		gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
+			__func__,
+			(long)ret);
+	return ret;
+}
+
+/*
+ * Copy from client-core's address space to the buffers specified
+ * by the iovec upto total_size bytes.
+ * NOTE: the iovector can either contain addresses which
+ *       can futher be kernel-space or user-space addresses.
+ *       or it can pointers to struct page's
+ */
+static int postcopy_buffers(struct pvfs2_bufmap *bufmap,
+			    int buffer_index,
+			    const struct iovec *vec,
+			    int nr_segs,
+			    size_t total_size,
+			    int to_user)
+{
+	int ret = 0;
+
+	/*
+	 * copy data to application/kernel by pushing it out to
+	 * the iovec. NOTE; target buffers can be addresses or
+	 * struct page pointers.
+	 */
+	if (total_size) {
+		/* Are we copying to User Virtual Addresses? */
+		if (to_user)
+			ret = pvfs_bufmap_copy_to_user_iovec(
+				bufmap,
+				buffer_index,
+				vec,
+				nr_segs,
+				total_size);
+		/* Are we copying to Kern Virtual Addresses? */
+		else
+			ret = pvfs_bufmap_copy_to_kernel_iovec(
+				bufmap,
+				buffer_index,
+				vec,
+				nr_segs,
+				total_size);
+		if (ret < 0)
+			gossip_err("%s: Failed to copy-out buffers.  Please make sure that the pvfs2-client is running (%ld)\n",
+				__func__,
+				(long)ret);
+	}
+	return ret;
+}
+
+/*
+ * Post and wait for the I/O upcall to finish
+ */
+static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode,
+		loff_t *offset, struct iovec *vec, unsigned long nr_segs,
+		size_t total_size, loff_t readahead_size, int to_user)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle;
+	struct pvfs2_bufmap *bufmap = NULL;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	int buffer_index = -1;
+	ssize_t ret;
+
+	new_op = op_alloc(PVFS2_VFS_OP_FILE_IO);
+	if (!new_op) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	/* synchronous I/O */
+	new_op->upcall.req.io.async_vfs_io = PVFS_VFS_SYNC_IO;
+	new_op->upcall.req.io.readahead_size = readahead_size;
+	new_op->upcall.req.io.io_type = type;
+	new_op->upcall.req.io.refn = pvfs2_inode->refn;
+
+populate_shared_memory:
+	/* get a shared buffer index */
+	ret = pvfs_bufmap_get(&bufmap, &buffer_index);
+	if (ret < 0) {
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s: pvfs_bufmap_get failure (%ld)\n",
+			     __func__, (long)ret);
+		goto out;
+	}
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): GET op %p -> buffer_index %d\n",
+		     __func__,
+		     handle,
+		     new_op,
+		     buffer_index);
+
+	new_op->uses_shared_memory = 1;
+	new_op->upcall.req.io.buf_index = buffer_index;
+	new_op->upcall.req.io.count = total_size;
+	new_op->upcall.req.io.offset = *offset;
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): copy_to_user %d nr_segs %lu, offset: %llu total_size: %zd\n",
+		     __func__,
+		     handle,
+		     to_user,
+		     nr_segs,
+		     llu(*offset),
+		     total_size);
+	/*
+	 * Stage 1: copy the buffers into client-core's address space
+	 * precopy_buffers only pertains to writes.
+	 */
+	if (type == PVFS_IO_WRITE) {
+		ret = precopy_buffers(bufmap,
+				      buffer_index,
+				      vec,
+				      nr_segs,
+				      total_size,
+				      to_user);
+		if (ret < 0)
+			goto out;
+	}
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): Calling post_io_request with tag (%llu)\n",
+		     __func__,
+		     handle,
+		     llu(new_op->tag));
+
+	/* Stage 2: Service the I/O operation */
+	ret = service_operation(new_op,
+				type == PVFS_IO_WRITE ?
+					"file_write" :
+					"file_read",
+				get_interruptible_flag(inode));
+
+	/*
+	 * If service_operation() returns -EAGAIN #and# the operation was
+	 * purged from pvfs2_request_list or htable_ops_in_progress, then
+	 * we know that the client was restarted, causing the shared memory
+	 * area to be wiped clean.  To restart a  write operation in this
+	 * case, we must re-copy the data from the user's iovec to a NEW
+	 * shared memory location. To restart a read operation, we must get
+	 * a new shared memory location.
+	 */
+	if (ret == -EAGAIN && op_state_purged(new_op)) {
+		pvfs_bufmap_put(bufmap, buffer_index);
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s:going to repopulate_shared_memory.\n",
+			     __func__);
+		goto populate_shared_memory;
+	}
+
+	if (ret < 0) {
+		handle_io_error(); /* defined in pvfs2-kernel.h */
+		/*
+		   don't write an error to syslog on signaled operation
+		   termination unless we've got debugging turned on, as
+		   this can happen regularly (i.e. ctrl-c)
+		 */
+		if (ret == -EINTR)
+			gossip_debug(GOSSIP_FILE_DEBUG,
+				     "%s: returning error %ld\n", __func__,
+				     (long)ret);
+		else
+			gossip_err("%s: error in %s handle %pU, returning %zd\n",
+				__func__,
+				type == PVFS_IO_READ ?
+					"read from" : "write to",
+				handle, ret);
+		goto out;
+	}
+
+	/*
+	 * Stage 3: Post copy buffers from client-core's address space
+	 * postcopy_buffers only pertains to reads.
+	 */
+	if (type == PVFS_IO_READ) {
+		ret = postcopy_buffers(bufmap,
+				       buffer_index,
+				       vec,
+				       nr_segs,
+				       new_op->downcall.resp.io.amt_complete,
+				       to_user);
+		if (ret < 0) {
+			/*
+			 * put error codes in downcall so that handle_io_error()
+			 * preserves it properly
+			 */
+			new_op->downcall.status = ret;
+			handle_io_error();
+			goto out;
+		}
+	}
+	gossip_debug(GOSSIP_FILE_DEBUG,
+	    "%s(%pU): Amount written as returned by the sys-io call:%d\n",
+	    __func__,
+	    handle,
+	    (int)new_op->downcall.resp.io.amt_complete);
+
+	ret = new_op->downcall.resp.io.amt_complete;
+
+	/*
+	   tell the device file owner waiting on I/O that this read has
+	   completed and it can return now.  in this exact case, on
+	   wakeup the daemon will free the op, so we *cannot* touch it
+	   after this.
+	 */
+	wake_up_daemon_for_return(new_op);
+	new_op = NULL;
+
+out:
+	if (buffer_index >= 0) {
+		pvfs_bufmap_put(bufmap, buffer_index);
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): PUT buffer_index %d\n",
+			     __func__, handle, buffer_index);
+		buffer_index = -1;
+	}
+	if (new_op) {
+		op_release(new_op);
+		new_op = NULL;
+	}
+	return ret;
+}
+
+/*
+ * The reason we need to do this is to be able to support readv and writev
+ * that are larger than (pvfs_bufmap_size_query()) Default is
+ * PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB. What that means is that we will
+ * create a new io vec descriptor for those memory addresses that
+ * go beyond the limit. Return value for this routine is negative in case
+ * of errors and 0 in case of success.
+ *
+ * Further, the new_nr_segs pointer is updated to hold the new value
+ * of number of iovecs, the new_vec pointer is updated to hold the pointer
+ * to the new split iovec, and the size array is an array of integers holding
+ * the number of iovecs that straddle pvfs_bufmap_size_query().
+ * The max_new_nr_segs value is computed by the caller and returned.
+ * (It will be (count of all iov_len/ block_size) + 1).
+ */
+static int split_iovecs(unsigned long max_new_nr_segs,		/* IN */
+			unsigned long nr_segs,			/* IN */
+			const struct iovec *original_iovec,	/* IN */
+			unsigned long *new_nr_segs,		/* OUT */
+			struct iovec **new_vec,			/* OUT */
+			unsigned long *seg_count,		/* OUT */
+			unsigned long **seg_array)		/* OUT */
+{
+	unsigned long seg;
+	unsigned long count = 0;
+	unsigned long begin_seg;
+	unsigned long tmpnew_nr_segs = 0;
+	struct iovec *new_iovec = NULL;
+	struct iovec *orig_iovec;
+	unsigned long *sizes = NULL;
+	unsigned long sizes_count = 0;
+
+	if (nr_segs <= 0 ||
+	    original_iovec == NULL ||
+	    new_nr_segs == NULL ||
+	    new_vec == NULL ||
+	    seg_count == NULL ||
+	    seg_array == NULL ||
+	    max_new_nr_segs <= 0) {
+		gossip_err("Invalid parameters to split_iovecs\n");
+		return -EINVAL;
+	}
+	*new_nr_segs = 0;
+	*new_vec = NULL;
+	*seg_count = 0;
+	*seg_array = NULL;
+	/* copy the passed in iovec descriptor to a temp structure */
+	orig_iovec = kmalloc_array(nr_segs,
+				   sizeof(*orig_iovec),
+				   PVFS2_BUFMAP_GFP_FLAGS);
+	if (orig_iovec == NULL) {
+		gossip_err(
+		    "split_iovecs: Could not allocate memory for %lu bytes!\n",
+		    (unsigned long)(nr_segs * sizeof(*orig_iovec)));
+		return -ENOMEM;
+	}
+	new_iovec = kcalloc(max_new_nr_segs,
+			    sizeof(*new_iovec),
+			    PVFS2_BUFMAP_GFP_FLAGS);
+	if (new_iovec == NULL) {
+		kfree(orig_iovec);
+		gossip_err(
+		    "split_iovecs: Could not allocate memory for %lu bytes!\n",
+		    (unsigned long)(max_new_nr_segs * sizeof(*new_iovec)));
+		return -ENOMEM;
+	}
+	sizes = kcalloc(max_new_nr_segs,
+			sizeof(*sizes),
+			PVFS2_BUFMAP_GFP_FLAGS);
+	if (sizes == NULL) {
+		kfree(new_iovec);
+		kfree(orig_iovec);
+		gossip_err(
+		    "split_iovecs: Could not allocate memory for %lu bytes!\n",
+		    (unsigned long)(max_new_nr_segs * sizeof(*sizes)));
+		return -ENOMEM;
+	}
+	/* copy the passed in iovec to a temp structure */
+	memcpy(orig_iovec, original_iovec, nr_segs * sizeof(*orig_iovec));
+	begin_seg = 0;
+repeat:
+	for (seg = begin_seg; seg < nr_segs; seg++) {
+		if (tmpnew_nr_segs >= max_new_nr_segs ||
+		    sizes_count >= max_new_nr_segs) {
+			kfree(sizes);
+			kfree(orig_iovec);
+			kfree(new_iovec);
+			gossip_err
+			    ("split_iovecs: exceeded the index limit (%lu)\n",
+			    tmpnew_nr_segs);
+			return -EINVAL;
+		}
+		if (count + orig_iovec[seg].iov_len <
+		    pvfs_bufmap_size_query()) {
+			count += orig_iovec[seg].iov_len;
+			memcpy(&new_iovec[tmpnew_nr_segs],
+			       &orig_iovec[seg],
+			       sizeof(*new_iovec));
+			tmpnew_nr_segs++;
+			sizes[sizes_count]++;
+		} else {
+			new_iovec[tmpnew_nr_segs].iov_base =
+			    orig_iovec[seg].iov_base;
+			new_iovec[tmpnew_nr_segs].iov_len =
+			    (pvfs_bufmap_size_query() - count);
+			tmpnew_nr_segs++;
+			sizes[sizes_count]++;
+			sizes_count++;
+			begin_seg = seg;
+			orig_iovec[seg].iov_base +=
+			    (pvfs_bufmap_size_query() - count);
+			orig_iovec[seg].iov_len -=
+			    (pvfs_bufmap_size_query() - count);
+			count = 0;
+			break;
+		}
+	}
+	if (seg != nr_segs)
+		goto repeat;
+	else
+		sizes_count++;
+
+	*new_nr_segs = tmpnew_nr_segs;
+	/* new_iovec is freed by the caller */
+	*new_vec = new_iovec;
+	*seg_count = sizes_count;
+	/* seg_array is also freed by the caller */
+	*seg_array = sizes;
+	kfree(orig_iovec);
+	return 0;
+}
+
+static long bound_max_iovecs(const struct iovec *curr, unsigned long nr_segs,
+			     ssize_t *total_count)
+{
+	unsigned long i;
+	long max_nr_iovecs;
+	ssize_t total;
+	ssize_t count;
+
+	total = 0;
+	count = 0;
+	max_nr_iovecs = 0;
+	for (i = 0; i < nr_segs; i++) {
+		const struct iovec *iv = &curr[i];
+
+		count += iv->iov_len;
+		if (unlikely((ssize_t) (count | iv->iov_len) < 0))
+			return -EINVAL;
+		if (total + iv->iov_len < pvfs_bufmap_size_query()) {
+			total += iv->iov_len;
+			max_nr_iovecs++;
+		} else {
+			total =
+			    (total + iv->iov_len - pvfs_bufmap_size_query());
+			max_nr_iovecs += (total / pvfs_bufmap_size_query() + 2);
+		}
+	}
+	*total_count = count;
+	return max_nr_iovecs;
+}
+
+/*
+ * Common entry point for read/write/readv/writev
+ * This function will dispatch it to either the direct I/O
+ * or buffered I/O path depending on the mount options and/or
+ * augmented/extended metadata attached to the file.
+ * Note: File extended attributes override any mount options.
+ */
+static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file,
+		loff_t *offset, const struct iovec *iov, unsigned long nr_segs)
+{
+	struct inode *inode = file->f_mapping->host;
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle;
+	ssize_t ret;
+	ssize_t total_count;
+	unsigned int to_free;
+	size_t count;
+	unsigned long seg;
+	unsigned long new_nr_segs;
+	unsigned long max_new_nr_segs;
+	unsigned long seg_count;
+	unsigned long *seg_array;
+	struct iovec *iovecptr;
+	struct iovec *ptr;
+
+	total_count = 0;
+	ret = -EINVAL;
+	count = 0;
+	to_free = 0;
+
+	/* Compute total and max number of segments after split */
+	max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count);
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		"%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n",
+		__func__,
+		handle,
+		(int)count);
+
+	if (type == PVFS_IO_WRITE) {
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): proceeding with offset : %llu, "
+			     "size %d\n",
+			     __func__,
+			     handle,
+			     llu(*offset),
+			     (int)count);
+	}
+
+	if (count == 0) {
+		ret = 0;
+		goto out;
+	}
+
+	/*
+	 * if the total size of data transfer requested is greater than
+	 * the kernel-set blocksize of PVFS2, then we split the iovecs
+	 * such that no iovec description straddles a block size limit
+	 */
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s: pvfs_bufmap_size:%d\n",
+		     __func__,
+		     pvfs_bufmap_size_query());
+
+	if (count > pvfs_bufmap_size_query()) {
+		/*
+		 * Split up the given iovec description such that
+		 * no iovec descriptor straddles over the block-size limitation.
+		 * This makes us our job easier to stage the I/O.
+		 * In addition, this function will also compute an array
+		 * with seg_count entries that will store the number of
+		 * segments that straddle the block-size boundaries.
+		 */
+		ret = split_iovecs(max_new_nr_segs,	/* IN */
+				   nr_segs,		/* IN */
+				   iov,			/* IN */
+				   &new_nr_segs,	/* OUT */
+				   &iovecptr,		/* OUT */
+				   &seg_count,		/* OUT */
+				   &seg_array);		/* OUT */
+		if (ret < 0) {
+			gossip_err("%s: Failed to split iovecs to satisfy larger than blocksize readv/writev request %zd\n",
+				__func__,
+				ret);
+			goto out;
+		}
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s: Splitting iovecs from %lu to %lu"
+			     " [max_new %lu]\n",
+			     __func__,
+			     nr_segs,
+			     new_nr_segs,
+			     max_new_nr_segs);
+		/* We must free seg_array and iovecptr */
+		to_free = 1;
+	} else {
+		new_nr_segs = nr_segs;
+		/* use the given iovec description */
+		iovecptr = (struct iovec *)iov;
+		/* There is only 1 element in the seg_array */
+		seg_count = 1;
+		/* and its value is the number of segments passed in */
+		seg_array = &nr_segs;
+		/* We dont have to free up anything */
+		to_free = 0;
+	}
+	ptr = iovecptr;
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU) %zd@%llu\n",
+		     __func__,
+		     handle,
+		     count,
+		     llu(*offset));
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): new_nr_segs: %lu, seg_count: %lu\n",
+		     __func__,
+		     handle,
+		     new_nr_segs, seg_count);
+
+/* PVFS2_KERNEL_DEBUG is a CFLAGS define. */
+#ifdef PVFS2_KERNEL_DEBUG
+	for (seg = 0; seg < new_nr_segs; seg++)
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s: %d) %p to %p [%d bytes]\n",
+			     __func__,
+			     (int)seg + 1,
+			     iovecptr[seg].iov_base,
+			     iovecptr[seg].iov_base + iovecptr[seg].iov_len,
+			     (int)iovecptr[seg].iov_len);
+	for (seg = 0; seg < seg_count; seg++)
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s: %zd) %lu\n",
+			     __func__,
+			     seg + 1,
+			     seg_array[seg]);
+#endif
+	seg = 0;
+	while (total_count < count) {
+		size_t each_count;
+		size_t amt_complete;
+
+		/* how much to transfer in this loop iteration */
+		each_count =
+		   (((count - total_count) > pvfs_bufmap_size_query()) ?
+			pvfs_bufmap_size_query() :
+			(count - total_count));
+
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): size of each_count(%d)\n",
+			     __func__,
+			     handle,
+			     (int)each_count);
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): BEFORE wait_for_io: offset is %d\n",
+			     __func__,
+			     handle,
+			     (int)*offset);
+
+		ret = wait_for_direct_io(type, inode, offset, ptr,
+				seg_array[seg], each_count, 0, 1);
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): return from wait_for_io:%d\n",
+			     __func__,
+			     handle,
+			     (int)ret);
+
+		if (ret < 0)
+			goto out;
+
+		/* advance the iovec pointer */
+		ptr += seg_array[seg];
+		seg++;
+		*offset += ret;
+		total_count += ret;
+		amt_complete = ret;
+
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s(%pU): AFTER wait_for_io: offset is %d\n",
+			     __func__,
+			     handle,
+			     (int)*offset);
+
+		/*
+		 * if we got a short I/O operations,
+		 * fall out and return what we got so far
+		 */
+		if (amt_complete < each_count)
+			break;
+	} /*end while */
+
+	if (total_count > 0)
+		ret = total_count;
+out:
+	if (to_free) {
+		kfree(iovecptr);
+		kfree(seg_array);
+	}
+	if (ret > 0) {
+		if (type == PVFS_IO_READ) {
+			file_accessed(file);
+		} else {
+			SetMtimeFlag(pvfs2_inode);
+			inode->i_mtime = CURRENT_TIME;
+			mark_inode_dirty_sync(inode);
+		}
+	}
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): Value(%d) returned.\n",
+		     __func__,
+		     handle,
+		     (int)ret);
+
+	return ret;
+}
+
+/*
+ * Read data from a specified offset in a file (referenced by inode).
+ * Data may be placed either in a user or kernel buffer.
+ */
+ssize_t pvfs2_inode_read(struct inode *inode,
+			 char __user *buf,
+			 size_t count,
+			 loff_t *offset,
+			 loff_t readahead_size)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	size_t bufmap_size;
+	struct iovec vec;
+	ssize_t ret = -EINVAL;
+
+	g_pvfs2_stats.reads++;
+
+	vec.iov_base = buf;
+	vec.iov_len = count;
+
+	bufmap_size = pvfs_bufmap_size_query();
+	if (count > bufmap_size) {
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "%s: count is too large (%zd/%zd)!\n",
+			     __func__, count, bufmap_size);
+		return -EINVAL;
+	}
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU) %zd@%llu\n",
+		     __func__,
+		     &pvfs2_inode->refn.khandle,
+		     count,
+		     llu(*offset));
+
+	ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &vec, 1,
+			count, readahead_size, 0);
+	if (ret > 0)
+		*offset += ret;
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "%s(%pU): Value(%zd) returned.\n",
+		     __func__,
+		     &pvfs2_inode->refn.khandle,
+		     ret);
+
+	return ret;
+}
+
+static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+	struct file *file = iocb->ki_filp;
+	loff_t pos = *(&iocb->ki_pos);
+	ssize_t rc = 0;
+	unsigned long nr_segs = iter->nr_segs;
+
+	BUG_ON(iocb->private);
+
+	gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_read_iter\n");
+
+	g_pvfs2_stats.reads++;
+
+	rc = do_readv_writev(PVFS_IO_READ,
+			     file,
+			     &pos,
+			     iter->iov,
+			     nr_segs);
+	iocb->ki_pos = pos;
+
+	return rc;
+}
+
+static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+	struct file *file = iocb->ki_filp;
+	loff_t pos = *(&iocb->ki_pos);
+	unsigned long nr_segs = iter->nr_segs;
+	ssize_t rc;
+
+	BUG_ON(iocb->private);
+
+	gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_write_iter\n");
+
+	mutex_lock(&file->f_mapping->host->i_mutex);
+
+	/* Make sure generic_write_checks sees an up to date inode size. */
+	if (file->f_flags & O_APPEND) {
+		rc = pvfs2_inode_getattr(file->f_mapping->host,
+					 PVFS_ATTR_SYS_SIZE);
+		if (rc) {
+			gossip_err("%s: pvfs2_inode_getattr failed, rc:%zd:.\n",
+				   __func__, rc);
+			goto out;
+		}
+	}
+
+	if (file->f_pos > i_size_read(file->f_mapping->host))
+		pvfs2_i_size_write(file->f_mapping->host, file->f_pos);
+
+	rc = generic_write_checks(iocb, iter);
+
+	if (rc <= 0) {
+		gossip_err("%s: generic_write_checks failed, rc:%zd:.\n",
+			   __func__, rc);
+		goto out;
+	}
+
+	rc = do_readv_writev(PVFS_IO_WRITE,
+			     file,
+			     &pos,
+			     iter->iov,
+			     nr_segs);
+	if (rc < 0) {
+		gossip_err("%s: do_readv_writev failed, rc:%zd:.\n",
+			   __func__, rc);
+		goto out;
+	}
+
+	iocb->ki_pos = pos;
+	g_pvfs2_stats.writes++;
+
+out:
+
+	mutex_unlock(&file->f_mapping->host->i_mutex);
+	return rc;
+}
+
+/*
+ * Perform a miscellaneous operation on a file.
+ */
+static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int ret = -ENOTTY;
+	__u64 val = 0;
+	unsigned long uval;
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "pvfs2_ioctl: called with cmd %d\n",
+		     cmd);
+
+	/*
+	 * we understand some general ioctls on files, such as the immutable
+	 * and append flags
+	 */
+	if (cmd == FS_IOC_GETFLAGS) {
+		val = 0;
+		ret = pvfs2_xattr_get_default(file->f_path.dentry,
+					      "user.pvfs2.meta_hint",
+					      &val,
+					      sizeof(val),
+					      0);
+		if (ret < 0 && ret != -ENODATA)
+			return ret;
+		else if (ret == -ENODATA)
+			val = 0;
+		uval = val;
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "pvfs2_ioctl: FS_IOC_GETFLAGS: %llu\n",
+			     (unsigned long long)uval);
+		return put_user(uval, (int __user *)arg);
+	} else if (cmd == FS_IOC_SETFLAGS) {
+		ret = 0;
+		if (get_user(uval, (int __user *)arg))
+			return -EFAULT;
+		/*
+		 * PVFS_MIRROR_FL is set internally when the mirroring mode
+		 * is turned on for a file. The user is not allowed to turn
+		 * on this bit, but the bit is present if the user first gets
+		 * the flags and then updates the flags with some new
+		 * settings. So, we ignore it in the following edit. bligon.
+		 */
+		if ((uval & ~PVFS_MIRROR_FL) &
+		    (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
+			gossip_err("pvfs2_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
+			return -EINVAL;
+		}
+		val = uval;
+		gossip_debug(GOSSIP_FILE_DEBUG,
+			     "pvfs2_ioctl: FS_IOC_SETFLAGS: %llu\n",
+			     (unsigned long long)val);
+		ret = pvfs2_xattr_set_default(file->f_path.dentry,
+					      "user.pvfs2.meta_hint",
+					      &val,
+					      sizeof(val),
+					      0,
+					      0);
+	}
+
+	return ret;
+}
+
+/*
+ * Memory map a region of a file.
+ */
+static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "pvfs2_file_mmap: called on %s\n",
+		     (file ?
+			(char *)file->f_path.dentry->d_name.name :
+			(char *)"Unknown"));
+
+	/* set the sequential readahead hint */
+	vma->vm_flags |= VM_SEQ_READ;
+	vma->vm_flags &= ~VM_RAND_READ;
+	return generic_file_mmap(file, vma);
+}
+
+#define mapping_nrpages(idata) ((idata)->nrpages)
+
+/*
+ * Called to notify the module that there are no more references to
+ * this file (i.e. no processes have it open).
+ *
+ * \note Not called when each file is closed.
+ */
+static int pvfs2_file_release(struct inode *inode, struct file *file)
+{
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "pvfs2_file_release: called on %s\n",
+		     file->f_path.dentry->d_name.name);
+
+	pvfs2_flush_inode(inode);
+
+	/*
+	   remove all associated inode pages from the page cache and mmap
+	   readahead cache (if any); this forces an expensive refresh of
+	   data for the next caller of mmap (or 'get_block' accesses)
+	 */
+	if (file->f_path.dentry->d_inode &&
+	    file->f_path.dentry->d_inode->i_mapping &&
+	    mapping_nrpages(&file->f_path.dentry->d_inode->i_data))
+		truncate_inode_pages(file->f_path.dentry->d_inode->i_mapping,
+				     0);
+	return 0;
+}
+
+/*
+ * Push all data for a specific file onto permanent storage.
+ */
+static int pvfs2_fsync(struct file *file,
+		       loff_t start,
+		       loff_t end,
+		       int datasync)
+{
+	int ret = -EINVAL;
+	struct pvfs2_inode_s *pvfs2_inode =
+		PVFS2_I(file->f_path.dentry->d_inode);
+	struct pvfs2_kernel_op_s *new_op = NULL;
+
+	/* required call */
+	filemap_write_and_wait_range(file->f_mapping, start, end);
+
+	new_op = op_alloc(PVFS2_VFS_OP_FSYNC);
+	if (!new_op)
+		return -ENOMEM;
+	new_op->upcall.req.fsync.refn = pvfs2_inode->refn;
+
+	ret = service_operation(new_op,
+			"pvfs2_fsync",
+			get_interruptible_flag(file->f_path.dentry->d_inode));
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "pvfs2_fsync got return value of %d\n",
+		     ret);
+
+	op_release(new_op);
+
+	pvfs2_flush_inode(file->f_path.dentry->d_inode);
+	return ret;
+}
+
+/*
+ * Change the file pointer position for an instance of an open file.
+ *
+ * \note If .llseek is overriden, we must acquire lock as described in
+ *       Documentation/filesystems/Locking.
+ *
+ * Future upgrade could support SEEK_DATA and SEEK_HOLE but would
+ * require much changes to the FS
+ */
+static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin)
+{
+	int ret = -EINVAL;
+	struct inode *inode = file->f_path.dentry->d_inode;
+
+	if (!inode) {
+		gossip_err("pvfs2_file_llseek: invalid inode (NULL)\n");
+		return ret;
+	}
+
+	if (origin == PVFS2_SEEK_END) {
+		/*
+		 * revalidate the inode's file size.
+		 * NOTE: We are only interested in file size here,
+		 * so we set mask accordingly.
+		 */
+		ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_SIZE);
+		if (ret) {
+			gossip_debug(GOSSIP_FILE_DEBUG,
+				     "%s:%s:%d calling make bad inode\n",
+				     __FILE__,
+				     __func__,
+				     __LINE__);
+			pvfs2_make_bad_inode(inode);
+			return ret;
+		}
+	}
+
+	gossip_debug(GOSSIP_FILE_DEBUG,
+		     "pvfs2_file_llseek: offset is %ld | origin is %d | "
+		     "inode size is %lu\n",
+		     (long)offset,
+		     origin,
+		     (unsigned long)file->f_path.dentry->d_inode->i_size);
+
+	return generic_file_llseek(file, offset, origin);
+}
+
+/*
+ * Support local locks (locks that only this kernel knows about)
+ * if Orangefs was mounted -o local_lock.
+ */
+static int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl)
+{
+	int rc = -ENOLCK;
+
+	if (PVFS2_SB(filp->f_inode->i_sb)->flags & PVFS2_OPT_LOCAL_LOCK) {
+		if (cmd == F_GETLK) {
+			rc = 0;
+			posix_test_lock(filp, fl);
+		} else {
+			rc = posix_lock_file(filp, fl, NULL);
+		}
+	}
+
+	return rc;
+}
+
+/** PVFS2 implementation of VFS file operations */
+const struct file_operations pvfs2_file_operations = {
+	.llseek		= pvfs2_file_llseek,
+	.read_iter	= pvfs2_file_read_iter,
+	.write_iter	= pvfs2_file_write_iter,
+	.lock		= pvfs2_lock,
+	.unlocked_ioctl	= pvfs2_ioctl,
+	.mmap		= pvfs2_file_mmap,
+	.open		= generic_file_open,
+	.release	= pvfs2_file_release,
+	.fsync		= pvfs2_fsync,
+};
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
new file mode 100644
index 000000000000..9ff6b2985240
--- /dev/null
+++ b/fs/orangefs/inode.c
@@ -0,0 +1,469 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Linux VFS inode operations.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+static int read_one_page(struct page *page)
+{
+	void *page_data;
+	int ret;
+	int max_block;
+	ssize_t bytes_read = 0;
+	struct inode *inode = page->mapping->host;
+	const __u32 blocksize = PAGE_CACHE_SIZE;	/* inode->i_blksize */
+	const __u32 blockbits = PAGE_CACHE_SHIFT;	/* inode->i_blkbits */
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		    "pvfs2_readpage called with page %p\n",
+		     page);
+	page_data = pvfs2_kmap(page);
+
+	max_block = ((inode->i_size / blocksize) + 1);
+
+	if (page->index < max_block) {
+		loff_t blockptr_offset = (((loff_t) page->index) << blockbits);
+
+		bytes_read = pvfs2_inode_read(inode,
+					      (char __user *) page_data,
+					      blocksize,
+					      &blockptr_offset,
+					      inode->i_size);
+	}
+	/* only zero remaining unread portions of the page data */
+	if (bytes_read > 0)
+		memset(page_data + bytes_read, 0, blocksize - bytes_read);
+	else
+		memset(page_data, 0, blocksize);
+	/* takes care of potential aliasing */
+	flush_dcache_page(page);
+	if (bytes_read < 0) {
+		ret = bytes_read;
+		SetPageError(page);
+	} else {
+		SetPageUptodate(page);
+		if (PageError(page))
+			ClearPageError(page);
+		ret = 0;
+	}
+	pvfs2_kunmap(page);
+	/* unlock the page after the ->readpage() routine completes */
+	unlock_page(page);
+	return ret;
+}
+
+static int pvfs2_readpage(struct file *file, struct page *page)
+{
+	return read_one_page(page);
+}
+
+static int pvfs2_readpages(struct file *file,
+			   struct address_space *mapping,
+			   struct list_head *pages,
+			   unsigned nr_pages)
+{
+	int page_idx;
+	int ret;
+
+	gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpages called\n");
+
+	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+		struct page *page;
+
+		page = list_entry(pages->prev, struct page, lru);
+		list_del(&page->lru);
+		if (!add_to_page_cache(page,
+				       mapping,
+				       page->index,
+				       GFP_KERNEL)) {
+			ret = read_one_page(page);
+			gossip_debug(GOSSIP_INODE_DEBUG,
+				"failure adding page to cache, read_one_page returned: %d\n",
+				ret);
+	      } else {
+			page_cache_release(page);
+	      }
+	}
+	BUG_ON(!list_empty(pages));
+	return 0;
+}
+
+static void pvfs2_invalidatepage(struct page *page,
+				 unsigned int offset,
+				 unsigned int length)
+{
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_invalidatepage called on page %p "
+		     "(offset is %u)\n",
+		     page,
+		     offset);
+
+	ClearPageUptodate(page);
+	ClearPageMappedToDisk(page);
+	return;
+
+}
+
+static int pvfs2_releasepage(struct page *page, gfp_t foo)
+{
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_releasepage called on page %p\n",
+		     page);
+	return 0;
+}
+
+/*
+ * Having a direct_IO entry point in the address_space_operations
+ * struct causes the kernel to allows us to use O_DIRECT on
+ * open. Nothing will ever call this thing, but in the future we
+ * will need to be able to use O_DIRECT on open in order to support
+ * AIO. Modeled after NFS, they do this too.
+ */
+/*
+static ssize_t pvfs2_direct_IO(int rw,
+			struct kiocb *iocb,
+			struct iov_iter *iter,
+			loff_t offset)
+{
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_direct_IO: %s\n",
+		     iocb->ki_filp->f_path.dentry->d_name.name);
+
+	return -EINVAL;
+}
+*/
+
+struct backing_dev_info pvfs2_backing_dev_info = {
+	.name = "pvfs2",
+	.ra_pages = 0,
+	.capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+/** PVFS2 implementation of address space operations */
+const struct address_space_operations pvfs2_address_operations = {
+	.readpage = pvfs2_readpage,
+	.readpages = pvfs2_readpages,
+	.invalidatepage = pvfs2_invalidatepage,
+	.releasepage = pvfs2_releasepage,
+/*	.direct_IO = pvfs2_direct_IO */
+};
+
+static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op;
+	loff_t orig_size = i_size_read(inode);
+	int ret = -EINVAL;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n",
+		     __func__,
+		     get_khandle_from_ino(inode),
+		     &pvfs2_inode->refn.khandle,
+		     pvfs2_inode->refn.fs_id,
+		     iattr->ia_size);
+
+	truncate_setsize(inode, iattr->ia_size);
+
+	new_op = op_alloc(PVFS2_VFS_OP_TRUNCATE);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.truncate.refn = pvfs2_inode->refn;
+	new_op->upcall.req.truncate.size = (__s64) iattr->ia_size;
+
+	ret = service_operation(new_op, __func__,
+				get_interruptible_flag(inode));
+
+	/*
+	 * the truncate has no downcall members to retrieve, but
+	 * the status value tells us if it went through ok or not
+	 */
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2: pvfs2_truncate got return value of %d\n",
+		     ret);
+
+	op_release(new_op);
+
+	if (ret != 0)
+		return ret;
+
+	/*
+	 * Only change the c/mtime if we are changing the size or we are
+	 * explicitly asked to change it.  This handles the semantic difference
+	 * between truncate() and ftruncate() as implemented in the VFS.
+	 *
+	 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
+	 * special case where we need to update the times despite not having
+	 * these flags set.  For all other operations the VFS set these flags
+	 * explicitly if it wants a timestamp update.
+	 */
+	if (orig_size != i_size_read(inode) &&
+	    !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
+		iattr->ia_ctime = iattr->ia_mtime =
+			current_fs_time(inode->i_sb);
+		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
+	}
+
+	return ret;
+}
+
+/*
+ * Change attributes of an object referenced by dentry.
+ */
+int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	int ret = -EINVAL;
+	struct inode *inode = dentry->d_inode;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_setattr: called on %s\n",
+		     dentry->d_name.name);
+
+	ret = inode_change_ok(inode, iattr);
+	if (ret)
+		goto out;
+
+	if ((iattr->ia_valid & ATTR_SIZE) &&
+	    iattr->ia_size != i_size_read(inode)) {
+		ret = pvfs2_setattr_size(inode, iattr);
+		if (ret)
+			goto out;
+	}
+
+	setattr_copy(inode, iattr);
+	mark_inode_dirty(inode);
+
+	ret = pvfs2_inode_setattr(inode, iattr);
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_setattr: inode_setattr returned %d\n",
+		     ret);
+
+	if (!ret && (iattr->ia_valid & ATTR_MODE))
+		/* change mod on a file that has ACLs */
+		ret = posix_acl_chmod(inode, inode->i_mode);
+
+out:
+	gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: returning %d\n", ret);
+	return ret;
+}
+
+/*
+ * Obtain attributes of an object given a dentry
+ */
+int pvfs2_getattr(struct vfsmount *mnt,
+		  struct dentry *dentry,
+		  struct kstat *kstat)
+{
+	int ret = -ENOENT;
+	struct inode *inode = dentry->d_inode;
+	struct pvfs2_inode_s *pvfs2_inode = NULL;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_getattr: called on %s\n",
+		     dentry->d_name.name);
+
+	/*
+	 * Similar to the above comment, a getattr also expects that all
+	 * fields/attributes of the inode would be refreshed. So again, we
+	 * dont have too much of a choice but refresh all the attributes.
+	 */
+	ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
+	if (ret == 0) {
+		generic_fillattr(inode, kstat);
+		/* override block size reported to stat */
+		pvfs2_inode = PVFS2_I(inode);
+		kstat->blksize = pvfs2_inode->blksize;
+	} else {
+		/* assume an I/O error and flag inode as bad */
+		gossip_debug(GOSSIP_INODE_DEBUG,
+			     "%s:%s:%d calling make bad inode\n",
+			     __FILE__,
+			     __func__,
+			     __LINE__);
+		pvfs2_make_bad_inode(inode);
+	}
+	return ret;
+}
+
+/* PVFS2 implementation of VFS inode operations for files */
+struct inode_operations pvfs2_file_inode_operations = {
+	.get_acl = pvfs2_get_acl,
+	.set_acl = pvfs2_set_acl,
+	.setattr = pvfs2_setattr,
+	.getattr = pvfs2_getattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
+	.listxattr = pvfs2_listxattr,
+	.removexattr = generic_removexattr,
+};
+
+static int pvfs2_init_iops(struct inode *inode)
+{
+	inode->i_mapping->a_ops = &pvfs2_address_operations;
+
+	switch (inode->i_mode & S_IFMT) {
+	case S_IFREG:
+		inode->i_op = &pvfs2_file_inode_operations;
+		inode->i_fop = &pvfs2_file_operations;
+		inode->i_blkbits = PAGE_CACHE_SHIFT;
+		break;
+	case S_IFLNK:
+		inode->i_op = &pvfs2_symlink_inode_operations;
+		break;
+	case S_IFDIR:
+		inode->i_op = &pvfs2_dir_inode_operations;
+		inode->i_fop = &pvfs2_dir_operations;
+		break;
+	default:
+		gossip_debug(GOSSIP_INODE_DEBUG,
+			     "%s: unsupported mode\n",
+			     __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Given a PVFS2 object identifier (fsid, handle), convert it into a ino_t type
+ * that will be used as a hash-index from where the handle will
+ * be searched for in the VFS hash table of inodes.
+ */
+static inline ino_t pvfs2_handle_hash(struct pvfs2_object_kref *ref)
+{
+	if (!ref)
+		return 0;
+	return pvfs2_khandle_to_ino(&(ref->khandle));
+}
+
+/*
+ * Called to set up an inode from iget5_locked.
+ */
+static int pvfs2_set_inode(struct inode *inode, void *data)
+{
+	struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data;
+	struct pvfs2_inode_s *pvfs2_inode = NULL;
+
+	/* Make sure that we have sane parameters */
+	if (!data || !inode)
+		return 0;
+	pvfs2_inode = PVFS2_I(inode);
+	if (!pvfs2_inode)
+		return 0;
+	pvfs2_inode->refn.fs_id = ref->fs_id;
+	pvfs2_inode->refn.khandle = ref->khandle;
+	return 0;
+}
+
+/*
+ * Called to determine if handles match.
+ */
+static int pvfs2_test_inode(struct inode *inode, void *data)
+{
+	struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data;
+	struct pvfs2_inode_s *pvfs2_inode = NULL;
+
+	pvfs2_inode = PVFS2_I(inode);
+	return (!PVFS_khandle_cmp(&(pvfs2_inode->refn.khandle), &(ref->khandle))
+		&& pvfs2_inode->refn.fs_id == ref->fs_id);
+}
+
+/*
+ * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2
+ * file handle.
+ *
+ * @sb: the file system super block instance.
+ * @ref: The PVFS2 object for which we are trying to locate an inode structure.
+ */
+struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref)
+{
+	struct inode *inode = NULL;
+	unsigned long hash;
+	int error;
+
+	hash = pvfs2_handle_hash(ref);
+	inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref);
+	if (!inode || !(inode->i_state & I_NEW))
+		return inode;
+
+	error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
+	if (error) {
+		iget_failed(inode);
+		return ERR_PTR(error);
+	}
+
+	inode->i_ino = hash;	/* needed for stat etc */
+	pvfs2_init_iops(inode);
+	unlock_new_inode(inode);
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "iget handle %pU, fsid %d hash %ld i_ino %lu\n",
+		     &ref->khandle,
+		     ref->fs_id,
+		     hash,
+		     inode->i_ino);
+
+	return inode;
+}
+
+/*
+ * Allocate an inode for a newly created file and insert it into the inode hash.
+ */
+struct inode *pvfs2_new_inode(struct super_block *sb, struct inode *dir,
+		int mode, dev_t dev, struct pvfs2_object_kref *ref)
+{
+	unsigned long hash = pvfs2_handle_hash(ref);
+	struct inode *inode;
+	int error;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "pvfs2_get_custom_inode_common: called\n"
+		     "(sb is %p | MAJOR(dev)=%u | MINOR(dev)=%u mode=%o)\n",
+		     sb,
+		     MAJOR(dev),
+		     MINOR(dev),
+		     mode);
+
+	inode = new_inode(sb);
+	if (!inode)
+		return NULL;
+
+	pvfs2_set_inode(inode, ref);
+	inode->i_ino = hash;	/* needed for stat etc */
+
+	error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
+	if (error)
+		goto out_iput;
+
+	pvfs2_init_iops(inode);
+
+	inode->i_mode = mode;
+	inode->i_uid = current_fsuid();
+	inode->i_gid = current_fsgid();
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_size = PAGE_CACHE_SIZE;
+	inode->i_rdev = dev;
+
+	error = insert_inode_locked4(inode, hash, pvfs2_test_inode, ref);
+	if (error < 0)
+		goto out_iput;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "Initializing ACL's for inode %pU\n",
+		     get_khandle_from_ino(inode));
+	pvfs2_init_acl(inode, dir);
+	return inode;
+
+out_iput:
+	iput(inode);
+	return ERR_PTR(error);
+}
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c
new file mode 100644
index 000000000000..747fe6a690af
--- /dev/null
+++ b/fs/orangefs/namei.c
@@ -0,0 +1,473 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Linux VFS namei operations.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+
+/*
+ * Get a newly allocated inode to go with a negative dentry.
+ */
+static int pvfs2_create(struct inode *dir,
+			struct dentry *dentry,
+			umode_t mode,
+			bool exclusive)
+{
+	struct pvfs2_inode_s *parent = PVFS2_I(dir);
+	struct pvfs2_kernel_op_s *new_op;
+	struct inode *inode;
+	int ret;
+
+	gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);
+
+	new_op = op_alloc(PVFS2_VFS_OP_CREATE);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.create.parent_refn = parent->refn;
+
+	fill_default_sys_attrs(new_op->upcall.req.create.attributes,
+			       PVFS_TYPE_METAFILE, mode);
+
+	strncpy(new_op->upcall.req.create.d_name,
+		dentry->d_name.name, PVFS2_NAME_LEN);
+
+	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Create Got PVFS2 handle %pU on fsid %d (ret=%d)\n",
+		     &new_op->downcall.resp.create.refn.khandle,
+		     new_op->downcall.resp.create.refn.fs_id, ret);
+
+	if (ret < 0) {
+		gossip_debug(GOSSIP_NAME_DEBUG,
+			     "%s: failed with error code %d\n",
+			     __func__, ret);
+		goto out;
+	}
+
+	inode = pvfs2_new_inode(dir->i_sb, dir, S_IFREG | mode, 0,
+				&new_op->downcall.resp.create.refn);
+	if (IS_ERR(inode)) {
+		gossip_err("*** Failed to allocate pvfs2 file inode\n");
+		ret = PTR_ERR(inode);
+		goto out;
+	}
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Assigned file inode new number of %pU\n",
+		     get_khandle_from_ino(inode));
+
+	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Inode (Regular File) %pU -> %s\n",
+		     get_khandle_from_ino(inode),
+		     dentry->d_name.name);
+
+	SetMtimeFlag(parent);
+	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
+	mark_inode_dirty_sync(dir);
+	ret = 0;
+out:
+	op_release(new_op);
+	gossip_debug(GOSSIP_NAME_DEBUG, "%s: returning %d\n", __func__, ret);
+	return ret;
+}
+
+/*
+ * Attempt to resolve an object name (dentry->d_name), parent handle, and
+ * fsid into a handle for the object.
+ */
+static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry,
+				   unsigned int flags)
+{
+	struct pvfs2_inode_s *parent = PVFS2_I(dir);
+	struct pvfs2_kernel_op_s *new_op;
+	struct inode *inode;
+	struct dentry *res;
+	int ret = -EINVAL;
+
+	/*
+	 * in theory we could skip a lookup here (if the intent is to
+	 * create) in order to avoid a potentially failed lookup, but
+	 * leaving it in can skip a valid lookup and try to create a file
+	 * that already exists (e.g. the vfs already handles checking for
+	 * -EEXIST on O_EXCL opens, which is broken if we skip this lookup
+	 * in the create path)
+	 */
+	gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %s\n",
+		     __func__, dentry->d_name.name);
+
+	if (dentry->d_name.len > (PVFS2_NAME_LEN - 1))
+		return ERR_PTR(-ENAMETOOLONG);
+
+	new_op = op_alloc(PVFS2_VFS_OP_LOOKUP);
+	if (!new_op)
+		return ERR_PTR(-ENOMEM);
+
+	new_op->upcall.req.lookup.sym_follow = flags & LOOKUP_FOLLOW;
+
+	gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n",
+		     __FILE__,
+		     __func__,
+		     __LINE__,
+		     &parent->refn.khandle);
+	new_op->upcall.req.lookup.parent_refn = parent->refn;
+
+	strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name,
+		PVFS2_NAME_LEN);
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "%s: doing lookup on %s under %pU,%d (follow=%s)\n",
+		     __func__,
+		     new_op->upcall.req.lookup.d_name,
+		     &new_op->upcall.req.lookup.parent_refn.khandle,
+		     new_op->upcall.req.lookup.parent_refn.fs_id,
+		     ((new_op->upcall.req.lookup.sym_follow ==
+		       PVFS2_LOOKUP_LINK_FOLLOW) ? "yes" : "no"));
+
+	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Lookup Got %pU, fsid %d (ret=%d)\n",
+		     &new_op->downcall.resp.lookup.refn.khandle,
+		     new_op->downcall.resp.lookup.refn.fs_id,
+		     ret);
+
+	if (ret < 0) {
+		if (ret == -ENOENT) {
+			/*
+			 * if no inode was found, add a negative dentry to
+			 * dcache anyway; if we don't, we don't hold expected
+			 * lookup semantics and we most noticeably break
+			 * during directory renames.
+			 *
+			 * however, if the operation failed or exited, do not
+			 * add the dentry (e.g. in the case that a touch is
+			 * issued on a file that already exists that was
+			 * interrupted during this lookup -- no need to add
+			 * another negative dentry for an existing file)
+			 */
+
+			gossip_debug(GOSSIP_NAME_DEBUG,
+				     "pvfs2_lookup: Adding *negative* dentry "
+				     "%p for %s\n",
+				     dentry,
+				     dentry->d_name.name);
+
+			d_add(dentry, NULL);
+			res = NULL;
+			goto out;
+		}
+
+		/* must be a non-recoverable error */
+		res = ERR_PTR(ret);
+		goto out;
+	}
+
+	inode = pvfs2_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn);
+	if (IS_ERR(inode)) {
+		gossip_debug(GOSSIP_NAME_DEBUG,
+			"error %ld from iget\n", PTR_ERR(inode));
+		res = ERR_CAST(inode);
+		goto out;
+	}
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "%s:%s:%d "
+		     "Found good inode [%lu] with count [%d]\n",
+		     __FILE__,
+		     __func__,
+		     __LINE__,
+		     inode->i_ino,
+		     (int)atomic_read(&inode->i_count));
+
+	/* update dentry/inode pair into dcache */
+	res = d_splice_alias(inode, dentry);
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Lookup success (inode ct = %d)\n",
+		     (int)atomic_read(&inode->i_count));
+out:
+	op_release(new_op);
+	return res;
+}
+
+/* return 0 on success; non-zero otherwise */
+static int pvfs2_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pvfs2_inode_s *parent = PVFS2_I(dir);
+	struct pvfs2_kernel_op_s *new_op;
+	int ret;
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "%s: called on %s\n"
+		     "  (inode %pU): Parent is %pU | fs_id %d\n",
+		     __func__,
+		     dentry->d_name.name,
+		     get_khandle_from_ino(inode),
+		     &parent->refn.khandle,
+		     parent->refn.fs_id);
+
+	new_op = op_alloc(PVFS2_VFS_OP_REMOVE);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.remove.parent_refn = parent->refn;
+	strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name,
+		PVFS2_NAME_LEN);
+
+	ret = service_operation(new_op, "pvfs2_unlink",
+				get_interruptible_flag(inode));
+
+	/* when request is serviced properly, free req op struct */
+	op_release(new_op);
+
+	if (!ret) {
+		drop_nlink(inode);
+
+		SetMtimeFlag(parent);
+		dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
+		mark_inode_dirty_sync(dir);
+	}
+	return ret;
+}
+
+/*
+ * pvfs2_link() is only implemented here to make sure that we return a
+ * reasonable error code (the kernel will return a misleading EPERM
+ * otherwise).  PVFS2 does not support hard links.
+ */
+static int pvfs2_link(struct dentry *old_dentry,
+		      struct inode *dir,
+		      struct dentry *dentry)
+{
+	return -EOPNOTSUPP;
+}
+
+/*
+ * pvfs2_mknod() is only implemented here to make sure that we return a
+ * reasonable error code (the kernel will return a misleading EPERM
+ * otherwise).  PVFS2 does not support special files such as fifos or devices.
+ */
+static int pvfs2_mknod(struct inode *dir,
+		       struct dentry *dentry,
+		       umode_t mode,
+		       dev_t rdev)
+{
+	return -EOPNOTSUPP;
+}
+
+static int pvfs2_symlink(struct inode *dir,
+			 struct dentry *dentry,
+			 const char *symname)
+{
+	struct pvfs2_inode_s *parent = PVFS2_I(dir);
+	struct pvfs2_kernel_op_s *new_op;
+	struct inode *inode;
+	int mode = 755;
+	int ret;
+
+	gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);
+
+	if (!symname)
+		return -EINVAL;
+
+	new_op = op_alloc(PVFS2_VFS_OP_SYMLINK);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.sym.parent_refn = parent->refn;
+
+	fill_default_sys_attrs(new_op->upcall.req.sym.attributes,
+			       PVFS_TYPE_SYMLINK,
+			       mode);
+
+	strncpy(new_op->upcall.req.sym.entry_name,
+		dentry->d_name.name,
+		PVFS2_NAME_LEN);
+	strncpy(new_op->upcall.req.sym.target, symname, PVFS2_NAME_LEN);
+
+	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Symlink Got PVFS2 handle %pU on fsid %d (ret=%d)\n",
+		     &new_op->downcall.resp.sym.refn.khandle,
+		     new_op->downcall.resp.sym.refn.fs_id, ret);
+
+	if (ret < 0) {
+		gossip_debug(GOSSIP_NAME_DEBUG,
+			    "%s: failed with error code %d\n",
+			    __func__, ret);
+		goto out;
+	}
+
+	inode = pvfs2_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0,
+				&new_op->downcall.resp.sym.refn);
+	if (IS_ERR(inode)) {
+		gossip_err
+		    ("*** Failed to allocate pvfs2 symlink inode\n");
+		ret = PTR_ERR(inode);
+		goto out;
+	}
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Assigned symlink inode new number of %pU\n",
+		     get_khandle_from_ino(inode));
+
+	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Inode (Symlink) %pU -> %s\n",
+		     get_khandle_from_ino(inode),
+		     dentry->d_name.name);
+
+	SetMtimeFlag(parent);
+	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
+	mark_inode_dirty_sync(dir);
+	ret = 0;
+out:
+	op_release(new_op);
+	return ret;
+}
+
+static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+	struct pvfs2_inode_s *parent = PVFS2_I(dir);
+	struct pvfs2_kernel_op_s *new_op;
+	struct inode *inode;
+	int ret;
+
+	new_op = op_alloc(PVFS2_VFS_OP_MKDIR);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.mkdir.parent_refn = parent->refn;
+
+	fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
+			       PVFS_TYPE_DIRECTORY, mode);
+
+	strncpy(new_op->upcall.req.mkdir.d_name,
+		dentry->d_name.name, PVFS2_NAME_LEN);
+
+	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Mkdir Got PVFS2 handle %pU on fsid %d\n",
+		     &new_op->downcall.resp.mkdir.refn.khandle,
+		     new_op->downcall.resp.mkdir.refn.fs_id);
+
+	if (ret < 0) {
+		gossip_debug(GOSSIP_NAME_DEBUG,
+			     "%s: failed with error code %d\n",
+			     __func__, ret);
+		goto out;
+	}
+
+	inode = pvfs2_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0,
+				&new_op->downcall.resp.mkdir.refn);
+	if (IS_ERR(inode)) {
+		gossip_err("*** Failed to allocate pvfs2 dir inode\n");
+		ret = PTR_ERR(inode);
+		goto out;
+	}
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Assigned dir inode new number of %pU\n",
+		     get_khandle_from_ino(inode));
+
+	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "Inode (Directory) %pU -> %s\n",
+		     get_khandle_from_ino(inode),
+		     dentry->d_name.name);
+
+	/*
+	 * NOTE: we have no good way to keep nlink consistent for directories
+	 * across clients; keep constant at 1.
+	 */
+	SetMtimeFlag(parent);
+	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
+	mark_inode_dirty_sync(dir);
+out:
+	op_release(new_op);
+	return ret;
+}
+
+static int pvfs2_rename(struct inode *old_dir,
+			struct dentry *old_dentry,
+			struct inode *new_dir,
+			struct dentry *new_dentry)
+{
+	struct pvfs2_kernel_op_s *new_op;
+	int ret;
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "pvfs2_rename: called (%s/%s => %s/%s) ct=%d\n",
+		     old_dentry->d_parent->d_name.name,
+		     old_dentry->d_name.name,
+		     new_dentry->d_parent->d_name.name,
+		     new_dentry->d_name.name,
+		     d_count(new_dentry));
+
+	new_op = op_alloc(PVFS2_VFS_OP_RENAME);
+	if (!new_op)
+		return -EINVAL;
+
+	new_op->upcall.req.rename.old_parent_refn = PVFS2_I(old_dir)->refn;
+	new_op->upcall.req.rename.new_parent_refn = PVFS2_I(new_dir)->refn;
+
+	strncpy(new_op->upcall.req.rename.d_old_name,
+		old_dentry->d_name.name,
+		PVFS2_NAME_LEN);
+	strncpy(new_op->upcall.req.rename.d_new_name,
+		new_dentry->d_name.name,
+		PVFS2_NAME_LEN);
+
+	ret = service_operation(new_op,
+				"pvfs2_rename",
+				get_interruptible_flag(old_dentry->d_inode));
+
+	gossip_debug(GOSSIP_NAME_DEBUG,
+		     "pvfs2_rename: got downcall status %d\n",
+		     ret);
+
+	if (new_dentry->d_inode)
+		new_dentry->d_inode->i_ctime = CURRENT_TIME;
+
+	op_release(new_op);
+	return ret;
+}
+
+/* PVFS2 implementation of VFS inode operations for directories */
+struct inode_operations pvfs2_dir_inode_operations = {
+	.lookup = pvfs2_lookup,
+	.get_acl = pvfs2_get_acl,
+	.set_acl = pvfs2_set_acl,
+	.create = pvfs2_create,
+	.link = pvfs2_link,
+	.unlink = pvfs2_unlink,
+	.symlink = pvfs2_symlink,
+	.mkdir = pvfs2_mkdir,
+	.rmdir = pvfs2_unlink,
+	.mknod = pvfs2_mknod,
+	.rename = pvfs2_rename,
+	.setattr = pvfs2_setattr,
+	.getattr = pvfs2_getattr,
+	.setxattr = generic_setxattr,
+	.getxattr = generic_getxattr,
+	.removexattr = generic_removexattr,
+	.listxattr = pvfs2_listxattr,
+};
diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h
new file mode 100644
index 000000000000..f571be21f66a
--- /dev/null
+++ b/fs/orangefs/protocol.h
@@ -0,0 +1,672 @@
+#include <linux/types.h>
+#include <linux/spinlock_types.h>
+#include <linux/slab.h>
+#include <linux/ioctl.h>
+
+extern struct client_debug_mask *cdm_array;
+extern char *debug_help_string;
+extern int help_string_initialized;
+extern struct dentry *debug_dir;
+extern struct dentry *help_file_dentry;
+extern struct dentry *client_debug_dentry;
+extern const struct file_operations debug_help_fops;
+extern int client_all_index;
+extern int client_verbose_index;
+extern int cdm_element_count;
+#define DEBUG_HELP_STRING_SIZE 4096
+#define HELP_STRING_UNINITIALIZED \
+	"Client Debug Keywords are unknown until the first time\n" \
+	"the client is started after boot.\n"
+#define ORANGEFS_KMOD_DEBUG_HELP_FILE "debug-help"
+#define ORANGEFS_KMOD_DEBUG_FILE "kernel-debug"
+#define ORANGEFS_CLIENT_DEBUG_FILE "client-debug"
+#define PVFS2_VERBOSE "verbose"
+#define PVFS2_ALL "all"
+
+/* pvfs2-config.h ***********************************************************/
+#define PVFS2_VERSION_MAJOR 2
+#define PVFS2_VERSION_MINOR 9
+#define PVFS2_VERSION_SUB 0
+
+/* khandle stuff  ***********************************************************/
+
+/*
+ * The 2.9 core will put 64 bit handles in here like this:
+ *    1234 0000 0000 5678
+ * The 3.0 and beyond cores will put 128 bit handles in here like this:
+ *    1234 5678 90AB CDEF
+ * The kernel module will always use the first four bytes and
+ * the last four bytes as an inum.
+ */
+struct pvfs2_khandle {
+	unsigned char u[16];
+}  __aligned(8);
+
+/*
+ * kernel version of an object ref.
+ */
+struct pvfs2_object_kref {
+	struct pvfs2_khandle khandle;
+	__s32 fs_id;
+	__s32 __pad1;
+};
+
+/*
+ * compare 2 khandles assumes little endian thus from large address to
+ * small address
+ */
+static inline int PVFS_khandle_cmp(const struct pvfs2_khandle *kh1,
+				   const struct pvfs2_khandle *kh2)
+{
+	int i;
+
+	for (i = 15; i >= 0; i--) {
+		if (kh1->u[i] > kh2->u[i])
+			return 1;
+		if (kh1->u[i] < kh2->u[i])
+			return -1;
+	}
+
+	return 0;
+}
+
+/* copy a khandle to a field of arbitrary size */
+static inline void PVFS_khandle_to(const struct pvfs2_khandle *kh,
+				   void *p, int size)
+{
+	int i;
+	unsigned char *c = p;
+
+	memset(p, 0, size);
+
+	for (i = 0; i < 16 && i < size; i++)
+		c[i] = kh->u[i];
+}
+
+/* copy a khandle from a field of arbitrary size */
+static inline void PVFS_khandle_from(struct pvfs2_khandle *kh,
+				     void *p, int size)
+{
+	int i;
+	unsigned char *c = p;
+
+	memset(kh, 0, 16);
+
+	for (i = 0; i < 16 && i < size; i++)
+		kh->u[i] = c[i];
+}
+
+/* pvfs2-types.h ************************************************************/
+typedef __u32 PVFS_uid;
+typedef __u32 PVFS_gid;
+typedef __s32 PVFS_fs_id;
+typedef __u32 PVFS_permissions;
+typedef __u64 PVFS_time;
+typedef __s64 PVFS_size;
+typedef __u64 PVFS_flags;
+typedef __u64 PVFS_ds_position;
+typedef __s32 PVFS_error;
+typedef __s64 PVFS_offset;
+
+#define PVFS2_SUPER_MAGIC 0x20030528
+#define PVFS_ERROR_BIT           (1 << 30)
+#define PVFS_NON_ERRNO_ERROR_BIT (1 << 29)
+#define IS_PVFS_ERROR(__error)   ((__error)&(PVFS_ERROR_BIT))
+#define IS_PVFS_NON_ERRNO_ERROR(__error)  \
+(((__error)&(PVFS_NON_ERRNO_ERROR_BIT)) && IS_PVFS_ERROR(__error))
+#define PVFS_ERROR_TO_ERRNO(__error) PVFS_get_errno_mapping(__error)
+
+/* 7 bits are used for the errno mapped error codes */
+#define PVFS_ERROR_CODE(__error) \
+((__error) & (__s32)(0x7f|PVFS_ERROR_BIT))
+#define PVFS_ERROR_CLASS(__error) \
+((__error) & ~((__s32)(0x7f|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT)))
+#define PVFS_NON_ERRNO_ERROR_CODE(__error) \
+((__error) & (__s32)(127|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT))
+
+/* PVFS2 error codes, compliments of asm/errno.h */
+#define PVFS_EPERM            E(1)	/* Operation not permitted */
+#define PVFS_ENOENT           E(2)	/* No such file or directory */
+#define PVFS_EINTR            E(3)	/* Interrupted system call */
+#define PVFS_EIO              E(4)	/* I/O error */
+#define PVFS_ENXIO            E(5)	/* No such device or address */
+#define PVFS_EBADF            E(6)	/* Bad file number */
+#define PVFS_EAGAIN           E(7)	/* Try again */
+#define PVFS_ENOMEM           E(8)	/* Out of memory */
+#define PVFS_EFAULT           E(9)	/* Bad address */
+#define PVFS_EBUSY           E(10)	/* Device or resource busy */
+#define PVFS_EEXIST          E(11)	/* File exists */
+#define PVFS_ENODEV          E(12)	/* No such device */
+#define PVFS_ENOTDIR         E(13)	/* Not a directory */
+#define PVFS_EISDIR          E(14)	/* Is a directory */
+#define PVFS_EINVAL          E(15)	/* Invalid argument */
+#define PVFS_EMFILE          E(16)	/* Too many open files */
+#define PVFS_EFBIG           E(17)	/* File too large */
+#define PVFS_ENOSPC          E(18)	/* No space left on device */
+#define PVFS_EROFS           E(19)	/* Read-only file system */
+#define PVFS_EMLINK          E(20)	/* Too many links */
+#define PVFS_EPIPE           E(21)	/* Broken pipe */
+#define PVFS_EDEADLK         E(22)	/* Resource deadlock would occur */
+#define PVFS_ENAMETOOLONG    E(23)	/* File name too long */
+#define PVFS_ENOLCK          E(24)	/* No record locks available */
+#define PVFS_ENOSYS          E(25)	/* Function not implemented */
+#define PVFS_ENOTEMPTY       E(26)	/* Directory not empty */
+					/*
+#define PVFS_ELOOP           E(27)	 * Too many symbolic links encountered
+					 */
+#define PVFS_EWOULDBLOCK     E(28)	/* Operation would block */
+#define PVFS_ENOMSG          E(29)	/* No message of desired type */
+#define PVFS_EUNATCH         E(30)	/* Protocol driver not attached */
+#define PVFS_EBADR           E(31)	/* Invalid request descriptor */
+#define PVFS_EDEADLOCK       E(32)
+#define PVFS_ENODATA         E(33)	/* No data available */
+#define PVFS_ETIME           E(34)	/* Timer expired */
+#define PVFS_ENONET          E(35)	/* Machine is not on the network */
+#define PVFS_EREMOTE         E(36)	/* Object is remote */
+#define PVFS_ECOMM           E(37)	/* Communication error on send */
+#define PVFS_EPROTO          E(38)	/* Protocol error */
+#define PVFS_EBADMSG         E(39)	/* Not a data message */
+					/*
+#define PVFS_EOVERFLOW       E(40)	 * Value too large for defined data
+					 * type
+					 */
+					/*
+#define PVFS_ERESTART        E(41)	 * Interrupted system call should be
+					 * restarted
+					 */
+#define PVFS_EMSGSIZE        E(42)	/* Message too long */
+#define PVFS_EPROTOTYPE      E(43)	/* Protocol wrong type for socket */
+#define PVFS_ENOPROTOOPT     E(44)	/* Protocol not available */
+#define PVFS_EPROTONOSUPPORT E(45)	/* Protocol not supported */
+					/*
+#define PVFS_EOPNOTSUPP      E(46)	 * Operation not supported on transport
+					 * endpoint
+					 */
+#define PVFS_EADDRINUSE      E(47)	/* Address already in use */
+#define PVFS_EADDRNOTAVAIL   E(48)	/* Cannot assign requested address */
+#define PVFS_ENETDOWN        E(49)	/* Network is down */
+#define PVFS_ENETUNREACH     E(50)	/* Network is unreachable */
+					/*
+#define PVFS_ENETRESET       E(51)	 * Network dropped connection because
+					 * of reset
+					 */
+#define PVFS_ENOBUFS         E(52)	/* No buffer space available */
+#define PVFS_ETIMEDOUT       E(53)	/* Connection timed out */
+#define PVFS_ECONNREFUSED    E(54)	/* Connection refused */
+#define PVFS_EHOSTDOWN       E(55)	/* Host is down */
+#define PVFS_EHOSTUNREACH    E(56)	/* No route to host */
+#define PVFS_EALREADY        E(57)	/* Operation already in progress */
+#define PVFS_EACCES          E(58)	/* Access not allowed */
+#define PVFS_ECONNRESET      E(59)	/* Connection reset by peer */
+#define PVFS_ERANGE          E(60)	/* Math out of range or buf too small */
+
+/***************** non-errno/pvfs2 specific error codes *****************/
+#define PVFS_ECANCEL    (1|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_EDEVINIT   (2|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_EDETAIL    (3|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_EHOSTNTFD  (4|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_EADDRNTFD  (5|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_ENORECVR   (6|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_ETRYAGAIN  (7|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_ENOTPVFS   (8|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+#define PVFS_ESECURITY  (9|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT))
+
+/*
+ * NOTE: PLEASE DO NOT ARBITRARILY ADD NEW ERRNO ERROR CODES!
+ *
+ * IF YOU CHOOSE TO ADD A NEW ERROR CODE (DESPITE OUR PLEA), YOU ALSO
+ * NEED TO INCREMENT PVFS_ERRNO MAX (BELOW) AND ADD A MAPPING TO A
+ * UNIX ERRNO VALUE IN THE MACROS BELOW (USED IN
+ * src/common/misc/errno-mapping.c and the kernel module)
+ */
+#define PVFS_ERRNO_MAX          61
+
+#define PVFS_ERROR_BMI    (1 << 7)	/* BMI-specific error */
+#define PVFS_ERROR_TROVE  (2 << 7)	/* Trove-specific error */
+#define PVFS_ERROR_FLOW   (3 << 7)
+#define PVFS_ERROR_SM     (4 << 7)	/* state machine specific error */
+#define PVFS_ERROR_SCHED  (5 << 7)
+#define PVFS_ERROR_CLIENT (6 << 7)
+#define PVFS_ERROR_DEV    (7 << 7)	/* device file interaction */
+
+#define PVFS_ERROR_CLASS_BITS	\
+	(PVFS_ERROR_BMI    |	\
+	 PVFS_ERROR_TROVE  |	\
+	 PVFS_ERROR_FLOW   |	\
+	 PVFS_ERROR_SM     |	\
+	 PVFS_ERROR_SCHED  |	\
+	 PVFS_ERROR_CLIENT |	\
+	 PVFS_ERROR_DEV)
+
+#define DECLARE_ERRNO_MAPPING()                       \
+__s32 PINT_errno_mapping[PVFS_ERRNO_MAX + 1] = { \
+	0,     /* leave this one empty */                 \
+	EPERM, /* 1 */                                    \
+	ENOENT,                                           \
+	EINTR,                                            \
+	EIO,                                              \
+	ENXIO,                                            \
+	EBADF,                                            \
+	EAGAIN,                                           \
+	ENOMEM,                                           \
+	EFAULT,                                           \
+	EBUSY, /* 10 */                                   \
+	EEXIST,                                           \
+	ENODEV,                                           \
+	ENOTDIR,                                          \
+	EISDIR,                                           \
+	EINVAL,                                           \
+	EMFILE,                                           \
+	EFBIG,                                            \
+	ENOSPC,                                           \
+	EROFS,                                            \
+	EMLINK, /* 20 */                                  \
+	EPIPE,                                            \
+	EDEADLK,                                          \
+	ENAMETOOLONG,                                     \
+	ENOLCK,                                           \
+	ENOSYS,                                           \
+	ENOTEMPTY,                                        \
+	ELOOP,                                            \
+	EWOULDBLOCK,                                      \
+	ENOMSG,                                           \
+	EUNATCH, /* 30 */                                 \
+	EBADR,                                            \
+	EDEADLOCK,                                        \
+	ENODATA,                                          \
+	ETIME,                                            \
+	ENONET,                                           \
+	EREMOTE,                                          \
+	ECOMM,                                            \
+	EPROTO,                                           \
+	EBADMSG,                                          \
+	EOVERFLOW, /* 40 */                               \
+	ERESTART,                                         \
+	EMSGSIZE,                                         \
+	EPROTOTYPE,                                       \
+	ENOPROTOOPT,                                      \
+	EPROTONOSUPPORT,                                  \
+	EOPNOTSUPP,                                       \
+	EADDRINUSE,                                       \
+	EADDRNOTAVAIL,                                    \
+	ENETDOWN,                                         \
+	ENETUNREACH, /* 50 */                             \
+	ENETRESET,                                        \
+	ENOBUFS,                                          \
+	ETIMEDOUT,                                        \
+	ECONNREFUSED,                                     \
+	EHOSTDOWN,                                        \
+	EHOSTUNREACH,                                     \
+	EALREADY,                                         \
+	EACCES,                                           \
+	ECONNRESET,   /* 59 */                            \
+	ERANGE,                                           \
+	0         /* PVFS_ERRNO_MAX */                    \
+};                                                    \
+const char *PINT_non_errno_strerror_mapping[] = {     \
+	"Success", /* 0 */                                \
+	"Operation cancelled (possibly due to timeout)",  \
+	"Device initialization failed",                   \
+	"Detailed per-server errors are available",       \
+	"Unknown host",                                   \
+	"No address associated with name",                \
+	"Unknown server error",                           \
+	"Host name lookup failure",                       \
+	"Path contains non-PVFS elements",                \
+	"Security error",                                 \
+};                                                    \
+__s32 PINT_non_errno_mapping[] = {               \
+	0,     /* leave this one empty */                 \
+	PVFS_ECANCEL,   /* 1 */                           \
+	PVFS_EDEVINIT,  /* 2 */                           \
+	PVFS_EDETAIL,   /* 3 */                           \
+	PVFS_EHOSTNTFD, /* 4 */                           \
+	PVFS_EADDRNTFD, /* 5 */                           \
+	PVFS_ENORECVR,  /* 6 */                           \
+	PVFS_ETRYAGAIN, /* 7 */                           \
+	PVFS_ENOTPVFS,  /* 8 */                           \
+	PVFS_ESECURITY, /* 9 */                           \
+}
+
+/*
+ *   NOTE: PVFS_get_errno_mapping will convert a PVFS_ERROR_CODE to an
+ *   errno value.  If the error code is a pvfs2 specific error code
+ *   (i.e. a PVFS_NON_ERRNO_ERROR_CODE), PVFS_get_errno_mapping will
+ *   return an index into the PINT_non_errno_strerror_mapping array which
+ *   can be used for getting the pvfs2 specific strerror message given
+ *   the error code.  if the value is not a recognized error code, the
+ *   passed in value will be returned unchanged.
+ */
+#define DECLARE_ERRNO_MAPPING_AND_FN()					\
+extern __s32 PINT_errno_mapping[];					\
+extern __s32 PINT_non_errno_mapping[];				\
+extern const char *PINT_non_errno_strerror_mapping[];			\
+static __s32 PVFS_get_errno_mapping(__s32 error)			\
+{									\
+	__s32 ret = error, mask = 0;				\
+	__s32 positive = ((error > -1) ? 1 : 0);			\
+	if (IS_PVFS_NON_ERRNO_ERROR((positive ? error : -error))) {	\
+		mask = (PVFS_NON_ERRNO_ERROR_BIT |			\
+			PVFS_ERROR_BIT |				\
+			PVFS_ERROR_CLASS_BITS);				\
+		ret = PVFS_NON_ERRNO_ERROR_CODE(((positive ?		\
+						     error :		\
+						     abs(error))) &	\
+						 ~mask);		\
+	}								\
+	else if (IS_PVFS_ERROR((positive ? error : -error))) {		\
+		mask = (PVFS_ERROR_BIT |				\
+			PVFS_ERROR_CLASS_BITS);				\
+		ret = PINT_errno_mapping[PVFS_ERROR_CODE(((positive ?	\
+								error :	\
+								abs(error))) & \
+							  ~mask)];	\
+	}								\
+	return ret;							\
+}									\
+DECLARE_ERRNO_MAPPING()
+
+/* permission bits */
+#define PVFS_O_EXECUTE (1 << 0)
+#define PVFS_O_WRITE   (1 << 1)
+#define PVFS_O_READ    (1 << 2)
+#define PVFS_G_EXECUTE (1 << 3)
+#define PVFS_G_WRITE   (1 << 4)
+#define PVFS_G_READ    (1 << 5)
+#define PVFS_U_EXECUTE (1 << 6)
+#define PVFS_U_WRITE   (1 << 7)
+#define PVFS_U_READ    (1 << 8)
+/* no PVFS_U_VTX (sticky bit) */
+#define PVFS_G_SGID    (1 << 10)
+#define PVFS_U_SUID    (1 << 11)
+
+/* definition taken from stdint.h */
+#define INT32_MAX (2147483647)
+#define PVFS_ITERATE_START    (INT32_MAX - 1)
+#define PVFS_ITERATE_END      (INT32_MAX - 2)
+#define PVFS_READDIR_START PVFS_ITERATE_START
+#define PVFS_READDIR_END   PVFS_ITERATE_END
+#define PVFS_IMMUTABLE_FL FS_IMMUTABLE_FL
+#define PVFS_APPEND_FL    FS_APPEND_FL
+#define PVFS_NOATIME_FL   FS_NOATIME_FL
+#define PVFS_MIRROR_FL    0x01000000ULL
+#define PVFS_O_EXECUTE (1 << 0)
+#define PVFS_FS_ID_NULL       ((__s32)0)
+#define PVFS_ATTR_SYS_UID                   (1 << 0)
+#define PVFS_ATTR_SYS_GID                   (1 << 1)
+#define PVFS_ATTR_SYS_PERM                  (1 << 2)
+#define PVFS_ATTR_SYS_ATIME                 (1 << 3)
+#define PVFS_ATTR_SYS_CTIME                 (1 << 4)
+#define PVFS_ATTR_SYS_MTIME                 (1 << 5)
+#define PVFS_ATTR_SYS_TYPE                  (1 << 6)
+#define PVFS_ATTR_SYS_ATIME_SET             (1 << 7)
+#define PVFS_ATTR_SYS_MTIME_SET             (1 << 8)
+#define PVFS_ATTR_SYS_SIZE                  (1 << 20)
+#define PVFS_ATTR_SYS_LNK_TARGET            (1 << 24)
+#define PVFS_ATTR_SYS_DFILE_COUNT           (1 << 25)
+#define PVFS_ATTR_SYS_DIRENT_COUNT          (1 << 26)
+#define PVFS_ATTR_SYS_BLKSIZE               (1 << 28)
+#define PVFS_ATTR_SYS_MIRROR_COPIES_COUNT   (1 << 29)
+#define PVFS_ATTR_SYS_COMMON_ALL	\
+	(PVFS_ATTR_SYS_UID	|	\
+	 PVFS_ATTR_SYS_GID	|	\
+	 PVFS_ATTR_SYS_PERM	|	\
+	 PVFS_ATTR_SYS_ATIME	|	\
+	 PVFS_ATTR_SYS_CTIME	|	\
+	 PVFS_ATTR_SYS_MTIME	|	\
+	 PVFS_ATTR_SYS_TYPE)
+
+#define PVFS_ATTR_SYS_ALL_SETABLE		\
+(PVFS_ATTR_SYS_COMMON_ALL-PVFS_ATTR_SYS_TYPE)
+
+#define PVFS_ATTR_SYS_ALL_NOHINT			\
+	(PVFS_ATTR_SYS_COMMON_ALL		|	\
+	 PVFS_ATTR_SYS_SIZE			|	\
+	 PVFS_ATTR_SYS_LNK_TARGET		|	\
+	 PVFS_ATTR_SYS_DFILE_COUNT		|	\
+	 PVFS_ATTR_SYS_MIRROR_COPIES_COUNT	|	\
+	 PVFS_ATTR_SYS_DIRENT_COUNT		|	\
+	 PVFS_ATTR_SYS_BLKSIZE)
+#define PVFS_XATTR_REPLACE 0x2
+#define PVFS_XATTR_CREATE  0x1
+#define PVFS_MAX_SERVER_ADDR_LEN 256
+#define PVFS_NAME_MAX            256
+/*
+ * max extended attribute name len as imposed by the VFS and exploited for the
+ * upcall request types.
+ * NOTE: Please retain them as multiples of 8 even if you wish to change them
+ * This is *NECESSARY* for supporting 32 bit user-space binaries on a 64-bit
+ * kernel. Due to implementation within DBPF, this really needs to be
+ * PVFS_NAME_MAX, which it was the same value as, but no reason to let it
+ * break if that changes in the future.
+ */
+#define PVFS_MAX_XATTR_NAMELEN   PVFS_NAME_MAX	/* Not the same as
+						 * XATTR_NAME_MAX defined
+						 * by <linux/xattr.h>
+						 */
+#define PVFS_MAX_XATTR_VALUELEN  8192	/* Not the same as XATTR_SIZE_MAX
+					 * defined by <linux/xattr.h>
+					 */
+#define PVFS_MAX_XATTR_LISTLEN   16	/* Not the same as XATTR_LIST_MAX
+					 * defined by <linux/xattr.h>
+					 */
+/*
+ * PVFS I/O operation types, used in both system and server interfaces.
+ */
+enum PVFS_io_type {
+	PVFS_IO_READ = 1,
+	PVFS_IO_WRITE = 2
+};
+
+/*
+ * If this enum is modified the server parameters related to the precreate pool
+ * batch and low threshold sizes may need to be modified  to reflect this
+ * change.
+ */
+enum pvfs2_ds_type {
+	PVFS_TYPE_NONE = 0,
+	PVFS_TYPE_METAFILE = (1 << 0),
+	PVFS_TYPE_DATAFILE = (1 << 1),
+	PVFS_TYPE_DIRECTORY = (1 << 2),
+	PVFS_TYPE_SYMLINK = (1 << 3),
+	PVFS_TYPE_DIRDATA = (1 << 4),
+	PVFS_TYPE_INTERNAL = (1 << 5)	/* for the server's private use */
+};
+
+/*
+ * PVFS_certificate simply stores a buffer with the buffer size.
+ * The buffer can be converted to an OpenSSL X509 struct for use.
+ */
+struct PVFS_certificate {
+	__u32 buf_size;
+	unsigned char *buf;
+};
+
+/*
+ * A credential identifies a user and is signed by the client/user
+ * private key.
+ */
+struct PVFS_credential {
+	__u32 userid;	/* user id */
+	__u32 num_groups;	/* length of group_array */
+	__u32 *group_array;	/* groups for which the user is a member */
+	char *issuer;		/* alias of the issuing server */
+	__u64 timeout;	/* seconds after epoch to time out */
+	__u32 sig_size;	/* length of the signature in bytes */
+	unsigned char *signature;	/* digital signature */
+	struct PVFS_certificate certificate;	/* user certificate buffer */
+};
+#define extra_size_PVFS_credential (PVFS_REQ_LIMIT_GROUPS	*	\
+				    sizeof(__u32)		+	\
+				    PVFS_REQ_LIMIT_ISSUER	+	\
+				    PVFS_REQ_LIMIT_SIGNATURE	+	\
+				    extra_size_PVFS_certificate)
+
+/* This structure is used by the VFS-client interaction alone */
+struct PVFS_keyval_pair {
+	char key[PVFS_MAX_XATTR_NAMELEN];
+	__s32 key_sz;	/* __s32 for portable, fixed-size structures */
+	__s32 val_sz;
+	char val[PVFS_MAX_XATTR_VALUELEN];
+};
+
+/* pvfs2-sysint.h ***********************************************************/
+/* Describes attributes for a file, directory, or symlink. */
+struct PVFS_sys_attr_s {
+	__u32 owner;
+	__u32 group;
+	__u32 perms;
+	__u64 atime;
+	__u64 mtime;
+	__u64 ctime;
+	__s64 size;
+
+	/* NOTE: caller must free if valid */
+	char *link_target;
+
+	/* Changed to __s32 so that size of structure does not change */
+	__s32 dfile_count;
+
+	/* Changed to __s32 so that size of structure does not change */
+	__s32 distr_dir_servers_initial;
+
+	/* Changed to __s32 so that size of structure does not change */
+	__s32 distr_dir_servers_max;
+
+	/* Changed to __s32 so that size of structure does not change */
+	__s32 distr_dir_split_size;
+
+	__u32 mirror_copies_count;
+
+	/* NOTE: caller must free if valid */
+	char *dist_name;
+
+	/* NOTE: caller must free if valid */
+	char *dist_params;
+
+	__s64 dirent_count;
+	enum pvfs2_ds_type objtype;
+	__u64 flags;
+	__u32 mask;
+	__s64 blksize;
+};
+
+#define PVFS2_LOOKUP_LINK_NO_FOLLOW 0
+#define PVFS2_LOOKUP_LINK_FOLLOW    1
+
+/* pint-dev.h ***************************************************************/
+
+/* parameter structure used in PVFS_DEV_DEBUG ioctl command */
+struct dev_mask_info_s {
+	enum {
+		KERNEL_MASK,
+		CLIENT_MASK,
+	} mask_type;
+	__u64 mask_value;
+};
+
+struct dev_mask2_info_s {
+	__u64 mask1_value;
+	__u64 mask2_value;
+};
+
+/* pvfs2-util.h *************************************************************/
+#define PVFS_util_min(x1, x2) (((x1) > (x2)) ? (x2) : (x1))
+__s32 PVFS_util_translate_mode(int mode);
+
+/* pvfs2-debug.h ************************************************************/
+#include "pvfs2-debug.h"
+
+/* pvfs2-internal.h *********************************************************/
+#define llu(x) (unsigned long long)(x)
+#define lld(x) (long long)(x)
+
+/* pint-dev-shared.h ********************************************************/
+#define PVFS_DEV_MAGIC 'k'
+
+#define PVFS2_READDIR_DEFAULT_DESC_COUNT  5
+
+#define DEV_GET_MAGIC           0x1
+#define DEV_GET_MAX_UPSIZE      0x2
+#define DEV_GET_MAX_DOWNSIZE    0x3
+#define DEV_MAP                 0x4
+#define DEV_REMOUNT_ALL         0x5
+#define DEV_DEBUG               0x6
+#define DEV_UPSTREAM            0x7
+#define DEV_CLIENT_MASK         0x8
+#define DEV_CLIENT_STRING       0x9
+#define DEV_MAX_NR              0xa
+
+/* supported ioctls, codes are with respect to user-space */
+enum {
+	PVFS_DEV_GET_MAGIC = _IOW(PVFS_DEV_MAGIC, DEV_GET_MAGIC, __s32),
+	PVFS_DEV_GET_MAX_UPSIZE =
+	    _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_UPSIZE, __s32),
+	PVFS_DEV_GET_MAX_DOWNSIZE =
+	    _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_DOWNSIZE, __s32),
+	PVFS_DEV_MAP = _IO(PVFS_DEV_MAGIC, DEV_MAP),
+	PVFS_DEV_REMOUNT_ALL = _IO(PVFS_DEV_MAGIC, DEV_REMOUNT_ALL),
+	PVFS_DEV_DEBUG = _IOR(PVFS_DEV_MAGIC, DEV_DEBUG, __s32),
+	PVFS_DEV_UPSTREAM = _IOW(PVFS_DEV_MAGIC, DEV_UPSTREAM, int),
+	PVFS_DEV_CLIENT_MASK = _IOW(PVFS_DEV_MAGIC,
+				    DEV_CLIENT_MASK,
+				    struct dev_mask2_info_s),
+	PVFS_DEV_CLIENT_STRING = _IOW(PVFS_DEV_MAGIC,
+				      DEV_CLIENT_STRING,
+				      char *),
+	PVFS_DEV_MAXNR = DEV_MAX_NR,
+};
+
+/*
+ * version number for use in communicating between kernel space and user
+ * space
+ */
+/*
+#define PVFS_KERNEL_PROTO_VERSION			\
+		((PVFS2_VERSION_MAJOR * 10000)	+	\
+		 (PVFS2_VERSION_MINOR * 100)	+	\
+		 PVFS2_VERSION_SUB)
+*/
+#define PVFS_KERNEL_PROTO_VERSION 0
+
+/*
+ * describes memory regions to map in the PVFS_DEV_MAP ioctl.
+ * NOTE: See devpvfs2-req.c for 32 bit compat structure.
+ * Since this structure has a variable-sized layout that is different
+ * on 32 and 64 bit platforms, we need to normalize to a 64 bit layout
+ * on such systems before servicing ioctl calls from user-space binaries
+ * that may be 32 bit!
+ */
+struct PVFS_dev_map_desc {
+	void *ptr;
+	__s32 total_size;
+	__s32 size;
+	__s32 count;
+};
+
+/* gossip.h *****************************************************************/
+
+#ifdef GOSSIP_DISABLE_DEBUG
+#define gossip_debug(mask, format, f...) do {} while (0)
+#else
+extern __u64 gossip_debug_mask;
+extern struct client_debug_mask client_debug_mask;
+
+/* try to avoid function call overhead by checking masks in macro */
+#define gossip_debug(mask, format, f...)			\
+do {								\
+	if (gossip_debug_mask & mask)				\
+		printk(format, ##f);				\
+} while (0)
+#endif /* GOSSIP_DISABLE_DEBUG */
+
+/* do file and line number printouts w/ the GNU preprocessor */
+#define gossip_ldebug(mask, format, f...)				\
+		gossip_debug(mask, "%s: " format, __func__, ##f)
+
+#define gossip_err printk
+#define gossip_lerr(format, f...)					\
+		gossip_err("%s line %d: " format,			\
+			   __FILE__,					\
+			   __LINE__,					\
+			   ##f)
diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c
new file mode 100644
index 000000000000..a439163f8d7c
--- /dev/null
+++ b/fs/orangefs/pvfs2-bufmap.c
@@ -0,0 +1,974 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+DECLARE_WAIT_QUEUE_HEAD(pvfs2_bufmap_init_waitq);
+
+static struct pvfs2_bufmap {
+	atomic_t refcnt;
+
+	int desc_size;
+	int desc_shift;
+	int desc_count;
+	int total_size;
+	int page_count;
+
+	struct page **page_array;
+	struct pvfs_bufmap_desc *desc_array;
+
+	/* array to track usage of buffer descriptors */
+	int *buffer_index_array;
+	spinlock_t buffer_index_lock;
+
+	/* array to track usage of buffer descriptors for readdir */
+	int readdir_index_array[PVFS2_READDIR_DEFAULT_DESC_COUNT];
+	spinlock_t readdir_index_lock;
+} *__pvfs2_bufmap;
+
+static DEFINE_SPINLOCK(pvfs2_bufmap_lock);
+
+static void
+pvfs2_bufmap_unmap(struct pvfs2_bufmap *bufmap)
+{
+	int i;
+
+	for (i = 0; i < bufmap->page_count; i++)
+		page_cache_release(bufmap->page_array[i]);
+}
+
+static void
+pvfs2_bufmap_free(struct pvfs2_bufmap *bufmap)
+{
+	kfree(bufmap->page_array);
+	kfree(bufmap->desc_array);
+	kfree(bufmap->buffer_index_array);
+	kfree(bufmap);
+}
+
+struct pvfs2_bufmap *pvfs2_bufmap_ref(void)
+{
+	struct pvfs2_bufmap *bufmap = NULL;
+
+	spin_lock(&pvfs2_bufmap_lock);
+	if (__pvfs2_bufmap) {
+		bufmap = __pvfs2_bufmap;
+		atomic_inc(&bufmap->refcnt);
+	}
+	spin_unlock(&pvfs2_bufmap_lock);
+	return bufmap;
+}
+
+void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap)
+{
+	if (atomic_dec_and_lock(&bufmap->refcnt, &pvfs2_bufmap_lock)) {
+		__pvfs2_bufmap = NULL;
+		spin_unlock(&pvfs2_bufmap_lock);
+
+		pvfs2_bufmap_unmap(bufmap);
+		pvfs2_bufmap_free(bufmap);
+	}
+}
+
+inline int pvfs_bufmap_size_query(void)
+{
+	struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref();
+	int size = bufmap ? bufmap->desc_size : 0;
+
+	pvfs2_bufmap_unref(bufmap);
+	return size;
+}
+
+inline int pvfs_bufmap_shift_query(void)
+{
+	struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref();
+	int shift = bufmap ? bufmap->desc_shift : 0;
+
+	pvfs2_bufmap_unref(bufmap);
+	return shift;
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(bufmap_waitq);
+static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq);
+
+/*
+ * get_bufmap_init
+ *
+ * If bufmap_init is 1, then the shared memory system, including the
+ * buffer_index_array, is available.  Otherwise, it is not.
+ *
+ * returns the value of bufmap_init
+ */
+int get_bufmap_init(void)
+{
+	return __pvfs2_bufmap ? 1 : 0;
+}
+
+
+static struct pvfs2_bufmap *
+pvfs2_bufmap_alloc(struct PVFS_dev_map_desc *user_desc)
+{
+	struct pvfs2_bufmap *bufmap;
+
+	bufmap = kzalloc(sizeof(*bufmap), GFP_KERNEL);
+	if (!bufmap)
+		goto out;
+
+	atomic_set(&bufmap->refcnt, 1);
+	bufmap->total_size = user_desc->total_size;
+	bufmap->desc_count = user_desc->count;
+	bufmap->desc_size = user_desc->size;
+	bufmap->desc_shift = ilog2(bufmap->desc_size);
+
+	spin_lock_init(&bufmap->buffer_index_lock);
+	bufmap->buffer_index_array =
+		kcalloc(bufmap->desc_count, sizeof(int), GFP_KERNEL);
+	if (!bufmap->buffer_index_array) {
+		gossip_err("pvfs2: could not allocate %d buffer indices\n",
+				bufmap->desc_count);
+		goto out_free_bufmap;
+	}
+	spin_lock_init(&bufmap->readdir_index_lock);
+
+	bufmap->desc_array =
+		kcalloc(bufmap->desc_count, sizeof(struct pvfs_bufmap_desc),
+			GFP_KERNEL);
+	if (!bufmap->desc_array) {
+		gossip_err("pvfs2: could not allocate %d descriptors\n",
+				bufmap->desc_count);
+		goto out_free_index_array;
+	}
+
+	bufmap->page_count = bufmap->total_size / PAGE_SIZE;
+
+	/* allocate storage to track our page mappings */
+	bufmap->page_array =
+		kcalloc(bufmap->page_count, sizeof(struct page *), GFP_KERNEL);
+	if (!bufmap->page_array)
+		goto out_free_desc_array;
+
+	return bufmap;
+
+out_free_desc_array:
+	kfree(bufmap->desc_array);
+out_free_index_array:
+	kfree(bufmap->buffer_index_array);
+out_free_bufmap:
+	kfree(bufmap);
+out:
+	return NULL;
+}
+
+static int
+pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap,
+		struct PVFS_dev_map_desc *user_desc)
+{
+	int pages_per_desc = bufmap->desc_size / PAGE_SIZE;
+	int offset = 0, ret, i;
+
+	/* map the pages */
+	down_write(&current->mm->mmap_sem);
+	ret = get_user_pages(current,
+			     current->mm,
+			     (unsigned long)user_desc->ptr,
+			     bufmap->page_count,
+			     1,
+			     0,
+			     bufmap->page_array,
+			     NULL);
+	up_write(&current->mm->mmap_sem);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret != bufmap->page_count) {
+		gossip_err("pvfs2 error: asked for %d pages, only got %d.\n",
+				bufmap->page_count, ret);
+
+		for (i = 0; i < ret; i++) {
+			SetPageError(bufmap->page_array[i]);
+			page_cache_release(bufmap->page_array[i]);
+		}
+		return -ENOMEM;
+	}
+
+	/*
+	 * ideally we want to get kernel space pointers for each page, but
+	 * we can't kmap that many pages at once if highmem is being used.
+	 * so instead, we just kmap/kunmap the page address each time the
+	 * kaddr is needed.
+	 */
+	for (i = 0; i < bufmap->page_count; i++)
+		flush_dcache_page(bufmap->page_array[i]);
+
+	/* build a list of available descriptors */
+	for (offset = 0, i = 0; i < bufmap->desc_count; i++) {
+		bufmap->desc_array[i].page_array = &bufmap->page_array[offset];
+		bufmap->desc_array[i].array_count = pages_per_desc;
+		bufmap->desc_array[i].uaddr =
+		    (user_desc->ptr + (i * pages_per_desc * PAGE_SIZE));
+		offset += pages_per_desc;
+	}
+
+	return 0;
+}
+
+/*
+ * pvfs_bufmap_initialize()
+ *
+ * initializes the mapped buffer interface
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc)
+{
+	struct pvfs2_bufmap *bufmap;
+	int ret = -EINVAL;
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_initialize: called (ptr ("
+		     "%p) sz (%d) cnt(%d).\n",
+		     user_desc->ptr,
+		     user_desc->size,
+		     user_desc->count);
+
+	/*
+	 * sanity check alignment and size of buffer that caller wants to
+	 * work with
+	 */
+	if (PAGE_ALIGN((unsigned long)user_desc->ptr) !=
+	    (unsigned long)user_desc->ptr) {
+		gossip_err("pvfs2 error: memory alignment (front). %p\n",
+			   user_desc->ptr);
+		goto out;
+	}
+
+	if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->total_size))
+	    != (unsigned long)(user_desc->ptr + user_desc->total_size)) {
+		gossip_err("pvfs2 error: memory alignment (back).(%p + %d)\n",
+			   user_desc->ptr,
+			   user_desc->total_size);
+		goto out;
+	}
+
+	if (user_desc->total_size != (user_desc->size * user_desc->count)) {
+		gossip_err("pvfs2 error: user provided an oddly sized buffer: (%d, %d, %d)\n",
+			   user_desc->total_size,
+			   user_desc->size,
+			   user_desc->count);
+		goto out;
+	}
+
+	if ((user_desc->size % PAGE_SIZE) != 0) {
+		gossip_err("pvfs2 error: bufmap size not page size divisible (%d).\n",
+			   user_desc->size);
+		goto out;
+	}
+
+	ret = -ENOMEM;
+	bufmap = pvfs2_bufmap_alloc(user_desc);
+	if (!bufmap)
+		goto out;
+
+	ret = pvfs2_bufmap_map(bufmap, user_desc);
+	if (ret)
+		goto out_free_bufmap;
+
+
+	spin_lock(&pvfs2_bufmap_lock);
+	if (__pvfs2_bufmap) {
+		spin_unlock(&pvfs2_bufmap_lock);
+		gossip_err("pvfs2: error: bufmap already initialized.\n");
+		ret = -EALREADY;
+		goto out_unmap_bufmap;
+	}
+	__pvfs2_bufmap = bufmap;
+	spin_unlock(&pvfs2_bufmap_lock);
+
+	/*
+	 * If there are operations in pvfs2_bufmap_init_waitq, wake them up.
+	 * This scenario occurs when the client-core is restarted and I/O
+	 * requests in the in-progress or waiting tables are restarted.  I/O
+	 * requests cannot be restarted until the shared memory system is
+	 * completely re-initialized, so we put the I/O requests in this
+	 * waitq until initialization has completed.  NOTE:  the I/O requests
+	 * are also on a timer, so they don't wait forever just in case the
+	 * client-core doesn't come back up.
+	 */
+	wake_up_interruptible(&pvfs2_bufmap_init_waitq);
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_initialize: exiting normally\n");
+	return 0;
+
+out_unmap_bufmap:
+	pvfs2_bufmap_unmap(bufmap);
+out_free_bufmap:
+	pvfs2_bufmap_free(bufmap);
+out:
+	return ret;
+}
+
+/*
+ * pvfs_bufmap_finalize()
+ *
+ * shuts down the mapped buffer interface and releases any resources
+ * associated with it
+ *
+ * no return value
+ */
+void pvfs_bufmap_finalize(void)
+{
+	gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: called\n");
+	BUG_ON(!__pvfs2_bufmap);
+	pvfs2_bufmap_unref(__pvfs2_bufmap);
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs2_bufmap_finalize: exiting normally\n");
+}
+
+struct slot_args {
+	int slot_count;
+	int *slot_array;
+	spinlock_t *slot_lock;
+	wait_queue_head_t *slot_wq;
+};
+
+static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index)
+{
+	int ret = -1;
+	int i = 0;
+	DECLARE_WAITQUEUE(my_wait, current);
+
+
+	add_wait_queue_exclusive(slargs->slot_wq, &my_wait);
+
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		/*
+		 * check for available desc, slot_lock is the appropriate
+		 * index_lock
+		 */
+		spin_lock(slargs->slot_lock);
+		for (i = 0; i < slargs->slot_count; i++)
+			if (slargs->slot_array[i] == 0) {
+				slargs->slot_array[i] = 1;
+				*buffer_index = i;
+				ret = 0;
+				break;
+			}
+		spin_unlock(slargs->slot_lock);
+
+		/* if we acquired a buffer, then break out of while */
+		if (ret == 0)
+			break;
+
+		if (!signal_pending(current)) {
+			int timeout =
+			    MSECS_TO_JIFFIES(1000 * slot_timeout_secs);
+			gossip_debug(GOSSIP_BUFMAP_DEBUG,
+				     "[BUFMAP]: waiting %d "
+				     "seconds for a slot\n",
+				     slot_timeout_secs);
+			if (!schedule_timeout(timeout)) {
+				gossip_debug(GOSSIP_BUFMAP_DEBUG,
+					     "*** wait_for_a_slot timed out\n");
+				ret = -ETIMEDOUT;
+				break;
+			}
+			gossip_debug(GOSSIP_BUFMAP_DEBUG,
+			  "[BUFMAP]: woken up by a slot becoming available.\n");
+			continue;
+		}
+
+		gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2: %s interrupted.\n",
+			     __func__);
+		ret = -EINTR;
+		break;
+	}
+
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(slargs->slot_wq, &my_wait);
+	return ret;
+}
+
+static void put_back_slot(struct slot_args *slargs, int buffer_index)
+{
+	/* slot_lock is the appropriate index_lock */
+	spin_lock(slargs->slot_lock);
+	if (buffer_index < 0 || buffer_index >= slargs->slot_count) {
+		spin_unlock(slargs->slot_lock);
+		return;
+	}
+
+	/* put the desc back on the queue */
+	slargs->slot_array[buffer_index] = 0;
+	spin_unlock(slargs->slot_lock);
+
+	/* wake up anyone who may be sleeping on the queue */
+	wake_up_interruptible(slargs->slot_wq);
+}
+
+/*
+ * pvfs_bufmap_get()
+ *
+ * gets a free mapped buffer descriptor, will sleep until one becomes
+ * available if necessary
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index)
+{
+	struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref();
+	struct slot_args slargs;
+	int ret;
+
+	if (!bufmap) {
+		gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
+		return -EIO;
+	}
+
+	slargs.slot_count = bufmap->desc_count;
+	slargs.slot_array = bufmap->buffer_index_array;
+	slargs.slot_lock = &bufmap->buffer_index_lock;
+	slargs.slot_wq = &bufmap_waitq;
+	ret = wait_for_a_slot(&slargs, buffer_index);
+	if (ret)
+		pvfs2_bufmap_unref(bufmap);
+	*mapp = bufmap;
+	return ret;
+}
+
+/*
+ * pvfs_bufmap_put()
+ *
+ * returns a mapped buffer descriptor to the collection
+ *
+ * no return value
+ */
+void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index)
+{
+	struct slot_args slargs;
+
+	slargs.slot_count = bufmap->desc_count;
+	slargs.slot_array = bufmap->buffer_index_array;
+	slargs.slot_lock = &bufmap->buffer_index_lock;
+	slargs.slot_wq = &bufmap_waitq;
+	put_back_slot(&slargs, buffer_index);
+	pvfs2_bufmap_unref(bufmap);
+}
+
+/*
+ * readdir_index_get()
+ *
+ * gets a free descriptor, will sleep until one becomes
+ * available if necessary.
+ * Although the readdir buffers are not mapped into kernel space
+ * we could do that at a later point of time. Regardless, these
+ * indices are used by the client-core.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index)
+{
+	struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref();
+	struct slot_args slargs;
+	int ret;
+
+	if (!bufmap) {
+		gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
+		return -EIO;
+	}
+
+	slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
+	slargs.slot_array = bufmap->readdir_index_array;
+	slargs.slot_lock = &bufmap->readdir_index_lock;
+	slargs.slot_wq = &readdir_waitq;
+	ret = wait_for_a_slot(&slargs, buffer_index);
+	if (ret)
+		pvfs2_bufmap_unref(bufmap);
+	*mapp = bufmap;
+	return ret;
+}
+
+void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index)
+{
+	struct slot_args slargs;
+
+	slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
+	slargs.slot_array = bufmap->readdir_index_array;
+	slargs.slot_lock = &bufmap->readdir_index_lock;
+	slargs.slot_wq = &readdir_waitq;
+	put_back_slot(&slargs, buffer_index);
+	pvfs2_bufmap_unref(bufmap);
+}
+
+/*
+ * pvfs_bufmap_copy_iovec_from_user()
+ *
+ * copies data from several user space address's in an iovec
+ * to a mapped buffer
+ *
+ * Note that the mapped buffer is a series of pages and therefore
+ * the copies have to be split by PAGE_SIZE bytes at a time.
+ * Note that this routine checks that summation of iov_len
+ * across all the elements of iov is equal to size.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap,
+				     int buffer_index,
+				     const struct iovec *iov,
+				     unsigned long nr_segs,
+				     size_t size)
+{
+	size_t ret = 0;
+	size_t amt_copied = 0;
+	size_t cur_copy_size = 0;
+	unsigned int to_page_offset = 0;
+	unsigned int to_page_index = 0;
+	void *to_kaddr = NULL;
+	void __user *from_addr = NULL;
+	struct iovec *copied_iovec = NULL;
+	struct pvfs_bufmap_desc *to;
+	unsigned int seg;
+	char *tmp_printer = NULL;
+	int tmp_int = 0;
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_copy_iovec_from_user: index %d, "
+		     "size %zd\n",
+		     buffer_index,
+		     size);
+
+	to = &bufmap->desc_array[buffer_index];
+
+	/*
+	 * copy the passed in iovec so that we can change some of its fields
+	 */
+	copied_iovec = kmalloc_array(nr_segs,
+				     sizeof(*copied_iovec),
+				     PVFS2_BUFMAP_GFP_FLAGS);
+	if (copied_iovec == NULL)
+		return -ENOMEM;
+
+	memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
+	/*
+	 * Go through each segment in the iovec and make sure that
+	 * the summation of iov_len matches the given size.
+	 */
+	for (seg = 0, amt_copied = 0; seg < nr_segs; seg++)
+		amt_copied += copied_iovec[seg].iov_len;
+	if (amt_copied != size) {
+		gossip_err(
+		    "pvfs2_bufmap_copy_iovec_from_user: computed total ("
+		    "%zd) is not equal to (%zd)\n",
+		    amt_copied,
+		    size);
+		kfree(copied_iovec);
+		return -EINVAL;
+	}
+
+	to_page_index = 0;
+	to_page_offset = 0;
+	amt_copied = 0;
+	seg = 0;
+	/*
+	 * Go through each segment in the iovec and copy its
+	 * buffer into the mapped buffer one page at a time though
+	 */
+	while (amt_copied < size) {
+		struct iovec *iv = &copied_iovec[seg];
+		int inc_to_page_index;
+
+		if (iv->iov_len < (PAGE_SIZE - to_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			from_addr = iv->iov_base;
+			inc_to_page_index = 0;
+		} else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			from_addr = iv->iov_base;
+			inc_to_page_index = 1;
+		} else {
+			cur_copy_size =
+			    PVFS_util_min(PAGE_SIZE - to_page_offset,
+					  size - amt_copied);
+			from_addr = iv->iov_base;
+			iv->iov_base += cur_copy_size;
+			iv->iov_len -= cur_copy_size;
+			inc_to_page_index = 1;
+		}
+		to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
+		ret =
+		    copy_from_user(to_kaddr + to_page_offset,
+				   from_addr,
+				   cur_copy_size);
+		if (!PageReserved(to->page_array[to_page_index]))
+			SetPageDirty(to->page_array[to_page_index]);
+
+		if (!tmp_printer) {
+			tmp_printer = (char *)(to_kaddr + to_page_offset);
+			tmp_int += tmp_printer[0];
+			gossip_debug(GOSSIP_BUFMAP_DEBUG,
+				     "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n",
+				     tmp_int);
+		}
+
+		pvfs2_kunmap(to->page_array[to_page_index]);
+		if (ret) {
+			gossip_err("Failed to copy data from user space\n");
+			kfree(copied_iovec);
+			return -EFAULT;
+		}
+
+		amt_copied += cur_copy_size;
+		if (inc_to_page_index) {
+			to_page_offset = 0;
+			to_page_index++;
+		} else {
+			to_page_offset += cur_copy_size;
+		}
+	}
+	kfree(copied_iovec);
+	return 0;
+}
+
+/*
+ * pvfs_bufmap_copy_iovec_from_kernel()
+ *
+ * copies data from several kernel space address's in an iovec
+ * to a mapped buffer
+ *
+ * Note that the mapped buffer is a series of pages and therefore
+ * the copies have to be split by PAGE_SIZE bytes at a time.
+ * Note that this routine checks that summation of iov_len
+ * across all the elements of iov is equal to size.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap,
+		int buffer_index, const struct iovec *iov,
+		unsigned long nr_segs, size_t size)
+{
+	size_t amt_copied = 0;
+	size_t cur_copy_size = 0;
+	int to_page_index = 0;
+	void *to_kaddr = NULL;
+	void *from_kaddr = NULL;
+	struct kvec *iv = NULL;
+	struct iovec *copied_iovec = NULL;
+	struct pvfs_bufmap_desc *to;
+	unsigned int seg;
+	unsigned to_page_offset = 0;
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_copy_iovec_from_kernel: index %d, "
+		     "size %zd\n",
+		     buffer_index,
+		     size);
+
+	to = &bufmap->desc_array[buffer_index];
+	/*
+	 * copy the passed in iovec so that we can change some of its fields
+	 */
+	copied_iovec = kmalloc_array(nr_segs,
+				     sizeof(*copied_iovec),
+				     PVFS2_BUFMAP_GFP_FLAGS);
+	if (copied_iovec == NULL)
+		return -ENOMEM;
+
+	memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
+	/*
+	 * Go through each segment in the iovec and make sure that
+	 * the summation of iov_len matches the given size.
+	 */
+	for (seg = 0, amt_copied = 0; seg < nr_segs; seg++)
+		amt_copied += copied_iovec[seg].iov_len;
+	if (amt_copied != size) {
+		gossip_err("pvfs2_bufmap_copy_iovec_from_kernel: computed total(%zd) is not equal to (%zd)\n",
+			   amt_copied,
+			   size);
+		kfree(copied_iovec);
+		return -EINVAL;
+	}
+
+	to_page_index = 0;
+	amt_copied = 0;
+	seg = 0;
+	to_page_offset = 0;
+	/*
+	 * Go through each segment in the iovec and copy its
+	 * buffer into the mapped buffer one page at a time though
+	 */
+	while (amt_copied < size) {
+		int inc_to_page_index;
+
+		iv = (struct kvec *) &copied_iovec[seg];
+
+		if (iv->iov_len < (PAGE_SIZE - to_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			from_kaddr = iv->iov_base;
+			inc_to_page_index = 0;
+		} else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			from_kaddr = iv->iov_base;
+			inc_to_page_index = 1;
+		} else {
+			cur_copy_size =
+			    PVFS_util_min(PAGE_SIZE - to_page_offset,
+					  size - amt_copied);
+			from_kaddr = iv->iov_base;
+			iv->iov_base += cur_copy_size;
+			iv->iov_len -= cur_copy_size;
+			inc_to_page_index = 1;
+		}
+		to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
+		memcpy(to_kaddr + to_page_offset, from_kaddr, cur_copy_size);
+		if (!PageReserved(to->page_array[to_page_index]))
+			SetPageDirty(to->page_array[to_page_index]);
+		pvfs2_kunmap(to->page_array[to_page_index]);
+		amt_copied += cur_copy_size;
+		if (inc_to_page_index) {
+			to_page_offset = 0;
+			to_page_index++;
+		} else {
+			to_page_offset += cur_copy_size;
+		}
+	}
+	kfree(copied_iovec);
+	return 0;
+}
+
+/*
+ * pvfs_bufmap_copy_to_user_iovec()
+ *
+ * copies data to several user space address's in an iovec
+ * from a mapped buffer
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap,
+		int buffer_index, const struct iovec *iov,
+		unsigned long nr_segs, size_t size)
+{
+	size_t ret = 0;
+	size_t amt_copied = 0;
+	size_t cur_copy_size = 0;
+	int from_page_index = 0;
+	void *from_kaddr = NULL;
+	void __user *to_addr = NULL;
+	struct iovec *copied_iovec = NULL;
+	struct pvfs_bufmap_desc *from;
+	unsigned int seg;
+	unsigned from_page_offset = 0;
+	char *tmp_printer = NULL;
+	int tmp_int = 0;
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_copy_to_user_iovec: index %d, size %zd\n",
+		     buffer_index,
+		     size);
+
+	from = &bufmap->desc_array[buffer_index];
+	/*
+	 * copy the passed in iovec so that we can change some of its fields
+	 */
+	copied_iovec = kmalloc_array(nr_segs,
+				     sizeof(*copied_iovec),
+				     PVFS2_BUFMAP_GFP_FLAGS);
+	if (copied_iovec == NULL)
+		return -ENOMEM;
+
+	memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
+	/*
+	 * Go through each segment in the iovec and make sure that
+	 * the summation of iov_len is greater than the given size.
+	 */
+	for (seg = 0, amt_copied = 0; seg < nr_segs; seg++)
+		amt_copied += copied_iovec[seg].iov_len;
+	if (amt_copied < size) {
+		gossip_err("pvfs2_bufmap_copy_to_user_iovec: computed total (%zd) is less than (%zd)\n",
+			   amt_copied,
+			   size);
+		kfree(copied_iovec);
+		return -EINVAL;
+	}
+
+	from_page_index = 0;
+	amt_copied = 0;
+	seg = 0;
+	from_page_offset = 0;
+	/*
+	 * Go through each segment in the iovec and copy from the mapper buffer,
+	 * but make sure that we do so one page at a time.
+	 */
+	while (amt_copied < size) {
+		struct iovec *iv = &copied_iovec[seg];
+		int inc_from_page_index;
+
+		if (iv->iov_len < (PAGE_SIZE - from_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			to_addr = iv->iov_base;
+			inc_from_page_index = 0;
+		} else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			to_addr = iv->iov_base;
+			inc_from_page_index = 1;
+		} else {
+			cur_copy_size =
+			    PVFS_util_min(PAGE_SIZE - from_page_offset,
+					  size - amt_copied);
+			to_addr = iv->iov_base;
+			iv->iov_base += cur_copy_size;
+			iv->iov_len -= cur_copy_size;
+			inc_from_page_index = 1;
+		}
+		from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+		if (!tmp_printer) {
+			tmp_printer = (char *)(from_kaddr + from_page_offset);
+			tmp_int += tmp_printer[0];
+			gossip_debug(GOSSIP_BUFMAP_DEBUG,
+				     "First character (integer value) in pvfs_bufmap_copy_to_user_iovec: %d\n",
+				     tmp_int);
+		}
+		ret =
+		    copy_to_user(to_addr,
+				 from_kaddr + from_page_offset,
+				 cur_copy_size);
+		pvfs2_kunmap(from->page_array[from_page_index]);
+		if (ret) {
+			gossip_err("Failed to copy data to user space\n");
+			kfree(copied_iovec);
+			return -EFAULT;
+		}
+
+		amt_copied += cur_copy_size;
+		if (inc_from_page_index) {
+			from_page_offset = 0;
+			from_page_index++;
+		} else {
+			from_page_offset += cur_copy_size;
+		}
+	}
+	kfree(copied_iovec);
+	return 0;
+}
+
+/*
+ * pvfs_bufmap_copy_to_kernel_iovec()
+ *
+ * copies data to several kernel space address's in an iovec
+ * from a mapped buffer
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap,
+		int buffer_index, const struct iovec *iov,
+		unsigned long nr_segs, size_t size)
+{
+	size_t amt_copied = 0;
+	size_t cur_copy_size = 0;
+	int from_page_index = 0;
+	void *from_kaddr = NULL;
+	void *to_kaddr = NULL;
+	struct kvec *iv;
+	struct iovec *copied_iovec = NULL;
+	struct pvfs_bufmap_desc *from;
+	unsigned int seg;
+	unsigned int from_page_offset = 0;
+
+	gossip_debug(GOSSIP_BUFMAP_DEBUG,
+		     "pvfs_bufmap_copy_to_kernel_iovec: index %d, size %zd\n",
+		      buffer_index,
+		      size);
+
+	from = &bufmap->desc_array[buffer_index];
+	/*
+	 * copy the passed in iovec so that we can change some of its fields
+	 */
+	copied_iovec = kmalloc_array(nr_segs,
+				     sizeof(*copied_iovec),
+				     PVFS2_BUFMAP_GFP_FLAGS);
+	if (copied_iovec == NULL)
+		return -ENOMEM;
+
+	memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
+	/*
+	 * Go through each segment in the iovec and make sure that
+	 * the summation of iov_len is greater than the given size.
+	 */
+	for (seg = 0, amt_copied = 0; seg < nr_segs; seg++)
+		amt_copied += copied_iovec[seg].iov_len;
+
+	if (amt_copied < size) {
+		gossip_err("pvfs2_bufmap_copy_to_kernel_iovec: computed total (%zd) is less than (%zd)\n",
+		     amt_copied,
+		     size);
+		kfree(copied_iovec);
+		return -EINVAL;
+	}
+
+	from_page_index = 0;
+	amt_copied = 0;
+	seg = 0;
+	from_page_offset = 0;
+	/*
+	 * Go through each segment in the iovec and copy from the mapper buffer,
+	 * but make sure that we do so one page at a time.
+	 */
+	while (amt_copied < size) {
+		int inc_from_page_index;
+
+		iv = (struct kvec *) &copied_iovec[seg];
+
+		if (iv->iov_len < (PAGE_SIZE - from_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			to_kaddr = iv->iov_base;
+			inc_from_page_index = 0;
+		} else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) {
+			cur_copy_size =
+			    PVFS_util_min(iv->iov_len, size - amt_copied);
+			seg++;
+			to_kaddr = iv->iov_base;
+			inc_from_page_index = 1;
+		} else {
+			cur_copy_size =
+			    PVFS_util_min(PAGE_SIZE - from_page_offset,
+					  size - amt_copied);
+			to_kaddr = iv->iov_base;
+			iv->iov_base += cur_copy_size;
+			iv->iov_len -= cur_copy_size;
+			inc_from_page_index = 1;
+		}
+		from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+		memcpy(to_kaddr, from_kaddr + from_page_offset, cur_copy_size);
+		pvfs2_kunmap(from->page_array[from_page_index]);
+		amt_copied += cur_copy_size;
+		if (inc_from_page_index) {
+			from_page_offset = 0;
+			from_page_index++;
+		} else {
+			from_page_offset += cur_copy_size;
+		}
+	}
+	kfree(copied_iovec);
+	return 0;
+}
diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/pvfs2-bufmap.h
new file mode 100644
index 000000000000..e269deafbb74
--- /dev/null
+++ b/fs/orangefs/pvfs2-bufmap.h
@@ -0,0 +1,76 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#ifndef __PVFS2_BUFMAP_H
+#define __PVFS2_BUFMAP_H
+
+/* used to describe mapped buffers */
+struct pvfs_bufmap_desc {
+	void *uaddr;			/* user space address pointer */
+	struct page **page_array;	/* array of mapped pages */
+	int array_count;		/* size of above arrays */
+	struct list_head list_link;
+};
+
+struct pvfs2_bufmap;
+
+struct pvfs2_bufmap *pvfs2_bufmap_ref(void);
+void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap);
+
+/*
+ * pvfs_bufmap_size_query is now an inline function because buffer
+ * sizes are not hardcoded
+ */
+int pvfs_bufmap_size_query(void);
+
+int pvfs_bufmap_shift_query(void);
+
+int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc);
+
+int get_bufmap_init(void);
+
+void pvfs_bufmap_finalize(void);
+
+int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index);
+
+void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index);
+
+int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index);
+
+void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index);
+
+int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap,
+				     int buffer_index,
+				     const struct iovec *iov,
+				     unsigned long nr_segs,
+				     size_t size);
+
+int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap,
+				       int buffer_index,
+				       const struct iovec *iov,
+				       unsigned long nr_segs,
+				       size_t size);
+
+int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap,
+				   int buffer_index,
+				   const struct iovec *iov,
+				   unsigned long nr_segs,
+				   size_t size);
+
+int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap,
+				     int buffer_index,
+				     const struct iovec *iov,
+				     unsigned long nr_segs,
+				     size_t size);
+
+size_t pvfs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk,
+					   struct iovec *iovec,
+					   unsigned long nr_segs,
+					   struct pvfs2_bufmap *bufmap,
+					   int buffer_index,
+					   size_t bytes_to_be_copied);
+
+#endif /* __PVFS2_BUFMAP_H */
diff --git a/fs/orangefs/pvfs2-cache.c b/fs/orangefs/pvfs2-cache.c
new file mode 100644
index 000000000000..15251884ba4a
--- /dev/null
+++ b/fs/orangefs/pvfs2-cache.c
@@ -0,0 +1,260 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+
+/* tags assigned to kernel upcall operations */
+static __u64 next_tag_value;
+static DEFINE_SPINLOCK(next_tag_value_lock);
+
+/* the pvfs2 memory caches */
+
+/* a cache for pvfs2 upcall/downcall operations */
+static struct kmem_cache *op_cache;
+
+/* a cache for device (/dev/pvfs2-req) communication */
+static struct kmem_cache *dev_req_cache;
+
+/* a cache for pvfs2_kiocb objects (i.e pvfs2 iocb structures ) */
+static struct kmem_cache *pvfs2_kiocb_cache;
+
+int op_cache_initialize(void)
+{
+	op_cache = kmem_cache_create("pvfs2_op_cache",
+				     sizeof(struct pvfs2_kernel_op_s),
+				     0,
+				     PVFS2_CACHE_CREATE_FLAGS,
+				     NULL);
+
+	if (!op_cache) {
+		gossip_err("Cannot create pvfs2_op_cache\n");
+		return -ENOMEM;
+	}
+
+	/* initialize our atomic tag counter */
+	spin_lock(&next_tag_value_lock);
+	next_tag_value = 100;
+	spin_unlock(&next_tag_value_lock);
+	return 0;
+}
+
+int op_cache_finalize(void)
+{
+	kmem_cache_destroy(op_cache);
+	return 0;
+}
+
+char *get_opname_string(struct pvfs2_kernel_op_s *new_op)
+{
+	if (new_op) {
+		__s32 type = new_op->upcall.type;
+
+		if (type == PVFS2_VFS_OP_FILE_IO)
+			return "OP_FILE_IO";
+		else if (type == PVFS2_VFS_OP_LOOKUP)
+			return "OP_LOOKUP";
+		else if (type == PVFS2_VFS_OP_CREATE)
+			return "OP_CREATE";
+		else if (type == PVFS2_VFS_OP_GETATTR)
+			return "OP_GETATTR";
+		else if (type == PVFS2_VFS_OP_REMOVE)
+			return "OP_REMOVE";
+		else if (type == PVFS2_VFS_OP_MKDIR)
+			return "OP_MKDIR";
+		else if (type == PVFS2_VFS_OP_READDIR)
+			return "OP_READDIR";
+		else if (type == PVFS2_VFS_OP_READDIRPLUS)
+			return "OP_READDIRPLUS";
+		else if (type == PVFS2_VFS_OP_SETATTR)
+			return "OP_SETATTR";
+		else if (type == PVFS2_VFS_OP_SYMLINK)
+			return "OP_SYMLINK";
+		else if (type == PVFS2_VFS_OP_RENAME)
+			return "OP_RENAME";
+		else if (type == PVFS2_VFS_OP_STATFS)
+			return "OP_STATFS";
+		else if (type == PVFS2_VFS_OP_TRUNCATE)
+			return "OP_TRUNCATE";
+		else if (type == PVFS2_VFS_OP_MMAP_RA_FLUSH)
+			return "OP_MMAP_RA_FLUSH";
+		else if (type == PVFS2_VFS_OP_FS_MOUNT)
+			return "OP_FS_MOUNT";
+		else if (type == PVFS2_VFS_OP_FS_UMOUNT)
+			return "OP_FS_UMOUNT";
+		else if (type == PVFS2_VFS_OP_GETXATTR)
+			return "OP_GETXATTR";
+		else if (type == PVFS2_VFS_OP_SETXATTR)
+			return "OP_SETXATTR";
+		else if (type == PVFS2_VFS_OP_LISTXATTR)
+			return "OP_LISTXATTR";
+		else if (type == PVFS2_VFS_OP_REMOVEXATTR)
+			return "OP_REMOVEXATTR";
+		else if (type == PVFS2_VFS_OP_PARAM)
+			return "OP_PARAM";
+		else if (type == PVFS2_VFS_OP_PERF_COUNT)
+			return "OP_PERF_COUNT";
+		else if (type == PVFS2_VFS_OP_CANCEL)
+			return "OP_CANCEL";
+		else if (type == PVFS2_VFS_OP_FSYNC)
+			return "OP_FSYNC";
+		else if (type == PVFS2_VFS_OP_FSKEY)
+			return "OP_FSKEY";
+		else if (type == PVFS2_VFS_OP_FILE_IOX)
+			return "OP_FILE_IOX";
+	}
+	return "OP_UNKNOWN?";
+}
+
+static struct pvfs2_kernel_op_s *op_alloc_common(__s32 op_linger, __s32 type)
+{
+	struct pvfs2_kernel_op_s *new_op = NULL;
+
+	new_op = kmem_cache_alloc(op_cache, PVFS2_CACHE_ALLOC_FLAGS);
+	if (new_op) {
+		memset(new_op, 0, sizeof(struct pvfs2_kernel_op_s));
+
+		INIT_LIST_HEAD(&new_op->list);
+		spin_lock_init(&new_op->lock);
+		init_waitqueue_head(&new_op->waitq);
+
+		init_waitqueue_head(&new_op->io_completion_waitq);
+		atomic_set(&new_op->aio_ref_count, 0);
+
+		pvfs2_op_initialize(new_op);
+
+		/* initialize the op specific tag and upcall credentials */
+		spin_lock(&next_tag_value_lock);
+		new_op->tag = next_tag_value++;
+		if (next_tag_value == 0)
+			next_tag_value = 100;
+		spin_unlock(&next_tag_value_lock);
+		new_op->upcall.type = type;
+		new_op->attempts = 0;
+		gossip_debug(GOSSIP_CACHE_DEBUG,
+			     "Alloced OP (%p: %llu %s)\n",
+			     new_op,
+			     llu(new_op->tag),
+			     get_opname_string(new_op));
+
+		new_op->upcall.uid = from_kuid(current_user_ns(),
+					       current_fsuid());
+
+		new_op->upcall.gid = from_kgid(current_user_ns(),
+					       current_fsgid());
+
+		new_op->op_linger = new_op->op_linger_tmp = op_linger;
+	} else {
+		gossip_err("op_alloc: kmem_cache_alloc failed!\n");
+	}
+	return new_op;
+}
+
+struct pvfs2_kernel_op_s *op_alloc(__s32 type)
+{
+	return op_alloc_common(1, type);
+}
+
+struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type)
+{
+	return op_alloc_common(2, type);
+}
+
+void op_release(struct pvfs2_kernel_op_s *pvfs2_op)
+{
+	if (pvfs2_op) {
+		gossip_debug(GOSSIP_CACHE_DEBUG,
+			     "Releasing OP (%p: %llu)\n",
+			     pvfs2_op,
+			     llu(pvfs2_op->tag));
+		pvfs2_op_initialize(pvfs2_op);
+		kmem_cache_free(op_cache, pvfs2_op);
+	} else {
+		gossip_err("NULL pointer in op_release\n");
+	}
+}
+
+int dev_req_cache_initialize(void)
+{
+	dev_req_cache = kmem_cache_create("pvfs2_devreqcache",
+					  MAX_ALIGNED_DEV_REQ_DOWNSIZE,
+					  0,
+					  PVFS2_CACHE_CREATE_FLAGS,
+					  NULL);
+
+	if (!dev_req_cache) {
+		gossip_err("Cannot create pvfs2_dev_req_cache\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+int dev_req_cache_finalize(void)
+{
+	kmem_cache_destroy(dev_req_cache);
+	return 0;
+}
+
+void *dev_req_alloc(void)
+{
+	void *buffer;
+
+	buffer = kmem_cache_alloc(dev_req_cache, PVFS2_CACHE_ALLOC_FLAGS);
+	if (buffer == NULL)
+		gossip_err("Failed to allocate from dev_req_cache\n");
+	else
+		memset(buffer, 0, sizeof(MAX_ALIGNED_DEV_REQ_DOWNSIZE));
+	return buffer;
+}
+
+void dev_req_release(void *buffer)
+{
+	if (buffer)
+		kmem_cache_free(dev_req_cache, buffer);
+	else
+		gossip_err("NULL pointer passed to dev_req_release\n");
+}
+
+int kiocb_cache_initialize(void)
+{
+	pvfs2_kiocb_cache = kmem_cache_create("pvfs2_kiocbcache",
+					      sizeof(struct pvfs2_kiocb_s),
+					      0,
+					      PVFS2_CACHE_CREATE_FLAGS,
+					      NULL);
+
+	if (!pvfs2_kiocb_cache) {
+		gossip_err("Cannot create pvfs2_kiocb_cache!\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+int kiocb_cache_finalize(void)
+{
+	kmem_cache_destroy(pvfs2_kiocb_cache);
+	return 0;
+}
+
+struct pvfs2_kiocb_s *kiocb_alloc(void)
+{
+	struct pvfs2_kiocb_s *x = NULL;
+
+	x = kmem_cache_alloc(pvfs2_kiocb_cache, PVFS2_CACHE_ALLOC_FLAGS);
+	if (x == NULL)
+		gossip_err("kiocb_alloc: kmem_cache_alloc failed!\n");
+	else
+		memset(x, 0, sizeof(struct pvfs2_kiocb_s));
+	return x;
+}
+
+void kiocb_release(struct pvfs2_kiocb_s *x)
+{
+	if (x)
+		kmem_cache_free(pvfs2_kiocb_cache, x);
+	else
+		gossip_err("kiocb_release: kmem_cache_free NULL pointer!\n");
+}
diff --git a/fs/orangefs/pvfs2-debug.h b/fs/orangefs/pvfs2-debug.h
new file mode 100644
index 000000000000..4c27ad77fa16
--- /dev/null
+++ b/fs/orangefs/pvfs2-debug.h
@@ -0,0 +1,290 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/* This file just defines debugging masks to be used with the gossip
+ * logging utility.  All debugging masks for PVFS2 are kept here to make
+ * sure we don't have collisions.
+ */
+
+#ifndef __PVFS2_DEBUG_H
+#define __PVFS2_DEBUG_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#define GOSSIP_NO_DEBUG                (__u64)0
+#define GOSSIP_BMI_DEBUG_TCP           ((__u64)1 << 0)
+#define GOSSIP_BMI_DEBUG_CONTROL       ((__u64)1 << 1)
+#define GOSSIP_BMI_DEBUG_OFFSETS       ((__u64)1 << 2)
+#define GOSSIP_BMI_DEBUG_GM            ((__u64)1 << 3)
+#define GOSSIP_JOB_DEBUG               ((__u64)1 << 4)
+#define GOSSIP_SERVER_DEBUG            ((__u64)1 << 5)
+#define GOSSIP_STO_DEBUG_CTRL          ((__u64)1 << 6)
+#define GOSSIP_STO_DEBUG_DEFAULT       ((__u64)1 << 7)
+#define GOSSIP_FLOW_DEBUG              ((__u64)1 << 8)
+#define GOSSIP_BMI_DEBUG_GM_MEM        ((__u64)1 << 9)
+#define GOSSIP_REQUEST_DEBUG           ((__u64)1 << 10)
+#define GOSSIP_FLOW_PROTO_DEBUG        ((__u64)1 << 11)
+#define GOSSIP_NCACHE_DEBUG            ((__u64)1 << 12)
+#define GOSSIP_CLIENT_DEBUG            ((__u64)1 << 13)
+#define GOSSIP_REQ_SCHED_DEBUG         ((__u64)1 << 14)
+#define GOSSIP_ACACHE_DEBUG            ((__u64)1 << 15)
+#define GOSSIP_TROVE_DEBUG             ((__u64)1 << 16)
+#define GOSSIP_TROVE_OP_DEBUG          ((__u64)1 << 17)
+#define GOSSIP_DIST_DEBUG              ((__u64)1 << 18)
+#define GOSSIP_BMI_DEBUG_IB            ((__u64)1 << 19)
+#define GOSSIP_DBPF_ATTRCACHE_DEBUG    ((__u64)1 << 20)
+#define GOSSIP_MMAP_RCACHE_DEBUG       ((__u64)1 << 21)
+#define GOSSIP_LOOKUP_DEBUG            ((__u64)1 << 22)
+#define GOSSIP_REMOVE_DEBUG            ((__u64)1 << 23)
+#define GOSSIP_GETATTR_DEBUG           ((__u64)1 << 24)
+#define GOSSIP_READDIR_DEBUG           ((__u64)1 << 25)
+#define GOSSIP_IO_DEBUG                ((__u64)1 << 26)
+#define GOSSIP_DBPF_OPEN_CACHE_DEBUG   ((__u64)1 << 27)
+#define GOSSIP_PERMISSIONS_DEBUG       ((__u64)1 << 28)
+#define GOSSIP_CANCEL_DEBUG            ((__u64)1 << 29)
+#define GOSSIP_MSGPAIR_DEBUG           ((__u64)1 << 30)
+#define GOSSIP_CLIENTCORE_DEBUG        ((__u64)1 << 31)
+#define GOSSIP_CLIENTCORE_TIMING_DEBUG ((__u64)1 << 32)
+#define GOSSIP_SETATTR_DEBUG           ((__u64)1 << 33)
+#define GOSSIP_MKDIR_DEBUG             ((__u64)1 << 34)
+#define GOSSIP_VARSTRIP_DEBUG          ((__u64)1 << 35)
+#define GOSSIP_GETEATTR_DEBUG          ((__u64)1 << 36)
+#define GOSSIP_SETEATTR_DEBUG          ((__u64)1 << 37)
+#define GOSSIP_ENDECODE_DEBUG          ((__u64)1 << 38)
+#define GOSSIP_DELEATTR_DEBUG          ((__u64)1 << 39)
+#define GOSSIP_ACCESS_DEBUG            ((__u64)1 << 40)
+#define GOSSIP_ACCESS_DETAIL_DEBUG     ((__u64)1 << 41)
+#define GOSSIP_LISTEATTR_DEBUG         ((__u64)1 << 42)
+#define GOSSIP_PERFCOUNTER_DEBUG       ((__u64)1 << 43)
+#define GOSSIP_STATE_MACHINE_DEBUG     ((__u64)1 << 44)
+#define GOSSIP_DBPF_KEYVAL_DEBUG       ((__u64)1 << 45)
+#define GOSSIP_LISTATTR_DEBUG          ((__u64)1 << 46)
+#define GOSSIP_DBPF_COALESCE_DEBUG     ((__u64)1 << 47)
+#define GOSSIP_ACCESS_HOSTNAMES        ((__u64)1 << 48)
+#define GOSSIP_FSCK_DEBUG              ((__u64)1 << 49)
+#define GOSSIP_BMI_DEBUG_MX            ((__u64)1 << 50)
+#define GOSSIP_BSTREAM_DEBUG           ((__u64)1 << 51)
+#define GOSSIP_BMI_DEBUG_PORTALS       ((__u64)1 << 52)
+#define GOSSIP_USER_DEV_DEBUG          ((__u64)1 << 53)
+#define GOSSIP_DIRECTIO_DEBUG          ((__u64)1 << 54)
+#define GOSSIP_MGMT_DEBUG              ((__u64)1 << 55)
+#define GOSSIP_MIRROR_DEBUG            ((__u64)1 << 56)
+#define GOSSIP_WIN_CLIENT_DEBUG        ((__u64)1 << 57)
+#define GOSSIP_SECURITY_DEBUG          ((__u64)1 << 58)
+#define GOSSIP_USRINT_DEBUG            ((__u64)1 << 59)
+#define GOSSIP_RCACHE_DEBUG            ((__u64)1 << 60)
+#define GOSSIP_SECCACHE_DEBUG          ((__u64)1 << 61)
+
+#define GOSSIP_BMI_DEBUG_ALL ((__u64) (GOSSIP_BMI_DEBUG_TCP +	\
+					 GOSSIP_BMI_DEBUG_CONTROL +	\
+					 GOSSIP_BMI_DEBUG_GM +		\
+					 GOSSIP_BMI_DEBUG_OFFSETS +	\
+					 GOSSIP_BMI_DEBUG_IB +		\
+					 GOSSIP_BMI_DEBUG_MX +		\
+					 GOSSIP_BMI_DEBUG_PORTALS))
+
+const char *PVFS_debug_get_next_debug_keyword(int position);
+
+#define GOSSIP_SUPER_DEBUG		((__u64)1 << 0)
+#define GOSSIP_INODE_DEBUG		((__u64)1 << 1)
+#define GOSSIP_FILE_DEBUG		((__u64)1 << 2)
+#define GOSSIP_DIR_DEBUG		((__u64)1 << 3)
+#define GOSSIP_UTILS_DEBUG		((__u64)1 << 4)
+#define GOSSIP_WAIT_DEBUG		((__u64)1 << 5)
+#define GOSSIP_ACL_DEBUG		((__u64)1 << 6)
+#define GOSSIP_DCACHE_DEBUG		((__u64)1 << 7)
+#define GOSSIP_DEV_DEBUG		((__u64)1 << 8)
+#define GOSSIP_NAME_DEBUG		((__u64)1 << 9)
+#define GOSSIP_BUFMAP_DEBUG		((__u64)1 << 10)
+#define GOSSIP_CACHE_DEBUG		((__u64)1 << 11)
+#define GOSSIP_DEBUGFS_DEBUG		((__u64)1 << 12)
+#define GOSSIP_XATTR_DEBUG		((__u64)1 << 13)
+#define GOSSIP_INIT_DEBUG		((__u64)1 << 14)
+#define GOSSIP_SYSFS_DEBUG		((__u64)1 << 15)
+
+#define GOSSIP_MAX_NR                 16
+#define GOSSIP_MAX_DEBUG              (((__u64)1 << GOSSIP_MAX_NR) - 1)
+
+/*function prototypes*/
+__u64 PVFS_kmod_eventlog_to_mask(const char *event_logging);
+__u64 PVFS_debug_eventlog_to_mask(const char *event_logging);
+char *PVFS_debug_mask_to_eventlog(__u64 mask);
+char *PVFS_kmod_mask_to_eventlog(__u64 mask);
+
+/* a private internal type */
+struct __keyword_mask_s {
+	const char *keyword;
+	__u64 mask_val;
+};
+
+#define __DEBUG_ALL ((__u64) -1)
+
+/* map all config keywords to pvfs2 debug masks here */
+static struct __keyword_mask_s s_keyword_mask_map[] = {
+	/* Log trove debugging info.  Same as 'trove'. */
+	{"storage", GOSSIP_TROVE_DEBUG},
+	/* Log trove debugging info.  Same as 'storage'. */
+	{"trove", GOSSIP_TROVE_DEBUG},
+	/* Log trove operations. */
+	{"trove_op", GOSSIP_TROVE_OP_DEBUG},
+	/* Log network debug info. */
+	{"network", GOSSIP_BMI_DEBUG_ALL},
+	/* Log server info, including new operations. */
+	{"server", GOSSIP_SERVER_DEBUG},
+	/* Log client sysint info.  This is only useful for the client. */
+	{"client", GOSSIP_CLIENT_DEBUG},
+	/* Debug the varstrip distribution */
+	{"varstrip", GOSSIP_VARSTRIP_DEBUG},
+	/* Log job info */
+	{"job", GOSSIP_JOB_DEBUG},
+	/* Debug PINT_process_request calls.  EXTREMELY verbose! */
+	{"request", GOSSIP_REQUEST_DEBUG},
+	/* Log request scheduler events */
+	{"reqsched", GOSSIP_REQ_SCHED_DEBUG},
+	/* Log the flow protocol events, including flowproto_multiqueue */
+	{"flowproto", GOSSIP_FLOW_PROTO_DEBUG},
+	/* Log flow calls */
+	{"flow", GOSSIP_FLOW_DEBUG},
+	/* Debug the client name cache.  Only useful on the client. */
+	{"ncache", GOSSIP_NCACHE_DEBUG},
+	/* Debug read-ahead cache events.  Only useful on the client. */
+	{"mmaprcache", GOSSIP_MMAP_RCACHE_DEBUG},
+	/* Debug the attribute cache.  Only useful on the client. */
+	{"acache", GOSSIP_ACACHE_DEBUG},
+	/* Log/Debug distribution calls */
+	{"distribution", GOSSIP_DIST_DEBUG},
+	/* Debug the server-side dbpf attribute cache */
+	{"dbpfattrcache", GOSSIP_DBPF_ATTRCACHE_DEBUG},
+	/* Debug the client lookup state machine. */
+	{"lookup", GOSSIP_LOOKUP_DEBUG},
+	/* Debug the client remove state macine. */
+	{"remove", GOSSIP_REMOVE_DEBUG},
+	/* Debug the server getattr state machine. */
+	{"getattr", GOSSIP_GETATTR_DEBUG},
+	/* Debug the server setattr state machine. */
+	{"setattr", GOSSIP_SETATTR_DEBUG},
+	/* vectored getattr server state machine */
+	{"listattr", GOSSIP_LISTATTR_DEBUG},
+	/* Debug the client and server get ext attributes SM. */
+	{"geteattr", GOSSIP_GETEATTR_DEBUG},
+	/* Debug the client and server set ext attributes SM. */
+	{"seteattr", GOSSIP_SETEATTR_DEBUG},
+	/* Debug the readdir operation (client and server) */
+	{"readdir", GOSSIP_READDIR_DEBUG},
+	/* Debug the mkdir operation (server only) */
+	{"mkdir", GOSSIP_MKDIR_DEBUG},
+	/* Debug the io operation (reads and writes)
+	 * for both the client and server */
+	{"io", GOSSIP_IO_DEBUG},
+	/* Debug the server's open file descriptor cache */
+	{"open_cache", GOSSIP_DBPF_OPEN_CACHE_DEBUG},
+	/* Debug permissions checking on the server */
+	{"permissions", GOSSIP_PERMISSIONS_DEBUG},
+	/* Debug the cancel operation */
+	{"cancel", GOSSIP_CANCEL_DEBUG},
+	/* Debug the msgpair state machine */
+	{"msgpair", GOSSIP_MSGPAIR_DEBUG},
+	/* Debug the client core app */
+	{"clientcore", GOSSIP_CLIENTCORE_DEBUG},
+	/* Debug the client timing state machines (job timeout, etc.) */
+	{"clientcore_timing", GOSSIP_CLIENTCORE_TIMING_DEBUG},
+	/* network encoding */
+	{"endecode", GOSSIP_ENDECODE_DEBUG},
+	/* Show server file (metadata) accesses (both modify and read-only). */
+	{"access", GOSSIP_ACCESS_DEBUG},
+	/* Show more detailed server file accesses */
+	{"access_detail", GOSSIP_ACCESS_DETAIL_DEBUG},
+	/* Debug the listeattr operation */
+	{"listeattr", GOSSIP_LISTEATTR_DEBUG},
+	/* Debug the state machine management code */
+	{"sm", GOSSIP_STATE_MACHINE_DEBUG},
+	/* Debug the metadata dbpf keyval functions */
+	{"keyval", GOSSIP_DBPF_KEYVAL_DEBUG},
+	/* Debug the metadata sync coalescing code */
+	{"coalesce", GOSSIP_DBPF_COALESCE_DEBUG},
+	/* Display the hostnames instead of IP addrs in debug output */
+	{"access_hostnames", GOSSIP_ACCESS_HOSTNAMES},
+	/* Show the client device events */
+	{"user_dev", GOSSIP_USER_DEV_DEBUG},
+	/* Debug the fsck tool */
+	{"fsck", GOSSIP_FSCK_DEBUG},
+	/* Debug the bstream code */
+	{"bstream", GOSSIP_BSTREAM_DEBUG},
+	/* Debug trove in direct io mode */
+	{"directio", GOSSIP_DIRECTIO_DEBUG},
+	/* Debug direct io thread management */
+	{"mgmt", GOSSIP_MGMT_DEBUG},
+	/* Debug mirroring process */
+	{"mirror", GOSSIP_MIRROR_DEBUG},
+	/* Windows client */
+	{"win_client", GOSSIP_WIN_CLIENT_DEBUG},
+	/* Debug robust security code */
+	{"security", GOSSIP_SECURITY_DEBUG},
+	/* Capability Cache */
+	{"seccache", GOSSIP_SECCACHE_DEBUG},
+	/* Client User Interface */
+	{"usrint", GOSSIP_USRINT_DEBUG},
+	/* rcache */
+	{"rcache", GOSSIP_RCACHE_DEBUG},
+	/* Everything except the periodic events.  Useful for debugging */
+	{"verbose",
+	 (__DEBUG_ALL &
+	  ~(GOSSIP_PERFCOUNTER_DEBUG | GOSSIP_STATE_MACHINE_DEBUG |
+	    GOSSIP_ENDECODE_DEBUG | GOSSIP_USER_DEV_DEBUG))
+	 },
+	/* No debug output */
+	{"none", GOSSIP_NO_DEBUG},
+	/* Everything */
+	{"all", __DEBUG_ALL}
+};
+
+#undef __DEBUG_ALL
+
+/*
+ * Map all kmod keywords to kmod debug masks here. Keep this
+ * structure "packed":
+ *
+ *   "all" is always last...
+ *
+ *   keyword     mask_val     index
+ *     foo          1           0
+ *     bar          2           1
+ *     baz          4           2
+ *     qux          8           3
+ *      .           .           .
+ */
+static struct __keyword_mask_s s_kmod_keyword_mask_map[] = {
+	{"super", GOSSIP_SUPER_DEBUG},
+	{"inode", GOSSIP_INODE_DEBUG},
+	{"file", GOSSIP_FILE_DEBUG},
+	{"dir", GOSSIP_DIR_DEBUG},
+	{"utils", GOSSIP_UTILS_DEBUG},
+	{"wait", GOSSIP_WAIT_DEBUG},
+	{"acl", GOSSIP_ACL_DEBUG},
+	{"dcache", GOSSIP_DCACHE_DEBUG},
+	{"dev", GOSSIP_DEV_DEBUG},
+	{"name", GOSSIP_NAME_DEBUG},
+	{"bufmap", GOSSIP_BUFMAP_DEBUG},
+	{"cache", GOSSIP_CACHE_DEBUG},
+	{"debugfs", GOSSIP_DEBUGFS_DEBUG},
+	{"xattr", GOSSIP_XATTR_DEBUG},
+	{"init", GOSSIP_INIT_DEBUG},
+	{"sysfs", GOSSIP_SYSFS_DEBUG},
+	{"none", GOSSIP_NO_DEBUG},
+	{"all", GOSSIP_MAX_DEBUG}
+};
+
+static const int num_kmod_keyword_mask_map = (int)
+	(sizeof(s_kmod_keyword_mask_map) / sizeof(struct __keyword_mask_s));
+
+static const int num_keyword_mask_map = (int)
+	(sizeof(s_keyword_mask_map) / sizeof(struct __keyword_mask_s));
+
+#endif /* __PVFS2_DEBUG_H */
diff --git a/fs/orangefs/pvfs2-debugfs.c b/fs/orangefs/pvfs2-debugfs.c
new file mode 100644
index 000000000000..ba5bfef7a3f3
--- /dev/null
+++ b/fs/orangefs/pvfs2-debugfs.c
@@ -0,0 +1,458 @@
+/*
+ * What:		/sys/kernel/debug/orangefs/debug-help
+ * Date:		June 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			List of client and kernel debug keywords.
+ *
+ *
+ * What:		/sys/kernel/debug/orangefs/client-debug
+ * Date:		June 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Debug setting for "the client", the userspace
+ * 			helper for the kernel module.
+ *
+ *
+ * What:		/sys/kernel/debug/orangefs/kernel-debug
+ * Date:		June 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Debug setting for the orangefs kernel module.
+ *
+ * 			Any of the keywords, or comma-separated lists
+ * 			of keywords, from debug-help can be catted to
+ * 			client-debug or kernel-debug.
+ *
+ * 			"none", "all" and "verbose" are special keywords
+ * 			for client-debug. Setting client-debug to "all"
+ * 			is kind of like trying to drink water from a
+ * 			fire hose, "verbose" triggers most of the same
+ * 			output except for the constant flow of output
+ * 			from the main wait loop.
+ *
+ * 			"none" and "all" are similar settings for kernel-debug
+ * 			no need for a "verbose".
+ */
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+
+#include <linux/uaccess.h>
+
+#include "pvfs2-debugfs.h"
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+
+static int orangefs_debug_disabled = 1;
+
+static int orangefs_debug_help_open(struct inode *, struct file *);
+
+const struct file_operations debug_help_fops = {
+	.open           = orangefs_debug_help_open,
+	.read           = seq_read,
+	.release        = seq_release,
+	.llseek         = seq_lseek,
+};
+
+static void *help_start(struct seq_file *, loff_t *);
+static void *help_next(struct seq_file *, void *, loff_t *);
+static void help_stop(struct seq_file *, void *);
+static int help_show(struct seq_file *, void *);
+
+static const struct seq_operations help_debug_ops = {
+	.start	= help_start,
+	.next	= help_next,
+	.stop	= help_stop,
+	.show	= help_show,
+};
+
+/*
+ * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and
+ * ORANGEFS_KMOD_DEBUG_FILE.
+ */
+static DEFINE_MUTEX(orangefs_debug_lock);
+
+int orangefs_debug_open(struct inode *, struct file *);
+
+static ssize_t orangefs_debug_read(struct file *,
+				 char __user *,
+				 size_t,
+				 loff_t *);
+
+static ssize_t orangefs_debug_write(struct file *,
+				  const char __user *,
+				  size_t,
+				  loff_t *);
+
+static const struct file_operations kernel_debug_fops = {
+	.open           = orangefs_debug_open,
+	.read           = orangefs_debug_read,
+	.write		= orangefs_debug_write,
+	.llseek         = generic_file_llseek,
+};
+
+/*
+ * initialize kmod debug operations, create orangefs debugfs dir and
+ * ORANGEFS_KMOD_DEBUG_HELP_FILE.
+ */
+int pvfs2_debugfs_init(void)
+{
+
+	int rc = -ENOMEM;
+
+	debug_dir = debugfs_create_dir("orangefs", NULL);
+	if (!debug_dir)
+		goto out;
+
+	help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE,
+				  0444,
+				  debug_dir,
+				  debug_help_string,
+				  &debug_help_fops);
+	if (!help_file_dentry)
+		goto out;
+
+	orangefs_debug_disabled = 0;
+	rc = 0;
+
+out:
+	if (rc)
+		pvfs2_debugfs_cleanup();
+
+	return rc;
+}
+
+void pvfs2_debugfs_cleanup(void)
+{
+	debugfs_remove_recursive(debug_dir);
+}
+
+/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
+static int orangefs_debug_help_open(struct inode *inode, struct file *file)
+{
+	int rc = -ENODEV;
+	int ret;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "orangefs_debug_help_open: start\n");
+
+	if (orangefs_debug_disabled)
+		goto out;
+
+	ret = seq_open(file, &help_debug_ops);
+	if (ret)
+		goto out;
+
+	((struct seq_file *)(file->private_data))->private = inode->i_private;
+
+	rc = 0;
+
+out:
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "orangefs_debug_help_open: rc:%d:\n",
+		     rc);
+	return rc;
+}
+
+/*
+ * I think start always gets called again after stop. Start
+ * needs to return NULL when it is done. The whole "payload"
+ * in this case is a single (long) string, so by the second
+ * time we get to start (pos = 1), we're done.
+ */
+static void *help_start(struct seq_file *m, loff_t *pos)
+{
+	void *payload = NULL;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n");
+
+	if (*pos == 0)
+		payload = m->private;
+
+	return payload;
+}
+
+static void *help_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n");
+
+	return NULL;
+}
+
+static void help_stop(struct seq_file *m, void *p)
+{
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n");
+}
+
+static int help_show(struct seq_file *m, void *v)
+{
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_show: start\n");
+
+	seq_puts(m, v);
+
+	return 0;
+}
+
+/*
+ * initialize the kernel-debug file.
+ */
+int pvfs2_kernel_debug_init(void)
+{
+
+	int rc = -ENOMEM;
+	struct dentry *ret;
+	char *k_buffer = NULL;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+
+	k_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+	if (!k_buffer)
+		goto out;
+
+	if (strlen(kernel_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) {
+		strcpy(k_buffer, kernel_debug_string);
+		strcat(k_buffer, "\n");
+	} else {
+		strcpy(k_buffer, "none\n");
+		pr_info("%s: overflow 1!\n", __func__);
+	}
+
+	ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE,
+				  0444,
+				  debug_dir,
+				  k_buffer,
+				  &kernel_debug_fops);
+	if (!ret) {
+		pr_info("%s: failed to create %s.\n",
+			__func__,
+			ORANGEFS_KMOD_DEBUG_FILE);
+		goto out;
+	}
+
+	rc = 0;
+
+out:
+	if (rc)
+		pvfs2_debugfs_cleanup();
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+	return rc;
+}
+
+/*
+ * initialize the client-debug file.
+ */
+int pvfs2_client_debug_init(void)
+{
+
+	int rc = -ENOMEM;
+	char *c_buffer = NULL;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+
+	c_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+	if (!c_buffer)
+		goto out;
+
+	if (strlen(client_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) {
+		strcpy(c_buffer, client_debug_string);
+		strcat(c_buffer, "\n");
+	} else {
+		strcpy(c_buffer, "none\n");
+		pr_info("%s: overflow! 2\n", __func__);
+	}
+
+	client_debug_dentry = debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE,
+						  0444,
+						  debug_dir,
+						  c_buffer,
+						  &kernel_debug_fops);
+	if (!client_debug_dentry) {
+		pr_info("%s: failed to create %s.\n",
+			__func__,
+			ORANGEFS_CLIENT_DEBUG_FILE);
+		goto out;
+	}
+
+	rc = 0;
+
+out:
+	if (rc)
+		pvfs2_debugfs_cleanup();
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+	return rc;
+}
+
+/* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
+int orangefs_debug_open(struct inode *inode, struct file *file)
+{
+	int rc = -ENODEV;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "%s: orangefs_debug_disabled: %d\n",
+		     __func__,
+		     orangefs_debug_disabled);
+
+	if (orangefs_debug_disabled)
+		goto out;
+
+	rc = 0;
+	mutex_lock(&orangefs_debug_lock);
+	file->private_data = inode->i_private;
+	mutex_unlock(&orangefs_debug_lock);
+
+out:
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "orangefs_debug_open: rc: %d\n",
+		     rc);
+	return rc;
+}
+
+static ssize_t orangefs_debug_read(struct file *file,
+				 char __user *ubuf,
+				 size_t count,
+				 loff_t *ppos)
+{
+	char *buf;
+	int sprintf_ret;
+	ssize_t read_ret = -ENOMEM;
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "orangefs_debug_read: start\n");
+
+	buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	mutex_lock(&orangefs_debug_lock);
+	sprintf_ret = sprintf(buf, "%s", (char *)file->private_data);
+	mutex_unlock(&orangefs_debug_lock);
+
+	read_ret = simple_read_from_buffer(ubuf, count, ppos, buf, sprintf_ret);
+
+	kfree(buf);
+
+out:
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "orangefs_debug_read: ret: %zu\n",
+		     read_ret);
+
+	return read_ret;
+}
+
+static ssize_t orangefs_debug_write(struct file *file,
+				  const char __user *ubuf,
+				  size_t count,
+				  loff_t *ppos)
+{
+	char *buf;
+	int rc = -EFAULT;
+	size_t silly = 0;
+	char *debug_string;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	struct client_debug_mask c_mask = { NULL, 0, 0 };
+
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		"orangefs_debug_write: %s\n",
+		file->f_path.dentry->d_name.name);
+
+	/*
+	 * Thwart users who try to jamb a ridiculous number
+	 * of bytes into the debug file...
+	 */
+	if (count > PVFS2_MAX_DEBUG_STRING_LEN + 1) {
+		silly = count;
+		count = PVFS2_MAX_DEBUG_STRING_LEN + 1;
+	}
+
+	buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+	if (!buf)
+		goto out;
+	memset(buf, 0, PVFS2_MAX_DEBUG_STRING_LEN);
+
+	if (copy_from_user(buf, ubuf, count - 1)) {
+		gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+			     "%s: copy_from_user failed!\n",
+			     __func__);
+		goto out;
+	}
+
+	/*
+	 * Map the keyword string from userspace into a valid debug mask.
+	 * The mapping process involves mapping the human-inputted string
+	 * into a valid mask, and then rebuilding the string from the
+	 * verified valid mask.
+	 *
+	 * A service operation is required to set a new client-side
+	 * debug mask.
+	 */
+	if (!strcmp(file->f_path.dentry->d_name.name,
+		    ORANGEFS_KMOD_DEBUG_FILE)) {
+		debug_string_to_mask(buf, &gossip_debug_mask, 0);
+		debug_mask_to_string(&gossip_debug_mask, 0);
+		debug_string = kernel_debug_string;
+		gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+			     "New kernel debug string is %s\n",
+			     kernel_debug_string);
+	} else {
+		/* Can't reset client debug mask if client is not running. */
+		if (is_daemon_in_service()) {
+			pr_info("%s: Client not running :%d:\n",
+				__func__,
+				is_daemon_in_service());
+			goto out;
+		}
+
+		debug_string_to_mask(buf, &c_mask, 1);
+		debug_mask_to_string(&c_mask, 1);
+		debug_string = client_debug_string;
+
+		new_op = op_alloc(PVFS2_VFS_OP_PARAM);
+		if (!new_op) {
+			pr_info("%s: op_alloc failed!\n", __func__);
+			goto out;
+		}
+
+		new_op->upcall.req.param.op =
+			PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES;
+		new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET;
+		memset(new_op->upcall.req.param.s_value,
+		       0,
+		       PVFS2_MAX_DEBUG_STRING_LEN);
+		sprintf(new_op->upcall.req.param.s_value,
+			"%llx %llx\n",
+			c_mask.mask1,
+			c_mask.mask2);
+
+		/* service_operation returns 0 on success... */
+		rc = service_operation(new_op,
+				       "pvfs2_param",
+					PVFS2_OP_INTERRUPTIBLE);
+
+		if (rc)
+			gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+				     "%s: service_operation failed! rc:%d:\n",
+				     __func__,
+				     rc);
+
+		op_release(new_op);
+	}
+
+	mutex_lock(&orangefs_debug_lock);
+	memset(file->f_inode->i_private, 0, PVFS2_MAX_DEBUG_STRING_LEN);
+	sprintf((char *)file->f_inode->i_private, "%s\n", debug_string);
+	mutex_unlock(&orangefs_debug_lock);
+
+	*ppos += count;
+	if (silly)
+		rc = silly;
+	else
+		rc = count;
+
+out:
+	gossip_debug(GOSSIP_DEBUGFS_DEBUG,
+		     "orangefs_debug_write: rc: %d\n",
+		     rc);
+	kfree(buf);
+	return rc;
+}
diff --git a/fs/orangefs/pvfs2-debugfs.h b/fs/orangefs/pvfs2-debugfs.h
new file mode 100644
index 000000000000..a66b7d08c14d
--- /dev/null
+++ b/fs/orangefs/pvfs2-debugfs.h
@@ -0,0 +1,3 @@
+int pvfs2_debugfs_init(void);
+int pvfs2_kernel_debug_init(void);
+void pvfs2_debugfs_cleanup(void);
diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/pvfs2-dev-proto.h
new file mode 100644
index 000000000000..9c82e6e651f3
--- /dev/null
+++ b/fs/orangefs/pvfs2-dev-proto.h
@@ -0,0 +1,102 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#ifndef _PVFS2_DEV_PROTO_H
+#define _PVFS2_DEV_PROTO_H
+
+/*
+ * types and constants shared between user space and kernel space for
+ * device interaction using a common protocol
+ */
+
+/*
+ * valid pvfs2 kernel operation types
+ */
+#define PVFS2_VFS_OP_INVALID           0xFF000000
+#define PVFS2_VFS_OP_FILE_IO           0xFF000001
+#define PVFS2_VFS_OP_LOOKUP            0xFF000002
+#define PVFS2_VFS_OP_CREATE            0xFF000003
+#define PVFS2_VFS_OP_GETATTR           0xFF000004
+#define PVFS2_VFS_OP_REMOVE            0xFF000005
+#define PVFS2_VFS_OP_MKDIR             0xFF000006
+#define PVFS2_VFS_OP_READDIR           0xFF000007
+#define PVFS2_VFS_OP_SETATTR           0xFF000008
+#define PVFS2_VFS_OP_SYMLINK           0xFF000009
+#define PVFS2_VFS_OP_RENAME            0xFF00000A
+#define PVFS2_VFS_OP_STATFS            0xFF00000B
+#define PVFS2_VFS_OP_TRUNCATE          0xFF00000C
+#define PVFS2_VFS_OP_MMAP_RA_FLUSH     0xFF00000D
+#define PVFS2_VFS_OP_FS_MOUNT          0xFF00000E
+#define PVFS2_VFS_OP_FS_UMOUNT         0xFF00000F
+#define PVFS2_VFS_OP_GETXATTR          0xFF000010
+#define PVFS2_VFS_OP_SETXATTR          0xFF000011
+#define PVFS2_VFS_OP_LISTXATTR         0xFF000012
+#define PVFS2_VFS_OP_REMOVEXATTR       0xFF000013
+#define PVFS2_VFS_OP_PARAM             0xFF000014
+#define PVFS2_VFS_OP_PERF_COUNT        0xFF000015
+#define PVFS2_VFS_OP_CANCEL            0xFF00EE00
+#define PVFS2_VFS_OP_FSYNC             0xFF00EE01
+#define PVFS2_VFS_OP_FSKEY             0xFF00EE02
+#define PVFS2_VFS_OP_READDIRPLUS       0xFF00EE03
+#define PVFS2_VFS_OP_FILE_IOX          0xFF00EE04
+
+/*
+ * Misc constants. Please retain them as multiples of 8!
+ * Otherwise 32-64 bit interactions will be messed up :)
+ */
+#define PVFS2_NAME_LEN			0x00000100
+#define PVFS2_MAX_DEBUG_STRING_LEN	0x00000400
+#define PVFS2_MAX_DEBUG_ARRAY_LEN	0x00000800
+
+/*
+ * MAX_DIRENT_COUNT cannot be larger than PVFS_REQ_LIMIT_LISTATTR.
+ * The value of PVFS_REQ_LIMIT_LISTATTR has been changed from 113 to 60
+ * to accomodate an attribute object with mirrored handles.
+ * MAX_DIRENT_COUNT is replaced by MAX_DIRENT_COUNT_READDIR and
+ * MAX_DIRENT_COUNT_READDIRPLUS, since readdir doesn't trigger a listattr
+ * but readdirplus might.
+*/
+#define MAX_DIRENT_COUNT_READDIR       0x00000060
+#define MAX_DIRENT_COUNT_READDIRPLUS   0x0000003C
+
+#include "upcall.h"
+#include "downcall.h"
+
+/*
+ * These macros differ from proto macros in that they don't do any
+ * byte-swappings and are used to ensure that kernel-clientcore interactions
+ * don't cause any unaligned accesses etc on 64 bit machines
+ */
+#ifndef roundup4
+#define roundup4(x) (((x)+3) & ~3)
+#endif
+
+#ifndef roundup8
+#define roundup8(x) (((x)+7) & ~7)
+#endif
+
+/* strings; decoding just points into existing character data */
+#define enc_string(pptr, pbuf) do { \
+	__u32 len = strlen(*pbuf); \
+	*(__u32 *) *(pptr) = (len); \
+	memcpy(*(pptr)+4, *pbuf, len+1); \
+	*(pptr) += roundup8(4 + len + 1); \
+} while (0)
+
+#define dec_string(pptr, pbuf, plen) do { \
+	__u32 len = (*(__u32 *) *(pptr)); \
+	*pbuf = *(pptr) + 4; \
+	*(pptr) += roundup8(4 + len + 1); \
+	if (plen) \
+		*plen = len;\
+} while (0)
+
+struct read_write_x {
+	__s64 off;
+	__s64 len;
+};
+
+#endif
diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h
new file mode 100644
index 000000000000..be30111b40d2
--- /dev/null
+++ b/fs/orangefs/pvfs2-kernel.h
@@ -0,0 +1,864 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  The PVFS2 Linux kernel support allows PVFS2 volumes to be mounted and
+ *  accessed through the Linux VFS (i.e. using standard I/O system calls).
+ *  This support is only needed on clients that wish to mount the file system.
+ *
+ */
+
+/*
+ *  Declarations and macros for the PVFS2 Linux kernel support.
+ */
+
+#ifndef __PVFS2KERNEL_H
+#define __PVFS2KERNEL_H
+
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/statfs.h>
+#include <linux/backing-dev.h>
+#include <linux/device.h>
+#include <linux/mpage.h>
+#include <linux/namei.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/aio.h>
+#include <linux/posix_acl.h>
+#include <linux/posix_acl_xattr.h>
+#include <linux/compat.h>
+#include <linux/mount.h>
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <linux/uio.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+#include <linux/dcache.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/rwsem.h>
+#include <linux/xattr.h>
+#include <linux/exportfs.h>
+
+#include <asm/unaligned.h>
+
+#include "pvfs2-dev-proto.h"
+
+#ifdef PVFS2_KERNEL_DEBUG
+#define PVFS2_DEFAULT_OP_TIMEOUT_SECS       10
+#else
+#define PVFS2_DEFAULT_OP_TIMEOUT_SECS       20
+#endif
+
+#define PVFS2_BUFMAP_WAIT_TIMEOUT_SECS      30
+
+#define PVFS2_DEFAULT_SLOT_TIMEOUT_SECS     900	/* 15 minutes */
+
+#define PVFS2_REQDEVICE_NAME          "pvfs2-req"
+
+#define PVFS2_DEVREQ_MAGIC             0x20030529
+#define PVFS2_LINK_MAX                 0x000000FF
+#define PVFS2_PURGE_RETRY_COUNT        0x00000005
+#define PVFS2_SEEK_END                 0x00000002
+#define PVFS2_MAX_NUM_OPTIONS          0x00000004
+#define PVFS2_MAX_MOUNT_OPT_LEN        0x00000080
+#define PVFS2_MAX_FSKEY_LEN            64
+
+#define MAX_DEV_REQ_UPSIZE (2*sizeof(__s32) +   \
+sizeof(__u64) + sizeof(struct pvfs2_upcall_s))
+#define MAX_DEV_REQ_DOWNSIZE (2*sizeof(__s32) + \
+sizeof(__u64) + sizeof(struct pvfs2_downcall_s))
+
+#define BITS_PER_LONG_DIV_8 (BITS_PER_LONG >> 3)
+
+/* borrowed from irda.h */
+#ifndef MSECS_TO_JIFFIES
+#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
+#endif
+
+#define MAX_ALIGNED_DEV_REQ_UPSIZE				\
+		(MAX_DEV_REQ_UPSIZE +				\
+			((((MAX_DEV_REQ_UPSIZE /		\
+				(BITS_PER_LONG_DIV_8)) *	\
+				(BITS_PER_LONG_DIV_8)) +	\
+			    (BITS_PER_LONG_DIV_8)) -		\
+			MAX_DEV_REQ_UPSIZE))
+
+#define MAX_ALIGNED_DEV_REQ_DOWNSIZE				\
+		(MAX_DEV_REQ_DOWNSIZE +				\
+			((((MAX_DEV_REQ_DOWNSIZE /		\
+				(BITS_PER_LONG_DIV_8)) *	\
+				(BITS_PER_LONG_DIV_8)) +	\
+			    (BITS_PER_LONG_DIV_8)) -		\
+			MAX_DEV_REQ_DOWNSIZE))
+
+/*
+ * valid pvfs2 kernel operation states
+ *
+ * unknown  - op was just initialized
+ * waiting  - op is on request_list (upward bound)
+ * inprogr  - op is in progress (waiting for downcall)
+ * serviced - op has matching downcall; ok
+ * purged   - op has to start a timer since client-core
+ *            exited uncleanly before servicing op
+ */
+enum pvfs2_vfs_op_states {
+	OP_VFS_STATE_UNKNOWN = 0,
+	OP_VFS_STATE_WAITING = 1,
+	OP_VFS_STATE_INPROGR = 2,
+	OP_VFS_STATE_SERVICED = 4,
+	OP_VFS_STATE_PURGED = 8,
+};
+
+#define set_op_state_waiting(op)     ((op)->op_state = OP_VFS_STATE_WAITING)
+#define set_op_state_inprogress(op)  ((op)->op_state = OP_VFS_STATE_INPROGR)
+#define set_op_state_serviced(op)    ((op)->op_state = OP_VFS_STATE_SERVICED)
+#define set_op_state_purged(op)      ((op)->op_state |= OP_VFS_STATE_PURGED)
+
+#define op_state_waiting(op)     ((op)->op_state & OP_VFS_STATE_WAITING)
+#define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR)
+#define op_state_serviced(op)    ((op)->op_state & OP_VFS_STATE_SERVICED)
+#define op_state_purged(op)      ((op)->op_state & OP_VFS_STATE_PURGED)
+
+#define get_op(op)					\
+	do {						\
+		atomic_inc(&(op)->aio_ref_count);	\
+		gossip_debug(GOSSIP_DEV_DEBUG,	\
+			"(get) Alloced OP (%p:%llu)\n",	\
+			op,				\
+			llu((op)->tag));		\
+	} while (0)
+
+#define put_op(op)							\
+	do {								\
+		if (atomic_sub_and_test(1, &(op)->aio_ref_count) == 1) {  \
+			gossip_debug(GOSSIP_DEV_DEBUG,		\
+				"(put) Releasing OP (%p:%llu)\n",	\
+				op,					\
+				llu((op)->tag));			\
+			op_release(op);					\
+			}						\
+	} while (0)
+
+#define op_wait(op) (atomic_read(&(op)->aio_ref_count) <= 2 ? 0 : 1)
+
+/*
+ * Defines for controlling whether I/O upcalls are for async or sync operations
+ */
+enum PVFS_async_io_type {
+	PVFS_VFS_SYNC_IO = 0,
+	PVFS_VFS_ASYNC_IO = 1,
+};
+
+/*
+ * An array of client_debug_mask will be built to hold debug keyword/mask
+ * values fetched from userspace.
+ */
+struct client_debug_mask {
+	char *keyword;
+	__u64 mask1;
+	__u64 mask2;
+};
+
+/*
+ * pvfs2 kernel memory related flags
+ */
+
+#if ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB))
+#define PVFS2_CACHE_CREATE_FLAGS SLAB_RED_ZONE
+#else
+#define PVFS2_CACHE_CREATE_FLAGS 0
+#endif /* ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */
+
+#define PVFS2_CACHE_ALLOC_FLAGS (GFP_KERNEL)
+#define PVFS2_GFP_FLAGS (GFP_KERNEL)
+#define PVFS2_BUFMAP_GFP_FLAGS (GFP_KERNEL)
+
+#define pvfs2_kmap(page) kmap(page)
+#define pvfs2_kunmap(page) kunmap(page)
+
+/* pvfs2 xattr and acl related defines */
+#define PVFS2_XATTR_INDEX_POSIX_ACL_ACCESS  1
+#define PVFS2_XATTR_INDEX_POSIX_ACL_DEFAULT 2
+#define PVFS2_XATTR_INDEX_TRUSTED           3
+#define PVFS2_XATTR_INDEX_DEFAULT           4
+
+#if 0
+#ifndef POSIX_ACL_XATTR_ACCESS
+#define POSIX_ACL_XATTR_ACCESS	"system.posix_acl_access"
+#endif
+#ifndef POSIX_ACL_XATTR_DEFAULT
+#define POSIX_ACL_XATTR_DEFAULT	"system.posix_acl_default"
+#endif
+#endif
+
+#define PVFS2_XATTR_NAME_ACL_ACCESS  POSIX_ACL_XATTR_ACCESS
+#define PVFS2_XATTR_NAME_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT
+#define PVFS2_XATTR_NAME_TRUSTED_PREFIX "trusted."
+#define PVFS2_XATTR_NAME_DEFAULT_PREFIX ""
+
+/* these functions are defined in pvfs2-utils.c */
+int orangefs_prepare_cdm_array(char *debug_array_string);
+int orangefs_prepare_debugfs_help_string(int);
+
+/* defined in pvfs2-debugfs.c */
+int pvfs2_client_debug_init(void);
+
+void debug_string_to_mask(char *, void *, int);
+void do_c_mask(int, char *, struct client_debug_mask **);
+void do_k_mask(int, char *, __u64 **);
+
+void debug_mask_to_string(void *, int);
+void do_k_string(void *, int);
+void do_c_string(void *, int);
+int check_amalgam_keyword(void *, int);
+int keyword_is_amalgam(char *);
+
+/*these variables are defined in pvfs2-mod.c */
+extern char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN];
+extern char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN];
+extern char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN];
+/* HELLO
+extern struct client_debug_mask current_client_mask;
+*/
+extern unsigned int kernel_mask_set_mod_init;
+
+extern int pvfs2_init_acl(struct inode *inode, struct inode *dir);
+extern const struct xattr_handler *pvfs2_xattr_handlers[];
+
+extern struct posix_acl *pvfs2_get_acl(struct inode *inode, int type);
+extern int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+
+int pvfs2_xattr_set_default(struct dentry *dentry,
+			    const char *name,
+			    const void *buffer,
+			    size_t size,
+			    int flags,
+			    int handler_flags);
+
+int pvfs2_xattr_get_default(struct dentry *dentry,
+			    const char *name,
+			    void *buffer,
+			    size_t size,
+			    int handler_flags);
+
+/*
+ * Redefine xtvec structure so that we could move helper functions out of
+ * the define
+ */
+struct xtvec {
+	__kernel_off_t xtv_off;		/* must be off_t */
+	__kernel_size_t xtv_len;	/* must be size_t */
+};
+
+/*
+ * pvfs2 data structures
+ */
+struct pvfs2_kernel_op_s {
+	enum pvfs2_vfs_op_states op_state;
+	__u64 tag;
+
+	/*
+	 * Set uses_shared_memory to 1 if this operation uses shared memory.
+	 * If true, then a retry on the op must also get a new shared memory
+	 * buffer and re-populate it.
+	 */
+	int uses_shared_memory;
+
+	struct pvfs2_upcall_s upcall;
+	struct pvfs2_downcall_s downcall;
+
+	wait_queue_head_t waitq;
+	spinlock_t lock;
+
+	int io_completed;
+	wait_queue_head_t io_completion_waitq;
+
+	/*
+	 * upcalls requiring variable length trailers require that this struct
+	 * be in the request list even after client-core does a read() on the
+	 * device to dequeue the upcall.
+	 * if op_linger field goes to 0, we dequeue this op off the list.
+	 * else we let it stay. What gets passed to the read() is
+	 * a) if op_linger field is = 1, pvfs2_kernel_op_s itself
+	 * b) else if = 0, we pass ->upcall.trailer_buf
+	 * We expect to have only a single upcall trailer buffer,
+	 * so we expect callers with trailers
+	 * to set this field to 2 and others to set it to 1.
+	 */
+	__s32 op_linger, op_linger_tmp;
+	/* VFS aio fields */
+
+	/* used by the async I/O code to stash the pvfs2_kiocb_s structure */
+	void *priv;
+
+	/* used again for the async I/O code for deallocation */
+	atomic_t aio_ref_count;
+
+	int attempts;
+
+	struct list_head list;
+};
+
+/* per inode private pvfs2 info */
+struct pvfs2_inode_s {
+	struct pvfs2_object_kref refn;
+	char link_target[PVFS_NAME_MAX];
+	__s64 blksize;
+	/*
+	 * Reading/Writing Extended attributes need to acquire the appropriate
+	 * reader/writer semaphore on the pvfs2_inode_s structure.
+	 */
+	struct rw_semaphore xattr_sem;
+
+	struct inode vfs_inode;
+	sector_t last_failed_block_index_read;
+
+	/*
+	 * State of in-memory attributes not yet flushed to disk associated
+	 * with this object
+	 */
+	unsigned long pinode_flags;
+
+	/* All allocated pvfs2_inode_s objects are chained to a list */
+	struct list_head list;
+};
+
+#define P_ATIME_FLAG 0
+#define P_MTIME_FLAG 1
+#define P_CTIME_FLAG 2
+#define P_MODE_FLAG  3
+
+#define ClearAtimeFlag(pinode) clear_bit(P_ATIME_FLAG, &(pinode)->pinode_flags)
+#define SetAtimeFlag(pinode)   set_bit(P_ATIME_FLAG, &(pinode)->pinode_flags)
+#define AtimeFlag(pinode)      test_bit(P_ATIME_FLAG, &(pinode)->pinode_flags)
+
+#define ClearMtimeFlag(pinode) clear_bit(P_MTIME_FLAG, &(pinode)->pinode_flags)
+#define SetMtimeFlag(pinode)   set_bit(P_MTIME_FLAG, &(pinode)->pinode_flags)
+#define MtimeFlag(pinode)      test_bit(P_MTIME_FLAG, &(pinode)->pinode_flags)
+
+#define ClearCtimeFlag(pinode) clear_bit(P_CTIME_FLAG, &(pinode)->pinode_flags)
+#define SetCtimeFlag(pinode)   set_bit(P_CTIME_FLAG, &(pinode)->pinode_flags)
+#define CtimeFlag(pinode)      test_bit(P_CTIME_FLAG, &(pinode)->pinode_flags)
+
+#define ClearModeFlag(pinode) clear_bit(P_MODE_FLAG, &(pinode)->pinode_flags)
+#define SetModeFlag(pinode)   set_bit(P_MODE_FLAG, &(pinode)->pinode_flags)
+#define ModeFlag(pinode)      test_bit(P_MODE_FLAG, &(pinode)->pinode_flags)
+
+/* per superblock private pvfs2 info */
+struct pvfs2_sb_info_s {
+	struct pvfs2_khandle root_khandle;
+	__s32 fs_id;
+	int id;
+	int flags;
+#define PVFS2_OPT_INTR		0x01
+#define PVFS2_OPT_LOCAL_LOCK	0x02
+	char devname[PVFS_MAX_SERVER_ADDR_LEN];
+	struct super_block *sb;
+	int mount_pending;
+	struct list_head list;
+};
+
+/*
+ * a temporary structure used only for sb mount time that groups the
+ * mount time data provided along with a private superblock structure
+ * that is allocated before a 'kernel' superblock is allocated.
+*/
+struct pvfs2_mount_sb_info_s {
+	void *data;
+	struct pvfs2_khandle root_khandle;
+	__s32 fs_id;
+	int id;
+};
+
+/*
+ * structure that holds the state of any async I/O operation issued
+ * through the VFS. Needed especially to handle cancellation requests
+ * or even completion notification so that the VFS client-side daemon
+ * can free up its vfs_request slots.
+ */
+struct pvfs2_kiocb_s {
+	/* the pointer to the task that initiated the AIO */
+	struct task_struct *tsk;
+
+	/* pointer to the kiocb that kicked this operation */
+	struct kiocb *kiocb;
+
+	/* buffer index that was used for the I/O */
+	struct pvfs2_bufmap *bufmap;
+	int buffer_index;
+
+	/* pvfs2 kernel operation type */
+	struct pvfs2_kernel_op_s *op;
+
+	/* The user space buffers from/to which I/O is being staged */
+	struct iovec *iov;
+
+	/* number of elements in the iovector */
+	unsigned long nr_segs;
+
+	/* set to indicate the type of the operation */
+	int rw;
+
+	/* file offset */
+	loff_t offset;
+
+	/* and the count in bytes */
+	size_t bytes_to_be_copied;
+
+	ssize_t bytes_copied;
+	int needs_cleanup;
+};
+
+struct pvfs2_stats {
+	unsigned long cache_hits;
+	unsigned long cache_misses;
+	unsigned long reads;
+	unsigned long writes;
+};
+
+extern struct pvfs2_stats g_pvfs2_stats;
+
+/*
+  NOTE: See Documentation/filesystems/porting for information
+  on implementing FOO_I and properly accessing fs private data
+*/
+static inline struct pvfs2_inode_s *PVFS2_I(struct inode *inode)
+{
+	return container_of(inode, struct pvfs2_inode_s, vfs_inode);
+}
+
+static inline struct pvfs2_sb_info_s *PVFS2_SB(struct super_block *sb)
+{
+	return (struct pvfs2_sb_info_s *) sb->s_fs_info;
+}
+
+/* ino_t descends from "unsigned long", 8 bytes, 64 bits. */
+static inline ino_t pvfs2_khandle_to_ino(struct pvfs2_khandle *khandle)
+{
+	union {
+		unsigned char u[8];
+		__u64 ino;
+	} ihandle;
+
+	ihandle.u[0] = khandle->u[0] ^ khandle->u[4];
+	ihandle.u[1] = khandle->u[1] ^ khandle->u[5];
+	ihandle.u[2] = khandle->u[2] ^ khandle->u[6];
+	ihandle.u[3] = khandle->u[3] ^ khandle->u[7];
+	ihandle.u[4] = khandle->u[12] ^ khandle->u[8];
+	ihandle.u[5] = khandle->u[13] ^ khandle->u[9];
+	ihandle.u[6] = khandle->u[14] ^ khandle->u[10];
+	ihandle.u[7] = khandle->u[15] ^ khandle->u[11];
+
+	return ihandle.ino;
+}
+
+static inline struct pvfs2_khandle *get_khandle_from_ino(struct inode *inode)
+{
+	return &(PVFS2_I(inode)->refn.khandle);
+}
+
+static inline __s32 get_fsid_from_ino(struct inode *inode)
+{
+	return PVFS2_I(inode)->refn.fs_id;
+}
+
+static inline ino_t get_ino_from_khandle(struct inode *inode)
+{
+	struct pvfs2_khandle *khandle;
+	ino_t ino;
+
+	khandle = get_khandle_from_ino(inode);
+	ino = pvfs2_khandle_to_ino(khandle);
+	return ino;
+}
+
+static inline ino_t get_parent_ino_from_dentry(struct dentry *dentry)
+{
+	return get_ino_from_khandle(dentry->d_parent->d_inode);
+}
+
+static inline int is_root_handle(struct inode *inode)
+{
+	gossip_debug(GOSSIP_DCACHE_DEBUG,
+		     "%s: root handle: %pU, this handle: %pU:\n",
+		     __func__,
+		     &PVFS2_SB(inode->i_sb)->root_khandle,
+		     get_khandle_from_ino(inode));
+
+	if (PVFS_khandle_cmp(&(PVFS2_SB(inode->i_sb)->root_khandle),
+			     get_khandle_from_ino(inode)))
+		return 0;
+	else
+		return 1;
+}
+
+static inline int match_handle(struct pvfs2_khandle resp_handle,
+			       struct inode *inode)
+{
+	gossip_debug(GOSSIP_DCACHE_DEBUG,
+		     "%s: one handle: %pU, another handle:%pU:\n",
+		     __func__,
+		     &resp_handle,
+		     get_khandle_from_ino(inode));
+
+	if (PVFS_khandle_cmp(&resp_handle, get_khandle_from_ino(inode)))
+		return 0;
+	else
+		return 1;
+}
+
+/*
+ * defined in pvfs2-cache.c
+ */
+int op_cache_initialize(void);
+int op_cache_finalize(void);
+struct pvfs2_kernel_op_s *op_alloc(__s32 type);
+struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type);
+char *get_opname_string(struct pvfs2_kernel_op_s *new_op);
+void op_release(struct pvfs2_kernel_op_s *op);
+
+int dev_req_cache_initialize(void);
+int dev_req_cache_finalize(void);
+void *dev_req_alloc(void);
+void dev_req_release(void *);
+
+int pvfs2_inode_cache_initialize(void);
+int pvfs2_inode_cache_finalize(void);
+
+int kiocb_cache_initialize(void);
+int kiocb_cache_finalize(void);
+struct pvfs2_kiocb_s *kiocb_alloc(void);
+void kiocb_release(struct pvfs2_kiocb_s *ptr);
+
+/*
+ * defined in pvfs2-mod.c
+ */
+void purge_inprogress_ops(void);
+
+/*
+ * defined in waitqueue.c
+ */
+int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op);
+int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op);
+void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op);
+void purge_waiting_ops(void);
+
+/*
+ * defined in super.c
+ */
+struct dentry *pvfs2_mount(struct file_system_type *fst,
+			   int flags,
+			   const char *devname,
+			   void *data);
+
+void pvfs2_kill_sb(struct super_block *sb);
+int pvfs2_remount(struct super_block *sb);
+
+int fsid_key_table_initialize(void);
+void fsid_key_table_finalize(void);
+
+/*
+ * defined in inode.c
+ */
+__u32 convert_to_pvfs2_mask(unsigned long lite_mask);
+struct inode *pvfs2_new_inode(struct super_block *sb,
+			      struct inode *dir,
+			      int mode,
+			      dev_t dev,
+			      struct pvfs2_object_kref *ref);
+
+int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr);
+
+int pvfs2_getattr(struct vfsmount *mnt,
+		  struct dentry *dentry,
+		  struct kstat *kstat);
+
+/*
+ * defined in xattr.c
+ */
+int pvfs2_setxattr(struct dentry *dentry,
+		   const char *name,
+		   const void *value,
+		   size_t size,
+		   int flags);
+
+ssize_t pvfs2_getxattr(struct dentry *dentry,
+		       const char *name,
+		       void *buffer,
+		       size_t size);
+
+ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size);
+
+/*
+ * defined in namei.c
+ */
+struct inode *pvfs2_iget(struct super_block *sb,
+			 struct pvfs2_object_kref *ref);
+
+ssize_t pvfs2_inode_read(struct inode *inode,
+			 char __user *buf,
+			 size_t count,
+			 loff_t *offset,
+			 loff_t readahead_size);
+
+/*
+ * defined in devpvfs2-req.c
+ */
+int pvfs2_dev_init(void);
+void pvfs2_dev_cleanup(void);
+int is_daemon_in_service(void);
+int fs_mount_pending(__s32 fsid);
+
+/*
+ * defined in pvfs2-utils.c
+ */
+__s32 fsid_of_op(struct pvfs2_kernel_op_s *op);
+
+int pvfs2_flush_inode(struct inode *inode);
+
+ssize_t pvfs2_inode_getxattr(struct inode *inode,
+			     const char *prefix,
+			     const char *name,
+			     void *buffer,
+			     size_t size);
+
+int pvfs2_inode_setxattr(struct inode *inode,
+			 const char *prefix,
+			 const char *name,
+			 const void *value,
+			 size_t size,
+			 int flags);
+
+int pvfs2_inode_getattr(struct inode *inode, __u32 mask);
+
+int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr);
+
+void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op);
+
+void pvfs2_make_bad_inode(struct inode *inode);
+
+void mask_blocked_signals(sigset_t *orig_sigset);
+
+void unmask_blocked_signals(sigset_t *orig_sigset);
+
+int pvfs2_unmount_sb(struct super_block *sb);
+
+int pvfs2_cancel_op_in_progress(__u64 tag);
+
+__u64 pvfs2_convert_time_field(void *time_ptr);
+
+int pvfs2_normalize_to_errno(__s32 error_code);
+
+extern struct mutex devreq_mutex;
+extern struct mutex request_mutex;
+extern int debug;
+extern int op_timeout_secs;
+extern int slot_timeout_secs;
+extern struct list_head pvfs2_superblocks;
+extern spinlock_t pvfs2_superblocks_lock;
+extern struct list_head pvfs2_request_list;
+extern spinlock_t pvfs2_request_list_lock;
+extern wait_queue_head_t pvfs2_request_list_waitq;
+extern struct list_head *htable_ops_in_progress;
+extern spinlock_t htable_ops_in_progress_lock;
+extern int hash_table_size;
+
+extern const struct address_space_operations pvfs2_address_operations;
+extern struct backing_dev_info pvfs2_backing_dev_info;
+extern struct inode_operations pvfs2_file_inode_operations;
+extern const struct file_operations pvfs2_file_operations;
+extern struct inode_operations pvfs2_symlink_inode_operations;
+extern struct inode_operations pvfs2_dir_inode_operations;
+extern const struct file_operations pvfs2_dir_operations;
+extern const struct dentry_operations pvfs2_dentry_operations;
+extern const struct file_operations pvfs2_devreq_file_operations;
+
+extern wait_queue_head_t pvfs2_bufmap_init_waitq;
+
+/*
+ * misc convenience macros
+ */
+#define add_op_to_request_list(op)				\
+do {								\
+	spin_lock(&pvfs2_request_list_lock);			\
+	spin_lock(&op->lock);					\
+	set_op_state_waiting(op);				\
+	list_add_tail(&op->list, &pvfs2_request_list);		\
+	spin_unlock(&pvfs2_request_list_lock);			\
+	spin_unlock(&op->lock);					\
+	wake_up_interruptible(&pvfs2_request_list_waitq);	\
+} while (0)
+
+#define add_priority_op_to_request_list(op)				\
+	do {								\
+		spin_lock(&pvfs2_request_list_lock);			\
+		spin_lock(&op->lock);					\
+		set_op_state_waiting(op);				\
+									\
+		list_add(&op->list, &pvfs2_request_list);		\
+		spin_unlock(&pvfs2_request_list_lock);			\
+		spin_unlock(&op->lock);					\
+		wake_up_interruptible(&pvfs2_request_list_waitq);	\
+} while (0)
+
+#define remove_op_from_request_list(op)					\
+	do {								\
+		struct list_head *tmp = NULL;				\
+		struct list_head *tmp_safe = NULL;			\
+		struct pvfs2_kernel_op_s *tmp_op = NULL;		\
+									\
+		spin_lock(&pvfs2_request_list_lock);			\
+		list_for_each_safe(tmp, tmp_safe, &pvfs2_request_list) { \
+			tmp_op = list_entry(tmp,			\
+					    struct pvfs2_kernel_op_s,	\
+					    list);			\
+			if (tmp_op && (tmp_op == op)) {			\
+				list_del(&tmp_op->list);		\
+				break;					\
+			}						\
+		}							\
+		spin_unlock(&pvfs2_request_list_lock);			\
+	} while (0)
+
+#define PVFS2_OP_INTERRUPTIBLE 1   /* service_operation() is interruptible */
+#define PVFS2_OP_PRIORITY      2   /* service_operation() is high priority */
+#define PVFS2_OP_CANCELLATION  4   /* this is a cancellation */
+#define PVFS2_OP_NO_SEMAPHORE  8   /* don't acquire semaphore */
+#define PVFS2_OP_ASYNC         16  /* Queue it, but don't wait */
+
+int service_operation(struct pvfs2_kernel_op_s *op,
+		      const char *op_name,
+		      int flags);
+
+/*
+ * handles two possible error cases, depending on context.
+ *
+ * by design, our vfs i/o errors need to be handled in one of two ways,
+ * depending on where the error occured.
+ *
+ * if the error happens in the waitqueue code because we either timed
+ * out or a signal was raised while waiting, we need to cancel the
+ * userspace i/o operation and free the op manually.  this is done to
+ * avoid having the device start writing application data to our shared
+ * bufmap pages without us expecting it.
+ *
+ * FIXME: POSSIBLE OPTIMIZATION:
+ * However, if we timed out or if we got a signal AND our upcall was never
+ * picked off the queue (i.e. we were in OP_VFS_STATE_WAITING), then we don't
+ * need to send a cancellation upcall. The way we can handle this is
+ * set error_exit to 2 in such cases and 1 whenever cancellation has to be
+ * sent and have handle_error
+ * take care of this situation as well..
+ *
+ * if a pvfs2 sysint level error occured and i/o has been completed,
+ * there is no need to cancel the operation, as the user has finished
+ * using the bufmap page and so there is no danger in this case.  in
+ * this case, we wake up the device normally so that it may free the
+ * op, as normal.
+ *
+ * note the only reason this is a macro is because both read and write
+ * cases need the exact same handling code.
+ */
+#define handle_io_error()					\
+do {								\
+	if (!op_state_serviced(new_op)) {			\
+		pvfs2_cancel_op_in_progress(new_op->tag);	\
+		op_release(new_op);				\
+	} else {						\
+		wake_up_daemon_for_return(new_op);		\
+	}							\
+	new_op = NULL;						\
+	pvfs_bufmap_put(bufmap, buffer_index);				\
+	buffer_index = -1;					\
+} while (0)
+
+#define get_interruptible_flag(inode) \
+	((PVFS2_SB(inode->i_sb)->flags & PVFS2_OPT_INTR) ? \
+		PVFS2_OP_INTERRUPTIBLE : 0)
+
+#define add_pvfs2_sb(sb)						\
+do {									\
+	gossip_debug(GOSSIP_SUPER_DEBUG,				\
+		     "Adding SB %p to pvfs2 superblocks\n",		\
+		     PVFS2_SB(sb));					\
+	spin_lock(&pvfs2_superblocks_lock);				\
+	list_add_tail(&PVFS2_SB(sb)->list, &pvfs2_superblocks);		\
+	spin_unlock(&pvfs2_superblocks_lock); \
+} while (0)
+
+#define remove_pvfs2_sb(sb)						\
+do {									\
+	struct list_head *tmp = NULL;					\
+	struct list_head *tmp_safe = NULL;				\
+	struct pvfs2_sb_info_s *pvfs2_sb = NULL;			\
+									\
+	spin_lock(&pvfs2_superblocks_lock);				\
+	list_for_each_safe(tmp, tmp_safe, &pvfs2_superblocks) {		\
+		pvfs2_sb = list_entry(tmp,				\
+				      struct pvfs2_sb_info_s,		\
+				      list);				\
+		if (pvfs2_sb && (pvfs2_sb->sb == sb)) {			\
+			gossip_debug(GOSSIP_SUPER_DEBUG,		\
+			    "Removing SB %p from pvfs2 superblocks\n",	\
+			pvfs2_sb);					\
+			list_del(&pvfs2_sb->list);			\
+			break;						\
+		}							\
+	}								\
+	spin_unlock(&pvfs2_superblocks_lock);				\
+} while (0)
+
+#define pvfs2_lock_inode(inode) spin_lock(&inode->i_lock)
+#define pvfs2_unlock_inode(inode) spin_unlock(&inode->i_lock)
+#define pvfs2_current_signal_lock current->sighand->siglock
+#define pvfs2_current_sigaction current->sighand->action
+
+#define fill_default_sys_attrs(sys_attr, type, mode)			\
+do {									\
+	sys_attr.owner = from_kuid(current_user_ns(), current_fsuid()); \
+	sys_attr.group = from_kgid(current_user_ns(), current_fsgid()); \
+	sys_attr.size = 0;						\
+	sys_attr.perms = PVFS_util_translate_mode(mode);		\
+	sys_attr.objtype = type;					\
+	sys_attr.mask = PVFS_ATTR_SYS_ALL_SETABLE;			\
+} while (0)
+
+#define pvfs2_inode_lock(__i)  mutex_lock(&(__i)->i_mutex)
+
+#define pvfs2_inode_unlock(__i) mutex_unlock(&(__i)->i_mutex)
+
+static inline void pvfs2_i_size_write(struct inode *inode, loff_t i_size)
+{
+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
+	pvfs2_inode_lock(inode);
+#endif
+	i_size_write(inode, i_size);
+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
+	pvfs2_inode_unlock(inode);
+#endif
+}
+
+static inline unsigned int diff(struct timeval *end, struct timeval *begin)
+{
+	if (end->tv_usec < begin->tv_usec) {
+		end->tv_usec += 1000000;
+		end->tv_sec--;
+	}
+	end->tv_sec -= begin->tv_sec;
+	end->tv_usec -= begin->tv_usec;
+	return (end->tv_sec * 1000000) + end->tv_usec;
+}
+
+#endif /* __PVFS2KERNEL_H */
diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c
new file mode 100644
index 000000000000..d80537dadcd8
--- /dev/null
+++ b/fs/orangefs/pvfs2-mod.c
@@ -0,0 +1,315 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * Changes by Acxiom Corporation to add proc file handler for pvfs2 client
+ * parameters, Copyright Acxiom Corporation, 2005.
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-debugfs.h"
+#include "pvfs2-sysfs.h"
+
+/* PVFS2_VERSION is a ./configure define */
+#ifndef PVFS2_VERSION
+#define PVFS2_VERSION "Unknown"
+#endif
+
+/*
+ * global variables declared here
+ */
+
+/* array of client debug keyword/mask values */
+struct client_debug_mask *cdm_array;
+int cdm_element_count;
+
+char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN] = "none";
+char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN];
+char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN];
+
+char *debug_help_string;
+int help_string_initialized;
+struct dentry *help_file_dentry;
+struct dentry *client_debug_dentry;
+struct dentry *debug_dir;
+int client_verbose_index;
+int client_all_index;
+struct pvfs2_stats g_pvfs2_stats;
+
+/* the size of the hash tables for ops in progress */
+int hash_table_size = 509;
+
+static ulong module_parm_debug_mask;
+__u64 gossip_debug_mask;
+struct client_debug_mask client_debug_mask = { NULL, 0, 0 };
+unsigned int kernel_mask_set_mod_init; /* implicitly false */
+int op_timeout_secs = PVFS2_DEFAULT_OP_TIMEOUT_SECS;
+int slot_timeout_secs = PVFS2_DEFAULT_SLOT_TIMEOUT_SECS;
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("PVFS2 Development Team");
+MODULE_DESCRIPTION("The Linux Kernel VFS interface to PVFS2");
+MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see pvfs2-debug.h for values)");
+MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds");
+MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds");
+MODULE_PARM_DESC(hash_table_size,
+		 "size of hash table for operations in progress");
+
+static struct file_system_type pvfs2_fs_type = {
+	.name = "pvfs2",
+	.mount = pvfs2_mount,
+	.kill_sb = pvfs2_kill_sb,
+	.owner = THIS_MODULE,
+};
+
+module_param(hash_table_size, int, 0);
+module_param(module_parm_debug_mask, ulong, 0644);
+module_param(op_timeout_secs, int, 0);
+module_param(slot_timeout_secs, int, 0);
+
+/* synchronizes the request device file */
+struct mutex devreq_mutex;
+
+/*
+  blocks non-priority requests from being queued for servicing.  this
+  could be used for protecting the request list data structure, but
+  for now it's only being used to stall the op addition to the request
+  list
+*/
+struct mutex request_mutex;
+
+/* hash table for storing operations waiting for matching downcall */
+struct list_head *htable_ops_in_progress;
+DEFINE_SPINLOCK(htable_ops_in_progress_lock);
+
+/* list for queueing upcall operations */
+LIST_HEAD(pvfs2_request_list);
+
+/* used to protect the above pvfs2_request_list */
+DEFINE_SPINLOCK(pvfs2_request_list_lock);
+
+/* used for incoming request notification */
+DECLARE_WAIT_QUEUE_HEAD(pvfs2_request_list_waitq);
+
+static int __init pvfs2_init(void)
+{
+	int ret = -1;
+	__u32 i = 0;
+
+	/* convert input debug mask to a 64-bit unsigned integer */
+	gossip_debug_mask = (unsigned long long) module_parm_debug_mask;
+
+	/*
+	 * set the kernel's gossip debug string; invalid mask values will
+	 * be ignored.
+	 */
+	debug_mask_to_string(&gossip_debug_mask, 0);
+
+	/* remove any invalid values from the mask */
+	debug_string_to_mask(kernel_debug_string, &gossip_debug_mask, 0);
+
+	/*
+	 * if the mask has a non-zero value, then indicate that the mask
+	 * was set when the kernel module was loaded.  The pvfs2 dev ioctl
+	 * command will look at this boolean to determine if the kernel's
+	 * debug mask should be overwritten when the client-core is started.
+	 */
+	if (gossip_debug_mask != 0)
+		kernel_mask_set_mod_init = true;
+
+	/* print information message to the system log */
+	pr_info("pvfs2: pvfs2_init called with debug mask: :%s: :%llx:\n",
+	       kernel_debug_string,
+	       (unsigned long long)gossip_debug_mask);
+
+	ret = bdi_init(&pvfs2_backing_dev_info);
+
+	if (ret)
+		return ret;
+
+	if (op_timeout_secs < 0)
+		op_timeout_secs = 0;
+
+	if (slot_timeout_secs < 0)
+		slot_timeout_secs = 0;
+
+	/* initialize global book keeping data structures */
+	ret = op_cache_initialize();
+	if (ret < 0)
+		goto err;
+
+	ret = dev_req_cache_initialize();
+	if (ret < 0)
+		goto cleanup_op;
+
+	ret = pvfs2_inode_cache_initialize();
+	if (ret < 0)
+		goto cleanup_req;
+
+	ret = kiocb_cache_initialize();
+	if (ret  < 0)
+		goto cleanup_inode;
+
+	/* Initialize the pvfsdev subsystem. */
+	ret = pvfs2_dev_init();
+	if (ret < 0) {
+		gossip_err("pvfs2: could not initialize device subsystem %d!\n",
+			   ret);
+		goto cleanup_kiocb;
+	}
+
+	mutex_init(&devreq_mutex);
+	mutex_init(&request_mutex);
+
+	htable_ops_in_progress =
+	    kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL);
+	if (!htable_ops_in_progress) {
+		gossip_err("Failed to initialize op hashtable");
+		ret = -ENOMEM;
+		goto cleanup_device;
+	}
+
+	/* initialize a doubly linked at each hash table index */
+	for (i = 0; i < hash_table_size; i++)
+		INIT_LIST_HEAD(&htable_ops_in_progress[i]);
+
+	ret = fsid_key_table_initialize();
+	if (ret < 0)
+		goto cleanup_progress_table;
+
+	/*
+	 * Build the contents of /sys/kernel/debug/orangefs/debug-help
+	 * from the keywords in the kernel keyword/mask array.
+	 *
+	 * The keywords in the client keyword/mask array are
+	 * unknown at boot time.
+	 *
+	 * orangefs_prepare_debugfs_help_string will be used again
+	 * later to rebuild the debug-help file after the client starts
+	 * and passes along the needed info. The argument signifies
+	 * which time orangefs_prepare_debugfs_help_string is being
+	 * called.
+	 *
+	 */
+	ret = orangefs_prepare_debugfs_help_string(1);
+	if (ret)
+		goto out;
+
+	pvfs2_debugfs_init();
+	pvfs2_kernel_debug_init();
+	orangefs_sysfs_init();
+
+	ret = register_filesystem(&pvfs2_fs_type);
+	if (ret == 0) {
+		pr_info("pvfs2: module version %s loaded\n", PVFS2_VERSION);
+		return 0;
+	}
+
+	pvfs2_debugfs_cleanup();
+	orangefs_sysfs_exit();
+	fsid_key_table_finalize();
+
+cleanup_progress_table:
+	kfree(htable_ops_in_progress);
+
+cleanup_device:
+	pvfs2_dev_cleanup();
+
+cleanup_kiocb:
+	kiocb_cache_finalize();
+
+cleanup_inode:
+	pvfs2_inode_cache_finalize();
+
+cleanup_req:
+	dev_req_cache_finalize();
+
+cleanup_op:
+	op_cache_finalize();
+
+err:
+	bdi_destroy(&pvfs2_backing_dev_info);
+
+out:
+	return ret;
+}
+
+static void __exit pvfs2_exit(void)
+{
+	int i = 0;
+	struct pvfs2_kernel_op_s *cur_op = NULL;
+
+	gossip_debug(GOSSIP_INIT_DEBUG, "pvfs2: pvfs2_exit called\n");
+
+	unregister_filesystem(&pvfs2_fs_type);
+	pvfs2_debugfs_cleanup();
+	orangefs_sysfs_exit();
+	fsid_key_table_finalize();
+	pvfs2_dev_cleanup();
+	/* clear out all pending upcall op requests */
+	spin_lock(&pvfs2_request_list_lock);
+	while (!list_empty(&pvfs2_request_list)) {
+		cur_op = list_entry(pvfs2_request_list.next,
+				    struct pvfs2_kernel_op_s,
+				    list);
+		list_del(&cur_op->list);
+		gossip_debug(GOSSIP_INIT_DEBUG,
+			     "Freeing unhandled upcall request type %d\n",
+			     cur_op->upcall.type);
+		op_release(cur_op);
+	}
+	spin_unlock(&pvfs2_request_list_lock);
+
+	for (i = 0; i < hash_table_size; i++)
+		while (!list_empty(&htable_ops_in_progress[i])) {
+			cur_op = list_entry(htable_ops_in_progress[i].next,
+					    struct pvfs2_kernel_op_s,
+					    list);
+			op_release(cur_op);
+		}
+
+	kiocb_cache_finalize();
+	pvfs2_inode_cache_finalize();
+	dev_req_cache_finalize();
+	op_cache_finalize();
+
+	kfree(htable_ops_in_progress);
+
+	bdi_destroy(&pvfs2_backing_dev_info);
+
+	pr_info("pvfs2: module version %s unloaded\n", PVFS2_VERSION);
+}
+
+/*
+ * What we do in this function is to walk the list of operations
+ * that are in progress in the hash table and mark them as purged as well.
+ */
+void purge_inprogress_ops(void)
+{
+	int i;
+
+	for (i = 0; i < hash_table_size; i++) {
+		struct pvfs2_kernel_op_s *op;
+		struct pvfs2_kernel_op_s *next;
+
+		list_for_each_entry_safe(op,
+					 next,
+					 &htable_ops_in_progress[i],
+					 list) {
+			spin_lock(&op->lock);
+			gossip_debug(GOSSIP_INIT_DEBUG,
+				"pvfs2-client-core: purging in-progress op tag "
+				"%llu %s\n",
+				llu(op->tag),
+				get_opname_string(op));
+			set_op_state_purged(op);
+			spin_unlock(&op->lock);
+			wake_up_interruptible(&op->waitq);
+		}
+	}
+}
+
+module_init(pvfs2_init);
+module_exit(pvfs2_exit);
diff --git a/fs/orangefs/pvfs2-sysfs.c b/fs/orangefs/pvfs2-sysfs.c
new file mode 100644
index 000000000000..ea635b5e431b
--- /dev/null
+++ b/fs/orangefs/pvfs2-sysfs.c
@@ -0,0 +1,1787 @@
+/*
+ * Documentation/ABI/stable/orangefs-sysfs:
+ *
+ * What:		/sys/fs/orangefs/perf_counter_reset
+ * Date:		June 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			echo a 0 or a 1 into perf_counter_reset to
+ * 			reset all the counters in
+ * 			/sys/fs/orangefs/perf_counters
+ * 			except ones with PINT_PERF_PRESERVE set.
+ *
+ *
+ * What:		/sys/fs/orangefs/perf_counters/...
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Counters and settings for various caches.
+ * 			Read only.
+ *
+ *
+ * What:		/sys/fs/orangefs/perf_time_interval_secs
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ *			Length of perf counter intervals in
+ *			seconds.
+ *
+ *
+ * What:		/sys/fs/orangefs/perf_history_size
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			The perf_counters cache statistics have N, or
+ * 			perf_history_size, samples. The default is
+ * 			one.
+ *
+ *			Every perf_time_interval_secs the (first)
+ *			samples are reset.
+ *
+ *			If N is greater than one, the "current" set
+ *			of samples is reset, and the samples from the
+ *			other N-1 intervals remain available.
+ *
+ *
+ * What:		/sys/fs/orangefs/op_timeout_secs
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ *			Service operation timeout in seconds.
+ *
+ *
+ * What:		/sys/fs/orangefs/slot_timeout_secs
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ *			"Slot" timeout in seconds. A "slot"
+ *			is an indexed buffer in the shared
+ *			memory segment used for communication
+ *			between the kernel module and userspace.
+ *			Slots are requested and waited for,
+ *			the wait times out after slot_timeout_secs.
+ *
+ *
+ * What:		/sys/fs/orangefs/acache/...
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Attribute cache configurable settings.
+ *
+ *
+ * What:		/sys/fs/orangefs/ncache/...
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Name cache configurable settings.
+ *
+ *
+ * What:		/sys/fs/orangefs/capcache/...
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Capability cache configurable settings.
+ *
+ *
+ * What:		/sys/fs/orangefs/ccache/...
+ * Date:		Jun 2015
+ * Contact:		Mike Marshall <hubcap@omnibond.com>
+ * Description:
+ * 			Credential cache configurable settings.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-sysfs.h"
+
+#define ORANGEFS_KOBJ_ID "orangefs"
+#define ACACHE_KOBJ_ID "acache"
+#define CAPCACHE_KOBJ_ID "capcache"
+#define CCACHE_KOBJ_ID "ccache"
+#define NCACHE_KOBJ_ID "ncache"
+#define PC_KOBJ_ID "pc"
+#define STATS_KOBJ_ID "stats"
+
+struct orangefs_obj {
+	struct kobject kobj;
+	int op_timeout_secs;
+	int perf_counter_reset;
+	int perf_history_size;
+	int perf_time_interval_secs;
+	int slot_timeout_secs;
+};
+
+struct acache_orangefs_obj {
+	struct kobject kobj;
+	int hard_limit;
+	int reclaim_percentage;
+	int soft_limit;
+	int timeout_msecs;
+};
+
+struct capcache_orangefs_obj {
+	struct kobject kobj;
+	int hard_limit;
+	int reclaim_percentage;
+	int soft_limit;
+	int timeout_secs;
+};
+
+struct ccache_orangefs_obj {
+	struct kobject kobj;
+	int hard_limit;
+	int reclaim_percentage;
+	int soft_limit;
+	int timeout_secs;
+};
+
+struct ncache_orangefs_obj {
+	struct kobject kobj;
+	int hard_limit;
+	int reclaim_percentage;
+	int soft_limit;
+	int timeout_msecs;
+};
+
+struct pc_orangefs_obj {
+	struct kobject kobj;
+	char *acache;
+	char *capcache;
+	char *ncache;
+};
+
+struct stats_orangefs_obj {
+	struct kobject kobj;
+	int reads;
+	int writes;
+};
+
+struct orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct orangefs_obj *orangefs_obj,
+			struct orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct orangefs_obj *orangefs_obj,
+			 struct orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct acache_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct acache_orangefs_obj *acache_orangefs_obj,
+			struct acache_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct acache_orangefs_obj *acache_orangefs_obj,
+			 struct acache_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct capcache_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct capcache_orangefs_obj *capcache_orangefs_obj,
+			struct capcache_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct capcache_orangefs_obj *capcache_orangefs_obj,
+			 struct capcache_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct ccache_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct ccache_orangefs_obj *ccache_orangefs_obj,
+			struct ccache_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct ccache_orangefs_obj *ccache_orangefs_obj,
+			 struct ccache_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct ncache_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct ncache_orangefs_obj *ncache_orangefs_obj,
+			struct ncache_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct ncache_orangefs_obj *ncache_orangefs_obj,
+			 struct ncache_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct pc_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct pc_orangefs_obj *pc_orangefs_obj,
+			struct pc_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct pc_orangefs_obj *pc_orangefs_obj,
+			 struct pc_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+struct stats_orangefs_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct stats_orangefs_obj *stats_orangefs_obj,
+			struct stats_orangefs_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct stats_orangefs_obj *stats_orangefs_obj,
+			 struct stats_orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count);
+};
+
+static ssize_t orangefs_attr_show(struct kobject *kobj,
+				  struct attribute *attr,
+				  char *buf)
+{
+	struct orangefs_attribute *attribute;
+	struct orangefs_obj *orangefs_obj;
+	int rc;
+
+	attribute = container_of(attr, struct orangefs_attribute, attr);
+	orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static ssize_t orangefs_attr_store(struct kobject *kobj,
+				   struct attribute *attr,
+				   const char *buf,
+				   size_t len)
+{
+	struct orangefs_attribute *attribute;
+	struct orangefs_obj *orangefs_obj;
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "orangefs_attr_store: start\n");
+
+	attribute = container_of(attr, struct orangefs_attribute, attr);
+	orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
+
+	if (!attribute->store) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->store(orangefs_obj, attribute, buf, len);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops orangefs_sysfs_ops = {
+	.show = orangefs_attr_show,
+	.store = orangefs_attr_store,
+};
+
+static ssize_t acache_orangefs_attr_show(struct kobject *kobj,
+					 struct attribute *attr,
+					 char *buf)
+{
+	struct acache_orangefs_attribute *attribute;
+	struct acache_orangefs_obj *acache_orangefs_obj;
+	int rc;
+
+	attribute = container_of(attr, struct acache_orangefs_attribute, attr);
+	acache_orangefs_obj =
+		container_of(kobj, struct acache_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(acache_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static ssize_t acache_orangefs_attr_store(struct kobject *kobj,
+					  struct attribute *attr,
+					  const char *buf,
+					  size_t len)
+{
+	struct acache_orangefs_attribute *attribute;
+	struct acache_orangefs_obj *acache_orangefs_obj;
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "acache_orangefs_attr_store: start\n");
+
+	attribute = container_of(attr, struct acache_orangefs_attribute, attr);
+	acache_orangefs_obj =
+		container_of(kobj, struct acache_orangefs_obj, kobj);
+
+	if (!attribute->store) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->store(acache_orangefs_obj, attribute, buf, len);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops acache_orangefs_sysfs_ops = {
+	.show = acache_orangefs_attr_show,
+	.store = acache_orangefs_attr_store,
+};
+
+static ssize_t capcache_orangefs_attr_show(struct kobject *kobj,
+					   struct attribute *attr,
+					   char *buf)
+{
+	struct capcache_orangefs_attribute *attribute;
+	struct capcache_orangefs_obj *capcache_orangefs_obj;
+	int rc;
+
+	attribute =
+		container_of(attr, struct capcache_orangefs_attribute, attr);
+	capcache_orangefs_obj =
+		container_of(kobj, struct capcache_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(capcache_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static ssize_t capcache_orangefs_attr_store(struct kobject *kobj,
+					    struct attribute *attr,
+					    const char *buf,
+					    size_t len)
+{
+	struct capcache_orangefs_attribute *attribute;
+	struct capcache_orangefs_obj *capcache_orangefs_obj;
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "capcache_orangefs_attr_store: start\n");
+
+	attribute =
+		container_of(attr, struct capcache_orangefs_attribute, attr);
+	capcache_orangefs_obj =
+		container_of(kobj, struct capcache_orangefs_obj, kobj);
+
+	if (!attribute->store) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->store(capcache_orangefs_obj, attribute, buf, len);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops capcache_orangefs_sysfs_ops = {
+	.show = capcache_orangefs_attr_show,
+	.store = capcache_orangefs_attr_store,
+};
+
+static ssize_t ccache_orangefs_attr_show(struct kobject *kobj,
+					 struct attribute *attr,
+					 char *buf)
+{
+	struct ccache_orangefs_attribute *attribute;
+	struct ccache_orangefs_obj *ccache_orangefs_obj;
+	int rc;
+
+	attribute =
+		container_of(attr, struct ccache_orangefs_attribute, attr);
+	ccache_orangefs_obj =
+		container_of(kobj, struct ccache_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(ccache_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static ssize_t ccache_orangefs_attr_store(struct kobject *kobj,
+					  struct attribute *attr,
+					  const char *buf,
+					  size_t len)
+{
+	struct ccache_orangefs_attribute *attribute;
+	struct ccache_orangefs_obj *ccache_orangefs_obj;
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "ccache_orangefs_attr_store: start\n");
+
+	attribute =
+		container_of(attr, struct ccache_orangefs_attribute, attr);
+	ccache_orangefs_obj =
+		container_of(kobj, struct ccache_orangefs_obj, kobj);
+
+	if (!attribute->store) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->store(ccache_orangefs_obj, attribute, buf, len);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops ccache_orangefs_sysfs_ops = {
+	.show = ccache_orangefs_attr_show,
+	.store = ccache_orangefs_attr_store,
+};
+
+static ssize_t ncache_orangefs_attr_show(struct kobject *kobj,
+					 struct attribute *attr,
+					 char *buf)
+{
+	struct ncache_orangefs_attribute *attribute;
+	struct ncache_orangefs_obj *ncache_orangefs_obj;
+	int rc;
+
+	attribute = container_of(attr, struct ncache_orangefs_attribute, attr);
+	ncache_orangefs_obj =
+		container_of(kobj, struct ncache_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(ncache_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static ssize_t ncache_orangefs_attr_store(struct kobject *kobj,
+					  struct attribute *attr,
+					  const char *buf,
+					  size_t len)
+{
+	struct ncache_orangefs_attribute *attribute;
+	struct ncache_orangefs_obj *ncache_orangefs_obj;
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "ncache_orangefs_attr_store: start\n");
+
+	attribute = container_of(attr, struct ncache_orangefs_attribute, attr);
+	ncache_orangefs_obj =
+		container_of(kobj, struct ncache_orangefs_obj, kobj);
+
+	if (!attribute->store) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->store(ncache_orangefs_obj, attribute, buf, len);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops ncache_orangefs_sysfs_ops = {
+	.show = ncache_orangefs_attr_show,
+	.store = ncache_orangefs_attr_store,
+};
+
+static ssize_t pc_orangefs_attr_show(struct kobject *kobj,
+				     struct attribute *attr,
+				     char *buf)
+{
+	struct pc_orangefs_attribute *attribute;
+	struct pc_orangefs_obj *pc_orangefs_obj;
+	int rc;
+
+	attribute = container_of(attr, struct pc_orangefs_attribute, attr);
+	pc_orangefs_obj =
+		container_of(kobj, struct pc_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(pc_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops pc_orangefs_sysfs_ops = {
+	.show = pc_orangefs_attr_show,
+};
+
+static ssize_t stats_orangefs_attr_show(struct kobject *kobj,
+					struct attribute *attr,
+					char *buf)
+{
+	struct stats_orangefs_attribute *attribute;
+	struct stats_orangefs_obj *stats_orangefs_obj;
+	int rc;
+
+	attribute = container_of(attr, struct stats_orangefs_attribute, attr);
+	stats_orangefs_obj =
+		container_of(kobj, struct stats_orangefs_obj, kobj);
+
+	if (!attribute->show) {
+		rc = -EIO;
+		goto out;
+	}
+
+	rc = attribute->show(stats_orangefs_obj, attribute, buf);
+
+out:
+	return rc;
+}
+
+static const struct sysfs_ops stats_orangefs_sysfs_ops = {
+	.show = stats_orangefs_attr_show,
+};
+
+static void orangefs_release(struct kobject *kobj)
+{
+	struct orangefs_obj *orangefs_obj;
+
+	orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
+	kfree(orangefs_obj);
+}
+
+static void acache_orangefs_release(struct kobject *kobj)
+{
+	struct acache_orangefs_obj *acache_orangefs_obj;
+
+	acache_orangefs_obj =
+		container_of(kobj, struct acache_orangefs_obj, kobj);
+	kfree(acache_orangefs_obj);
+}
+
+static void capcache_orangefs_release(struct kobject *kobj)
+{
+	struct capcache_orangefs_obj *capcache_orangefs_obj;
+
+	capcache_orangefs_obj =
+		container_of(kobj, struct capcache_orangefs_obj, kobj);
+	kfree(capcache_orangefs_obj);
+}
+
+static void ccache_orangefs_release(struct kobject *kobj)
+{
+	struct ccache_orangefs_obj *ccache_orangefs_obj;
+
+	ccache_orangefs_obj =
+		container_of(kobj, struct ccache_orangefs_obj, kobj);
+	kfree(ccache_orangefs_obj);
+}
+
+static void ncache_orangefs_release(struct kobject *kobj)
+{
+	struct ncache_orangefs_obj *ncache_orangefs_obj;
+
+	ncache_orangefs_obj =
+		container_of(kobj, struct ncache_orangefs_obj, kobj);
+	kfree(ncache_orangefs_obj);
+}
+
+static void pc_orangefs_release(struct kobject *kobj)
+{
+	struct pc_orangefs_obj *pc_orangefs_obj;
+
+	pc_orangefs_obj =
+		container_of(kobj, struct pc_orangefs_obj, kobj);
+	kfree(pc_orangefs_obj);
+}
+
+static void stats_orangefs_release(struct kobject *kobj)
+{
+	struct stats_orangefs_obj *stats_orangefs_obj;
+
+	stats_orangefs_obj =
+		container_of(kobj, struct stats_orangefs_obj, kobj);
+	kfree(stats_orangefs_obj);
+}
+
+static ssize_t sysfs_int_show(char *kobj_id, char *buf, void *attr)
+{
+	int rc = -EIO;
+	struct orangefs_attribute *orangefs_attr;
+	struct stats_orangefs_attribute *stats_orangefs_attr;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", kobj_id);
+
+	if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
+		orangefs_attr = (struct orangefs_attribute *)attr;
+
+		if (!strcmp(orangefs_attr->attr.name, "op_timeout_secs")) {
+			rc = scnprintf(buf,
+				       PAGE_SIZE,
+				       "%d\n",
+				       op_timeout_secs);
+			goto out;
+		} else if (!strcmp(orangefs_attr->attr.name,
+				   "slot_timeout_secs")) {
+			rc = scnprintf(buf,
+				       PAGE_SIZE,
+				       "%d\n",
+				       slot_timeout_secs);
+			goto out;
+		} else {
+			goto out;
+		}
+
+	} else if (!strcmp(kobj_id, STATS_KOBJ_ID)) {
+		stats_orangefs_attr = (struct stats_orangefs_attribute *)attr;
+
+		if (!strcmp(stats_orangefs_attr->attr.name, "reads")) {
+			rc = scnprintf(buf,
+				       PAGE_SIZE,
+				       "%lu\n",
+				       g_pvfs2_stats.reads);
+			goto out;
+		} else if (!strcmp(stats_orangefs_attr->attr.name, "writes")) {
+			rc = scnprintf(buf,
+				       PAGE_SIZE,
+				       "%lu\n",
+				       g_pvfs2_stats.writes);
+			goto out;
+		} else {
+			goto out;
+		}
+	}
+
+out:
+
+	return rc;
+}
+
+static ssize_t int_orangefs_show(struct orangefs_obj *orangefs_obj,
+				 struct orangefs_attribute *attr,
+				 char *buf)
+{
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "int_orangefs_show:start attr->attr.name:%s:\n",
+		     attr->attr.name);
+
+	rc = sysfs_int_show(ORANGEFS_KOBJ_ID, buf, (void *) attr);
+
+	return rc;
+}
+
+static ssize_t int_stats_show(struct stats_orangefs_obj *stats_orangefs_obj,
+			struct stats_orangefs_attribute *attr,
+			char *buf)
+{
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "int_stats_show:start attr->attr.name:%s:\n",
+		     attr->attr.name);
+
+	rc = sysfs_int_show(STATS_KOBJ_ID, buf, (void *) attr);
+
+	return rc;
+}
+
+static ssize_t int_store(struct orangefs_obj *orangefs_obj,
+			 struct orangefs_attribute *attr,
+			 const char *buf,
+			 size_t count)
+{
+	int rc = 0;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "int_store: start attr->attr.name:%s: buf:%s:\n",
+		     attr->attr.name, buf);
+
+	if (!strcmp(attr->attr.name, "op_timeout_secs")) {
+		rc = kstrtoint(buf, 0, &op_timeout_secs);
+		goto out;
+	} else if (!strcmp(attr->attr.name, "slot_timeout_secs")) {
+		rc = kstrtoint(buf, 0, &slot_timeout_secs);
+		goto out;
+	} else {
+		goto out;
+	}
+
+out:
+	if (rc)
+		rc = -EINVAL;
+	else
+		rc = count;
+
+	return rc;
+}
+
+/*
+ * obtain attribute values from userspace with a service operation.
+ */
+static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr)
+{
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	int rc = 0;
+	char *ser_op_type = NULL;
+	struct orangefs_attribute *orangefs_attr;
+	struct acache_orangefs_attribute *acache_attr;
+	struct capcache_orangefs_attribute *capcache_attr;
+	struct ccache_orangefs_attribute *ccache_attr;
+	struct ncache_orangefs_attribute *ncache_attr;
+	struct pc_orangefs_attribute *pc_attr;
+	__u32 op_alloc_type;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "sysfs_service_op_show: id:%s:\n",
+		     kobj_id);
+
+	if (strcmp(kobj_id, PC_KOBJ_ID))
+		op_alloc_type = PVFS2_VFS_OP_PARAM;
+	else
+		op_alloc_type = PVFS2_VFS_OP_PERF_COUNT;
+
+	new_op = op_alloc(op_alloc_type);
+	if (!new_op) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Can't do a service_operation if the client is not running... */
+	rc = is_daemon_in_service();
+	if (rc) {
+		pr_info("%s: Client not running :%d:\n",
+			__func__,
+			is_daemon_in_service());
+		goto out;
+	}
+
+	if (strcmp(kobj_id, PC_KOBJ_ID))
+		new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_GET;
+
+	if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
+		orangefs_attr = (struct orangefs_attribute *)attr;
+
+		if (!strcmp(orangefs_attr->attr.name, "perf_history_size"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
+		else if (!strcmp(orangefs_attr->attr.name,
+				 "perf_time_interval_secs"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
+		else if (!strcmp(orangefs_attr->attr.name,
+				 "perf_counter_reset"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_PERF_RESET;
+
+	} else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
+		acache_attr = (struct acache_orangefs_attribute *)attr;
+
+		if (!strcmp(acache_attr->attr.name, "timeout_msecs"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
+
+		if (!strcmp(acache_attr->attr.name, "hard_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
+
+		if (!strcmp(acache_attr->attr.name, "soft_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
+
+		if (!strcmp(acache_attr->attr.name, "reclaim_percentage"))
+			new_op->upcall.req.param.op =
+			  PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
+
+	} else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
+		capcache_attr = (struct capcache_orangefs_attribute *)attr;
+
+		if (!strcmp(capcache_attr->attr.name, "timeout_secs"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
+
+		if (!strcmp(capcache_attr->attr.name, "hard_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
+
+		if (!strcmp(capcache_attr->attr.name, "soft_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
+
+		if (!strcmp(capcache_attr->attr.name, "reclaim_percentage"))
+			new_op->upcall.req.param.op =
+			  PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
+
+	} else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
+		ccache_attr = (struct ccache_orangefs_attribute *)attr;
+
+		if (!strcmp(ccache_attr->attr.name, "timeout_secs"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
+
+		if (!strcmp(ccache_attr->attr.name, "hard_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
+
+		if (!strcmp(ccache_attr->attr.name, "soft_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
+
+		if (!strcmp(ccache_attr->attr.name, "reclaim_percentage"))
+			new_op->upcall.req.param.op =
+			  PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
+
+	} else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
+		ncache_attr = (struct ncache_orangefs_attribute *)attr;
+
+		if (!strcmp(ncache_attr->attr.name, "timeout_msecs"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
+
+		if (!strcmp(ncache_attr->attr.name, "hard_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
+
+		if (!strcmp(ncache_attr->attr.name, "soft_limit"))
+			new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
+
+		if (!strcmp(ncache_attr->attr.name, "reclaim_percentage"))
+			new_op->upcall.req.param.op =
+			  PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
+
+	} else if (!strcmp(kobj_id, PC_KOBJ_ID)) {
+		pc_attr = (struct pc_orangefs_attribute *)attr;
+
+		if (!strcmp(pc_attr->attr.name, ACACHE_KOBJ_ID))
+			new_op->upcall.req.perf_count.type =
+				PVFS2_PERF_COUNT_REQUEST_ACACHE;
+
+		if (!strcmp(pc_attr->attr.name, CAPCACHE_KOBJ_ID))
+			new_op->upcall.req.perf_count.type =
+				PVFS2_PERF_COUNT_REQUEST_CAPCACHE;
+
+		if (!strcmp(pc_attr->attr.name, NCACHE_KOBJ_ID))
+			new_op->upcall.req.perf_count.type =
+				PVFS2_PERF_COUNT_REQUEST_NCACHE;
+
+	} else {
+		gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n",
+			   kobj_id);
+		rc = -EINVAL;
+		goto out;
+	}
+
+
+	if (strcmp(kobj_id, PC_KOBJ_ID))
+		ser_op_type = "pvfs2_param";
+	else
+		ser_op_type = "pvfs2_perf_count";
+
+	/*
+	 * The service_operation will return an errno return code on
+	 * error, and zero on success.
+	 */
+	rc = service_operation(new_op, ser_op_type, PVFS2_OP_INTERRUPTIBLE);
+
+out:
+	if (!rc) {
+		if (strcmp(kobj_id, PC_KOBJ_ID)) {
+			rc = scnprintf(buf,
+				       PAGE_SIZE,
+				       "%d\n",
+				       (int)new_op->downcall.resp.param.value);
+		} else {
+			rc = scnprintf(
+				buf,
+				PAGE_SIZE,
+				"%s",
+				new_op->downcall.resp.perf_count.buffer);
+		}
+	}
+
+	/*
+	 * if we got ENOMEM, then op_alloc probably failed...
+	 */
+	if (rc != -ENOMEM)
+		op_release(new_op);
+
+	return rc;
+
+}
+
+static ssize_t service_orangefs_show(struct orangefs_obj *orangefs_obj,
+				     struct orangefs_attribute *attr,
+				     char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(ORANGEFS_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+static ssize_t
+	service_acache_show(struct acache_orangefs_obj *acache_orangefs_obj,
+			    struct acache_orangefs_attribute *attr,
+			    char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(ACACHE_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+static ssize_t service_capcache_show(struct capcache_orangefs_obj
+					*capcache_orangefs_obj,
+				     struct capcache_orangefs_attribute *attr,
+				     char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(CAPCACHE_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+static ssize_t service_ccache_show(struct ccache_orangefs_obj
+					*ccache_orangefs_obj,
+				   struct ccache_orangefs_attribute *attr,
+				   char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(CCACHE_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+static ssize_t
+	service_ncache_show(struct ncache_orangefs_obj *ncache_orangefs_obj,
+			    struct ncache_orangefs_attribute *attr,
+			    char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(NCACHE_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+static ssize_t
+	service_pc_show(struct pc_orangefs_obj *pc_orangefs_obj,
+			    struct pc_orangefs_attribute *attr,
+			    char *buf)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_show(PC_KOBJ_ID, buf, (void *)attr);
+
+	return rc;
+}
+
+/*
+ * pass attribute values back to userspace with a service operation.
+ *
+ * We have to do a memory allocation, an sscanf and a service operation.
+ * And we have to evaluate what the user entered, to make sure the
+ * value is within the range supported by the attribute. So, there's
+ * a lot of return code checking and mapping going on here.
+ *
+ * We want to return 1 if we think everything went OK, and
+ * EINVAL if not.
+ */
+static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr)
+{
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	int val = 0;
+	int rc = 0;
+	struct orangefs_attribute *orangefs_attr;
+	struct acache_orangefs_attribute *acache_attr;
+	struct capcache_orangefs_attribute *capcache_attr;
+	struct ccache_orangefs_attribute *ccache_attr;
+	struct ncache_orangefs_attribute *ncache_attr;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG,
+		     "sysfs_service_op_store: id:%s:\n",
+		     kobj_id);
+
+	new_op = op_alloc(PVFS2_VFS_OP_PARAM);
+	if (!new_op) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Can't do a service_operation if the client is not running... */
+	rc = is_daemon_in_service();
+	if (rc) {
+		pr_info("%s: Client not running :%d:\n",
+			__func__,
+			is_daemon_in_service());
+		goto out;
+	}
+
+	/*
+	 * The value we want to send back to userspace is in buf.
+	 */
+	rc = kstrtoint(buf, 0, &val);
+	if (rc)
+		goto out;
+
+	if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
+		orangefs_attr = (struct orangefs_attribute *)attr;
+
+		if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) {
+			if (val > 0) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(orangefs_attr->attr.name,
+				   "perf_time_interval_secs")) {
+			if (val > 0) {
+				new_op->upcall.req.param.op =
+				PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(orangefs_attr->attr.name,
+				   "perf_counter_reset")) {
+			if ((val == 0) || (val == 1)) {
+				new_op->upcall.req.param.op =
+					PVFS2_PARAM_REQUEST_OP_PERF_RESET;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		}
+
+	} else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
+		acache_attr = (struct acache_orangefs_attribute *)attr;
+
+		if (!strcmp(acache_attr->attr.name, "hard_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(acache_attr->attr.name, "soft_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(acache_attr->attr.name,
+				   "reclaim_percentage")) {
+			if ((val > -1) && (val < 101)) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(acache_attr->attr.name, "timeout_msecs")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		}
+
+	} else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
+		capcache_attr = (struct capcache_orangefs_attribute *)attr;
+
+		if (!strcmp(capcache_attr->attr.name, "hard_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(capcache_attr->attr.name, "soft_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(capcache_attr->attr.name,
+				   "reclaim_percentage")) {
+			if ((val > -1) && (val < 101)) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(capcache_attr->attr.name, "timeout_secs")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		}
+
+	} else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
+		ccache_attr = (struct ccache_orangefs_attribute *)attr;
+
+		if (!strcmp(ccache_attr->attr.name, "hard_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ccache_attr->attr.name, "soft_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ccache_attr->attr.name,
+				   "reclaim_percentage")) {
+			if ((val > -1) && (val < 101)) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ccache_attr->attr.name, "timeout_secs")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		}
+
+	} else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
+		ncache_attr = (struct ncache_orangefs_attribute *)attr;
+
+		if (!strcmp(ncache_attr->attr.name, "hard_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ncache_attr->attr.name, "soft_limit")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ncache_attr->attr.name,
+				   "reclaim_percentage")) {
+			if ((val > -1) && (val < 101)) {
+				new_op->upcall.req.param.op =
+					PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		} else if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) {
+			if (val > -1) {
+				new_op->upcall.req.param.op =
+				  PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
+			} else {
+				rc = 0;
+				goto out;
+			}
+		}
+
+	} else {
+		gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n",
+			   kobj_id);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET;
+
+	new_op->upcall.req.param.value = val;
+
+	/*
+	 * The service_operation will return a errno return code on
+	 * error, and zero on success.
+	 */
+	rc = service_operation(new_op, "pvfs2_param", PVFS2_OP_INTERRUPTIBLE);
+
+	if (rc < 0) {
+		gossip_err("sysfs_service_op_store: service op returned:%d:\n",
+			rc);
+		rc = 0;
+	} else {
+		rc = 1;
+	}
+
+out:
+	/*
+	 * if we got ENOMEM, then op_alloc probably failed...
+	 */
+	if (rc == -ENOMEM)
+		rc = 0;
+	else
+		op_release(new_op);
+
+	if (rc == 0)
+		rc = -EINVAL;
+
+	return rc;
+}
+
+static ssize_t
+	service_orangefs_store(struct orangefs_obj *orangefs_obj,
+			       struct orangefs_attribute *attr,
+			       const char *buf,
+			       size_t count)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_store(ORANGEFS_KOBJ_ID, buf, (void *) attr);
+
+	/* rc should have an errno value if the service_op went bad. */
+	if (rc == 1)
+		rc = count;
+
+	return rc;
+}
+
+static ssize_t
+	service_acache_store(struct acache_orangefs_obj *acache_orangefs_obj,
+			     struct acache_orangefs_attribute *attr,
+			     const char *buf,
+			     size_t count)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_store(ACACHE_KOBJ_ID, buf, (void *) attr);
+
+	/* rc should have an errno value if the service_op went bad. */
+	if (rc == 1)
+		rc = count;
+
+	return rc;
+}
+
+static ssize_t
+	service_capcache_store(struct capcache_orangefs_obj
+				*capcache_orangefs_obj,
+			       struct capcache_orangefs_attribute *attr,
+			       const char *buf,
+			       size_t count)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_store(CAPCACHE_KOBJ_ID, buf, (void *) attr);
+
+	/* rc should have an errno value if the service_op went bad. */
+	if (rc == 1)
+		rc = count;
+
+	return rc;
+}
+
+static ssize_t service_ccache_store(struct ccache_orangefs_obj
+					*ccache_orangefs_obj,
+				    struct ccache_orangefs_attribute *attr,
+				    const char *buf,
+				    size_t count)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_store(CCACHE_KOBJ_ID, buf, (void *) attr);
+
+	/* rc should have an errno value if the service_op went bad. */
+	if (rc == 1)
+		rc = count;
+
+	return rc;
+}
+
+static ssize_t
+	service_ncache_store(struct ncache_orangefs_obj *ncache_orangefs_obj,
+			     struct ncache_orangefs_attribute *attr,
+			     const char *buf,
+			     size_t count)
+{
+	int rc = 0;
+
+	rc = sysfs_service_op_store(NCACHE_KOBJ_ID, buf, (void *) attr);
+
+	/* rc should have an errno value if the service_op went bad. */
+	if (rc == 1)
+		rc = count;
+
+	return rc;
+}
+
+static struct orangefs_attribute op_timeout_secs_attribute =
+	__ATTR(op_timeout_secs, 0664, int_orangefs_show, int_store);
+
+static struct orangefs_attribute slot_timeout_secs_attribute =
+	__ATTR(slot_timeout_secs, 0664, int_orangefs_show, int_store);
+
+static struct orangefs_attribute perf_counter_reset_attribute =
+	__ATTR(perf_counter_reset,
+	       0664,
+	       service_orangefs_show,
+	       service_orangefs_store);
+
+static struct orangefs_attribute perf_history_size_attribute =
+	__ATTR(perf_history_size,
+	       0664,
+	       service_orangefs_show,
+	       service_orangefs_store);
+
+static struct orangefs_attribute perf_time_interval_secs_attribute =
+	__ATTR(perf_time_interval_secs,
+	       0664,
+	       service_orangefs_show,
+	       service_orangefs_store);
+
+static struct attribute *orangefs_default_attrs[] = {
+	&op_timeout_secs_attribute.attr,
+	&slot_timeout_secs_attribute.attr,
+	&perf_counter_reset_attribute.attr,
+	&perf_history_size_attribute.attr,
+	&perf_time_interval_secs_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type orangefs_ktype = {
+	.sysfs_ops = &orangefs_sysfs_ops,
+	.release = orangefs_release,
+	.default_attrs = orangefs_default_attrs,
+};
+
+static struct acache_orangefs_attribute acache_hard_limit_attribute =
+	__ATTR(hard_limit,
+	       0664,
+	       service_acache_show,
+	       service_acache_store);
+
+static struct acache_orangefs_attribute acache_reclaim_percent_attribute =
+	__ATTR(reclaim_percentage,
+	       0664,
+	       service_acache_show,
+	       service_acache_store);
+
+static struct acache_orangefs_attribute acache_soft_limit_attribute =
+	__ATTR(soft_limit,
+	       0664,
+	       service_acache_show,
+	       service_acache_store);
+
+static struct acache_orangefs_attribute acache_timeout_msecs_attribute =
+	__ATTR(timeout_msecs,
+	       0664,
+	       service_acache_show,
+	       service_acache_store);
+
+static struct attribute *acache_orangefs_default_attrs[] = {
+	&acache_hard_limit_attribute.attr,
+	&acache_reclaim_percent_attribute.attr,
+	&acache_soft_limit_attribute.attr,
+	&acache_timeout_msecs_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type acache_orangefs_ktype = {
+	.sysfs_ops = &acache_orangefs_sysfs_ops,
+	.release = acache_orangefs_release,
+	.default_attrs = acache_orangefs_default_attrs,
+};
+
+static struct capcache_orangefs_attribute capcache_hard_limit_attribute =
+	__ATTR(hard_limit,
+	       0664,
+	       service_capcache_show,
+	       service_capcache_store);
+
+static struct capcache_orangefs_attribute capcache_reclaim_percent_attribute =
+	__ATTR(reclaim_percentage,
+	       0664,
+	       service_capcache_show,
+	       service_capcache_store);
+
+static struct capcache_orangefs_attribute capcache_soft_limit_attribute =
+	__ATTR(soft_limit,
+	       0664,
+	       service_capcache_show,
+	       service_capcache_store);
+
+static struct capcache_orangefs_attribute capcache_timeout_secs_attribute =
+	__ATTR(timeout_secs,
+	       0664,
+	       service_capcache_show,
+	       service_capcache_store);
+
+static struct attribute *capcache_orangefs_default_attrs[] = {
+	&capcache_hard_limit_attribute.attr,
+	&capcache_reclaim_percent_attribute.attr,
+	&capcache_soft_limit_attribute.attr,
+	&capcache_timeout_secs_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type capcache_orangefs_ktype = {
+	.sysfs_ops = &capcache_orangefs_sysfs_ops,
+	.release = capcache_orangefs_release,
+	.default_attrs = capcache_orangefs_default_attrs,
+};
+
+static struct ccache_orangefs_attribute ccache_hard_limit_attribute =
+	__ATTR(hard_limit,
+	       0664,
+	       service_ccache_show,
+	       service_ccache_store);
+
+static struct ccache_orangefs_attribute ccache_reclaim_percent_attribute =
+	__ATTR(reclaim_percentage,
+	       0664,
+	       service_ccache_show,
+	       service_ccache_store);
+
+static struct ccache_orangefs_attribute ccache_soft_limit_attribute =
+	__ATTR(soft_limit,
+	       0664,
+	       service_ccache_show,
+	       service_ccache_store);
+
+static struct ccache_orangefs_attribute ccache_timeout_secs_attribute =
+	__ATTR(timeout_secs,
+	       0664,
+	       service_ccache_show,
+	       service_ccache_store);
+
+static struct attribute *ccache_orangefs_default_attrs[] = {
+	&ccache_hard_limit_attribute.attr,
+	&ccache_reclaim_percent_attribute.attr,
+	&ccache_soft_limit_attribute.attr,
+	&ccache_timeout_secs_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type ccache_orangefs_ktype = {
+	.sysfs_ops = &ccache_orangefs_sysfs_ops,
+	.release = ccache_orangefs_release,
+	.default_attrs = ccache_orangefs_default_attrs,
+};
+
+static struct ncache_orangefs_attribute ncache_hard_limit_attribute =
+	__ATTR(hard_limit,
+	       0664,
+	       service_ncache_show,
+	       service_ncache_store);
+
+static struct ncache_orangefs_attribute ncache_reclaim_percent_attribute =
+	__ATTR(reclaim_percentage,
+	       0664,
+	       service_ncache_show,
+	       service_ncache_store);
+
+static struct ncache_orangefs_attribute ncache_soft_limit_attribute =
+	__ATTR(soft_limit,
+	       0664,
+	       service_ncache_show,
+	       service_ncache_store);
+
+static struct ncache_orangefs_attribute ncache_timeout_msecs_attribute =
+	__ATTR(timeout_msecs,
+	       0664,
+	       service_ncache_show,
+	       service_ncache_store);
+
+static struct attribute *ncache_orangefs_default_attrs[] = {
+	&ncache_hard_limit_attribute.attr,
+	&ncache_reclaim_percent_attribute.attr,
+	&ncache_soft_limit_attribute.attr,
+	&ncache_timeout_msecs_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type ncache_orangefs_ktype = {
+	.sysfs_ops = &ncache_orangefs_sysfs_ops,
+	.release = ncache_orangefs_release,
+	.default_attrs = ncache_orangefs_default_attrs,
+};
+
+static struct pc_orangefs_attribute pc_acache_attribute =
+	__ATTR(acache,
+	       0664,
+	       service_pc_show,
+	       NULL);
+
+static struct pc_orangefs_attribute pc_capcache_attribute =
+	__ATTR(capcache,
+	       0664,
+	       service_pc_show,
+	       NULL);
+
+static struct pc_orangefs_attribute pc_ncache_attribute =
+	__ATTR(ncache,
+	       0664,
+	       service_pc_show,
+	       NULL);
+
+static struct attribute *pc_orangefs_default_attrs[] = {
+	&pc_acache_attribute.attr,
+	&pc_capcache_attribute.attr,
+	&pc_ncache_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type pc_orangefs_ktype = {
+	.sysfs_ops = &pc_orangefs_sysfs_ops,
+	.release = pc_orangefs_release,
+	.default_attrs = pc_orangefs_default_attrs,
+};
+
+static struct stats_orangefs_attribute stats_reads_attribute =
+	__ATTR(reads,
+	       0664,
+	       int_stats_show,
+	       NULL);
+
+static struct stats_orangefs_attribute stats_writes_attribute =
+	__ATTR(writes,
+	       0664,
+	       int_stats_show,
+	       NULL);
+
+static struct attribute *stats_orangefs_default_attrs[] = {
+	&stats_reads_attribute.attr,
+	&stats_writes_attribute.attr,
+	NULL,
+};
+
+static struct kobj_type stats_orangefs_ktype = {
+	.sysfs_ops = &stats_orangefs_sysfs_ops,
+	.release = stats_orangefs_release,
+	.default_attrs = stats_orangefs_default_attrs,
+};
+
+static struct orangefs_obj *orangefs_obj;
+static struct acache_orangefs_obj *acache_orangefs_obj;
+static struct capcache_orangefs_obj *capcache_orangefs_obj;
+static struct ccache_orangefs_obj *ccache_orangefs_obj;
+static struct ncache_orangefs_obj *ncache_orangefs_obj;
+static struct pc_orangefs_obj *pc_orangefs_obj;
+static struct stats_orangefs_obj *stats_orangefs_obj;
+
+int orangefs_sysfs_init(void)
+{
+	int rc;
+
+	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n");
+
+	/* create /sys/fs/orangefs. */
+	orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL);
+	if (!orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&orangefs_obj->kobj,
+				  &orangefs_ktype,
+				  fs_kobj,
+				  ORANGEFS_KOBJ_ID);
+
+	if (rc) {
+		kobject_put(&orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/acache. */
+	acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL);
+	if (!acache_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&acache_orangefs_obj->kobj,
+				  &acache_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  ACACHE_KOBJ_ID);
+
+	if (rc) {
+		kobject_put(&acache_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&acache_orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/capcache. */
+	capcache_orangefs_obj =
+		kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL);
+	if (!capcache_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&capcache_orangefs_obj->kobj,
+				  &capcache_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  CAPCACHE_KOBJ_ID);
+	if (rc) {
+		kobject_put(&capcache_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&capcache_orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/ccache. */
+	ccache_orangefs_obj =
+		kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL);
+	if (!ccache_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&ccache_orangefs_obj->kobj,
+				  &ccache_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  CCACHE_KOBJ_ID);
+	if (rc) {
+		kobject_put(&ccache_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&ccache_orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/ncache. */
+	ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL);
+	if (!ncache_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&ncache_orangefs_obj->kobj,
+				  &ncache_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  NCACHE_KOBJ_ID);
+
+	if (rc) {
+		kobject_put(&ncache_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&ncache_orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/perf_counters. */
+	pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL);
+	if (!pc_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&pc_orangefs_obj->kobj,
+				  &pc_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  "perf_counters");
+
+	if (rc) {
+		kobject_put(&pc_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&pc_orangefs_obj->kobj, KOBJ_ADD);
+
+	/* create /sys/fs/orangefs/stats. */
+	stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL);
+	if (!stats_orangefs_obj) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = kobject_init_and_add(&stats_orangefs_obj->kobj,
+				  &stats_orangefs_ktype,
+				  &orangefs_obj->kobj,
+				  STATS_KOBJ_ID);
+
+	if (rc) {
+		kobject_put(&stats_orangefs_obj->kobj);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	kobject_uevent(&stats_orangefs_obj->kobj, KOBJ_ADD);
+out:
+	return rc;
+}
+
+void orangefs_sysfs_exit(void)
+{
+	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n");
+
+	kobject_put(&acache_orangefs_obj->kobj);
+	kobject_put(&capcache_orangefs_obj->kobj);
+	kobject_put(&ccache_orangefs_obj->kobj);
+	kobject_put(&ncache_orangefs_obj->kobj);
+	kobject_put(&pc_orangefs_obj->kobj);
+	kobject_put(&stats_orangefs_obj->kobj);
+
+	kobject_put(&orangefs_obj->kobj);
+}
diff --git a/fs/orangefs/pvfs2-sysfs.h b/fs/orangefs/pvfs2-sysfs.h
new file mode 100644
index 000000000000..f0b76382db02
--- /dev/null
+++ b/fs/orangefs/pvfs2-sysfs.h
@@ -0,0 +1,2 @@
+extern int orangefs_sysfs_init(void);
+extern void orangefs_sysfs_exit(void);
diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c
new file mode 100644
index 000000000000..11ee073ecd19
--- /dev/null
+++ b/fs/orangefs/pvfs2-utils.c
@@ -0,0 +1,1129 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-dev-proto.h"
+#include "pvfs2-bufmap.h"
+
+__s32 fsid_of_op(struct pvfs2_kernel_op_s *op)
+{
+	__s32 fsid = PVFS_FS_ID_NULL;
+
+	if (op) {
+		switch (op->upcall.type) {
+		case PVFS2_VFS_OP_FILE_IO:
+			fsid = op->upcall.req.io.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_LOOKUP:
+			fsid = op->upcall.req.lookup.parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_CREATE:
+			fsid = op->upcall.req.create.parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_GETATTR:
+			fsid = op->upcall.req.getattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_REMOVE:
+			fsid = op->upcall.req.remove.parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_MKDIR:
+			fsid = op->upcall.req.mkdir.parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_READDIR:
+			fsid = op->upcall.req.readdir.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_SETATTR:
+			fsid = op->upcall.req.setattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_SYMLINK:
+			fsid = op->upcall.req.sym.parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_RENAME:
+			fsid = op->upcall.req.rename.old_parent_refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_STATFS:
+			fsid = op->upcall.req.statfs.fs_id;
+			break;
+		case PVFS2_VFS_OP_TRUNCATE:
+			fsid = op->upcall.req.truncate.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_MMAP_RA_FLUSH:
+			fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_FS_UMOUNT:
+			fsid = op->upcall.req.fs_umount.fs_id;
+			break;
+		case PVFS2_VFS_OP_GETXATTR:
+			fsid = op->upcall.req.getxattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_SETXATTR:
+			fsid = op->upcall.req.setxattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_LISTXATTR:
+			fsid = op->upcall.req.listxattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_REMOVEXATTR:
+			fsid = op->upcall.req.removexattr.refn.fs_id;
+			break;
+		case PVFS2_VFS_OP_FSYNC:
+			fsid = op->upcall.req.fsync.refn.fs_id;
+			break;
+		default:
+			break;
+		}
+	}
+	return fsid;
+}
+
+static void pvfs2_set_inode_flags(struct inode *inode,
+				  struct PVFS_sys_attr_s *attrs)
+{
+	if (attrs->flags & PVFS_IMMUTABLE_FL)
+		inode->i_flags |= S_IMMUTABLE;
+	else
+		inode->i_flags &= ~S_IMMUTABLE;
+
+	if (attrs->flags & PVFS_APPEND_FL)
+		inode->i_flags |= S_APPEND;
+	else
+		inode->i_flags &= ~S_APPEND;
+
+	if (attrs->flags & PVFS_NOATIME_FL)
+		inode->i_flags |= S_NOATIME;
+	else
+		inode->i_flags &= ~S_NOATIME;
+
+}
+
+/* NOTE: symname is ignored unless the inode is a sym link */
+static int copy_attributes_to_inode(struct inode *inode,
+				    struct PVFS_sys_attr_s *attrs,
+				    char *symname)
+{
+	int ret = -1;
+	int perm_mode = 0;
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	loff_t inode_size = 0;
+	loff_t rounded_up_size = 0;
+
+
+	/*
+	   arbitrarily set the inode block size; FIXME: we need to
+	   resolve the difference between the reported inode blocksize
+	   and the PAGE_CACHE_SIZE, since our block count will always
+	   be wrong.
+
+	   For now, we're setting the block count to be the proper
+	   number assuming the block size is 512 bytes, and the size is
+	   rounded up to the nearest 4K.  This is apparently required
+	   to get proper size reports from the 'du' shell utility.
+
+	   changing the inode->i_blkbits to something other than
+	   PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that.
+	 */
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "attrs->mask = %x (objtype = %s)\n",
+		     attrs->mask,
+		     attrs->objtype == PVFS_TYPE_METAFILE ? "file" :
+		     attrs->objtype == PVFS_TYPE_DIRECTORY ? "directory" :
+		     attrs->objtype == PVFS_TYPE_SYMLINK ? "symlink" :
+			"invalid/unknown");
+
+	switch (attrs->objtype) {
+	case PVFS_TYPE_METAFILE:
+		pvfs2_set_inode_flags(inode, attrs);
+		if (attrs->mask & PVFS_ATTR_SYS_SIZE) {
+			inode_size = (loff_t) attrs->size;
+			rounded_up_size =
+			    (inode_size + (4096 - (inode_size % 4096)));
+
+			pvfs2_lock_inode(inode);
+			inode->i_bytes = inode_size;
+			inode->i_blocks =
+			    (unsigned long)(rounded_up_size / 512);
+			pvfs2_unlock_inode(inode);
+
+			/*
+			 * NOTE: make sure all the places we're called
+			 * from have the inode->i_sem lock. We're fine
+			 * in 99% of the cases since we're mostly
+			 * called from a lookup.
+			 */
+			inode->i_size = inode_size;
+		}
+		break;
+	case PVFS_TYPE_SYMLINK:
+		if (symname != NULL) {
+			inode->i_size = (loff_t) strlen(symname);
+			break;
+		}
+		/*FALLTHRU*/
+	default:
+		inode->i_size = PAGE_CACHE_SIZE;
+
+		pvfs2_lock_inode(inode);
+		inode_set_bytes(inode, inode->i_size);
+		pvfs2_unlock_inode(inode);
+		break;
+	}
+
+	inode->i_uid = make_kuid(&init_user_ns, attrs->owner);
+	inode->i_gid = make_kgid(&init_user_ns, attrs->group);
+	inode->i_atime.tv_sec = (time_t) attrs->atime;
+	inode->i_mtime.tv_sec = (time_t) attrs->mtime;
+	inode->i_ctime.tv_sec = (time_t) attrs->ctime;
+	inode->i_atime.tv_nsec = 0;
+	inode->i_mtime.tv_nsec = 0;
+	inode->i_ctime.tv_nsec = 0;
+
+	if (attrs->perms & PVFS_O_EXECUTE)
+		perm_mode |= S_IXOTH;
+	if (attrs->perms & PVFS_O_WRITE)
+		perm_mode |= S_IWOTH;
+	if (attrs->perms & PVFS_O_READ)
+		perm_mode |= S_IROTH;
+
+	if (attrs->perms & PVFS_G_EXECUTE)
+		perm_mode |= S_IXGRP;
+	if (attrs->perms & PVFS_G_WRITE)
+		perm_mode |= S_IWGRP;
+	if (attrs->perms & PVFS_G_READ)
+		perm_mode |= S_IRGRP;
+
+	if (attrs->perms & PVFS_U_EXECUTE)
+		perm_mode |= S_IXUSR;
+	if (attrs->perms & PVFS_U_WRITE)
+		perm_mode |= S_IWUSR;
+	if (attrs->perms & PVFS_U_READ)
+		perm_mode |= S_IRUSR;
+
+	if (attrs->perms & PVFS_G_SGID)
+		perm_mode |= S_ISGID;
+	if (attrs->perms & PVFS_U_SUID)
+		perm_mode |= S_ISUID;
+
+	inode->i_mode = perm_mode;
+
+	if (is_root_handle(inode)) {
+		/* special case: mark the root inode as sticky */
+		inode->i_mode |= S_ISVTX;
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "Marking inode %pU as sticky\n",
+			     get_khandle_from_ino(inode));
+	}
+
+	switch (attrs->objtype) {
+	case PVFS_TYPE_METAFILE:
+		inode->i_mode |= S_IFREG;
+		ret = 0;
+		break;
+	case PVFS_TYPE_DIRECTORY:
+		inode->i_mode |= S_IFDIR;
+		/* NOTE: we have no good way to keep nlink consistent
+		 * for directories across clients; keep constant at 1.
+		 * Why 1?  If we go with 2, then find(1) gets confused
+		 * and won't work properly withouth the -noleaf option
+		 */
+		set_nlink(inode, 1);
+		ret = 0;
+		break;
+	case PVFS_TYPE_SYMLINK:
+		inode->i_mode |= S_IFLNK;
+
+		/* copy link target to inode private data */
+		if (pvfs2_inode && symname) {
+			strncpy(pvfs2_inode->link_target,
+				symname,
+				PVFS_NAME_MAX);
+			gossip_debug(GOSSIP_UTILS_DEBUG,
+				     "Copied attr link target %s\n",
+				     pvfs2_inode->link_target);
+		}
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "symlink mode %o\n",
+			     inode->i_mode);
+		ret = 0;
+		break;
+	default:
+		gossip_err("pvfs2: copy_attributes_to_inode: got invalid attribute type %x\n",
+			attrs->objtype);
+	}
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n",
+		     inode->i_mode,
+		     (unsigned long)i_size_read(inode));
+
+	return ret;
+}
+
+/*
+ * NOTE: in kernel land, we never use the sys_attr->link_target for
+ * anything, so don't bother copying it into the sys_attr object here.
+ */
+static inline int copy_attributes_from_inode(struct inode *inode,
+					     struct PVFS_sys_attr_s *attrs,
+					     struct iattr *iattr)
+{
+	umode_t tmp_mode;
+
+	if (!iattr || !inode || !attrs) {
+		gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
+			   "in copy_attributes_from_inode!\n",
+			   iattr,
+			   inode,
+			   attrs);
+		return -EINVAL;
+	}
+	/*
+	 * We need to be careful to only copy the attributes out of the
+	 * iattr object that we know are valid.
+	 */
+	attrs->mask = 0;
+	if (iattr->ia_valid & ATTR_UID) {
+		attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid);
+		attrs->mask |= PVFS_ATTR_SYS_UID;
+		gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
+	}
+	if (iattr->ia_valid & ATTR_GID) {
+		attrs->group = from_kgid(current_user_ns(), iattr->ia_gid);
+		attrs->mask |= PVFS_ATTR_SYS_GID;
+		gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
+	}
+
+	if (iattr->ia_valid & ATTR_ATIME) {
+		attrs->mask |= PVFS_ATTR_SYS_ATIME;
+		if (iattr->ia_valid & ATTR_ATIME_SET) {
+			attrs->atime =
+			    pvfs2_convert_time_field((void *)&iattr->ia_atime);
+			attrs->mask |= PVFS_ATTR_SYS_ATIME_SET;
+		}
+	}
+	if (iattr->ia_valid & ATTR_MTIME) {
+		attrs->mask |= PVFS_ATTR_SYS_MTIME;
+		if (iattr->ia_valid & ATTR_MTIME_SET) {
+			attrs->mtime =
+			    pvfs2_convert_time_field((void *)&iattr->ia_mtime);
+			attrs->mask |= PVFS_ATTR_SYS_MTIME_SET;
+		}
+	}
+	if (iattr->ia_valid & ATTR_CTIME)
+		attrs->mask |= PVFS_ATTR_SYS_CTIME;
+
+	/*
+	 * PVFS2 cannot set size with a setattr operation.  Probably not likely
+	 * to be requested through the VFS, but just in case, don't worry about
+	 * ATTR_SIZE
+	 */
+
+	if (iattr->ia_valid & ATTR_MODE) {
+		tmp_mode = iattr->ia_mode;
+		if (tmp_mode & (S_ISVTX)) {
+			if (is_root_handle(inode)) {
+				/*
+				 * allow sticky bit to be set on root (since
+				 * it shows up that way by default anyhow),
+				 * but don't show it to the server
+				 */
+				tmp_mode -= S_ISVTX;
+			} else {
+				gossip_debug(GOSSIP_UTILS_DEBUG,
+					     "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
+				return -EINVAL;
+			}
+		}
+
+		if (tmp_mode & (S_ISUID)) {
+			gossip_debug(GOSSIP_UTILS_DEBUG,
+				     "Attempting to set setuid bit (not supported); returning EINVAL.\n");
+			return -EINVAL;
+		}
+
+		attrs->perms = PVFS_util_translate_mode(tmp_mode);
+		attrs->mask |= PVFS_ATTR_SYS_PERM;
+	}
+
+	return 0;
+}
+
+/*
+ * issues a pvfs2 getattr request and fills in the appropriate inode
+ * attributes if successful.  returns 0 on success; -errno otherwise
+ */
+int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op;
+	int ret = -EINVAL;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "%s: called on inode %pU\n",
+		     __func__,
+		     get_khandle_from_ino(inode));
+
+	new_op = op_alloc(PVFS2_VFS_OP_GETATTR);
+	if (!new_op)
+		return -ENOMEM;
+	new_op->upcall.req.getattr.refn = pvfs2_inode->refn;
+	new_op->upcall.req.getattr.mask = getattr_mask;
+
+	ret = service_operation(new_op, __func__,
+				get_interruptible_flag(inode));
+	if (ret != 0)
+		goto out;
+
+	if (copy_attributes_to_inode(inode,
+			&new_op->downcall.resp.getattr.attributes,
+			new_op->downcall.resp.getattr.link_target)) {
+		gossip_err("%s: failed to copy attributes\n", __func__);
+		ret = -ENOENT;
+		goto out;
+	}
+
+	/*
+	 * Store blksize in pvfs2 specific part of inode structure; we are
+	 * only going to use this to report to stat to make sure it doesn't
+	 * perturb any inode related code paths.
+	 */
+	if (new_op->downcall.resp.getattr.attributes.objtype ==
+			PVFS_TYPE_METAFILE) {
+		pvfs2_inode->blksize =
+			new_op->downcall.resp.getattr.attributes.blksize;
+	} else {
+		/* mimic behavior of generic_fillattr() for other types. */
+		pvfs2_inode->blksize = (1 << inode->i_blkbits);
+
+	}
+
+out:
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "Getattr on handle %pU, "
+		     "fsid %d\n  (inode ct = %d) returned %d\n",
+		     &pvfs2_inode->refn.khandle,
+		     pvfs2_inode->refn.fs_id,
+		     (int)atomic_read(&inode->i_count),
+		     ret);
+
+	op_release(new_op);
+	return ret;
+}
+
+/*
+ * issues a pvfs2 setattr request to make sure the new attribute values
+ * take effect if successful.  returns 0 on success; -errno otherwise
+ */
+int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op;
+	int ret;
+
+	new_op = op_alloc(PVFS2_VFS_OP_SETATTR);
+	if (!new_op)
+		return -ENOMEM;
+
+	new_op->upcall.req.setattr.refn = pvfs2_inode->refn;
+	ret = copy_attributes_from_inode(inode,
+		       &new_op->upcall.req.setattr.attributes,
+		       iattr);
+	if (ret < 0) {
+		op_release(new_op);
+		return ret;
+	}
+
+	ret = service_operation(new_op, __func__,
+				get_interruptible_flag(inode));
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_inode_setattr: returning %d\n",
+		     ret);
+
+	/* when request is serviced properly, free req op struct */
+	op_release(new_op);
+
+	/*
+	 * successful setattr should clear the atime, mtime and
+	 * ctime flags.
+	 */
+	if (ret == 0) {
+		ClearAtimeFlag(pvfs2_inode);
+		ClearMtimeFlag(pvfs2_inode);
+		ClearCtimeFlag(pvfs2_inode);
+		ClearModeFlag(pvfs2_inode);
+	}
+
+	return ret;
+}
+
+int pvfs2_flush_inode(struct inode *inode)
+{
+	/*
+	 * If it is a dirty inode, this function gets called.
+	 * Gather all the information that needs to be setattr'ed
+	 * Right now, this will only be used for mode, atime, mtime
+	 * and/or ctime.
+	 */
+	struct iattr wbattr;
+	int ret;
+	int mtime_flag;
+	int ctime_flag;
+	int atime_flag;
+	int mode_flag;
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+
+	memset(&wbattr, 0, sizeof(wbattr));
+
+	/*
+	 * check inode flags up front, and clear them if they are set.  This
+	 * will prevent multiple processes from all trying to flush the same
+	 * inode if they call close() simultaneously
+	 */
+	mtime_flag = MtimeFlag(pvfs2_inode);
+	ClearMtimeFlag(pvfs2_inode);
+	ctime_flag = CtimeFlag(pvfs2_inode);
+	ClearCtimeFlag(pvfs2_inode);
+	atime_flag = AtimeFlag(pvfs2_inode);
+	ClearAtimeFlag(pvfs2_inode);
+	mode_flag = ModeFlag(pvfs2_inode);
+	ClearModeFlag(pvfs2_inode);
+
+	/*  -- Lazy atime,mtime and ctime update --
+	 * Note: all times are dictated by server in the new scheme
+	 * and not by the clients
+	 *
+	 * Also mode updates are being handled now..
+	 */
+
+	if (mtime_flag)
+		wbattr.ia_valid |= ATTR_MTIME;
+	if (ctime_flag)
+		wbattr.ia_valid |= ATTR_CTIME;
+	if (atime_flag)
+		wbattr.ia_valid |= ATTR_ATIME;
+
+	if (mode_flag) {
+		wbattr.ia_mode = inode->i_mode;
+		wbattr.ia_valid |= ATTR_MODE;
+	}
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "*********** pvfs2_flush_inode: %pU "
+		     "(ia_valid %d)\n",
+		     get_khandle_from_ino(inode),
+		     wbattr.ia_valid);
+	if (wbattr.ia_valid == 0) {
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "pvfs2_flush_inode skipping setattr()\n");
+		return 0;
+	}
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_flush_inode (%pU) writing mode %o\n",
+		     get_khandle_from_ino(inode),
+		     inode->i_mode);
+
+	ret = pvfs2_inode_setattr(inode, &wbattr);
+
+	return ret;
+}
+
+int pvfs2_unmount_sb(struct super_block *sb)
+{
+	int ret = -EINVAL;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_unmount_sb called on sb %p\n",
+		     sb);
+
+	new_op = op_alloc(PVFS2_VFS_OP_FS_UMOUNT);
+	if (!new_op)
+		return -ENOMEM;
+	new_op->upcall.req.fs_umount.id = PVFS2_SB(sb)->id;
+	new_op->upcall.req.fs_umount.fs_id = PVFS2_SB(sb)->fs_id;
+	strncpy(new_op->upcall.req.fs_umount.pvfs2_config_server,
+		PVFS2_SB(sb)->devname,
+		PVFS_MAX_SERVER_ADDR_LEN);
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "Attempting PVFS2 Unmount via host %s\n",
+		     new_op->upcall.req.fs_umount.pvfs2_config_server);
+
+	ret = service_operation(new_op, "pvfs2_fs_umount", 0);
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_unmount: got return value of %d\n", ret);
+	if (ret)
+		sb = ERR_PTR(ret);
+	else
+		PVFS2_SB(sb)->mount_pending = 1;
+
+	op_release(new_op);
+	return ret;
+}
+
+/*
+ * NOTE: on successful cancellation, be sure to return -EINTR, as
+ * that's the return value the caller expects
+ */
+int pvfs2_cancel_op_in_progress(__u64 tag)
+{
+	int ret = -EINVAL;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_cancel_op_in_progress called on tag %llu\n",
+		     llu(tag));
+
+	new_op = op_alloc(PVFS2_VFS_OP_CANCEL);
+	if (!new_op)
+		return -ENOMEM;
+	new_op->upcall.req.cancel.op_tag = tag;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "Attempting PVFS2 operation cancellation of tag %llu\n",
+		     llu(new_op->upcall.req.cancel.op_tag));
+
+	ret = service_operation(new_op, "pvfs2_cancel", PVFS2_OP_CANCELLATION);
+
+	gossip_debug(GOSSIP_UTILS_DEBUG,
+		     "pvfs2_cancel_op_in_progress: got return value of %d\n",
+		     ret);
+
+	op_release(new_op);
+	return ret;
+}
+
+void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op)
+{
+	if (op) {
+		spin_lock(&op->lock);
+		op->io_completed = 0;
+
+		op->upcall.type = PVFS2_VFS_OP_INVALID;
+		op->downcall.type = PVFS2_VFS_OP_INVALID;
+		op->downcall.status = -1;
+
+		op->op_state = OP_VFS_STATE_UNKNOWN;
+		op->tag = 0;
+		spin_unlock(&op->lock);
+	}
+}
+
+void pvfs2_make_bad_inode(struct inode *inode)
+{
+	if (is_root_handle(inode)) {
+		/*
+		 * if this occurs, the pvfs2-client-core was killed but we
+		 * can't afford to lose the inode operations and such
+		 * associated with the root handle in any case.
+		 */
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "*** NOT making bad root inode %pU\n",
+			     get_khandle_from_ino(inode));
+	} else {
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "*** making bad inode %pU\n",
+			     get_khandle_from_ino(inode));
+		make_bad_inode(inode);
+	}
+}
+
+/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigmask */
+void mask_blocked_signals(sigset_t *orig_sigset)
+{
+	unsigned long sigallow = sigmask(SIGKILL);
+	unsigned long irqflags = 0;
+	struct k_sigaction *action = pvfs2_current_sigaction;
+
+	sigallow |= ((action[SIGINT - 1].sa.sa_handler == SIG_DFL) ?
+		     sigmask(SIGINT) :
+		     0);
+	sigallow |= ((action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) ?
+		     sigmask(SIGQUIT) :
+		     0);
+
+	spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags);
+	*orig_sigset = current->blocked;
+	siginitsetinv(&current->blocked, sigallow & ~orig_sigset->sig[0]);
+	recalc_sigpending();
+	spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags);
+}
+
+/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigunmask */
+void unmask_blocked_signals(sigset_t *orig_sigset)
+{
+	unsigned long irqflags = 0;
+
+	spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags);
+	current->blocked = *orig_sigset;
+	recalc_sigpending();
+	spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags);
+}
+
+__u64 pvfs2_convert_time_field(void *time_ptr)
+{
+	__u64 pvfs2_time;
+	struct timespec *tspec = (struct timespec *)time_ptr;
+
+	pvfs2_time = (__u64) ((time_t) tspec->tv_sec);
+	return pvfs2_time;
+}
+
+/* macro defined in include/pvfs2-types.h */
+DECLARE_ERRNO_MAPPING_AND_FN();
+
+int pvfs2_normalize_to_errno(__s32 error_code)
+{
+	if (error_code > 0) {
+		gossip_err("pvfs2: error status receieved.\n");
+		gossip_err("pvfs2: assuming error code is inverted.\n");
+		error_code = -error_code;
+	}
+
+	/* convert any error codes that are in pvfs2 format */
+	if (IS_PVFS_NON_ERRNO_ERROR(-error_code)) {
+		if (PVFS_NON_ERRNO_ERROR_CODE(-error_code) == PVFS_ECANCEL) {
+			/*
+			 * cancellation error codes generally correspond to
+			 * a timeout from the client's perspective
+			 */
+			error_code = -ETIMEDOUT;
+		} else {
+			/* assume a default error code */
+			gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n",
+				   error_code);
+			error_code = -EINVAL;
+		}
+	} else if (IS_PVFS_ERROR(-error_code)) {
+		error_code = -PVFS_ERROR_TO_ERRNO(-error_code);
+	}
+	return error_code;
+}
+
+#define NUM_MODES 11
+__s32 PVFS_util_translate_mode(int mode)
+{
+	int ret = 0;
+	int i = 0;
+	static int modes[NUM_MODES] = {
+		S_IXOTH, S_IWOTH, S_IROTH,
+		S_IXGRP, S_IWGRP, S_IRGRP,
+		S_IXUSR, S_IWUSR, S_IRUSR,
+		S_ISGID, S_ISUID
+	};
+	static int pvfs2_modes[NUM_MODES] = {
+		PVFS_O_EXECUTE, PVFS_O_WRITE, PVFS_O_READ,
+		PVFS_G_EXECUTE, PVFS_G_WRITE, PVFS_G_READ,
+		PVFS_U_EXECUTE, PVFS_U_WRITE, PVFS_U_READ,
+		PVFS_G_SGID, PVFS_U_SUID
+	};
+
+	for (i = 0; i < NUM_MODES; i++)
+		if (mode & modes[i])
+			ret |= pvfs2_modes[i];
+
+	return ret;
+}
+#undef NUM_MODES
+
+/*
+ * After obtaining a string representation of the client's debug
+ * keywords and their associated masks, this function is called to build an
+ * array of these values.
+ */
+int orangefs_prepare_cdm_array(char *debug_array_string)
+{
+	int i;
+	int rc = -EINVAL;
+	char *cds_head = NULL;
+	char *cds_delimiter = NULL;
+	int keyword_len = 0;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
+
+	/*
+	 * figure out how many elements the cdm_array needs.
+	 */
+	for (i = 0; i < strlen(debug_array_string); i++)
+		if (debug_array_string[i] == '\n')
+			cdm_element_count++;
+
+	if (!cdm_element_count) {
+		pr_info("No elements in client debug array string!\n");
+		goto out;
+	}
+
+	cdm_array =
+		kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
+			GFP_KERNEL);
+	if (!cdm_array) {
+		pr_info("malloc failed for cdm_array!\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	cds_head = debug_array_string;
+
+	for (i = 0; i < cdm_element_count; i++) {
+		cds_delimiter = strchr(cds_head, '\n');
+		*cds_delimiter = '\0';
+
+		keyword_len = strcspn(cds_head, " ");
+
+		cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
+		if (!cdm_array[i].keyword) {
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		sscanf(cds_head,
+		       "%s %llx %llx",
+		       cdm_array[i].keyword,
+		       (unsigned long long *)&(cdm_array[i].mask1),
+		       (unsigned long long *)&(cdm_array[i].mask2));
+
+		if (!strcmp(cdm_array[i].keyword, PVFS2_VERBOSE))
+			client_verbose_index = i;
+
+		if (!strcmp(cdm_array[i].keyword, PVFS2_ALL))
+			client_all_index = i;
+
+		cds_head = cds_delimiter + 1;
+	}
+
+	rc = cdm_element_count;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+
+out:
+
+	return rc;
+
+}
+
+/*
+ * /sys/kernel/debug/orangefs/debug-help can be catted to
+ * see all the available kernel and client debug keywords.
+ *
+ * When the kernel boots, we have no idea what keywords the
+ * client supports, nor their associated masks.
+ *
+ * We pass through this function once at boot and stamp a
+ * boilerplate "we don't know" message for the client in the
+ * debug-help file. We pass through here again when the client
+ * starts and then we can fill out the debug-help file fully.
+ *
+ * The client might be restarted any number of times between
+ * reboots, we only build the debug-help file the first time.
+ */
+int orangefs_prepare_debugfs_help_string(int at_boot)
+{
+	int rc = -EINVAL;
+	int i;
+	int byte_count = 0;
+	char *client_title = "Client Debug Keywords:\n";
+	char *kernel_title = "Kernel Debug Keywords:\n";
+
+	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
+
+	if (at_boot) {
+		byte_count += strlen(HELP_STRING_UNINITIALIZED);
+		client_title = HELP_STRING_UNINITIALIZED;
+	} else {
+		/*
+		 * fill the client keyword/mask array and remember
+		 * how many elements there were.
+		 */
+		cdm_element_count =
+			orangefs_prepare_cdm_array(client_debug_array_string);
+		if (cdm_element_count <= 0)
+			goto out;
+
+		/* Count the bytes destined for debug_help_string. */
+		byte_count += strlen(client_title);
+
+		for (i = 0; i < cdm_element_count; i++) {
+			byte_count += strlen(cdm_array[i].keyword + 2);
+			if (byte_count >= DEBUG_HELP_STRING_SIZE) {
+				pr_info("%s: overflow 1!\n", __func__);
+				goto out;
+			}
+		}
+
+		gossip_debug(GOSSIP_UTILS_DEBUG,
+			     "%s: cdm_element_count:%d:\n",
+			     __func__,
+			     cdm_element_count);
+	}
+
+	byte_count += strlen(kernel_title);
+	for (i = 0; i < num_kmod_keyword_mask_map; i++) {
+		byte_count +=
+			strlen(s_kmod_keyword_mask_map[i].keyword + 2);
+		if (byte_count >= DEBUG_HELP_STRING_SIZE) {
+			pr_info("%s: overflow 2!\n", __func__);
+			goto out;
+		}
+	}
+
+	/* build debug_help_string. */
+	debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
+	if (!debug_help_string) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	strcat(debug_help_string, client_title);
+
+	if (!at_boot) {
+		for (i = 0; i < cdm_element_count; i++) {
+			strcat(debug_help_string, "\t");
+			strcat(debug_help_string, cdm_array[i].keyword);
+			strcat(debug_help_string, "\n");
+		}
+	}
+
+	strcat(debug_help_string, "\n");
+	strcat(debug_help_string, kernel_title);
+
+	for (i = 0; i < num_kmod_keyword_mask_map; i++) {
+		strcat(debug_help_string, "\t");
+		strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
+		strcat(debug_help_string, "\n");
+	}
+
+	rc = 0;
+
+out:
+
+	return rc;
+
+}
+
+/*
+ * kernel = type 0
+ * client = type 1
+ */
+void debug_mask_to_string(void *mask, int type)
+{
+	int i;
+	int len = 0;
+	char *debug_string;
+	int element_count = 0;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
+
+	if (type) {
+		debug_string = client_debug_string;
+		element_count = cdm_element_count;
+	} else {
+		debug_string = kernel_debug_string;
+		element_count = num_kmod_keyword_mask_map;
+	}
+
+	memset(debug_string, 0, PVFS2_MAX_DEBUG_STRING_LEN);
+
+	/*
+	 * Some keywords, like "all" or "verbose", are amalgams of
+	 * numerous other keywords. Make a special check for those
+	 * before grinding through the whole mask only to find out
+	 * later...
+	 */
+	if (check_amalgam_keyword(mask, type))
+		goto out;
+
+	/* Build the debug string. */
+	for (i = 0; i < element_count; i++)
+		if (type)
+			do_c_string(mask, i);
+		else
+			do_k_string(mask, i);
+
+	len = strlen(debug_string);
+
+	if ((len) && (type))
+		client_debug_string[len - 1] = '\0';
+	else if (len)
+		kernel_debug_string[len - 1] = '\0';
+	else if (type)
+		strcpy(client_debug_string, "none");
+	else
+		strcpy(kernel_debug_string, "none");
+
+out:
+gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
+
+	return;
+
+}
+
+void do_k_string(void *k_mask, int index)
+{
+	__u64 *mask = (__u64 *) k_mask;
+
+	if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
+			goto out;
+
+	if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
+		if ((strlen(kernel_debug_string) +
+		     strlen(s_kmod_keyword_mask_map[index].keyword))
+			< PVFS2_MAX_DEBUG_STRING_LEN - 1) {
+				strcat(kernel_debug_string,
+				       s_kmod_keyword_mask_map[index].keyword);
+				strcat(kernel_debug_string, ",");
+			} else {
+				gossip_err("%s: overflow!\n", __func__);
+				strcpy(kernel_debug_string, PVFS2_ALL);
+				goto out;
+			}
+	}
+
+out:
+
+	return;
+}
+
+void do_c_string(void *c_mask, int index)
+{
+	struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
+
+	if (keyword_is_amalgam(cdm_array[index].keyword))
+		goto out;
+
+	if ((mask->mask1 & cdm_array[index].mask1) ||
+	    (mask->mask2 & cdm_array[index].mask2)) {
+		if ((strlen(client_debug_string) +
+		     strlen(cdm_array[index].keyword) + 1)
+			< PVFS2_MAX_DEBUG_STRING_LEN - 2) {
+				strcat(client_debug_string,
+				       cdm_array[index].keyword);
+				strcat(client_debug_string, ",");
+			} else {
+				gossip_err("%s: overflow!\n", __func__);
+				strcpy(client_debug_string, PVFS2_ALL);
+				goto out;
+			}
+	}
+out:
+	return;
+}
+
+int keyword_is_amalgam(char *keyword)
+{
+	int rc = 0;
+
+	if ((!strcmp(keyword, PVFS2_ALL)) || (!strcmp(keyword, PVFS2_VERBOSE)))
+		rc = 1;
+
+	return rc;
+}
+
+/*
+ * kernel = type 0
+ * client = type 1
+ *
+ * return 1 if we found an amalgam.
+ */
+int check_amalgam_keyword(void *mask, int type)
+{
+	__u64 *k_mask;
+	struct client_debug_mask *c_mask;
+	int k_all_index = num_kmod_keyword_mask_map - 1;
+	int rc = 0;
+
+	if (type) {
+		c_mask = (struct client_debug_mask *) mask;
+
+		if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
+		    (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
+			strcpy(client_debug_string, PVFS2_ALL);
+			rc = 1;
+			goto out;
+		}
+
+		if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
+		    (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
+			strcpy(client_debug_string, PVFS2_VERBOSE);
+			rc = 1;
+			goto out;
+		}
+
+	} else {
+		k_mask = (__u64 *) mask;
+
+		if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
+			strcpy(kernel_debug_string, PVFS2_ALL);
+			rc = 1;
+			goto out;
+		}
+	}
+
+out:
+
+	return rc;
+}
+
+/*
+ * kernel = type 0
+ * client = type 1
+ */
+void debug_string_to_mask(char *debug_string, void *mask, int type)
+{
+	char *unchecked_keyword;
+	int i;
+	char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
+	char *original_pointer;
+	int element_count = 0;
+	struct client_debug_mask *c_mask;
+	__u64 *k_mask;
+
+	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
+
+	if (type) {
+		c_mask = (struct client_debug_mask *)mask;
+		element_count = cdm_element_count;
+	} else {
+		k_mask = (__u64 *)mask;
+		*k_mask = 0;
+		element_count = num_kmod_keyword_mask_map;
+	}
+
+	original_pointer = strsep_fodder;
+	while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
+		if (strlen(unchecked_keyword)) {
+			for (i = 0; i < element_count; i++)
+				if (type)
+					do_c_mask(i,
+						  unchecked_keyword,
+						  &c_mask);
+				else
+					do_k_mask(i,
+						  unchecked_keyword,
+						  &k_mask);
+		}
+
+	kfree(original_pointer);
+}
+
+void do_c_mask(int i,
+	       char *unchecked_keyword,
+	       struct client_debug_mask **sane_mask)
+{
+
+	if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
+		(**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
+		(**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
+	}
+}
+
+void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
+{
+
+	if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
+		**sane_mask = (**sane_mask) |
+				s_kmod_keyword_mask_map[i].mask_val;
+}
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
new file mode 100644
index 000000000000..90c7a1c9f201
--- /dev/null
+++ b/fs/orangefs/super.c
@@ -0,0 +1,558 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+#include <linux/parser.h>
+
+/* a cache for pvfs2-inode objects (i.e. pvfs2 inode private data) */
+static struct kmem_cache *pvfs2_inode_cache;
+
+/* list for storing pvfs2 specific superblocks in use */
+LIST_HEAD(pvfs2_superblocks);
+
+DEFINE_SPINLOCK(pvfs2_superblocks_lock);
+
+enum {
+	Opt_intr,
+	Opt_acl,
+	Opt_local_lock,
+
+	Opt_err
+};
+
+static const match_table_t tokens = {
+	{ Opt_acl,		"acl" },
+	{ Opt_intr,		"intr" },
+	{ Opt_local_lock,	"local_lock" },
+	{ Opt_err,	NULL }
+};
+
+
+static int parse_mount_options(struct super_block *sb, char *options,
+		int silent)
+{
+	struct pvfs2_sb_info_s *pvfs2_sb = PVFS2_SB(sb);
+	substring_t args[MAX_OPT_ARGS];
+	char *p;
+
+	/*
+	 * Force any potential flags that might be set from the mount
+	 * to zero, ie, initialize to unset.
+	 */
+	sb->s_flags &= ~MS_POSIXACL;
+	pvfs2_sb->flags &= ~PVFS2_OPT_INTR;
+	pvfs2_sb->flags &= ~PVFS2_OPT_LOCAL_LOCK;
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token;
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_acl:
+			sb->s_flags |= MS_POSIXACL;
+			break;
+		case Opt_intr:
+			pvfs2_sb->flags |= PVFS2_OPT_INTR;
+			break;
+		case Opt_local_lock:
+			pvfs2_sb->flags |= PVFS2_OPT_LOCAL_LOCK;
+			break;
+		default:
+			goto fail;
+		}
+	}
+
+	return 0;
+fail:
+	if (!silent)
+		gossip_err("Error: mount option [%s] is not supported.\n", p);
+	return -EINVAL;
+}
+
+static void pvfs2_inode_cache_ctor(void *req)
+{
+	struct pvfs2_inode_s *pvfs2_inode = req;
+
+	inode_init_once(&pvfs2_inode->vfs_inode);
+	init_rwsem(&pvfs2_inode->xattr_sem);
+
+	pvfs2_inode->vfs_inode.i_version = 1;
+}
+
+static struct inode *pvfs2_alloc_inode(struct super_block *sb)
+{
+	struct pvfs2_inode_s *pvfs2_inode;
+
+	pvfs2_inode = kmem_cache_alloc(pvfs2_inode_cache,
+				       PVFS2_CACHE_ALLOC_FLAGS);
+	if (pvfs2_inode == NULL) {
+		gossip_err("Failed to allocate pvfs2_inode\n");
+		return NULL;
+	}
+
+	/*
+	 * We want to clear everything except for rw_semaphore and the
+	 * vfs_inode.
+	 */
+	memset(&pvfs2_inode->refn.khandle, 0, 16);
+	pvfs2_inode->refn.fs_id = PVFS_FS_ID_NULL;
+	pvfs2_inode->last_failed_block_index_read = 0;
+	memset(pvfs2_inode->link_target, 0, sizeof(pvfs2_inode->link_target));
+	pvfs2_inode->pinode_flags = 0;
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_alloc_inode: allocated %p\n",
+		     &pvfs2_inode->vfs_inode);
+	return &pvfs2_inode->vfs_inode;
+}
+
+static void pvfs2_destroy_inode(struct inode *inode)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+			"%s: deallocated %p destroying inode %pU\n",
+			__func__, pvfs2_inode, get_khandle_from_ino(inode));
+
+	kmem_cache_free(pvfs2_inode_cache, pvfs2_inode);
+}
+
+/*
+ * NOTE: information filled in here is typically reflected in the
+ * output of the system command 'df'
+*/
+static int pvfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	int ret = -ENOMEM;
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	int flags = 0;
+	struct super_block *sb = NULL;
+
+	sb = dentry->d_sb;
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_statfs: called on sb %p (fs_id is %d)\n",
+		     sb,
+		     (int)(PVFS2_SB(sb)->fs_id));
+
+	new_op = op_alloc(PVFS2_VFS_OP_STATFS);
+	if (!new_op)
+		return ret;
+	new_op->upcall.req.statfs.fs_id = PVFS2_SB(sb)->fs_id;
+
+	if (PVFS2_SB(sb)->flags & PVFS2_OPT_INTR)
+		flags = PVFS2_OP_INTERRUPTIBLE;
+
+	ret = service_operation(new_op, "pvfs2_statfs", flags);
+
+	if (new_op->downcall.status < 0)
+		goto out_op_release;
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_statfs: got %ld blocks available | "
+		     "%ld blocks total | %ld block size\n",
+		     (long)new_op->downcall.resp.statfs.blocks_avail,
+		     (long)new_op->downcall.resp.statfs.blocks_total,
+		     (long)new_op->downcall.resp.statfs.block_size);
+
+	buf->f_type = sb->s_magic;
+	memcpy(&buf->f_fsid, &PVFS2_SB(sb)->fs_id, sizeof(buf->f_fsid));
+	buf->f_bsize = new_op->downcall.resp.statfs.block_size;
+	buf->f_namelen = PVFS2_NAME_LEN;
+
+	buf->f_blocks = (sector_t) new_op->downcall.resp.statfs.blocks_total;
+	buf->f_bfree = (sector_t) new_op->downcall.resp.statfs.blocks_avail;
+	buf->f_bavail = (sector_t) new_op->downcall.resp.statfs.blocks_avail;
+	buf->f_files = (sector_t) new_op->downcall.resp.statfs.files_total;
+	buf->f_ffree = (sector_t) new_op->downcall.resp.statfs.files_avail;
+	buf->f_frsize = sb->s_blocksize;
+
+out_op_release:
+	op_release(new_op);
+	gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_statfs: returning %d\n", ret);
+	return ret;
+}
+
+/*
+ * Remount as initiated by VFS layer.  We just need to reparse the mount
+ * options, no need to signal pvfs2-client-core about it.
+ */
+static int pvfs2_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+	gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount_fs: called\n");
+	return parse_mount_options(sb, data, 1);
+}
+
+/*
+ * Remount as initiated by pvfs2-client-core on restart.  This is used to
+ * repopulate mount information left from previous pvfs2-client-core.
+ *
+ * the idea here is that given a valid superblock, we're
+ * re-initializing the user space client with the initial mount
+ * information specified when the super block was first initialized.
+ * this is very different than the first initialization/creation of a
+ * superblock.  we use the special service_priority_operation to make
+ * sure that the mount gets ahead of any other pending operation that
+ * is waiting for servicing.  this means that the pvfs2-client won't
+ * fail to start several times for all other pending operations before
+ * the client regains all of the mount information from us.
+ * NOTE: this function assumes that the request_mutex is already acquired!
+ */
+int pvfs2_remount(struct super_block *sb)
+{
+	struct pvfs2_kernel_op_s *new_op;
+	int ret = -EINVAL;
+
+	gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount: called\n");
+
+	new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT);
+	if (!new_op)
+		return -ENOMEM;
+	strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server,
+		PVFS2_SB(sb)->devname,
+		PVFS_MAX_SERVER_ADDR_LEN);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "Attempting PVFS2 Remount via host %s\n",
+		     new_op->upcall.req.fs_mount.pvfs2_config_server);
+
+	/*
+	 * we assume that the calling function has already acquire the
+	 * request_mutex to prevent other operations from bypassing
+	 * this one
+	 */
+	ret = service_operation(new_op, "pvfs2_remount",
+		PVFS2_OP_PRIORITY | PVFS2_OP_NO_SEMAPHORE);
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_remount: mount got return value of %d\n",
+		     ret);
+	if (ret == 0) {
+		/*
+		 * store the id assigned to this sb -- it's just a
+		 * short-lived mapping that the system interface uses
+		 * to map this superblock to a particular mount entry
+		 */
+		PVFS2_SB(sb)->id = new_op->downcall.resp.fs_mount.id;
+		PVFS2_SB(sb)->mount_pending = 0;
+	}
+
+	op_release(new_op);
+	return ret;
+}
+
+int fsid_key_table_initialize(void)
+{
+	return 0;
+}
+
+void fsid_key_table_finalize(void)
+{
+}
+
+/* Called whenever the VFS dirties the inode in response to atime updates */
+static void pvfs2_dirty_inode(struct inode *inode, int flags)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_dirty_inode: %pU\n",
+		     get_khandle_from_ino(inode));
+	SetAtimeFlag(pvfs2_inode);
+}
+
+static const struct super_operations pvfs2_s_ops = {
+	.alloc_inode = pvfs2_alloc_inode,
+	.destroy_inode = pvfs2_destroy_inode,
+	.dirty_inode = pvfs2_dirty_inode,
+	.drop_inode = generic_delete_inode,
+	.statfs = pvfs2_statfs,
+	.remount_fs = pvfs2_remount_fs,
+	.show_options = generic_show_options,
+};
+
+static struct dentry *pvfs2_fh_to_dentry(struct super_block *sb,
+				  struct fid *fid,
+				  int fh_len,
+				  int fh_type)
+{
+	struct pvfs2_object_kref refn;
+
+	if (fh_len < 5 || fh_type > 2)
+		return NULL;
+
+	PVFS_khandle_from(&(refn.khandle), fid->raw, 16);
+	refn.fs_id = (u32) fid->raw[4];
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "fh_to_dentry: handle %pU, fs_id %d\n",
+		     &refn.khandle,
+		     refn.fs_id);
+
+	return d_obtain_alias(pvfs2_iget(sb, &refn));
+}
+
+static int pvfs2_encode_fh(struct inode *inode,
+		    __u32 *fh,
+		    int *max_len,
+		    struct inode *parent)
+{
+	int len = parent ? 10 : 5;
+	int type = 1;
+	struct pvfs2_object_kref refn;
+
+	if (*max_len < len) {
+		gossip_lerr("fh buffer is too small for encoding\n");
+		*max_len = len;
+		type = 255;
+		goto out;
+	}
+
+	refn = PVFS2_I(inode)->refn;
+	PVFS_khandle_to(&refn.khandle, fh, 16);
+	fh[4] = refn.fs_id;
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "Encoding fh: handle %pU, fsid %u\n",
+		     &refn.khandle,
+		     refn.fs_id);
+
+
+	if (parent) {
+		refn = PVFS2_I(parent)->refn;
+		PVFS_khandle_to(&refn.khandle, (char *) fh + 20, 16);
+		fh[9] = refn.fs_id;
+
+		type = 2;
+		gossip_debug(GOSSIP_SUPER_DEBUG,
+			     "Encoding parent: handle %pU, fsid %u\n",
+			     &refn.khandle,
+			     refn.fs_id);
+	}
+	*max_len = len;
+
+out:
+	return type;
+}
+
+static struct export_operations pvfs2_export_ops = {
+	.encode_fh = pvfs2_encode_fh,
+	.fh_to_dentry = pvfs2_fh_to_dentry,
+};
+
+static int pvfs2_fill_sb(struct super_block *sb, void *data, int silent)
+{
+	int ret = -EINVAL;
+	struct inode *root = NULL;
+	struct dentry *root_dentry = NULL;
+	struct pvfs2_mount_sb_info_s *mount_sb_info =
+		(struct pvfs2_mount_sb_info_s *) data;
+	struct pvfs2_object_kref root_object;
+
+	/* alloc and init our private pvfs2 sb info */
+	sb->s_fs_info =
+		kmalloc(sizeof(struct pvfs2_sb_info_s), PVFS2_GFP_FLAGS);
+	if (!PVFS2_SB(sb))
+		return -ENOMEM;
+	memset(sb->s_fs_info, 0, sizeof(struct pvfs2_sb_info_s));
+	PVFS2_SB(sb)->sb = sb;
+
+	PVFS2_SB(sb)->root_khandle = mount_sb_info->root_khandle;
+	PVFS2_SB(sb)->fs_id = mount_sb_info->fs_id;
+	PVFS2_SB(sb)->id = mount_sb_info->id;
+
+	if (mount_sb_info->data) {
+		ret = parse_mount_options(sb, mount_sb_info->data,
+					  silent);
+		if (ret)
+			return ret;
+	}
+
+	/* Hang the xattr handlers off the superblock */
+	sb->s_xattr = pvfs2_xattr_handlers;
+	sb->s_magic = PVFS2_SUPER_MAGIC;
+	sb->s_op = &pvfs2_s_ops;
+	sb->s_d_op = &pvfs2_dentry_operations;
+
+	sb->s_blocksize = pvfs_bufmap_size_query();
+	sb->s_blocksize_bits = pvfs_bufmap_shift_query();
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+
+	root_object.khandle = PVFS2_SB(sb)->root_khandle;
+	root_object.fs_id = PVFS2_SB(sb)->fs_id;
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "get inode %pU, fsid %d\n",
+		     &root_object.khandle,
+		     root_object.fs_id);
+
+	root = pvfs2_iget(sb, &root_object);
+	if (IS_ERR(root))
+		return PTR_ERR(root);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "Allocated root inode [%p] with mode %x\n",
+		     root,
+		     root->i_mode);
+
+	/* allocates and places root dentry in dcache */
+	root_dentry = d_make_root(root);
+	if (!root_dentry) {
+		iput(root);
+		return -ENOMEM;
+	}
+
+	sb->s_export_op = &pvfs2_export_ops;
+	sb->s_root = root_dentry;
+	return 0;
+}
+
+struct dentry *pvfs2_mount(struct file_system_type *fst,
+			   int flags,
+			   const char *devname,
+			   void *data)
+{
+	int ret = -EINVAL;
+	struct super_block *sb = ERR_PTR(-EINVAL);
+	struct pvfs2_kernel_op_s *new_op;
+	struct pvfs2_mount_sb_info_s mount_sb_info;
+	struct dentry *mnt_sb_d = ERR_PTR(-EINVAL);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_mount: called with devname %s\n",
+		     devname);
+
+	if (!devname) {
+		gossip_err("ERROR: device name not specified.\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT);
+	if (!new_op)
+		return ERR_PTR(-ENOMEM);
+
+	strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server,
+		devname,
+		PVFS_MAX_SERVER_ADDR_LEN);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "Attempting PVFS2 Mount via host %s\n",
+		     new_op->upcall.req.fs_mount.pvfs2_config_server);
+
+	ret = service_operation(new_op, "pvfs2_mount", 0);
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_mount: mount got return value of %d\n", ret);
+	if (ret)
+		goto free_op;
+
+	if (new_op->downcall.resp.fs_mount.fs_id == PVFS_FS_ID_NULL) {
+		gossip_err("ERROR: Retrieved null fs_id\n");
+		ret = -EINVAL;
+		goto free_op;
+	}
+
+	/* fill in temporary structure passed to fill_sb method */
+	mount_sb_info.data = data;
+	mount_sb_info.root_khandle =
+		new_op->downcall.resp.fs_mount.root_khandle;
+	mount_sb_info.fs_id = new_op->downcall.resp.fs_mount.fs_id;
+	mount_sb_info.id = new_op->downcall.resp.fs_mount.id;
+
+	/*
+	 * the mount_sb_info structure looks odd, but it's used because
+	 * the private sb info isn't allocated until we call
+	 * pvfs2_fill_sb, yet we have the info we need to fill it with
+	 * here.  so we store it temporarily and pass all of the info
+	 * to fill_sb where it's properly copied out
+	 */
+	mnt_sb_d = mount_nodev(fst,
+			       flags,
+			       (void *)&mount_sb_info,
+			       pvfs2_fill_sb);
+	if (IS_ERR(mnt_sb_d)) {
+		sb = ERR_CAST(mnt_sb_d);
+		goto free_op;
+	}
+
+	sb = mnt_sb_d->d_sb;
+
+	/*
+	 * on successful mount, store the devname and data
+	 * used
+	 */
+	strncpy(PVFS2_SB(sb)->devname,
+		devname,
+		PVFS_MAX_SERVER_ADDR_LEN);
+
+	/* mount_pending must be cleared */
+	PVFS2_SB(sb)->mount_pending = 0;
+
+	/*
+	 * finally, add this sb to our list of known pvfs2
+	 * sb's
+	 */
+	add_pvfs2_sb(sb);
+	op_release(new_op);
+	return mnt_sb_d;
+
+free_op:
+	gossip_err("pvfs2_mount: mount request failed with %d\n", ret);
+	if (ret == -EINVAL) {
+		gossip_err("Ensure that all pvfs2-servers have the same FS configuration files\n");
+		gossip_err("Look at pvfs2-client-core log file (typically /tmp/pvfs2-client.log) for more details\n");
+	}
+
+	op_release(new_op);
+
+	gossip_debug(GOSSIP_SUPER_DEBUG,
+		     "pvfs2_mount: returning dentry %p\n",
+		     mnt_sb_d);
+	return mnt_sb_d;
+}
+
+void pvfs2_kill_sb(struct super_block *sb)
+{
+	gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_kill_sb: called\n");
+
+	/*
+	 * issue the unmount to userspace to tell it to remove the
+	 * dynamic mount info it has for this superblock
+	 */
+	pvfs2_unmount_sb(sb);
+
+	/* remove the sb from our list of pvfs2 specific sb's */
+	remove_pvfs2_sb(sb);
+
+	/* provided sb cleanup */
+	kill_anon_super(sb);
+
+	/* free the pvfs2 superblock private data */
+	kfree(PVFS2_SB(sb));
+}
+
+int pvfs2_inode_cache_initialize(void)
+{
+	pvfs2_inode_cache = kmem_cache_create("pvfs2_inode_cache",
+					      sizeof(struct pvfs2_inode_s),
+					      0,
+					      PVFS2_CACHE_CREATE_FLAGS,
+					      pvfs2_inode_cache_ctor);
+
+	if (!pvfs2_inode_cache) {
+		gossip_err("Cannot create pvfs2_inode_cache\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+int pvfs2_inode_cache_finalize(void)
+{
+	kmem_cache_destroy(pvfs2_inode_cache);
+	return 0;
+}
diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c
new file mode 100644
index 000000000000..2adfceff7730
--- /dev/null
+++ b/fs/orangefs/symlink.c
@@ -0,0 +1,31 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+static const char *pvfs2_follow_link(struct dentry *dentry, void **cookie)
+{
+	char *target =  PVFS2_I(dentry->d_inode)->link_target;
+
+	gossip_debug(GOSSIP_INODE_DEBUG,
+		     "%s: called on %s (target is %p)\n",
+		     __func__, (char *)dentry->d_name.name, target);
+
+	*cookie = target;
+
+	return target;
+}
+
+struct inode_operations pvfs2_symlink_inode_operations = {
+	.readlink = generic_readlink,
+	.follow_link = pvfs2_follow_link,
+	.setattr = pvfs2_setattr,
+	.getattr = pvfs2_getattr,
+	.listxattr = pvfs2_listxattr,
+	.setxattr = generic_setxattr,
+};
diff --git a/fs/orangefs/upcall.h b/fs/orangefs/upcall.h
new file mode 100644
index 000000000000..1e07f626aac6
--- /dev/null
+++ b/fs/orangefs/upcall.h
@@ -0,0 +1,255 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#ifndef __UPCALL_H
+#define __UPCALL_H
+
+/*
+ * Sanitized this header file to fix
+ * 32-64 bit interaction issues between
+ * client-core and device
+ */
+struct pvfs2_io_request_s {
+	__s32 async_vfs_io;
+	__s32 buf_index;
+	__s32 count;
+	__s32 __pad1;
+	__s64 offset;
+	struct pvfs2_object_kref refn;
+	enum PVFS_io_type io_type;
+	__s32 readahead_size;
+};
+
+struct pvfs2_iox_request_s {
+	__s32 buf_index;
+	__s32 count;
+	struct pvfs2_object_kref refn;
+	enum PVFS_io_type io_type;
+	__s32 __pad1;
+};
+
+struct pvfs2_lookup_request_s {
+	__s32 sym_follow;
+	__s32 __pad1;
+	struct pvfs2_object_kref parent_refn;
+	char d_name[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_create_request_s {
+	struct pvfs2_object_kref parent_refn;
+	struct PVFS_sys_attr_s attributes;
+	char d_name[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_symlink_request_s {
+	struct pvfs2_object_kref parent_refn;
+	struct PVFS_sys_attr_s attributes;
+	char entry_name[PVFS2_NAME_LEN];
+	char target[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_getattr_request_s {
+	struct pvfs2_object_kref refn;
+	__u32 mask;
+	__u32 __pad1;
+};
+
+struct pvfs2_setattr_request_s {
+	struct pvfs2_object_kref refn;
+	struct PVFS_sys_attr_s attributes;
+};
+
+struct pvfs2_remove_request_s {
+	struct pvfs2_object_kref parent_refn;
+	char d_name[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_mkdir_request_s {
+	struct pvfs2_object_kref parent_refn;
+	struct PVFS_sys_attr_s attributes;
+	char d_name[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_readdir_request_s {
+	struct pvfs2_object_kref refn;
+	__u64 token;
+	__s32 max_dirent_count;
+	__s32 buf_index;
+};
+
+struct pvfs2_readdirplus_request_s {
+	struct pvfs2_object_kref refn;
+	__u64 token;
+	__s32 max_dirent_count;
+	__u32 mask;
+	__s32 buf_index;
+	__s32 __pad1;
+};
+
+struct pvfs2_rename_request_s {
+	struct pvfs2_object_kref old_parent_refn;
+	struct pvfs2_object_kref new_parent_refn;
+	char d_old_name[PVFS2_NAME_LEN];
+	char d_new_name[PVFS2_NAME_LEN];
+};
+
+struct pvfs2_statfs_request_s {
+	__s32 fs_id;
+	__s32 __pad1;
+};
+
+struct pvfs2_truncate_request_s {
+	struct pvfs2_object_kref refn;
+	__s64 size;
+};
+
+struct pvfs2_mmap_ra_cache_flush_request_s {
+	struct pvfs2_object_kref refn;
+};
+
+struct pvfs2_fs_mount_request_s {
+	char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN];
+};
+
+struct pvfs2_fs_umount_request_s {
+	__s32 id;
+	__s32 fs_id;
+	char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN];
+};
+
+struct pvfs2_getxattr_request_s {
+	struct pvfs2_object_kref refn;
+	__s32 key_sz;
+	__s32 __pad1;
+	char key[PVFS_MAX_XATTR_NAMELEN];
+};
+
+struct pvfs2_setxattr_request_s {
+	struct pvfs2_object_kref refn;
+	struct PVFS_keyval_pair keyval;
+	__s32 flags;
+	__s32 __pad1;
+};
+
+struct pvfs2_listxattr_request_s {
+	struct pvfs2_object_kref refn;
+	__s32 requested_count;
+	__s32 __pad1;
+	__u64 token;
+};
+
+struct pvfs2_removexattr_request_s {
+	struct pvfs2_object_kref refn;
+	__s32 key_sz;
+	__s32 __pad1;
+	char key[PVFS_MAX_XATTR_NAMELEN];
+};
+
+struct pvfs2_op_cancel_s {
+	__u64 op_tag;
+};
+
+struct pvfs2_fsync_request_s {
+	struct pvfs2_object_kref refn;
+};
+
+enum pvfs2_param_request_type {
+	PVFS2_PARAM_REQUEST_SET = 1,
+	PVFS2_PARAM_REQUEST_GET = 2
+};
+
+enum pvfs2_param_request_op {
+	PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS = 1,
+	PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT = 2,
+	PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT = 3,
+	PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE = 4,
+	PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS = 5,
+	PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE = 6,
+	PVFS2_PARAM_REQUEST_OP_PERF_RESET = 7,
+	PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS = 8,
+	PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT = 9,
+	PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT = 10,
+	PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE = 11,
+	PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_TIMEOUT_MSECS = 12,
+	PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_HARD_LIMIT = 13,
+	PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_SOFT_LIMIT = 14,
+	PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_RECLAIM_PERCENTAGE = 15,
+	PVFS2_PARAM_REQUEST_OP_CLIENT_DEBUG = 16,
+	PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS = 17,
+	PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT = 18,
+	PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT = 19,
+	PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE = 20,
+	PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS = 21,
+	PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT = 22,
+	PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT = 23,
+	PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE = 24,
+	PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES = 25,
+};
+
+struct pvfs2_param_request_s {
+	enum pvfs2_param_request_type type;
+	enum pvfs2_param_request_op op;
+	__s64 value;
+	char s_value[PVFS2_MAX_DEBUG_STRING_LEN];
+};
+
+enum pvfs2_perf_count_request_type {
+	PVFS2_PERF_COUNT_REQUEST_ACACHE = 1,
+	PVFS2_PERF_COUNT_REQUEST_NCACHE = 2,
+	PVFS2_PERF_COUNT_REQUEST_CAPCACHE = 3,
+};
+
+struct pvfs2_perf_count_request_s {
+	enum pvfs2_perf_count_request_type type;
+	__s32 __pad1;
+};
+
+struct pvfs2_fs_key_request_s {
+	__s32 fsid;
+	__s32 __pad1;
+};
+
+struct pvfs2_upcall_s {
+	__s32 type;
+	__u32 uid;
+	__u32 gid;
+	int pid;
+	int tgid;
+	/* currently trailer is used only by readx/writex (iox) */
+	__s64 trailer_size;
+	char *trailer_buf;
+
+	union {
+		struct pvfs2_io_request_s io;
+		struct pvfs2_iox_request_s iox;
+		struct pvfs2_lookup_request_s lookup;
+		struct pvfs2_create_request_s create;
+		struct pvfs2_symlink_request_s sym;
+		struct pvfs2_getattr_request_s getattr;
+		struct pvfs2_setattr_request_s setattr;
+		struct pvfs2_remove_request_s remove;
+		struct pvfs2_mkdir_request_s mkdir;
+		struct pvfs2_readdir_request_s readdir;
+		struct pvfs2_readdirplus_request_s readdirplus;
+		struct pvfs2_rename_request_s rename;
+		struct pvfs2_statfs_request_s statfs;
+		struct pvfs2_truncate_request_s truncate;
+		struct pvfs2_mmap_ra_cache_flush_request_s ra_cache_flush;
+		struct pvfs2_fs_mount_request_s fs_mount;
+		struct pvfs2_fs_umount_request_s fs_umount;
+		struct pvfs2_getxattr_request_s getxattr;
+		struct pvfs2_setxattr_request_s setxattr;
+		struct pvfs2_listxattr_request_s listxattr;
+		struct pvfs2_removexattr_request_s removexattr;
+		struct pvfs2_op_cancel_s cancel;
+		struct pvfs2_fsync_request_s fsync;
+		struct pvfs2_param_request_s param;
+		struct pvfs2_perf_count_request_s perf_count;
+		struct pvfs2_fs_key_request_s fs_key;
+	} req;
+};
+
+#endif /* __UPCALL_H */
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c
new file mode 100644
index 000000000000..ad79e534dc8e
--- /dev/null
+++ b/fs/orangefs/waitqueue.c
@@ -0,0 +1,529 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ * (C) 2011 Omnibond Systems
+ *
+ * Changes by Acxiom Corporation to implement generic service_operation()
+ * function, Copyright Acxiom Corporation, 2005.
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  In-kernel waitqueue operations.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+
+/*
+ * What we do in this function is to walk the list of operations that are
+ * present in the request queue and mark them as purged.
+ * NOTE: This is called from the device close after client-core has
+ * guaranteed that no new operations could appear on the list since the
+ * client-core is anyway going to exit.
+ */
+void purge_waiting_ops(void)
+{
+	struct pvfs2_kernel_op_s *op;
+
+	spin_lock(&pvfs2_request_list_lock);
+	list_for_each_entry(op, &pvfs2_request_list, list) {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "pvfs2-client-core: purging op tag %llu %s\n",
+			     llu(op->tag),
+			     get_opname_string(op));
+		spin_lock(&op->lock);
+		set_op_state_purged(op);
+		spin_unlock(&op->lock);
+		wake_up_interruptible(&op->waitq);
+	}
+	spin_unlock(&pvfs2_request_list_lock);
+}
+
+/*
+ * submits a PVFS2 operation and waits for it to complete
+ *
+ * Note op->downcall.status will contain the status of the operation (in
+ * errno format), whether provided by pvfs2-client or a result of failure to
+ * service the operation.  If the caller wishes to distinguish, then
+ * op->state can be checked to see if it was serviced or not.
+ *
+ * Returns contents of op->downcall.status for convenience
+ */
+int service_operation(struct pvfs2_kernel_op_s *op,
+		      const char *op_name,
+		      int flags)
+{
+	/* flags to modify behavior */
+	sigset_t orig_sigset;
+	int ret = 0;
+
+	/* irqflags and wait_entry are only used IF the client-core aborts */
+	unsigned long irqflags;
+
+	DECLARE_WAITQUEUE(wait_entry, current);
+
+	op->upcall.tgid = current->tgid;
+	op->upcall.pid = current->pid;
+
+retry_servicing:
+	op->downcall.status = 0;
+	gossip_debug(GOSSIP_WAIT_DEBUG,
+		     "pvfs2: service_operation: %s %p\n",
+		     op_name,
+		     op);
+	gossip_debug(GOSSIP_WAIT_DEBUG,
+		     "pvfs2: operation posted by process: %s, pid: %i\n",
+		     current->comm,
+		     current->pid);
+
+	/* mask out signals if this operation is not to be interrupted */
+	if (!(flags & PVFS2_OP_INTERRUPTIBLE))
+		mask_blocked_signals(&orig_sigset);
+
+	if (!(flags & PVFS2_OP_NO_SEMAPHORE)) {
+		ret = mutex_lock_interruptible(&request_mutex);
+		/*
+		 * check to see if we were interrupted while waiting for
+		 * semaphore
+		 */
+		if (ret < 0) {
+			if (!(flags & PVFS2_OP_INTERRUPTIBLE))
+				unmask_blocked_signals(&orig_sigset);
+			op->downcall.status = ret;
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "pvfs2: service_operation interrupted.\n");
+			return ret;
+		}
+	}
+
+	gossip_debug(GOSSIP_WAIT_DEBUG,
+		     "%s:About to call is_daemon_in_service().\n",
+		     __func__);
+
+	if (is_daemon_in_service() < 0) {
+		/*
+		 * By incrementing the per-operation attempt counter, we
+		 * directly go into the timeout logic while waiting for
+		 * the matching downcall to be read
+		 */
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:client core is NOT in service(%d).\n",
+			     __func__,
+			     is_daemon_in_service());
+		op->attempts++;
+	}
+
+	/* queue up the operation */
+	if (flags & PVFS2_OP_PRIORITY) {
+		add_priority_op_to_request_list(op);
+	} else {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:About to call add_op_to_request_list().\n",
+			     __func__);
+		add_op_to_request_list(op);
+	}
+
+	if (!(flags & PVFS2_OP_NO_SEMAPHORE))
+		mutex_unlock(&request_mutex);
+
+	/*
+	 * If we are asked to service an asynchronous operation from
+	 * VFS perspective, we are done.
+	 */
+	if (flags & PVFS2_OP_ASYNC)
+		return 0;
+
+	if (flags & PVFS2_OP_CANCELLATION) {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:"
+			     "About to call wait_for_cancellation_downcall.\n",
+			     __func__);
+		ret = wait_for_cancellation_downcall(op);
+	} else {
+		ret = wait_for_matching_downcall(op);
+	}
+
+	if (ret < 0) {
+		/* failed to get matching downcall */
+		if (ret == -ETIMEDOUT) {
+			gossip_err("pvfs2: %s -- wait timed out; aborting attempt.\n",
+				   op_name);
+		}
+		op->downcall.status = ret;
+	} else {
+		/* got matching downcall; make sure status is in errno format */
+		op->downcall.status =
+		    pvfs2_normalize_to_errno(op->downcall.status);
+		ret = op->downcall.status;
+	}
+
+	if (!(flags & PVFS2_OP_INTERRUPTIBLE))
+		unmask_blocked_signals(&orig_sigset);
+
+	BUG_ON(ret != op->downcall.status);
+	/* retry if operation has not been serviced and if requested */
+	if (!op_state_serviced(op) && op->downcall.status == -EAGAIN) {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "pvfs2: tag %llu (%s)"
+			     " -- operation to be retried (%d attempt)\n",
+			     llu(op->tag),
+			     op_name,
+			     op->attempts + 1);
+
+		if (!op->uses_shared_memory)
+			/*
+			 * this operation doesn't use the shared memory
+			 * system
+			 */
+			goto retry_servicing;
+
+		/* op uses shared memory */
+		if (get_bufmap_init() == 0) {
+			/*
+			 * This operation uses the shared memory system AND
+			 * the system is not yet ready. This situation occurs
+			 * when the client-core is restarted AND there were
+			 * operations waiting to be processed or were already
+			 * in process.
+			 */
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "uses_shared_memory is true.\n");
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "Client core in-service status(%d).\n",
+				     is_daemon_in_service());
+			gossip_debug(GOSSIP_WAIT_DEBUG, "bufmap_init:%d.\n",
+				     get_bufmap_init());
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "operation's status is 0x%0x.\n",
+				     op->op_state);
+
+			/*
+			 * let process sleep for a few seconds so shared
+			 * memory system can be initialized.
+			 */
+			spin_lock_irqsave(&op->lock, irqflags);
+			add_wait_queue(&pvfs2_bufmap_init_waitq, &wait_entry);
+			spin_unlock_irqrestore(&op->lock, irqflags);
+
+			set_current_state(TASK_INTERRUPTIBLE);
+
+			/*
+			 * Wait for pvfs_bufmap_initialize() to wake me up
+			 * within the allotted time.
+			 */
+			ret = schedule_timeout(MSECS_TO_JIFFIES
+				(1000 * PVFS2_BUFMAP_WAIT_TIMEOUT_SECS));
+
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "Value returned from schedule_timeout:"
+				     "%d.\n",
+				     ret);
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "Is shared memory available? (%d).\n",
+				     get_bufmap_init());
+
+			spin_lock_irqsave(&op->lock, irqflags);
+			remove_wait_queue(&pvfs2_bufmap_init_waitq,
+					  &wait_entry);
+			spin_unlock_irqrestore(&op->lock, irqflags);
+
+			if (get_bufmap_init() == 0) {
+				gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted.  Aborting user's request(%s).\n",
+					   __func__,
+					   PVFS2_BUFMAP_WAIT_TIMEOUT_SECS,
+					   get_opname_string(op));
+				return -EIO;
+			}
+
+			/*
+			 * Return to the calling function and re-populate a
+			 * shared memory buffer.
+			 */
+			return -EAGAIN;
+		}
+	}
+
+	gossip_debug(GOSSIP_WAIT_DEBUG,
+		     "pvfs2: service_operation %s returning: %d for %p.\n",
+		     op_name,
+		     ret,
+		     op);
+	return ret;
+}
+
+void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op)
+{
+	/*
+	 * handle interrupted cases depending on what state we were in when
+	 * the interruption is detected.  there is a coarse grained lock
+	 * across the operation.
+	 *
+	 * NOTE: be sure not to reverse lock ordering by locking an op lock
+	 * while holding the request_list lock.  Here, we first lock the op
+	 * and then lock the appropriate list.
+	 */
+	if (!op) {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			    "%s: op is null, ignoring\n",
+			     __func__);
+		return;
+	}
+
+	/*
+	 * one more sanity check, make sure it's in one of the possible states
+	 * or don't try to cancel it
+	 */
+	if (!(op_state_waiting(op) ||
+	      op_state_in_progress(op) ||
+	      op_state_serviced(op) ||
+	      op_state_purged(op))) {
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s: op %p not in a valid state (%0x), "
+			     "ignoring\n",
+			     __func__,
+			     op,
+			     op->op_state);
+		return;
+	}
+
+	spin_lock(&op->lock);
+
+	if (op_state_waiting(op)) {
+		/*
+		 * upcall hasn't been read; remove op from upcall request
+		 * list.
+		 */
+		spin_unlock(&op->lock);
+		remove_op_from_request_list(op);
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "Interrupted: Removed op %p from request_list\n",
+			     op);
+	} else if (op_state_in_progress(op)) {
+		/* op must be removed from the in progress htable */
+		spin_unlock(&op->lock);
+		spin_lock(&htable_ops_in_progress_lock);
+		list_del(&op->list);
+		spin_unlock(&htable_ops_in_progress_lock);
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "Interrupted: Removed op %p"
+			     " from htable_ops_in_progress\n",
+			     op);
+	} else if (!op_state_serviced(op)) {
+		spin_unlock(&op->lock);
+		gossip_err("interrupted operation is in a weird state 0x%x\n",
+			   op->op_state);
+	} else {
+		/*
+		 * It is not intended for execution to flow here,
+		 * but having this unlock here makes sparse happy.
+		 */
+		gossip_err("%s: can't get here.\n", __func__);
+		spin_unlock(&op->lock);
+	}
+}
+
+/*
+ * sleeps on waitqueue waiting for matching downcall.
+ * if client-core finishes servicing, then we are good to go.
+ * else if client-core exits, we get woken up here, and retry with a timeout
+ *
+ * Post when this call returns to the caller, the specified op will no
+ * longer be on any list or htable.
+ *
+ * Returns 0 on success and -errno on failure
+ * Errors are:
+ * EAGAIN in case we want the caller to requeue and try again..
+ * EINTR/EIO/ETIMEDOUT indicating we are done trying to service this
+ * operation since client-core seems to be exiting too often
+ * or if we were interrupted.
+ */
+int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op)
+{
+	int ret = -EINVAL;
+	DECLARE_WAITQUEUE(wait_entry, current);
+
+	spin_lock(&op->lock);
+	add_wait_queue(&op->waitq, &wait_entry);
+	spin_unlock(&op->lock);
+
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		spin_lock(&op->lock);
+		if (op_state_serviced(op)) {
+			spin_unlock(&op->lock);
+			ret = 0;
+			break;
+		}
+		spin_unlock(&op->lock);
+
+		if (!signal_pending(current)) {
+			/*
+			 * if this was our first attempt and client-core
+			 * has not purged our operation, we are happy to
+			 * simply wait
+			 */
+			spin_lock(&op->lock);
+			if (op->attempts == 0 && !op_state_purged(op)) {
+				spin_unlock(&op->lock);
+				schedule();
+			} else {
+				spin_unlock(&op->lock);
+				/*
+				 * subsequent attempts, we retry exactly once
+				 * with timeouts
+				 */
+				if (!schedule_timeout(MSECS_TO_JIFFIES
+				      (1000 * op_timeout_secs))) {
+					gossip_debug(GOSSIP_WAIT_DEBUG,
+						     "*** %s:"
+						     " operation timed out (tag"
+						     " %llu, %p, att %d)\n",
+						     __func__,
+						     llu(op->tag),
+						     op,
+						     op->attempts);
+					ret = -ETIMEDOUT;
+					pvfs2_clean_up_interrupted_operation
+					    (op);
+					break;
+				}
+			}
+			spin_lock(&op->lock);
+			op->attempts++;
+			/*
+			 * if the operation was purged in the meantime, it
+			 * is better to requeue it afresh but ensure that
+			 * we have not been purged repeatedly. This could
+			 * happen if client-core crashes when an op
+			 * is being serviced, so we requeue the op, client
+			 * core crashes again so we requeue the op, client
+			 * core starts, and so on...
+			 */
+			if (op_state_purged(op)) {
+				ret = (op->attempts < PVFS2_PURGE_RETRY_COUNT) ?
+					 -EAGAIN :
+					 -EIO;
+				spin_unlock(&op->lock);
+				gossip_debug(GOSSIP_WAIT_DEBUG,
+					     "*** %s:"
+					     " operation purged (tag "
+					     "%llu, %p, att %d)\n",
+					     __func__,
+					     llu(op->tag),
+					     op,
+					     op->attempts);
+				pvfs2_clean_up_interrupted_operation(op);
+				break;
+			}
+			spin_unlock(&op->lock);
+			continue;
+		}
+
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "*** %s:"
+			     " operation interrupted by a signal (tag "
+			     "%llu, op %p)\n",
+			     __func__,
+			     llu(op->tag),
+			     op);
+		pvfs2_clean_up_interrupted_operation(op);
+		ret = -EINTR;
+		break;
+	}
+
+	set_current_state(TASK_RUNNING);
+
+	spin_lock(&op->lock);
+	remove_wait_queue(&op->waitq, &wait_entry);
+	spin_unlock(&op->lock);
+
+	return ret;
+}
+
+/*
+ * similar to wait_for_matching_downcall(), but used in the special case
+ * of I/O cancellations.
+ *
+ * Note we need a special wait function because if this is called we already
+ *      know that a signal is pending in current and need to service the
+ *      cancellation upcall anyway.  the only way to exit this is to either
+ *      timeout or have the cancellation be serviced properly.
+ */
+int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op)
+{
+	int ret = -EINVAL;
+	DECLARE_WAITQUEUE(wait_entry, current);
+
+	spin_lock(&op->lock);
+	add_wait_queue(&op->waitq, &wait_entry);
+	spin_unlock(&op->lock);
+
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		spin_lock(&op->lock);
+		if (op_state_serviced(op)) {
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "%s:op-state is SERVICED.\n",
+				     __func__);
+			spin_unlock(&op->lock);
+			ret = 0;
+			break;
+		}
+		spin_unlock(&op->lock);
+
+		if (signal_pending(current)) {
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "%s:operation interrupted by a signal (tag"
+				     " %llu, op %p)\n",
+				     __func__,
+				     llu(op->tag),
+				     op);
+			pvfs2_clean_up_interrupted_operation(op);
+			ret = -EINTR;
+			break;
+		}
+
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:About to call schedule_timeout.\n",
+			     __func__);
+		ret =
+		    schedule_timeout(MSECS_TO_JIFFIES(1000 * op_timeout_secs));
+
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:Value returned from schedule_timeout(%d).\n",
+			     __func__,
+			     ret);
+		if (!ret) {
+			gossip_debug(GOSSIP_WAIT_DEBUG,
+				     "%s:*** operation timed out: %p\n",
+				     __func__,
+				     op);
+			pvfs2_clean_up_interrupted_operation(op);
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		gossip_debug(GOSSIP_WAIT_DEBUG,
+			     "%s:Breaking out of loop, regardless of value returned by schedule_timeout.\n",
+			     __func__);
+		ret = -ETIMEDOUT;
+		break;
+	}
+
+	set_current_state(TASK_RUNNING);
+
+	spin_lock(&op->lock);
+	remove_wait_queue(&op->waitq, &wait_entry);
+	spin_unlock(&op->lock);
+
+	gossip_debug(GOSSIP_WAIT_DEBUG,
+		     "%s:returning ret(%d)\n",
+		     __func__,
+		     ret);
+
+	return ret;
+}
diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c
new file mode 100644
index 000000000000..227eaa47b1e1
--- /dev/null
+++ b/fs/orangefs/xattr.c
@@ -0,0 +1,530 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ *  Linux VFS extended attribute operations.
+ */
+
+#include "protocol.h"
+#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
+#include <linux/posix_acl_xattr.h>
+#include <linux/xattr.h>
+
+
+#define SYSTEM_PVFS2_KEY "system.pvfs2."
+#define SYSTEM_PVFS2_KEY_LEN 13
+
+/*
+ * this function returns
+ *   0 if the key corresponding to name is not meant to be printed as part
+ *     of a listxattr.
+ *   1 if the key corresponding to name is meant to be returned as part of
+ *     a listxattr.
+ * The ones that start SYSTEM_PVFS2_KEY are the ones to avoid printing.
+ */
+static int is_reserved_key(const char *key, size_t size)
+{
+
+	if (size < SYSTEM_PVFS2_KEY_LEN)
+		return 1;
+
+	return strncmp(key, SYSTEM_PVFS2_KEY, SYSTEM_PVFS2_KEY_LEN) ?  1 : 0;
+}
+
+static inline int convert_to_internal_xattr_flags(int setxattr_flags)
+{
+	int internal_flag = 0;
+
+	if (setxattr_flags & XATTR_REPLACE) {
+		/* Attribute must exist! */
+		internal_flag = PVFS_XATTR_REPLACE;
+	} else if (setxattr_flags & XATTR_CREATE) {
+		/* Attribute must not exist */
+		internal_flag = PVFS_XATTR_CREATE;
+	}
+	return internal_flag;
+}
+
+
+/*
+ * Tries to get a specified key's attributes of a given
+ * file into a user-specified buffer. Note that the getxattr
+ * interface allows for the users to probe the size of an
+ * extended attribute by passing in a value of 0 to size.
+ * Thus our return value is always the size of the attribute
+ * unless the key does not exist for the file and/or if
+ * there were errors in fetching the attribute value.
+ */
+ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix,
+		const char *name, void *buffer, size_t size)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	ssize_t ret = -ENOMEM;
+	ssize_t length = 0;
+	int fsuid;
+	int fsgid;
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "%s: prefix %s name %s, buffer_size %zd\n",
+		     __func__, prefix, name, size);
+
+	if (name == NULL || (size > 0 && buffer == NULL)) {
+		gossip_err("pvfs2_inode_getxattr: bogus NULL pointers\n");
+		return -EINVAL;
+	}
+	if ((strlen(name) + strlen(prefix)) >= PVFS_MAX_XATTR_NAMELEN) {
+		gossip_err("Invalid key length (%d)\n",
+			   (int)(strlen(name) + strlen(prefix)));
+		return -EINVAL;
+	}
+
+	fsuid = from_kuid(current_user_ns(), current_fsuid());
+	fsgid = from_kgid(current_user_ns(), current_fsgid());
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "getxattr on inode %pU, name %s "
+		     "(uid %o, gid %o)\n",
+		     get_khandle_from_ino(inode),
+		     name,
+		     fsuid,
+		     fsgid);
+
+	down_read(&pvfs2_inode->xattr_sem);
+
+	new_op = op_alloc(PVFS2_VFS_OP_GETXATTR);
+	if (!new_op)
+		goto out_unlock;
+
+	new_op->upcall.req.getxattr.refn = pvfs2_inode->refn;
+	ret = snprintf((char *)new_op->upcall.req.getxattr.key,
+		       PVFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name);
+
+	/*
+	 * NOTE: Although keys are meant to be NULL terminated textual
+	 * strings, I am going to explicitly pass the length just in case
+	 * we change this later on...
+	 */
+	new_op->upcall.req.getxattr.key_sz = ret + 1;
+
+	ret = service_operation(new_op, "pvfs2_inode_getxattr",
+				get_interruptible_flag(inode));
+	if (ret != 0) {
+		if (ret == -ENOENT) {
+			ret = -ENODATA;
+			gossip_debug(GOSSIP_XATTR_DEBUG,
+				     "pvfs2_inode_getxattr: inode %pU key %s"
+				     " does not exist!\n",
+				     get_khandle_from_ino(inode),
+				     (char *)new_op->upcall.req.getxattr.key);
+		}
+		goto out_release_op;
+	}
+
+	/*
+	 * Length returned includes null terminator.
+	 */
+	length = new_op->downcall.resp.getxattr.val_sz;
+
+	/*
+	 * Just return the length of the queried attribute.
+	 */
+	if (size == 0) {
+		ret = length;
+		goto out_release_op;
+	}
+
+	/*
+	 * Check to see if key length is > provided buffer size.
+	 */
+	if (length > size) {
+		ret = -ERANGE;
+		goto out_release_op;
+	}
+
+	memset(buffer, 0, size);
+	memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+	     "pvfs2_inode_getxattr: inode %pU "
+	     "key %s key_sz %d, val_len %d\n",
+	     get_khandle_from_ino(inode),
+	     (char *)new_op->
+		upcall.req.getxattr.key,
+		     (int)new_op->
+		upcall.req.getxattr.key_sz,
+	     (int)ret);
+
+	ret = length;
+
+out_release_op:
+	op_release(new_op);
+out_unlock:
+	up_read(&pvfs2_inode->xattr_sem);
+	return ret;
+}
+
+static int pvfs2_inode_removexattr(struct inode *inode,
+			    const char *prefix,
+			    const char *name,
+			    int flags)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op = NULL;
+	int ret = -ENOMEM;
+
+	down_write(&pvfs2_inode->xattr_sem);
+	new_op = op_alloc(PVFS2_VFS_OP_REMOVEXATTR);
+	if (!new_op)
+		goto out_unlock;
+
+	new_op->upcall.req.removexattr.refn = pvfs2_inode->refn;
+	/*
+	 * NOTE: Although keys are meant to be NULL terminated
+	 * textual strings, I am going to explicitly pass the
+	 * length just in case we change this later on...
+	 */
+	ret = snprintf((char *)new_op->upcall.req.removexattr.key,
+		       PVFS_MAX_XATTR_NAMELEN,
+		       "%s%s",
+		       (prefix ? prefix : ""),
+		       name);
+	new_op->upcall.req.removexattr.key_sz = ret + 1;
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "pvfs2_inode_removexattr: key %s, key_sz %d\n",
+		     (char *)new_op->upcall.req.removexattr.key,
+		     (int)new_op->upcall.req.removexattr.key_sz);
+
+	ret = service_operation(new_op,
+				"pvfs2_inode_removexattr",
+				get_interruptible_flag(inode));
+	if (ret == -ENOENT) {
+		/*
+		 * Request to replace a non-existent attribute is an error.
+		 */
+		if (flags & XATTR_REPLACE)
+			ret = -ENODATA;
+		else
+			ret = 0;
+	}
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "pvfs2_inode_removexattr: returning %d\n", ret);
+
+	op_release(new_op);
+out_unlock:
+	up_write(&pvfs2_inode->xattr_sem);
+	return ret;
+}
+
+/*
+ * Tries to set an attribute for a given key on a file.
+ *
+ * Returns a -ve number on error and 0 on success.  Key is text, but value
+ * can be binary!
+ */
+int pvfs2_inode_setxattr(struct inode *inode, const char *prefix,
+		const char *name, const void *value, size_t size, int flags)
+{
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op;
+	int internal_flag = 0;
+	int ret = -ENOMEM;
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "%s: prefix %s, name %s, buffer_size %zd\n",
+		     __func__, prefix, name, size);
+
+	if (size < 0 ||
+	    size >= PVFS_MAX_XATTR_VALUELEN ||
+	    flags < 0) {
+		gossip_err("pvfs2_inode_setxattr: bogus values of size(%d), flags(%d)\n",
+			   (int)size,
+			   flags);
+		return -EINVAL;
+	}
+
+	if (name == NULL ||
+	    (size > 0 && value == NULL)) {
+		gossip_err("pvfs2_inode_setxattr: bogus NULL pointers!\n");
+		return -EINVAL;
+	}
+
+	internal_flag = convert_to_internal_xattr_flags(flags);
+
+	if (prefix) {
+		if (strlen(name) + strlen(prefix) >= PVFS_MAX_XATTR_NAMELEN) {
+			gossip_err
+			    ("pvfs2_inode_setxattr: bogus key size (%d)\n",
+			     (int)(strlen(name) + strlen(prefix)));
+			return -EINVAL;
+		}
+	} else {
+		if (strlen(name) >= PVFS_MAX_XATTR_NAMELEN) {
+			gossip_err
+			    ("pvfs2_inode_setxattr: bogus key size (%d)\n",
+			     (int)(strlen(name)));
+			return -EINVAL;
+		}
+	}
+
+	/* This is equivalent to a removexattr */
+	if (size == 0 && value == NULL) {
+		gossip_debug(GOSSIP_XATTR_DEBUG,
+			     "removing xattr (%s%s)\n",
+			     prefix,
+			     name);
+		return pvfs2_inode_removexattr(inode, prefix, name, flags);
+	}
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "setxattr on inode %pU, name %s\n",
+		     get_khandle_from_ino(inode),
+		     name);
+
+	down_write(&pvfs2_inode->xattr_sem);
+	new_op = op_alloc(PVFS2_VFS_OP_SETXATTR);
+	if (!new_op)
+		goto out_unlock;
+
+
+	new_op->upcall.req.setxattr.refn = pvfs2_inode->refn;
+	new_op->upcall.req.setxattr.flags = internal_flag;
+	/*
+	 * NOTE: Although keys are meant to be NULL terminated textual
+	 * strings, I am going to explicitly pass the length just in
+	 * case we change this later on...
+	 */
+	ret = snprintf((char *)new_op->upcall.req.setxattr.keyval.key,
+		       PVFS_MAX_XATTR_NAMELEN,
+		       "%s%s",
+		       prefix, name);
+	new_op->upcall.req.setxattr.keyval.key_sz = ret + 1;
+	memcpy(new_op->upcall.req.setxattr.keyval.val, value, size);
+	new_op->upcall.req.setxattr.keyval.val_sz = size;
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "pvfs2_inode_setxattr: key %s, key_sz %d "
+		     " value size %zd\n",
+		     (char *)new_op->upcall.req.setxattr.keyval.key,
+		     (int)new_op->upcall.req.setxattr.keyval.key_sz,
+		     size);
+
+	ret = service_operation(new_op,
+				"pvfs2_inode_setxattr",
+				get_interruptible_flag(inode));
+
+	gossip_debug(GOSSIP_XATTR_DEBUG,
+		     "pvfs2_inode_setxattr: returning %d\n",
+		     ret);
+
+	/* when request is serviced properly, free req op struct */
+	op_release(new_op);
+out_unlock:
+	up_write(&pvfs2_inode->xattr_sem);
+	return ret;
+}
+
+/*
+ * Tries to get a specified object's keys into a user-specified buffer of a
+ * given size.  Note that like the previous instances of xattr routines, this
+ * also allows you to pass in a NULL pointer and 0 size to probe the size for
+ * subsequent memory allocations. Thus our return value is always the size of
+ * all the keys unless there were errors in fetching the keys!
+ */
+ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+	struct pvfs2_kernel_op_s *new_op;
+	__u64 token = PVFS_ITERATE_START;
+	ssize_t ret = -ENOMEM;
+	ssize_t total = 0;
+	ssize_t length = 0;
+	int count_keys = 0;
+	int key_size;
+	int i = 0;
+
+	if (size > 0 && buffer == NULL) {
+		gossip_err("%s: bogus NULL pointers\n", __func__);
+		return -EINVAL;
+	}
+	if (size < 0) {
+		gossip_err("Invalid size (%d)\n", (int)size);
+		return -EINVAL;
+	}
+
+	down_read(&pvfs2_inode->xattr_sem);
+	new_op = op_alloc(PVFS2_VFS_OP_LISTXATTR);
+	if (!new_op)
+		goto out_unlock;
+
+	if (buffer && size > 0)
+		memset(buffer, 0, size);
+
+try_again:
+	key_size = 0;
+	new_op->upcall.req.listxattr.refn = pvfs2_inode->refn;
+	new_op->upcall.req.listxattr.token = token;
+	new_op->upcall.req.listxattr.requested_count =
+	    (size == 0) ? 0 : PVFS_MAX_XATTR_LISTLEN;
+	ret = service_operation(new_op, __func__,
+				get_interruptible_flag(inode));
+	if (ret != 0)
+		goto done;
+
+	if (size == 0) {
+		/*
+		 * This is a bit of a big upper limit, but I did not want to
+		 * spend too much time getting this correct, since users end
+		 * up allocating memory rather than us...
+		 */
+		total = new_op->downcall.resp.listxattr.returned_count *
+			PVFS_MAX_XATTR_NAMELEN;
+		goto done;
+	}
+
+	length = new_op->downcall.resp.listxattr.keylen;
+	if (length == 0)
+		goto done;
+
+	/*
+	 * Check to see how much can be fit in the buffer. Fit only whole keys.
+	 */
+	for (i = 0; i < new_op->downcall.resp.listxattr.returned_count; i++) {
+		if (total + new_op->downcall.resp.listxattr.lengths[i] > size)
+			goto done;
+
+		/*
+		 * Since many dumb programs try to setxattr() on our reserved
+		 * xattrs this is a feeble attempt at defeating those by not
+		 * listing them in the output of listxattr.. sigh
+		 */
+		if (is_reserved_key(new_op->downcall.resp.listxattr.key +
+				    key_size,
+				    new_op->downcall.resp.
+					listxattr.lengths[i])) {
+			gossip_debug(GOSSIP_XATTR_DEBUG, "Copying key %d -> %s\n",
+					i, new_op->downcall.resp.listxattr.key +
+						key_size);
+			memcpy(buffer + total,
+				new_op->downcall.resp.listxattr.key + key_size,
+				new_op->downcall.resp.listxattr.lengths[i]);
+			total += new_op->downcall.resp.listxattr.lengths[i];
+			count_keys++;
+		} else {
+			gossip_debug(GOSSIP_XATTR_DEBUG, "[RESERVED] key %d -> %s\n",
+					i, new_op->downcall.resp.listxattr.key +
+						key_size);
+		}
+		key_size += new_op->downcall.resp.listxattr.lengths[i];
+	}
+
+	/*
+	 * Since the buffer was large enough, we might have to continue
+	 * fetching more keys!
+	 */
+	token = new_op->downcall.resp.listxattr.token;
+	if (token != PVFS_ITERATE_END)
+		goto try_again;
+
+done:
+	gossip_debug(GOSSIP_XATTR_DEBUG, "%s: returning %d"
+		     " [size of buffer %ld] (filled in %d keys)\n",
+		     __func__,
+		     ret ? (int)ret : (int)total,
+		     (long)size,
+		     count_keys);
+	op_release(new_op);
+	if (ret == 0)
+		ret = total;
+out_unlock:
+	up_read(&pvfs2_inode->xattr_sem);
+	return ret;
+}
+
+int pvfs2_xattr_set_default(struct dentry *dentry,
+			    const char *name,
+			    const void *buffer,
+			    size_t size,
+			    int flags,
+			    int handler_flags)
+{
+	return pvfs2_inode_setxattr(dentry->d_inode,
+				    PVFS2_XATTR_NAME_DEFAULT_PREFIX,
+				    name,
+				    buffer,
+				    size,
+				    flags);
+}
+
+int pvfs2_xattr_get_default(struct dentry *dentry,
+			    const char *name,
+			    void *buffer,
+			    size_t size,
+			    int handler_flags)
+{
+	return pvfs2_inode_getxattr(dentry->d_inode,
+				    PVFS2_XATTR_NAME_DEFAULT_PREFIX,
+				    name,
+				    buffer,
+				    size);
+
+}
+
+static int pvfs2_xattr_set_trusted(struct dentry *dentry,
+			    const char *name,
+			    const void *buffer,
+			    size_t size,
+			    int flags,
+			    int handler_flags)
+{
+	return pvfs2_inode_setxattr(dentry->d_inode,
+				    PVFS2_XATTR_NAME_TRUSTED_PREFIX,
+				    name,
+				    buffer,
+				    size,
+				    flags);
+}
+
+static int pvfs2_xattr_get_trusted(struct dentry *dentry,
+			    const char *name,
+			    void *buffer,
+			    size_t size,
+			    int handler_flags)
+{
+	return pvfs2_inode_getxattr(dentry->d_inode,
+				    PVFS2_XATTR_NAME_TRUSTED_PREFIX,
+				    name,
+				    buffer,
+				    size);
+}
+
+static struct xattr_handler pvfs2_xattr_trusted_handler = {
+	.prefix = PVFS2_XATTR_NAME_TRUSTED_PREFIX,
+	.get = pvfs2_xattr_get_trusted,
+	.set = pvfs2_xattr_set_trusted,
+};
+
+static struct xattr_handler pvfs2_xattr_default_handler = {
+	/*
+	 * NOTE: this is set to be the empty string.
+	 * so that all un-prefixed xattrs keys get caught
+	 * here!
+	 */
+	.prefix = PVFS2_XATTR_NAME_DEFAULT_PREFIX,
+	.get = pvfs2_xattr_get_default,
+	.set = pvfs2_xattr_set_default,
+};
+
+const struct xattr_handler *pvfs2_xattr_handlers[] = {
+	&posix_acl_access_xattr_handler,
+	&posix_acl_default_xattr_handler,
+	&pvfs2_xattr_trusted_handler,
+	&pvfs2_xattr_default_handler,
+	NULL
+};
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index dc9f27e9d61b..9a517109da0f 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1498,11 +1498,10 @@ static struct ubifs_nnode *dirty_cow_nnode(struct ubifs_info *c,
 	}
 
 	/* nnode is being committed, so copy it */
-	n = kmalloc(sizeof(struct ubifs_nnode), GFP_NOFS);
+	n = kmemdup(nnode, sizeof(struct ubifs_nnode), GFP_NOFS);
 	if (unlikely(!n))
 		return ERR_PTR(-ENOMEM);
 
-	memcpy(n, nnode, sizeof(struct ubifs_nnode));
 	n->cnext = NULL;
 	__set_bit(DIRTY_CNODE, &n->flags);
 	__clear_bit(COW_CNODE, &n->flags);
@@ -1549,11 +1548,10 @@ static struct ubifs_pnode *dirty_cow_pnode(struct ubifs_info *c,
 	}
 
 	/* pnode is being committed, so copy it */
-	p = kmalloc(sizeof(struct ubifs_pnode), GFP_NOFS);
+	p = kmemdup(pnode, sizeof(struct ubifs_pnode), GFP_NOFS);
 	if (unlikely(!p))
 		return ERR_PTR(-ENOMEM);
 
-	memcpy(p, pnode, sizeof(struct ubifs_pnode));
 	p->cnext = NULL;
 	__set_bit(DIRTY_CNODE, &p->flags);
 	__clear_bit(COW_CNODE, &p->flags);
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 957f5757f374..fa9a20cc60d6 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -198,11 +198,10 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
 {
 	struct ubifs_znode *zn;
 
-	zn = kmalloc(c->max_znode_sz, GFP_NOFS);
+	zn = kmemdup(znode, c->max_znode_sz, GFP_NOFS);
 	if (unlikely(!zn))
 		return ERR_PTR(-ENOMEM);
 
-	memcpy(zn, znode, c->max_znode_sz);
 	zn->cnext = NULL;
 	__set_bit(DIRTY_ZNODE, &zn->flags);
 	__clear_bit(COW_ZNODE, &zn->flags);
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index de759022f3d6..6ef2415aad9d 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -858,9 +858,9 @@ struct ubifs_compressor {
  * @mod_dent: non-zero if the operation removes or modifies an existing
  *            directory entry
  * @new_ino: non-zero if the operation adds a new inode
- * @new_ino_d: now much data newly created inode contains
+ * @new_ino_d: how much data newly created inode contains
  * @dirtied_ino: how many inodes the operation makes dirty
- * @dirtied_ino_d: now much data dirtied inode contains
+ * @dirtied_ino_d: how much data dirtied inode contains
  * @idx_growth: how much the index will supposedly grow
  * @data_growth: how much new data the operation will supposedly add
  * @dd_growth: how much data that makes other data dirty the operation will
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index 83bfb87f5bf1..e2aadbc7151f 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -111,8 +111,8 @@ static inline void queued_spin_unlock_wait(struct qspinlock *lock)
 		cpu_relax();
 }
 
-#ifndef virt_queued_spin_lock
-static __always_inline bool virt_queued_spin_lock(struct qspinlock *lock)
+#ifndef virt_spin_lock
+static __always_inline bool virt_spin_lock(struct qspinlock *lock)
 {
 	return false;
 }
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 11266d147a29..1547eb43c14a 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -55,7 +55,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 				     struct drm_atomic_state *state);
 void drm_atomic_helper_commit_planes(struct drm_device *dev,
-				     struct drm_atomic_state *state);
+				     struct drm_atomic_state *state,
+				     bool active_only);
 void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
 				      struct drm_atomic_state *old_state);
 void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
@@ -117,6 +118,9 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
 					   struct drm_connector_state *state);
 struct drm_connector_state *
 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector);
+struct drm_atomic_state *
+drm_atomic_helper_duplicate_state(struct drm_device *dev,
+				  struct drm_modeset_acquire_ctx *ctx);
 void
 __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 					    struct drm_connector_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index faaeff7db684..c0366e9152e2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -210,8 +210,6 @@ struct drm_framebuffer {
 	int flags;
 	uint32_t pixel_format; /* fourcc format */
 	struct list_head filp_head;
-	/* if you are using the helper */
-	void *helper_private;
 };
 
 struct drm_property_blob {
@@ -1390,7 +1388,7 @@ extern int drm_property_add_enum(struct drm_property *property, int index,
 extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 extern int drm_mode_create_tv_properties(struct drm_device *dev,
 					 unsigned int num_modes,
-					 char *modes[]);
+					 const char * const modes[]);
 extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 extern int drm_mode_create_dirty_info_property(struct drm_device *dev);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 499e9f625aef..d0c88107996a 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -46,7 +46,7 @@
 
 #define DP_AUX_I2C_WRITE		0x0
 #define DP_AUX_I2C_READ			0x1
-#define DP_AUX_I2C_STATUS		0x2
+#define DP_AUX_I2C_WRITE_STATUS_UPDATE	0x2
 #define DP_AUX_I2C_MOT			0x4
 #define DP_AUX_NATIVE_WRITE		0x8
 #define DP_AUX_NATIVE_READ		0x9
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 53c53c459b15..2af97691e878 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -326,9 +326,8 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
 int drm_av_sync_delay(struct drm_connector *connector,
-		      struct drm_display_mode *mode);
-struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode);
+		      const struct drm_display_mode *mode);
+struct drm_connector *drm_select_eld(struct drm_encoder *encoder);
 int drm_load_edid_firmware(struct drm_connector *connector);
 
 int
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index dbab4622b58f..67de1f10008e 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -136,7 +136,7 @@ int drm_fb_helper_set_par(struct fb_info *info);
 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 			    struct fb_info *info);
 
-bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
+int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
 
 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
@@ -226,10 +226,10 @@ static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 	return 0;
 }
 
-static inline bool
+static inline int
 drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
 {
-	return true;
+	return 0;
 }
 
 static inline struct fb_info *
diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h
index 5dd18bfdf601..94938d89347c 100644
--- a/include/drm/drm_modeset_lock.h
+++ b/include/drm/drm_modeset_lock.h
@@ -43,19 +43,19 @@ struct drm_modeset_acquire_ctx {
 
 	struct ww_acquire_ctx ww_ctx;
 
-	/**
+	/*
 	 * Contended lock: if a lock is contended you should only call
 	 * drm_modeset_backoff() which drops locks and slow-locks the
 	 * contended lock.
 	 */
 	struct drm_modeset_lock *contended;
 
-	/**
+	/*
 	 * list of held locks (drm_modeset_lock)
 	 */
 	struct list_head locked;
 
-	/**
+	/*
 	 * Trylock mode, use only for panic handlers!
 	 */
 	bool trylock_only;
@@ -70,12 +70,12 @@ struct drm_modeset_acquire_ctx {
  * Used for locking CRTCs and other modeset resources.
  */
 struct drm_modeset_lock {
-	/**
+	/*
 	 * modeset lock
 	 */
 	struct ww_mutex mutex;
 
-	/**
+	/*
 	 * Resources that are locked as part of an atomic update are added
 	 * to a list (so we know what to unlock at the end).
 	 */
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index dda401bf910e..5a7f9d4efb1d 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -58,10 +58,8 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
  */
 struct drm_plane_helper_funcs {
 	int (*prepare_fb)(struct drm_plane *plane,
-			  struct drm_framebuffer *fb,
 			  const struct drm_plane_state *new_state);
 	void (*cleanup_fb)(struct drm_plane *plane,
-			   struct drm_framebuffer *fb,
 			   const struct drm_plane_state *old_state);
 
 	int (*atomic_check)(struct drm_plane *plane,
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index 1dc1f4ed4001..db01492814d3 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -205,6 +205,31 @@ enum {
 	IEEE802154_SCAN_IN_PROGRESS = 0xfc,
 };
 
+/* frame control handling */
+#define IEEE802154_FCTL_FTYPE		0x0003
+#define IEEE802154_FCTL_INTRA_PAN	0x0040
+
+#define IEEE802154_FTYPE_DATA		0x0001
+
+/*
+ * ieee802154_is_data - check if type is IEEE802154_FTYPE_DATA
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline int ieee802154_is_data(__le16 fc)
+{
+	return (fc & cpu_to_le16(IEEE802154_FCTL_FTYPE)) ==
+		cpu_to_le16(IEEE802154_FTYPE_DATA);
+}
+
+/**
+ * ieee802154_is_intra_pan - check if intra pan id communication
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline bool ieee802154_is_intra_pan(__le16 fc)
+{
+	return fc & cpu_to_le16(IEEE802154_FCTL_INTRA_PAN);
+}
+
 /**
  * ieee802154_is_valid_psdu_len - check if psdu len is valid
  * available lengths:
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 6240063bdcac..a868a0f93615 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -327,6 +327,9 @@ enum {
 #define VTD_FLAG_TRANS_PRE_ENABLED	(1 << 0)
 #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED	(1 << 1)
 
+struct pasid_entry;
+struct pasid_state_entry;
+
 struct intel_iommu {
 	void __iomem	*reg; /* Pointer to hardware regs, virtual addr */
 	u64 		reg_phys; /* physical address of hw register set */
@@ -350,6 +353,15 @@ struct intel_iommu {
 
 	struct iommu_flush flush;
 #endif
+#ifdef CONFIG_INTEL_IOMMU_SVM
+	/* These are large and need to be contiguous, so we allocate just
+	 * one for now. We'll maybe want to rethink that if we truly give
+	 * devices away to userspace processes (e.g. for DPDK) and don't
+	 * want to trust that userspace will use *only* the PASID it was
+	 * told to. But while it's all driver-arbitrated, we're fine. */
+	struct pasid_entry *pasid_table;
+	struct pasid_state_entry *pasid_state_table;
+#endif
 	struct q_inval  *qi;            /* Queued invalidation info */
 	u32 *iommu_state; /* Store iommu states between suspend and resume.*/
 
@@ -389,6 +401,9 @@ extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
 extern int dmar_ir_support(void);
 
+extern int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu);
+extern int intel_svm_free_pasid_tables(struct intel_iommu *iommu);
+
 extern const struct attribute_group *intel_iommu_groups[];
 
 #endif
diff --git a/include/linux/iova.h b/include/linux/iova.h
index 3920a19d8194..92f7177db2ce 100644
--- a/include/linux/iova.h
+++ b/include/linux/iova.h
@@ -68,8 +68,8 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
 	return iova >> iova_shift(iovad);
 }
 
-int iommu_iova_cache_init(void);
-void iommu_iova_cache_destroy(void);
+int iova_cache_get(void);
+void iova_cache_put(void);
 
 struct iova *alloc_iova_mem(void);
 void free_iova_mem(struct iova *iova);
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 7f653e8f6690..0684bd3a48fc 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -22,7 +22,7 @@
  * DEFINE_STATIC_KEY_TRUE(key);
  * DEFINE_STATIC_KEY_FALSE(key);
  * static_key_likely()
- * statick_key_unlikely()
+ * static_key_unlikely()
  *
  * Jump labels provide an interface to generate dynamic branches using
  * self-modifying code. Assuming toolchain and architecture support, if we
diff --git a/include/linux/namei.h b/include/linux/namei.h
index d8c6334cd150..d0f25d81b46a 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -77,6 +77,7 @@ extern struct dentry *kern_path_locked(const char *, struct path *);
 extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int);
 
 extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
+extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int);
 
 extern int follow_down_one(struct path *);
 extern int follow_down(struct path *);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 092a0e8a479a..d841d33bcdc9 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -140,33 +140,67 @@ struct hw_perf_event {
 		};
 #endif
 	};
+	/*
+	 * If the event is a per task event, this will point to the task in
+	 * question. See the comment in perf_event_alloc().
+	 */
 	struct task_struct		*target;
+
+/*
+ * hw_perf_event::state flags; used to track the PERF_EF_* state.
+ */
+#define PERF_HES_STOPPED	0x01 /* the counter is stopped */
+#define PERF_HES_UPTODATE	0x02 /* event->count up-to-date */
+#define PERF_HES_ARCH		0x04
+
 	int				state;
+
+	/*
+	 * The last observed hardware counter value, updated with a
+	 * local64_cmpxchg() such that pmu::read() can be called nested.
+	 */
 	local64_t			prev_count;
+
+	/*
+	 * The period to start the next sample with.
+	 */
 	u64				sample_period;
+
+	/*
+	 * The period we started this sample with.
+	 */
 	u64				last_period;
+
+	/*
+	 * However much is left of the current period; note that this is
+	 * a full 64bit value and allows for generation of periods longer
+	 * than hardware might allow.
+	 */
 	local64_t			period_left;
+
+	/*
+	 * State for throttling the event, see __perf_event_overflow() and
+	 * perf_adjust_freq_unthr_context().
+	 */
 	u64                             interrupts_seq;
 	u64				interrupts;
 
+	/*
+	 * State for freq target events, see __perf_event_overflow() and
+	 * perf_adjust_freq_unthr_context().
+	 */
 	u64				freq_time_stamp;
 	u64				freq_count_stamp;
 #endif
 };
 
-/*
- * hw_perf_event::state flags
- */
-#define PERF_HES_STOPPED	0x01 /* the counter is stopped */
-#define PERF_HES_UPTODATE	0x02 /* event->count up-to-date */
-#define PERF_HES_ARCH		0x04
-
 struct perf_event;
 
 /*
  * Common implementation detail of pmu::{start,commit,cancel}_txn
  */
-#define PERF_EVENT_TXN 0x1
+#define PERF_PMU_TXN_ADD  0x1		/* txn to add/schedule event on PMU */
+#define PERF_PMU_TXN_READ 0x2		/* txn to read event group from PMU */
 
 /**
  * pmu::capabilities flags
@@ -210,7 +244,19 @@ struct pmu {
 
 	/*
 	 * Try and initialize the event for this PMU.
-	 * Should return -ENOENT when the @event doesn't match this PMU.
+	 *
+	 * Returns:
+	 *  -ENOENT	-- @event is not for this PMU
+	 *
+	 *  -ENODEV	-- @event is for this PMU but PMU not present
+	 *  -EBUSY	-- @event is for this PMU but PMU temporarily unavailable
+	 *  -EINVAL	-- @event is for this PMU but @event is not valid
+	 *  -EOPNOTSUPP -- @event is for this PMU, @event is valid, but not supported
+	 *  -EACCESS	-- @event is for this PMU, @event is valid, but no privilidges
+	 *
+	 *  0		-- @event is for this PMU and valid
+	 *
+	 * Other error return values are allowed.
 	 */
 	int (*event_init)		(struct perf_event *event);
 
@@ -221,27 +267,61 @@ struct pmu {
 	void (*event_mapped)		(struct perf_event *event); /*optional*/
 	void (*event_unmapped)		(struct perf_event *event); /*optional*/
 
+	/*
+	 * Flags for ->add()/->del()/ ->start()/->stop(). There are
+	 * matching hw_perf_event::state flags.
+	 */
 #define PERF_EF_START	0x01		/* start the counter when adding    */
 #define PERF_EF_RELOAD	0x02		/* reload the counter when starting */
 #define PERF_EF_UPDATE	0x04		/* update the counter when stopping */
 
 	/*
-	 * Adds/Removes a counter to/from the PMU, can be done inside
-	 * a transaction, see the ->*_txn() methods.
+	 * Adds/Removes a counter to/from the PMU, can be done inside a
+	 * transaction, see the ->*_txn() methods.
+	 *
+	 * The add/del callbacks will reserve all hardware resources required
+	 * to service the event, this includes any counter constraint
+	 * scheduling etc.
+	 *
+	 * Called with IRQs disabled and the PMU disabled on the CPU the event
+	 * is on.
+	 *
+	 * ->add() called without PERF_EF_START should result in the same state
+	 *  as ->add() followed by ->stop().
+	 *
+	 * ->del() must always PERF_EF_UPDATE stop an event. If it calls
+	 *  ->stop() that must deal with already being stopped without
+	 *  PERF_EF_UPDATE.
 	 */
 	int  (*add)			(struct perf_event *event, int flags);
 	void (*del)			(struct perf_event *event, int flags);
 
 	/*
-	 * Starts/Stops a counter present on the PMU. The PMI handler
-	 * should stop the counter when perf_event_overflow() returns
-	 * !0. ->start() will be used to continue.
+	 * Starts/Stops a counter present on the PMU.
+	 *
+	 * The PMI handler should stop the counter when perf_event_overflow()
+	 * returns !0. ->start() will be used to continue.
+	 *
+	 * Also used to change the sample period.
+	 *
+	 * Called with IRQs disabled and the PMU disabled on the CPU the event
+	 * is on -- will be called from NMI context with the PMU generates
+	 * NMIs.
+	 *
+	 * ->stop() with PERF_EF_UPDATE will read the counter and update
+	 *  period/count values like ->read() would.
+	 *
+	 * ->start() with PERF_EF_RELOAD will reprogram the the counter
+	 *  value, must be preceded by a ->stop() with PERF_EF_UPDATE.
 	 */
 	void (*start)			(struct perf_event *event, int flags);
 	void (*stop)			(struct perf_event *event, int flags);
 
 	/*
 	 * Updates the counter value of the event.
+	 *
+	 * For sampling capable PMUs this will also update the software period
+	 * hw_perf_event::period_left field.
 	 */
 	void (*read)			(struct perf_event *event);
 
@@ -252,20 +332,26 @@ struct pmu {
 	 *
 	 * Start the transaction, after this ->add() doesn't need to
 	 * do schedulability tests.
+	 *
+	 * Optional.
 	 */
-	void (*start_txn)		(struct pmu *pmu); /* optional */
+	void (*start_txn)		(struct pmu *pmu, unsigned int txn_flags);
 	/*
 	 * If ->start_txn() disabled the ->add() schedulability test
 	 * then ->commit_txn() is required to perform one. On success
 	 * the transaction is closed. On error the transaction is kept
 	 * open until ->cancel_txn() is called.
+	 *
+	 * Optional.
 	 */
-	int  (*commit_txn)		(struct pmu *pmu); /* optional */
+	int  (*commit_txn)		(struct pmu *pmu);
 	/*
 	 * Will cancel the transaction, assumes ->del() is called
 	 * for each successful ->add() during the transaction.
+	 *
+	 * Optional.
 	 */
-	void (*cancel_txn)		(struct pmu *pmu); /* optional */
+	void (*cancel_txn)		(struct pmu *pmu);
 
 	/*
 	 * Will return the value for perf_event_mmap_page::index for this event,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a4ab9daa387c..bd38b3ee9e83 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1177,10 +1177,10 @@ struct load_weight {
 
 /*
  * The load_avg/util_avg accumulates an infinite geometric series.
- * 1) load_avg factors the amount of time that a sched_entity is
- * runnable on a rq into its weight. For cfs_rq, it is the aggregated
- * such weights of all runnable and blocked sched_entities.
- * 2) util_avg factors frequency scaling into the amount of time
+ * 1) load_avg factors frequency scaling into the amount of time that a
+ * sched_entity is runnable on a rq into its weight. For cfs_rq, it is the
+ * aggregated such weights of all runnable and blocked sched_entities.
+ * 2) util_avg factors frequency and cpu scaling into the amount of time
  * that a sched_entity is running on a CPU, in the range [0..SCHED_LOAD_SCALE].
  * For cfs_rq, it is the aggregated such times of all runnable and
  * blocked sched_entities.
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 48d901f83f92..e312219ff823 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -147,11 +147,20 @@ static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
 		cpumask_or(mask, mask, tick_nohz_full_mask);
 }
 
+static inline int housekeeping_any_cpu(void)
+{
+	return cpumask_any_and(housekeeping_mask, cpu_online_mask);
+}
+
 extern void tick_nohz_full_kick(void);
 extern void tick_nohz_full_kick_cpu(int cpu);
 extern void tick_nohz_full_kick_all(void);
 extern void __tick_nohz_task_switch(void);
 #else
+static inline int housekeeping_any_cpu(void)
+{
+	return smp_processor_id();
+}
 static inline bool tick_nohz_full_enabled(void) { return false; }
 static inline bool tick_nohz_full_cpu(int cpu) { return false; }
 static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index a2f59ec98d24..eeae5eb58754 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -126,13 +126,19 @@
 	 (((a)[6]) == 0xFF) &&	\
 	 (((a)[7]) == 0xFF))
 
-#define LOWPAN_DISPATCH_IPV6	0x41 /* 01000001 = 65 */
-#define LOWPAN_DISPATCH_HC1	0x42 /* 01000010 = 66 */
-#define LOWPAN_DISPATCH_IPHC	0x60 /* 011xxxxx = ... */
-#define LOWPAN_DISPATCH_FRAG1	0xc0 /* 11000xxx */
-#define LOWPAN_DISPATCH_FRAGN	0xe0 /* 11100xxx */
+#define LOWPAN_DISPATCH_IPV6		0x41 /* 01000001 = 65 */
+#define LOWPAN_DISPATCH_IPHC		0x60 /* 011xxxxx = ... */
+#define LOWPAN_DISPATCH_IPHC_MASK	0xe0
 
-#define LOWPAN_DISPATCH_MASK	0xf8 /* 11111000 */
+static inline bool lowpan_is_ipv6(u8 dispatch)
+{
+	return dispatch == LOWPAN_DISPATCH_IPV6;
+}
+
+static inline bool lowpan_is_iphc(u8 dispatch)
+{
+	return (dispatch & LOWPAN_DISPATCH_IPHC_MASK) == LOWPAN_DISPATCH_IPHC;
+}
 
 #define LOWPAN_FRAG_TIMEOUT	(HZ * 60)	/* time-out 60 sec */
 
@@ -218,6 +224,19 @@ struct lowpan_priv *lowpan_priv(const struct net_device *dev)
 	return netdev_priv(dev);
 }
 
+struct lowpan_802154_cb {
+	u16 d_tag;
+	unsigned int d_size;
+	u8 d_offset;
+};
+
+static inline
+struct lowpan_802154_cb *lowpan_802154_cb(const struct sk_buff *skb)
+{
+	BUILD_BUG_ON(sizeof(struct lowpan_802154_cb) > sizeof(skb->cb));
+	return (struct lowpan_802154_cb *)skb->cb;
+}
+
 #ifdef DEBUG
 /* print data in line */
 static inline void raw_dump_inline(const char *caller, char *msg,
@@ -280,119 +299,6 @@ static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
 	*hc_ptr += len;
 }
 
-static inline u8 lowpan_addr_mode_size(const u8 addr_mode)
-{
-	static const u8 addr_sizes[] = {
-		[LOWPAN_IPHC_ADDR_00] = 16,
-		[LOWPAN_IPHC_ADDR_01] = 8,
-		[LOWPAN_IPHC_ADDR_02] = 2,
-		[LOWPAN_IPHC_ADDR_03] = 0,
-	};
-	return addr_sizes[addr_mode];
-}
-
-static inline u8 lowpan_next_hdr_size(const u8 h_enc, u16 *uncomp_header)
-{
-	u8 ret = 1;
-
-	if ((h_enc & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
-		*uncomp_header += sizeof(struct udphdr);
-
-		switch (h_enc & LOWPAN_NHC_UDP_CS_P_11) {
-		case LOWPAN_NHC_UDP_CS_P_00:
-			ret += 4;
-			break;
-		case LOWPAN_NHC_UDP_CS_P_01:
-		case LOWPAN_NHC_UDP_CS_P_10:
-			ret += 3;
-			break;
-		case LOWPAN_NHC_UDP_CS_P_11:
-			ret++;
-			break;
-		default:
-			break;
-		}
-
-		if (!(h_enc & LOWPAN_NHC_UDP_CS_C))
-			ret += 2;
-	}
-
-	return ret;
-}
-
-/**
- *	lowpan_uncompress_size - returns skb->len size with uncompressed header
- *	@skb: sk_buff with 6lowpan header inside
- *	@datagram_offset: optional to get the datagram_offset value
- *
- *	Returns the skb->len with uncompressed header
- */
-static inline u16
-lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
-{
-	u16 ret = 2, uncomp_header = sizeof(struct ipv6hdr);
-	u8 iphc0, iphc1, h_enc;
-
-	iphc0 = skb_network_header(skb)[0];
-	iphc1 = skb_network_header(skb)[1];
-
-	switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) {
-	case 0:
-		ret += 4;
-		break;
-	case 1:
-		ret += 3;
-		break;
-	case 2:
-		ret++;
-		break;
-	default:
-		break;
-	}
-
-	if (!(iphc0 & LOWPAN_IPHC_NH_C))
-		ret++;
-
-	if (!(iphc0 & 0x03))
-		ret++;
-
-	ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_SAM) >>
-				     LOWPAN_IPHC_SAM_BIT);
-
-	if (iphc1 & LOWPAN_IPHC_M) {
-		switch ((iphc1 & LOWPAN_IPHC_DAM_11) >>
-			LOWPAN_IPHC_DAM_BIT) {
-		case LOWPAN_IPHC_DAM_00:
-			ret += 16;
-			break;
-		case LOWPAN_IPHC_DAM_01:
-			ret += 6;
-			break;
-		case LOWPAN_IPHC_DAM_10:
-			ret += 4;
-			break;
-		case LOWPAN_IPHC_DAM_11:
-			ret++;
-			break;
-		default:
-			break;
-		}
-	} else {
-		ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_DAM_11) >>
-					     LOWPAN_IPHC_DAM_BIT);
-	}
-
-	if (iphc0 & LOWPAN_IPHC_NH_C) {
-		h_enc = skb_network_header(skb)[ret];
-		ret += lowpan_next_hdr_size(h_enc, &uncomp_header);
-	}
-
-	if (dgram_offset)
-		*dgram_offset = uncomp_header;
-
-	return skb->len + uncomp_header - ret;
-}
-
 void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype);
 
 int
diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h
index 7d38e2ffd256..a5563d27a3eb 100644
--- a/include/net/af_ieee802154.h
+++ b/include/net/af_ieee802154.h
@@ -1,5 +1,5 @@
 /*
- * IEEE 802.15.4 inteface for userspace
+ * IEEE 802.15.4 interface for userspace
  *
  * Copyright 2007, 2008 Siemens AG
  *
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 38d8a34d3589..fcf2ae7dbfa0 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -128,6 +128,13 @@ void bt_err(const char *fmt, ...);
 #define BT_ERR(fmt, ...)	bt_err(fmt "\n", ##__VA_ARGS__)
 #define BT_DBG(fmt, ...)	pr_debug(fmt "\n", ##__VA_ARGS__)
 
+#define bt_dev_info(hdev, fmt, ...)				\
+	BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
+#define bt_dev_err(hdev, fmt, ...)				\
+	BT_ERR("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
+#define bt_dev_dbg(hdev, fmt, ...)				\
+	BT_DBG("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
+
 /* Connection and socket states */
 enum {
 	BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9e1a59e01fa2..256e6734c1fb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -987,6 +987,7 @@ int hci_resume_dev(struct hci_dev *hdev);
 int hci_reset_dev(struct hci_dev *hdev);
 int hci_dev_open(__u16 dev);
 int hci_dev_close(__u16 dev);
+int hci_dev_do_close(struct hci_dev *hdev);
 int hci_dev_reset(__u16 dev);
 int hci_dev_reset_stat(__u16 dev);
 int hci_dev_cmd(unsigned int cmd, void __user *arg);
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index b7f99615224b..32bd7c0467d4 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -250,6 +250,21 @@ struct ieee802154_ops {
 };
 
 /**
+ * ieee802154_get_fc_from_skb - get the frame control field from an skb
+ * @skb: skb where the frame control field will be get from
+ */
+static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
+{
+	/* return some invalid fc on failure */
+	if (unlikely(skb->mac_len < 2)) {
+		WARN_ON(1);
+		return cpu_to_le16(0);
+	}
+
+	return (__force __le16)__get_unaligned_memmove16(skb_mac_header(skb));
+}
+
+/**
  * ieee802154_be64_to_le64 - copies and convert be64 to le64
  * @le64_dst: le64 destination pointer
  * @be64_src: be64 source pointer
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 691e7ee0a510..a4fcc9456194 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -285,8 +285,6 @@ struct snd_pcm_hw_constraint_ranges {
 	unsigned int mask;
 };
 
-struct snd_pcm_hwptr_log;
-
 /*
  * userspace-provided audio timestamp config to kernel,
  * structure is for internal use only and filled with dedicated unpack routine
@@ -428,10 +426,6 @@ struct snd_pcm_runtime {
 	/* -- OSS things -- */
 	struct snd_pcm_oss_runtime oss;
 #endif
-
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
-	struct snd_pcm_hwptr_log *hwptr_log;
-#endif
 };
 
 struct snd_pcm_group {		/* keep linked substreams */
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 359107ab629e..6c11ca401de8 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -105,8 +105,16 @@
 
 struct drm_mode_modeinfo {
 	__u32 clock;
-	__u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
-	__u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
+	__u16 hdisplay;
+	__u16 hsync_start;
+	__u16 hsync_end;
+	__u16 htotal;
+	__u16 hskew;
+	__u16 vdisplay;
+	__u16 vsync_start;
+	__u16 vsync_end;
+	__u16 vtotal;
+	__u16 vscan;
 
 	__u32 vrefresh;
 
@@ -124,8 +132,10 @@ struct drm_mode_card_res {
 	__u32 count_crtcs;
 	__u32 count_connectors;
 	__u32 count_encoders;
-	__u32 min_width, max_width;
-	__u32 min_height, max_height;
+	__u32 min_width;
+	__u32 max_width;
+	__u32 min_height;
+	__u32 max_height;
 };
 
 struct drm_mode_crtc {
@@ -135,7 +145,8 @@ struct drm_mode_crtc {
 	__u32 crtc_id; /**< Id */
 	__u32 fb_id; /**< Id of framebuffer */
 
-	__u32 x, y; /**< Position on the frameuffer */
+	__u32 x; /**< x Position on the framebuffer */
+	__u32 y; /**< y Position on the framebuffer */
 
 	__u32 gamma_size;
 	__u32 mode_valid;
@@ -153,12 +164,16 @@ struct drm_mode_set_plane {
 	__u32 flags; /* see above flags */
 
 	/* Signed dest location allows it to be partially off screen */
-	__s32 crtc_x, crtc_y;
-	__u32 crtc_w, crtc_h;
+	__s32 crtc_x;
+	__s32 crtc_y;
+	__u32 crtc_w;
+	__u32 crtc_h;
 
 	/* Source values are 16.16 fixed point */
-	__u32 src_x, src_y;
-	__u32 src_h, src_w;
+	__u32 src_x;
+	__u32 src_y;
+	__u32 src_h;
+	__u32 src_w;
 };
 
 struct drm_mode_get_plane {
@@ -244,7 +259,8 @@ struct drm_mode_get_connector {
 	__u32 connector_type_id;
 
 	__u32 connection;
-	__u32 mm_width, mm_height; /**< HxW in millimeters */
+	__u32 mm_width;  /**< width in millimeters */
+	__u32 mm_height; /**< height in millimeters */
 	__u32 subpixel;
 
 	__u32 pad;
@@ -327,7 +343,8 @@ struct drm_mode_get_blob {
 
 struct drm_mode_fb_cmd {
 	__u32 fb_id;
-	__u32 width, height;
+	__u32 width;
+	__u32 height;
 	__u32 pitch;
 	__u32 bpp;
 	__u32 depth;
@@ -340,7 +357,8 @@ struct drm_mode_fb_cmd {
 
 struct drm_mode_fb_cmd2 {
 	__u32 fb_id;
-	__u32 width, height;
+	__u32 width;
+	__u32 height;
 	__u32 pixel_format; /* fourcc code from drm_fourcc.h */
 	__u32 flags; /* see above flags */
 
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index f7b2db44eb4b..e77707802dcc 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -216,6 +216,7 @@ header-y += ixjuser.h
 header-y += jffs2.h
 header-y += joystick.h
 header-y += kcmp.h
+header-y += kdbus.h
 header-y += kdev_t.h
 header-y += kd.h
 header-y += kernelcapi.h
diff --git a/include/uapi/linux/kdbus.h b/include/uapi/linux/kdbus.h
new file mode 100644
index 000000000000..4fc44cb1d4a8
--- /dev/null
+++ b/include/uapi/linux/kdbus.h
@@ -0,0 +1,984 @@
+/*
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _UAPI_KDBUS_H_
+#define _UAPI_KDBUS_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define KDBUS_IOCTL_MAGIC		0x95
+#define KDBUS_SRC_ID_KERNEL		(0)
+#define KDBUS_DST_ID_NAME		(0)
+#define KDBUS_MATCH_ID_ANY		(~0ULL)
+#define KDBUS_DST_ID_BROADCAST		(~0ULL)
+#define KDBUS_FLAG_NEGOTIATE		(1ULL << 63)
+
+/**
+ * struct kdbus_notify_id_change - name registry change message
+ * @id:			New or former owner of the name
+ * @flags:		flags field from KDBUS_HELLO_*
+ *
+ * Sent from kernel to userspace when the owner or activator of
+ * a well-known name changes.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_ID_ADD
+ *   KDBUS_ITEM_ID_REMOVE
+ */
+struct kdbus_notify_id_change {
+	__u64 id;
+	__u64 flags;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_notify_name_change - name registry change message
+ * @old_id:		ID and flags of former owner of a name
+ * @new_id:		ID and flags of new owner of a name
+ * @name:		Well-known name
+ *
+ * Sent from kernel to userspace when the owner or activator of
+ * a well-known name changes.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_NAME_ADD
+ *   KDBUS_ITEM_NAME_REMOVE
+ *   KDBUS_ITEM_NAME_CHANGE
+ */
+struct kdbus_notify_name_change {
+	struct kdbus_notify_id_change old_id;
+	struct kdbus_notify_id_change new_id;
+	char name[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_creds - process credentials
+ * @uid:		User ID
+ * @euid:		Effective UID
+ * @suid:		Saved UID
+ * @fsuid:		Filesystem UID
+ * @gid:		Group ID
+ * @egid:		Effective GID
+ * @sgid:		Saved GID
+ * @fsgid:		Filesystem GID
+ *
+ * Attached to:
+ *   KDBUS_ITEM_CREDS
+ */
+struct kdbus_creds {
+	__u64 uid;
+	__u64 euid;
+	__u64 suid;
+	__u64 fsuid;
+	__u64 gid;
+	__u64 egid;
+	__u64 sgid;
+	__u64 fsgid;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_pids - process identifiers
+ * @pid:		Process ID
+ * @tid:		Thread ID
+ * @ppid:		Parent process ID
+ *
+ * The PID and TID of a process.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_PIDS
+ */
+struct kdbus_pids {
+	__u64 pid;
+	__u64 tid;
+	__u64 ppid;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_caps - process capabilities
+ * @last_cap:	Highest currently known capability bit
+ * @caps:	Variable number of 32-bit capabilities flags
+ *
+ * Contains a variable number of 32-bit capabilities flags.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_CAPS
+ */
+struct kdbus_caps {
+	__u32 last_cap;
+	__u32 caps[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_audit - audit information
+ * @sessionid:		The audit session ID
+ * @loginuid:		The audit login uid
+ *
+ * Attached to:
+ *   KDBUS_ITEM_AUDIT
+ */
+struct kdbus_audit {
+	__u32 sessionid;
+	__u32 loginuid;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_timestamp
+ * @seqnum:		Global per-domain message sequence number
+ * @monotonic_ns:	Monotonic timestamp, in nanoseconds
+ * @realtime_ns:	Realtime timestamp, in nanoseconds
+ *
+ * Attached to:
+ *   KDBUS_ITEM_TIMESTAMP
+ */
+struct kdbus_timestamp {
+	__u64 seqnum;
+	__u64 monotonic_ns;
+	__u64 realtime_ns;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_vec - I/O vector for kdbus payload items
+ * @size:		The size of the vector
+ * @address:		Memory address of data buffer
+ * @offset:		Offset in the in-message payload memory,
+ *			relative to the message head
+ *
+ * Attached to:
+ *   KDBUS_ITEM_PAYLOAD_VEC, KDBUS_ITEM_PAYLOAD_OFF
+ */
+struct kdbus_vec {
+	__u64 size;
+	union {
+		__u64 address;
+		__u64 offset;
+	};
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_bloom_parameter - bus-wide bloom parameters
+ * @size:		Size of the bit field in bytes (m / 8)
+ * @n_hash:		Number of hash functions used (k)
+ */
+struct kdbus_bloom_parameter {
+	__u64 size;
+	__u64 n_hash;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_bloom_filter - bloom filter containing n elements
+ * @generation:		Generation of the element set in the filter
+ * @data:		Bit field, multiple of 8 bytes
+ */
+struct kdbus_bloom_filter {
+	__u64 generation;
+	__u64 data[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_memfd - a kdbus memfd
+ * @start:		The offset into the memfd where the segment starts
+ * @size:		The size of the memfd segment
+ * @fd:			The file descriptor number
+ * @__pad:		Padding to ensure proper alignment and size
+ *
+ * Attached to:
+ *   KDBUS_ITEM_PAYLOAD_MEMFD
+ */
+struct kdbus_memfd {
+	__u64 start;
+	__u64 size;
+	int fd;
+	__u32 __pad;
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_name - a registered well-known name with its flags
+ * @flags:		Flags from KDBUS_NAME_*
+ * @name:		Well-known name
+ *
+ * Attached to:
+ *   KDBUS_ITEM_OWNED_NAME
+ */
+struct kdbus_name {
+	__u64 flags;
+	char name[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_policy_access_type - permissions of a policy record
+ * @_KDBUS_POLICY_ACCESS_NULL:	Uninitialized/invalid
+ * @KDBUS_POLICY_ACCESS_USER:	Grant access to a uid
+ * @KDBUS_POLICY_ACCESS_GROUP:	Grant access to gid
+ * @KDBUS_POLICY_ACCESS_WORLD:	World-accessible
+ */
+enum kdbus_policy_access_type {
+	_KDBUS_POLICY_ACCESS_NULL,
+	KDBUS_POLICY_ACCESS_USER,
+	KDBUS_POLICY_ACCESS_GROUP,
+	KDBUS_POLICY_ACCESS_WORLD,
+};
+
+/**
+ * enum kdbus_policy_access_flags - mode flags
+ * @KDBUS_POLICY_OWN:		Allow to own a well-known name
+ *				Implies KDBUS_POLICY_TALK and KDBUS_POLICY_SEE
+ * @KDBUS_POLICY_TALK:		Allow communication to a well-known name
+ *				Implies KDBUS_POLICY_SEE
+ * @KDBUS_POLICY_SEE:		Allow to see a well-known name
+ */
+enum kdbus_policy_type {
+	KDBUS_POLICY_SEE	= 0,
+	KDBUS_POLICY_TALK,
+	KDBUS_POLICY_OWN,
+};
+
+/**
+ * struct kdbus_policy_access - policy access item
+ * @type:		One of KDBUS_POLICY_ACCESS_* types
+ * @access:		Access to grant
+ * @id:			For KDBUS_POLICY_ACCESS_USER, the uid
+ *			For KDBUS_POLICY_ACCESS_GROUP, the gid
+ */
+struct kdbus_policy_access {
+	__u64 type;	/* USER, GROUP, WORLD */
+	__u64 access;	/* OWN, TALK, SEE */
+	__u64 id;	/* uid, gid, 0 */
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_attach_flags - flags for metadata attachments
+ * @KDBUS_ATTACH_TIMESTAMP:		Timestamp
+ * @KDBUS_ATTACH_CREDS:			Credentials
+ * @KDBUS_ATTACH_PIDS:			PIDs
+ * @KDBUS_ATTACH_AUXGROUPS:		Auxiliary groups
+ * @KDBUS_ATTACH_NAMES:			Well-known names
+ * @KDBUS_ATTACH_TID_COMM:		The "comm" process identifier of the TID
+ * @KDBUS_ATTACH_PID_COMM:		The "comm" process identifier of the PID
+ * @KDBUS_ATTACH_EXE:			The path of the executable
+ * @KDBUS_ATTACH_CMDLINE:		The process command line
+ * @KDBUS_ATTACH_CGROUP:		The croup membership
+ * @KDBUS_ATTACH_CAPS:			The process capabilities
+ * @KDBUS_ATTACH_SECLABEL:		The security label
+ * @KDBUS_ATTACH_AUDIT:			The audit IDs
+ * @KDBUS_ATTACH_CONN_DESCRIPTION:	The human-readable connection name
+ * @_KDBUS_ATTACH_ALL:			All of the above
+ * @_KDBUS_ATTACH_ANY:			Wildcard match to enable any kind of
+ *					metatdata.
+ */
+enum kdbus_attach_flags {
+	KDBUS_ATTACH_TIMESTAMP		=  1ULL <<  0,
+	KDBUS_ATTACH_CREDS		=  1ULL <<  1,
+	KDBUS_ATTACH_PIDS		=  1ULL <<  2,
+	KDBUS_ATTACH_AUXGROUPS		=  1ULL <<  3,
+	KDBUS_ATTACH_NAMES		=  1ULL <<  4,
+	KDBUS_ATTACH_TID_COMM		=  1ULL <<  5,
+	KDBUS_ATTACH_PID_COMM		=  1ULL <<  6,
+	KDBUS_ATTACH_EXE		=  1ULL <<  7,
+	KDBUS_ATTACH_CMDLINE		=  1ULL <<  8,
+	KDBUS_ATTACH_CGROUP		=  1ULL <<  9,
+	KDBUS_ATTACH_CAPS		=  1ULL << 10,
+	KDBUS_ATTACH_SECLABEL		=  1ULL << 11,
+	KDBUS_ATTACH_AUDIT		=  1ULL << 12,
+	KDBUS_ATTACH_CONN_DESCRIPTION	=  1ULL << 13,
+	_KDBUS_ATTACH_ALL		=  (1ULL << 14) - 1,
+	_KDBUS_ATTACH_ANY		=  ~0ULL
+};
+
+/**
+ * enum kdbus_item_type - item types to chain data in a list
+ * @_KDBUS_ITEM_NULL:			Uninitialized/invalid
+ * @_KDBUS_ITEM_USER_BASE:		Start of user items
+ * @KDBUS_ITEM_NEGOTIATE:		Negotiate supported items
+ * @KDBUS_ITEM_PAYLOAD_VEC:		Vector to data
+ * @KDBUS_ITEM_PAYLOAD_OFF:		Data at returned offset to message head
+ * @KDBUS_ITEM_PAYLOAD_MEMFD:		Data as sealed memfd
+ * @KDBUS_ITEM_FDS:			Attached file descriptors
+ * @KDBUS_ITEM_CANCEL_FD:		FD used to cancel a synchronous
+ *					operation by writing to it from
+ *					userspace
+ * @KDBUS_ITEM_BLOOM_PARAMETER:		Bus-wide bloom parameters, used with
+ *					KDBUS_CMD_BUS_MAKE, carries a
+ *					struct kdbus_bloom_parameter
+ * @KDBUS_ITEM_BLOOM_FILTER:		Bloom filter carried with a message,
+ *					used to match against a bloom mask of a
+ *					connection, carries a struct
+ *					kdbus_bloom_filter
+ * @KDBUS_ITEM_BLOOM_MASK:		Bloom mask used to match against a
+ *					message'sbloom filter
+ * @KDBUS_ITEM_DST_NAME:		Destination's well-known name
+ * @KDBUS_ITEM_MAKE_NAME:		Name of domain, bus, endpoint
+ * @KDBUS_ITEM_ATTACH_FLAGS_SEND:	Attach-flags, used for updating which
+ *					metadata a connection opts in to send
+ * @KDBUS_ITEM_ATTACH_FLAGS_RECV:	Attach-flags, used for updating which
+ *					metadata a connection requests to
+ *					receive for each reeceived message
+ * @KDBUS_ITEM_ID:			Connection ID
+ * @KDBUS_ITEM_NAME:			Well-know name with flags
+ * @_KDBUS_ITEM_ATTACH_BASE:		Start of metadata attach items
+ * @KDBUS_ITEM_TIMESTAMP:		Timestamp
+ * @KDBUS_ITEM_CREDS:			Process credentials
+ * @KDBUS_ITEM_PIDS:			Process identifiers
+ * @KDBUS_ITEM_AUXGROUPS:		Auxiliary process groups
+ * @KDBUS_ITEM_OWNED_NAME:		A name owned by the associated
+ *					connection
+ * @KDBUS_ITEM_TID_COMM:		Thread ID "comm" identifier
+ *					(Don't trust this, see below.)
+ * @KDBUS_ITEM_PID_COMM:		Process ID "comm" identifier
+ *					(Don't trust this, see below.)
+ * @KDBUS_ITEM_EXE:			The path of the executable
+ *					(Don't trust this, see below.)
+ * @KDBUS_ITEM_CMDLINE:			The process command line
+ *					(Don't trust this, see below.)
+ * @KDBUS_ITEM_CGROUP:			The croup membership
+ * @KDBUS_ITEM_CAPS:			The process capabilities
+ * @KDBUS_ITEM_SECLABEL:		The security label
+ * @KDBUS_ITEM_AUDIT:			The audit IDs
+ * @KDBUS_ITEM_CONN_DESCRIPTION:	The connection's human-readable name
+ *					(debugging)
+ * @_KDBUS_ITEM_POLICY_BASE:		Start of policy items
+ * @KDBUS_ITEM_POLICY_ACCESS:		Policy access block
+ * @_KDBUS_ITEM_KERNEL_BASE:		Start of kernel-generated message items
+ * @KDBUS_ITEM_NAME_ADD:		Notification in kdbus_notify_name_change
+ * @KDBUS_ITEM_NAME_REMOVE:		Notification in kdbus_notify_name_change
+ * @KDBUS_ITEM_NAME_CHANGE:		Notification in kdbus_notify_name_change
+ * @KDBUS_ITEM_ID_ADD:			Notification in kdbus_notify_id_change
+ * @KDBUS_ITEM_ID_REMOVE:		Notification in kdbus_notify_id_change
+ * @KDBUS_ITEM_REPLY_TIMEOUT:		Timeout has been reached
+ * @KDBUS_ITEM_REPLY_DEAD:		Destination died
+ *
+ * N.B: The process and thread COMM fields, as well as the CMDLINE and
+ * EXE fields may be altered by unprivileged processes und should
+ * hence *not* used for security decisions. Peers should make use of
+ * these items only for informational purposes, such as generating log
+ * records.
+ */
+enum kdbus_item_type {
+	_KDBUS_ITEM_NULL,
+	_KDBUS_ITEM_USER_BASE,
+	KDBUS_ITEM_NEGOTIATE	= _KDBUS_ITEM_USER_BASE,
+	KDBUS_ITEM_PAYLOAD_VEC,
+	KDBUS_ITEM_PAYLOAD_OFF,
+	KDBUS_ITEM_PAYLOAD_MEMFD,
+	KDBUS_ITEM_FDS,
+	KDBUS_ITEM_CANCEL_FD,
+	KDBUS_ITEM_BLOOM_PARAMETER,
+	KDBUS_ITEM_BLOOM_FILTER,
+	KDBUS_ITEM_BLOOM_MASK,
+	KDBUS_ITEM_DST_NAME,
+	KDBUS_ITEM_MAKE_NAME,
+	KDBUS_ITEM_ATTACH_FLAGS_SEND,
+	KDBUS_ITEM_ATTACH_FLAGS_RECV,
+	KDBUS_ITEM_ID,
+	KDBUS_ITEM_NAME,
+	KDBUS_ITEM_DST_ID,
+
+	/* keep these item types in sync with KDBUS_ATTACH_* flags */
+	_KDBUS_ITEM_ATTACH_BASE	= 0x1000,
+	KDBUS_ITEM_TIMESTAMP	= _KDBUS_ITEM_ATTACH_BASE,
+	KDBUS_ITEM_CREDS,
+	KDBUS_ITEM_PIDS,
+	KDBUS_ITEM_AUXGROUPS,
+	KDBUS_ITEM_OWNED_NAME,
+	KDBUS_ITEM_TID_COMM,
+	KDBUS_ITEM_PID_COMM,
+	KDBUS_ITEM_EXE,
+	KDBUS_ITEM_CMDLINE,
+	KDBUS_ITEM_CGROUP,
+	KDBUS_ITEM_CAPS,
+	KDBUS_ITEM_SECLABEL,
+	KDBUS_ITEM_AUDIT,
+	KDBUS_ITEM_CONN_DESCRIPTION,
+
+	_KDBUS_ITEM_POLICY_BASE	= 0x2000,
+	KDBUS_ITEM_POLICY_ACCESS = _KDBUS_ITEM_POLICY_BASE,
+
+	_KDBUS_ITEM_KERNEL_BASE	= 0x8000,
+	KDBUS_ITEM_NAME_ADD	= _KDBUS_ITEM_KERNEL_BASE,
+	KDBUS_ITEM_NAME_REMOVE,
+	KDBUS_ITEM_NAME_CHANGE,
+	KDBUS_ITEM_ID_ADD,
+	KDBUS_ITEM_ID_REMOVE,
+	KDBUS_ITEM_REPLY_TIMEOUT,
+	KDBUS_ITEM_REPLY_DEAD,
+};
+
+/**
+ * struct kdbus_item - chain of data blocks
+ * @size:		Overall data record size
+ * @type:		Kdbus_item type of data
+ * @data:		Generic bytes
+ * @data32:		Generic 32 bit array
+ * @data64:		Generic 64 bit array
+ * @str:		Generic string
+ * @id:			Connection ID
+ * @vec:		KDBUS_ITEM_PAYLOAD_VEC
+ * @creds:		KDBUS_ITEM_CREDS
+ * @audit:		KDBUS_ITEM_AUDIT
+ * @timestamp:		KDBUS_ITEM_TIMESTAMP
+ * @name:		KDBUS_ITEM_NAME
+ * @bloom_parameter:	KDBUS_ITEM_BLOOM_PARAMETER
+ * @bloom_filter:	KDBUS_ITEM_BLOOM_FILTER
+ * @memfd:		KDBUS_ITEM_PAYLOAD_MEMFD
+ * @name_change:	KDBUS_ITEM_NAME_ADD
+ *			KDBUS_ITEM_NAME_REMOVE
+ *			KDBUS_ITEM_NAME_CHANGE
+ * @id_change:		KDBUS_ITEM_ID_ADD
+ *			KDBUS_ITEM_ID_REMOVE
+ * @policy:		KDBUS_ITEM_POLICY_ACCESS
+ */
+struct kdbus_item {
+	__u64 size;
+	__u64 type;
+	union {
+		__u8 data[0];
+		__u32 data32[0];
+		__u64 data64[0];
+		char str[0];
+
+		__u64 id;
+		struct kdbus_vec vec;
+		struct kdbus_creds creds;
+		struct kdbus_pids pids;
+		struct kdbus_audit audit;
+		struct kdbus_caps caps;
+		struct kdbus_timestamp timestamp;
+		struct kdbus_name name;
+		struct kdbus_bloom_parameter bloom_parameter;
+		struct kdbus_bloom_filter bloom_filter;
+		struct kdbus_memfd memfd;
+		int fds[0];
+		struct kdbus_notify_name_change name_change;
+		struct kdbus_notify_id_change id_change;
+		struct kdbus_policy_access policy_access;
+	};
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_msg_flags - type of message
+ * @KDBUS_MSG_EXPECT_REPLY:	Expect a reply message, used for
+ *				method calls. The userspace-supplied
+ *				cookie identifies the message and the
+ *				respective reply carries the cookie
+ *				in cookie_reply
+ * @KDBUS_MSG_NO_AUTO_START:	Do not start a service if the addressed
+ *				name is not currently active. This flag is
+ *				not looked at by the kernel but only
+ *				serves as hint for userspace implementations.
+ * @KDBUS_MSG_SIGNAL:		Treat this message as signal
+ */
+enum kdbus_msg_flags {
+	KDBUS_MSG_EXPECT_REPLY	= 1ULL << 0,
+	KDBUS_MSG_NO_AUTO_START	= 1ULL << 1,
+	KDBUS_MSG_SIGNAL	= 1ULL << 2,
+};
+
+/**
+ * enum kdbus_payload_type - type of payload carried by message
+ * @KDBUS_PAYLOAD_KERNEL:	Kernel-generated simple message
+ * @KDBUS_PAYLOAD_DBUS:		D-Bus marshalling "DBusDBus"
+ *
+ * Any payload-type is accepted. Common types will get added here once
+ * established.
+ */
+enum kdbus_payload_type {
+	KDBUS_PAYLOAD_KERNEL,
+	KDBUS_PAYLOAD_DBUS	= 0x4442757344427573ULL,
+};
+
+/**
+ * struct kdbus_msg - the representation of a kdbus message
+ * @size:		Total size of the message
+ * @flags:		Message flags (KDBUS_MSG_*), userspace → kernel
+ * @priority:		Message queue priority value
+ * @dst_id:		64-bit ID of the destination connection
+ * @src_id:		64-bit ID of the source connection
+ * @payload_type:	Payload type (KDBUS_PAYLOAD_*)
+ * @cookie:		Userspace-supplied cookie, for the connection
+ *			to identify its messages
+ * @timeout_ns:		The time to wait for a message reply from the peer.
+ *			If there is no reply, and the send command is
+ *			executed asynchronously, a kernel-generated message
+ *			with an attached KDBUS_ITEM_REPLY_TIMEOUT item
+ *			is sent to @src_id. For synchronously executed send
+ *			command, the value denotes the maximum time the call
+ *			blocks to wait for a reply. The timeout is expected in
+ *			nanoseconds and as absolute CLOCK_MONOTONIC value.
+ * @cookie_reply:	A reply to the requesting message with the same
+ *			cookie. The requesting connection can match its
+ *			request and the reply with this value
+ * @items:		A list of kdbus_items containing the message payload
+ */
+struct kdbus_msg {
+	__u64 size;
+	__u64 flags;
+	__s64 priority;
+	__u64 dst_id;
+	__u64 src_id;
+	__u64 payload_type;
+	__u64 cookie;
+	union {
+		__u64 timeout_ns;
+		__u64 cookie_reply;
+	};
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_msg_info - returned message container
+ * @offset:		Offset of kdbus_msg slice in pool
+ * @msg_size:		Copy of the kdbus_msg.size field
+ * @return_flags:	Command return flags, kernel → userspace
+ */
+struct kdbus_msg_info {
+	__u64 offset;
+	__u64 msg_size;
+	__u64 return_flags;
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_send_flags - flags for sending messages
+ * @KDBUS_SEND_SYNC_REPLY:	Wait for destination connection to
+ *				reply to this message. The
+ *				KDBUS_CMD_SEND ioctl() will block
+ *				until the reply is received, and
+ *				reply in struct kdbus_cmd_send will
+ *				yield the offset in the sender's pool
+ *				where the reply can be found.
+ *				This flag is only valid if
+ *				@KDBUS_MSG_EXPECT_REPLY is set as well.
+ */
+enum kdbus_send_flags {
+	KDBUS_SEND_SYNC_REPLY		= 1ULL << 0,
+};
+
+/**
+ * struct kdbus_cmd_send - send message
+ * @size:		Overall size of this structure
+ * @flags:		Flags to change send behavior (KDBUS_SEND_*)
+ * @return_flags:	Command return flags, kernel → userspace
+ * @msg_address:	Storage address of the kdbus_msg to send
+ * @reply:		Storage for message reply if KDBUS_SEND_SYNC_REPLY
+ *			was given
+ * @items:		Additional items for this command
+ */
+struct kdbus_cmd_send {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 msg_address;
+	struct kdbus_msg_info reply;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_recv_flags - flags for de-queuing messages
+ * @KDBUS_RECV_PEEK:		Return the next queued message without
+ *				actually de-queuing it, and without installing
+ *				any file descriptors or other resources. It is
+ *				usually used to determine the activating
+ *				connection of a bus name.
+ * @KDBUS_RECV_DROP:		Drop and free the next queued message and all
+ *				its resources without actually receiving it.
+ * @KDBUS_RECV_USE_PRIORITY:	Only de-queue messages with the specified or
+ *				higher priority (lowest values); if not set,
+ *				the priority value is ignored.
+ */
+enum kdbus_recv_flags {
+	KDBUS_RECV_PEEK		= 1ULL <<  0,
+	KDBUS_RECV_DROP		= 1ULL <<  1,
+	KDBUS_RECV_USE_PRIORITY	= 1ULL <<  2,
+};
+
+/**
+ * enum kdbus_recv_return_flags - return flags for message receive commands
+ * @KDBUS_RECV_RETURN_INCOMPLETE_FDS:	One or more file descriptors could not
+ *					be installed. These descriptors in
+ *					KDBUS_ITEM_FDS will carry the value -1.
+ * @KDBUS_RECV_RETURN_DROPPED_MSGS:	There have been dropped messages since
+ *					the last time a message was received.
+ *					The 'dropped_msgs' counter contains the
+ *					number of messages dropped pool
+ *					overflows or other missed broadcasts.
+ */
+enum kdbus_recv_return_flags {
+	KDBUS_RECV_RETURN_INCOMPLETE_FDS	= 1ULL <<  0,
+	KDBUS_RECV_RETURN_DROPPED_MSGS		= 1ULL <<  1,
+};
+
+/**
+ * struct kdbus_cmd_recv - struct to de-queue a buffered message
+ * @size:		Overall size of this object
+ * @flags:		KDBUS_RECV_* flags, userspace → kernel
+ * @return_flags:	Command return flags, kernel → userspace
+ * @priority:		Minimum priority of the messages to de-queue. Lowest
+ *			values have the highest priority.
+ * @dropped_msgs:	In case there were any dropped messages since the last
+ *			time a message was received, this will be set to the
+ *			number of lost messages and
+ *			KDBUS_RECV_RETURN_DROPPED_MSGS will be set in
+ *			'return_flags'. This can only happen if the ioctl
+ *			returns 0 or EAGAIN.
+ * @msg:		Return storage for received message.
+ * @items:		Additional items for this command.
+ *
+ * This struct is used with the KDBUS_CMD_RECV ioctl.
+ */
+struct kdbus_cmd_recv {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__s64 priority;
+	__u64 dropped_msgs;
+	struct kdbus_msg_info msg;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_cmd_free - struct to free a slice of memory in the pool
+ * @size:		Overall size of this structure
+ * @flags:		Flags for the free command, userspace → kernel
+ * @return_flags:	Command return flags, kernel → userspace
+ * @offset:		The offset of the memory slice, as returned by other
+ *			ioctls
+ * @items:		Additional items to modify the behavior
+ *
+ * This struct is used with the KDBUS_CMD_FREE ioctl.
+ */
+struct kdbus_cmd_free {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 offset;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_hello_flags - flags for struct kdbus_cmd_hello
+ * @KDBUS_HELLO_ACCEPT_FD:	The connection allows the reception of
+ *				any passed file descriptors
+ * @KDBUS_HELLO_ACTIVATOR:	Special-purpose connection which registers
+ *				a well-know name for a process to be started
+ *				when traffic arrives
+ * @KDBUS_HELLO_POLICY_HOLDER:	Special-purpose connection which registers
+ *				policy entries for a name. The provided name
+ *				is not activated and not registered with the
+ *				name database, it only allows unprivileged
+ *				connections to acquire a name, talk or discover
+ *				a service
+ * @KDBUS_HELLO_MONITOR:	Special-purpose connection to monitor
+ *				bus traffic
+ */
+enum kdbus_hello_flags {
+	KDBUS_HELLO_ACCEPT_FD		=  1ULL <<  0,
+	KDBUS_HELLO_ACTIVATOR		=  1ULL <<  1,
+	KDBUS_HELLO_POLICY_HOLDER	=  1ULL <<  2,
+	KDBUS_HELLO_MONITOR		=  1ULL <<  3,
+};
+
+/**
+ * struct kdbus_cmd_hello - struct to say hello to kdbus
+ * @size:		The total size of the structure
+ * @flags:		Connection flags (KDBUS_HELLO_*), userspace → kernel
+ * @return_flags:	Command return flags, kernel → userspace
+ * @attach_flags_send:	Mask of metadata to attach to each message sent
+ *			off by this connection (KDBUS_ATTACH_*)
+ * @attach_flags_recv:	Mask of metadata to attach to each message receieved
+ *			by the new connection (KDBUS_ATTACH_*)
+ * @bus_flags:		The flags field copied verbatim from the original
+ *			KDBUS_CMD_BUS_MAKE ioctl. It's intended to be useful
+ *			to do negotiation of features of the payload that is
+ *			transferred (kernel → userspace)
+ * @id:			The ID of this connection (kernel → userspace)
+ * @pool_size:		Size of the connection's buffer where the received
+ *			messages are placed
+ * @offset:		Pool offset where items are returned to report
+ *			additional information about the bus and the newly
+ *			created connection.
+ * @items_size:		Size of buffer returned in the pool slice at @offset.
+ * @id128:		Unique 128-bit ID of the bus (kernel → userspace)
+ * @items:		A list of items
+ *
+ * This struct is used with the KDBUS_CMD_HELLO ioctl.
+ */
+struct kdbus_cmd_hello {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 attach_flags_send;
+	__u64 attach_flags_recv;
+	__u64 bus_flags;
+	__u64 id;
+	__u64 pool_size;
+	__u64 offset;
+	__u64 items_size;
+	__u8 id128[16];
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_info - connection information
+ * @size:		total size of the struct
+ * @id:			64bit object ID
+ * @flags:		object creation flags
+ * @items:		list of items
+ *
+ * Note that the user is responsible for freeing the allocated memory with
+ * the KDBUS_CMD_FREE ioctl.
+ */
+struct kdbus_info {
+	__u64 size;
+	__u64 id;
+	__u64 flags;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_list_flags - what to include into the returned list
+ * @KDBUS_LIST_UNIQUE:		active connections
+ * @KDBUS_LIST_ACTIVATORS:	activator connections
+ * @KDBUS_LIST_NAMES:		known well-known names
+ * @KDBUS_LIST_QUEUED:		queued-up names
+ */
+enum kdbus_list_flags {
+	KDBUS_LIST_UNIQUE		= 1ULL <<  0,
+	KDBUS_LIST_NAMES		= 1ULL <<  1,
+	KDBUS_LIST_ACTIVATORS		= 1ULL <<  2,
+	KDBUS_LIST_QUEUED		= 1ULL <<  3,
+};
+
+/**
+ * struct kdbus_cmd_list - list connections
+ * @size:		overall size of this object
+ * @flags:		flags for the query (KDBUS_LIST_*), userspace → kernel
+ * @return_flags:	command return flags, kernel → userspace
+ * @offset:		Offset in the caller's pool buffer where an array of
+ *			kdbus_info objects is stored.
+ *			The user must use KDBUS_CMD_FREE to free the
+ *			allocated memory.
+ * @list_size:		size of returned list in bytes
+ * @items:		Items for the command. Reserved for future use.
+ *
+ * This structure is used with the KDBUS_CMD_LIST ioctl.
+ */
+struct kdbus_cmd_list {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 offset;
+	__u64 list_size;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * struct kdbus_cmd_info - struct used for KDBUS_CMD_CONN_INFO ioctl
+ * @size:		The total size of the struct
+ * @flags:		Flags for this ioctl, userspace → kernel
+ * @return_flags:	Command return flags, kernel → userspace
+ * @id:			The 64-bit ID of the connection. If set to zero, passing
+ *			@name is required. kdbus will look up the name to
+ *			determine the ID in this case.
+ * @attach_flags:	Set of attach flags to specify the set of information
+ *			to receive, userspace → kernel
+ * @offset:		Returned offset in the caller's pool buffer where the
+ *			kdbus_info struct result is stored. The user must
+ *			use KDBUS_CMD_FREE to free the allocated memory.
+ * @info_size:		Output buffer to report size of data at @offset.
+ * @items:		The optional item list, containing the
+ *			well-known name to look up as a KDBUS_ITEM_NAME.
+ *			Only needed in case @id is zero.
+ *
+ * On success, the KDBUS_CMD_CONN_INFO ioctl will return 0 and @offset will
+ * tell the user the offset in the connection pool buffer at which to find the
+ * result in a struct kdbus_info.
+ */
+struct kdbus_cmd_info {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 id;
+	__u64 attach_flags;
+	__u64 offset;
+	__u64 info_size;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_cmd_match_flags - flags to control the KDBUS_CMD_MATCH_ADD ioctl
+ * @KDBUS_MATCH_REPLACE:	If entries with the supplied cookie already
+ *				exists, remove them before installing the new
+ *				matches.
+ */
+enum kdbus_cmd_match_flags {
+	KDBUS_MATCH_REPLACE	= 1ULL <<  0,
+};
+
+/**
+ * struct kdbus_cmd_match - struct to add or remove matches
+ * @size:		The total size of the struct
+ * @flags:		Flags for match command (KDBUS_MATCH_*),
+ *			userspace → kernel
+ * @return_flags:	Command return flags, kernel → userspace
+ * @cookie:		Userspace supplied cookie. When removing, the cookie
+ *			identifies the match to remove
+ * @items:		A list of items for additional information
+ *
+ * This structure is used with the KDBUS_CMD_MATCH_ADD and
+ * KDBUS_CMD_MATCH_REMOVE ioctl.
+ */
+struct kdbus_cmd_match {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	__u64 cookie;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * enum kdbus_make_flags - Flags for KDBUS_CMD_{BUS,ENDPOINT}_MAKE
+ * @KDBUS_MAKE_ACCESS_GROUP:	Make the bus or endpoint node group-accessible
+ * @KDBUS_MAKE_ACCESS_WORLD:	Make the bus or endpoint node world-accessible
+ */
+enum kdbus_make_flags {
+	KDBUS_MAKE_ACCESS_GROUP		= 1ULL <<  0,
+	KDBUS_MAKE_ACCESS_WORLD		= 1ULL <<  1,
+};
+
+/**
+ * enum kdbus_name_flags - flags for KDBUS_CMD_NAME_ACQUIRE
+ * @KDBUS_NAME_REPLACE_EXISTING:	Try to replace name of other connections
+ * @KDBUS_NAME_ALLOW_REPLACEMENT:	Allow the replacement of the name
+ * @KDBUS_NAME_QUEUE:			Name should be queued if busy
+ * @KDBUS_NAME_IN_QUEUE:		Name is queued
+ * @KDBUS_NAME_ACTIVATOR:		Name is owned by a activator connection
+ * @KDBUS_NAME_PRIMARY:			Primary owner of the name
+ * @KDBUS_NAME_ACQUIRED:		Name was acquired/queued _now_
+ */
+enum kdbus_name_flags {
+	KDBUS_NAME_REPLACE_EXISTING	= 1ULL <<  0,
+	KDBUS_NAME_ALLOW_REPLACEMENT	= 1ULL <<  1,
+	KDBUS_NAME_QUEUE		= 1ULL <<  2,
+	KDBUS_NAME_IN_QUEUE		= 1ULL <<  3,
+	KDBUS_NAME_ACTIVATOR		= 1ULL <<  4,
+	KDBUS_NAME_PRIMARY		= 1ULL <<  5,
+	KDBUS_NAME_ACQUIRED		= 1ULL <<  6,
+};
+
+/**
+ * struct kdbus_cmd - generic ioctl payload
+ * @size:		Overall size of this structure
+ * @flags:		Flags for this ioctl, userspace → kernel
+ * @return_flags:	Ioctl return flags, kernel → userspace
+ * @items:		Additional items to modify the behavior
+ *
+ * This is a generic ioctl payload object. It's used by all ioctls that only
+ * take flags and items as input.
+ */
+struct kdbus_cmd {
+	__u64 size;
+	__u64 flags;
+	__u64 return_flags;
+	struct kdbus_item items[0];
+} __attribute__((__aligned__(8)));
+
+/**
+ * Ioctl API
+ *
+ * KDBUS_CMD_BUS_MAKE:		After opening the "control" node, this command
+ *				creates a new bus with the specified
+ *				name. The bus is immediately shut down and
+ *				cleaned up when the opened file descriptor is
+ *				closed.
+ *
+ * KDBUS_CMD_ENDPOINT_MAKE:	Creates a new named special endpoint to talk to
+ *				the bus. Such endpoints usually carry a more
+ *				restrictive policy and grant restricted access
+ *				to specific applications.
+ * KDBUS_CMD_ENDPOINT_UPDATE:	Update the properties of a custom enpoint. Used
+ *				to update the policy.
+ *
+ * KDBUS_CMD_HELLO:		By opening the bus node, a connection is
+ *				created. After a HELLO the opened connection
+ *				becomes an active peer on the bus.
+ * KDBUS_CMD_UPDATE:		Update the properties of a connection. Used to
+ *				update the metadata subscription mask and
+ *				policy.
+ * KDBUS_CMD_BYEBYE:		Disconnect a connection. If there are no
+ *				messages queued up in the connection's pool,
+ *				the call succeeds, and the handle is rendered
+ *				unusable. Otherwise, -EBUSY is returned without
+ *				any further side-effects.
+ * KDBUS_CMD_FREE:		Release the allocated memory in the receiver's
+ *				pool.
+ * KDBUS_CMD_CONN_INFO:		Retrieve credentials and properties of the
+ *				initial creator of the connection. The data was
+ *				stored at registration time and does not
+ *				necessarily represent the connected process or
+ *				the actual state of the process.
+ * KDBUS_CMD_BUS_CREATOR_INFO:	Retrieve information of the creator of the bus
+ *				a connection is attached to.
+ *
+ * KDBUS_CMD_SEND:		Send a message and pass data from userspace to
+ *				the kernel.
+ * KDBUS_CMD_RECV:		Receive a message from the kernel which is
+ *				placed in the receiver's pool.
+ *
+ * KDBUS_CMD_NAME_ACQUIRE:	Request a well-known bus name to associate with
+ *				the connection. Well-known names are used to
+ *				address a peer on the bus.
+ * KDBUS_CMD_NAME_RELEASE:	Release a well-known name the connection
+ *				currently owns.
+ * KDBUS_CMD_LIST:		Retrieve the list of all currently registered
+ *				well-known and unique names.
+ *
+ * KDBUS_CMD_MATCH_ADD:		Install a match which broadcast messages should
+ *				be delivered to the connection.
+ * KDBUS_CMD_MATCH_REMOVE:	Remove a current match for broadcast messages.
+ */
+enum kdbus_ioctl_type {
+	/* bus owner (00-0f) */
+	KDBUS_CMD_BUS_MAKE =		_IOW(KDBUS_IOCTL_MAGIC, 0x00,
+					     struct kdbus_cmd),
+
+	/* endpoint owner (10-1f) */
+	KDBUS_CMD_ENDPOINT_MAKE =	_IOW(KDBUS_IOCTL_MAGIC, 0x10,
+					     struct kdbus_cmd),
+	KDBUS_CMD_ENDPOINT_UPDATE =	_IOW(KDBUS_IOCTL_MAGIC, 0x11,
+					     struct kdbus_cmd),
+
+	/* connection owner (80-ff) */
+	KDBUS_CMD_HELLO =		_IOWR(KDBUS_IOCTL_MAGIC, 0x80,
+					      struct kdbus_cmd_hello),
+	KDBUS_CMD_UPDATE =		_IOW(KDBUS_IOCTL_MAGIC, 0x81,
+					     struct kdbus_cmd),
+	KDBUS_CMD_BYEBYE =		_IOW(KDBUS_IOCTL_MAGIC, 0x82,
+					     struct kdbus_cmd),
+	KDBUS_CMD_FREE =		_IOW(KDBUS_IOCTL_MAGIC, 0x83,
+					     struct kdbus_cmd_free),
+	KDBUS_CMD_CONN_INFO =		_IOR(KDBUS_IOCTL_MAGIC, 0x84,
+					     struct kdbus_cmd_info),
+	KDBUS_CMD_BUS_CREATOR_INFO =	_IOR(KDBUS_IOCTL_MAGIC, 0x85,
+					     struct kdbus_cmd_info),
+	KDBUS_CMD_LIST =		_IOR(KDBUS_IOCTL_MAGIC, 0x86,
+					     struct kdbus_cmd_list),
+
+	KDBUS_CMD_SEND =		_IOW(KDBUS_IOCTL_MAGIC, 0x90,
+					     struct kdbus_cmd_send),
+	KDBUS_CMD_RECV =		_IOR(KDBUS_IOCTL_MAGIC, 0x91,
+					     struct kdbus_cmd_recv),
+
+	KDBUS_CMD_NAME_ACQUIRE =	_IOW(KDBUS_IOCTL_MAGIC, 0xa0,
+					     struct kdbus_cmd),
+	KDBUS_CMD_NAME_RELEASE =	_IOW(KDBUS_IOCTL_MAGIC, 0xa1,
+					     struct kdbus_cmd),
+
+	KDBUS_CMD_MATCH_ADD =		_IOW(KDBUS_IOCTL_MAGIC, 0xb0,
+					     struct kdbus_cmd_match),
+	KDBUS_CMD_MATCH_REMOVE =	_IOW(KDBUS_IOCTL_MAGIC, 0xb1,
+					     struct kdbus_cmd_match),
+};
+
+#endif /* _UAPI_KDBUS_H_ */
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 7b1425a6b370..ce2ac5a06b1b 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -76,4 +76,6 @@
 #define BTRFS_TEST_MAGIC	0x73727279
 #define NSFS_MAGIC		0x6e736673
 
+#define KDBUS_SUPER_MAGIC	0x44427573
+
 #endif /* __LINUX_MAGIC_H__ */
diff --git a/init/Kconfig b/init/Kconfig
index c24b6f767bf0..964427abf01d 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -261,6 +261,19 @@ config POSIX_MQUEUE_SYSCTL
 	depends on SYSCTL
 	default y
 
+config KDBUS
+	tristate "kdbus interprocess communication"
+	depends on TMPFS
+	help
+	  D-Bus is a system for low-latency, low-overhead, easy to use
+	  interprocess communication (IPC).
+
+	  See the man-pages and HTML files in Documentation/kdbus/
+	  that are generated by 'make mandocs' and 'make htmldocs'.
+
+	  If you have an ordinary machine, select M here. The module
+	  will be called kdbus.
+
 config CROSS_MEMORY_ATTACH
 	bool "Enable process_vm_readv/writev syscalls"
 	depends on MMU
@@ -283,6 +296,9 @@ config FHANDLE
 	  get renamed. Enables open_by_handle_at(2) and name_to_handle_at(2)
 	  syscalls.
 
+	  Some distributions (such as Fedora) will not boot without this
+	  system call, so if unsure, say Y.
+
 config USELIB
 	bool "uselib syscall"
 	default y
@@ -1316,6 +1332,77 @@ config CC_OPTIMIZE_FOR_SIZE
 
 	  If unsure, say N.
 
+config LTO_MENU
+	bool "Enable gcc link time optimization (LTO)"
+	# Only tested on X86 for now. For other architectures you likely
+	# have to fix some things first, like adding asmlinkages etc.
+	depends on X86
+	# lto does not support excluding flags for specific files
+	# right now. Can be removed if that is fixed.
+	depends on !FUNCTION_TRACER
+	help
+	  With this option gcc will do whole program optimizations for
+	  the whole kernel and module. This increases compile time, but can
+	  lead to better code. It allows gcc to inline functions between
+	  different files and do other optimization.  It might also trigger
+	  bugs due to more aggressive optimization. It allows gcc to drop unused
+	  code. On smaller monolithic kernel configurations
+	  it usually leads to smaller kernels, especially when modules
+	  are disabled.
+
+	  With this option gcc will also do some global checking over
+	  different source files. It also disables a number of kernel
+	  features.
+
+	  This option is recommended for release builds. With LTO
+	  the kernel always has to be re-optimized (but not re-parsed)
+	  on each build.
+
+	  This requires a gcc 4.8 or later compiler and
+	  Linux binutils 2.21.51.0.3 or later.  gcc 4.9 builds significantly
+	  faster than 4.8 It does not currently work with a FSF release of
+	  binutils or with the gold linker.
+
+	  On larger configurations this may need more than 4GB of RAM.
+	  It will likely not work on those with a 32bit compiler.
+
+	  When the toolchain support is not available this will (hopefully)
+	  be automatically disabled.
+
+	  For more information see Documentation/lto-build
+
+config LTO_DISABLE
+         bool "Disable LTO again"
+         depends on LTO_MENU
+         default n
+         help
+           This option is merely here so that allyesconfig or allmodconfig do
+           not enable LTO. If you want to actually use LTO do not enable.
+
+config LTO
+	bool
+	default y
+	depends on LTO_MENU && !LTO_DISABLE
+
+config LTO_DEBUG
+	bool "Enable LTO compile time debugging"
+	depends on LTO
+	help
+	  Enable LTO debugging in the compiler. The compiler dumps
+	  some log files that make it easier to figure out LTO
+	  behavior. The log files also allow to reconstruct
+	  the global inlining and a global callgraph.
+	  They however add some (single threaded) cost to the
+	  compilation.  When in doubt do not enable.
+
+config LTO_CP_CLONE
+	bool "Allow aggressive cloning for function specialization"
+	depends on LTO
+	help
+	  Allow the compiler to clone and specialize functions for specific
+	  arguments when it determines these arguments are very commonly
+	  called.  Experimential. Will increase text size.
+
 config SYSCTL
 	bool
 
@@ -1881,6 +1968,8 @@ config MODULE_FORCE_UNLOAD
 
 config MODVERSIONS
 	bool "Module versioning support"
+	# LTO should work with gcc 4.9
+	depends on !LTO
 	help
 	  Usually, you have to use modules compiled with your kernel.
 	  Saying Y here makes it sometimes possible to use modules
diff --git a/ipc/Makefile b/ipc/Makefile
index 86c7300ecdf5..68ec4167d11b 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -9,4 +9,4 @@ obj_mq-$(CONFIG_COMPAT) += compat_mq.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
 obj-$(CONFIG_IPC_NS) += namespace.o
 obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
-
+obj-$(CONFIG_KDBUS) += kdbus/
diff --git a/ipc/kdbus/Makefile b/ipc/kdbus/Makefile
new file mode 100644
index 000000000000..66663a124104
--- /dev/null
+++ b/ipc/kdbus/Makefile
@@ -0,0 +1,33 @@
+#
+# By setting KDBUS_EXT=2, the kdbus module will be built as kdbus2.ko, and
+# KBUILD_MODNAME=kdbus2. This has the effect that all exported objects have
+# different names than usually (kdbus2fs, /sys/fs/kdbus2/) and you can run
+# your test-infrastructure against the kdbus2.ko, while running your system
+# on kdbus.ko.
+#
+# To just build the module, use:
+#     make KDBUS_EXT=2 M=ipc/kdbus
+#
+
+kdbus$(KDBUS_EXT)-y := \
+	bus.o \
+	connection.o \
+	endpoint.o \
+	fs.o \
+	handle.o \
+	item.o \
+	main.o \
+	match.o \
+	message.o \
+	metadata.o \
+	names.o \
+	node.o \
+	notify.o \
+	domain.o \
+	policy.o \
+	pool.o \
+	reply.o \
+	queue.o \
+	util.o
+
+obj-$(CONFIG_KDBUS) += kdbus$(KDBUS_EXT).o
diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
new file mode 100644
index 000000000000..a67f825bdeaf
--- /dev/null
+++ b/ipc/kdbus/bus.c
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/hashtable.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/uio.h>
+
+#include "bus.h"
+#include "notify.h"
+#include "connection.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "item.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "policy.h"
+#include "util.h"
+
+static void kdbus_bus_free(struct kdbus_node *node)
+{
+	struct kdbus_bus *bus = container_of(node, struct kdbus_bus, node);
+
+	WARN_ON(!list_empty(&bus->monitors_list));
+	WARN_ON(!hash_empty(bus->conn_hash));
+
+	kdbus_notify_free(bus);
+
+	kdbus_user_unref(bus->creator);
+	kdbus_name_registry_free(bus->name_registry);
+	kdbus_domain_unref(bus->domain);
+	kdbus_policy_db_clear(&bus->policy_db);
+	kdbus_meta_proc_unref(bus->creator_meta);
+	kfree(bus);
+}
+
+static void kdbus_bus_release(struct kdbus_node *node, bool was_active)
+{
+	struct kdbus_bus *bus = container_of(node, struct kdbus_bus, node);
+
+	if (was_active)
+		atomic_dec(&bus->creator->buses);
+}
+
+static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain,
+				       const char *name,
+				       struct kdbus_bloom_parameter *bloom,
+				       const u64 *pattach_owner,
+				       u64 flags, kuid_t uid, kgid_t gid)
+{
+	struct kdbus_bus *b;
+	u64 attach_owner;
+	int ret;
+
+	if (bloom->size < 8 || bloom->size > KDBUS_BUS_BLOOM_MAX_SIZE ||
+	    !KDBUS_IS_ALIGNED8(bloom->size) || bloom->n_hash < 1)
+		return ERR_PTR(-EINVAL);
+
+	ret = kdbus_sanitize_attach_flags(pattach_owner ? *pattach_owner : 0,
+					  &attach_owner);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	ret = kdbus_verify_uid_prefix(name, domain->user_namespace, uid);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	b = kzalloc(sizeof(*b), GFP_KERNEL);
+	if (!b)
+		return ERR_PTR(-ENOMEM);
+
+	kdbus_node_init(&b->node, KDBUS_NODE_BUS);
+
+	b->node.free_cb = kdbus_bus_free;
+	b->node.release_cb = kdbus_bus_release;
+	b->node.uid = uid;
+	b->node.gid = gid;
+	b->node.mode = S_IRUSR | S_IXUSR;
+
+	if (flags & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
+		b->node.mode |= S_IRGRP | S_IXGRP;
+	if (flags & KDBUS_MAKE_ACCESS_WORLD)
+		b->node.mode |= S_IROTH | S_IXOTH;
+
+	b->id = atomic64_inc_return(&domain->last_id);
+	b->bus_flags = flags;
+	b->attach_flags_owner = attach_owner;
+	generate_random_uuid(b->id128);
+	b->bloom = *bloom;
+	b->domain = kdbus_domain_ref(domain);
+
+	kdbus_policy_db_init(&b->policy_db);
+
+	init_rwsem(&b->conn_rwlock);
+	hash_init(b->conn_hash);
+	INIT_LIST_HEAD(&b->monitors_list);
+
+	INIT_LIST_HEAD(&b->notify_list);
+	spin_lock_init(&b->notify_lock);
+	mutex_init(&b->notify_flush_lock);
+
+	ret = kdbus_node_link(&b->node, &domain->node, name);
+	if (ret < 0)
+		goto exit_unref;
+
+	/* cache the metadata/credentials of the creator */
+	b->creator_meta = kdbus_meta_proc_new();
+	if (IS_ERR(b->creator_meta)) {
+		ret = PTR_ERR(b->creator_meta);
+		b->creator_meta = NULL;
+		goto exit_unref;
+	}
+
+	ret = kdbus_meta_proc_collect(b->creator_meta,
+				      KDBUS_ATTACH_CREDS |
+				      KDBUS_ATTACH_PIDS |
+				      KDBUS_ATTACH_AUXGROUPS |
+				      KDBUS_ATTACH_TID_COMM |
+				      KDBUS_ATTACH_PID_COMM |
+				      KDBUS_ATTACH_EXE |
+				      KDBUS_ATTACH_CMDLINE |
+				      KDBUS_ATTACH_CGROUP |
+				      KDBUS_ATTACH_CAPS |
+				      KDBUS_ATTACH_SECLABEL |
+				      KDBUS_ATTACH_AUDIT);
+	if (ret < 0)
+		goto exit_unref;
+
+	b->name_registry = kdbus_name_registry_new();
+	if (IS_ERR(b->name_registry)) {
+		ret = PTR_ERR(b->name_registry);
+		b->name_registry = NULL;
+		goto exit_unref;
+	}
+
+	/*
+	 * Bus-limits of the creator are accounted on its real UID, just like
+	 * all other per-user limits.
+	 */
+	b->creator = kdbus_user_lookup(domain, current_uid());
+	if (IS_ERR(b->creator)) {
+		ret = PTR_ERR(b->creator);
+		b->creator = NULL;
+		goto exit_unref;
+	}
+
+	return b;
+
+exit_unref:
+	kdbus_node_deactivate(&b->node);
+	kdbus_node_unref(&b->node);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_bus_ref() - increase the reference counter of a kdbus_bus
+ * @bus:		The bus to reference
+ *
+ * Every user of a bus, except for its creator, must add a reference to the
+ * kdbus_bus using this function.
+ *
+ * Return: the bus itself
+ */
+struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus)
+{
+	if (bus)
+		kdbus_node_ref(&bus->node);
+	return bus;
+}
+
+/**
+ * kdbus_bus_unref() - decrease the reference counter of a kdbus_bus
+ * @bus:		The bus to unref
+ *
+ * Release a reference. If the reference count drops to 0, the bus will be
+ * freed.
+ *
+ * Return: NULL
+ */
+struct kdbus_bus *kdbus_bus_unref(struct kdbus_bus *bus)
+{
+	if (bus)
+		kdbus_node_unref(&bus->node);
+	return NULL;
+}
+
+/**
+ * kdbus_bus_find_conn_by_id() - find a connection with a given id
+ * @bus:		The bus to look for the connection
+ * @id:			The 64-bit connection id
+ *
+ * Looks up a connection with a given id. The returned connection
+ * is ref'ed, and needs to be unref'ed by the user. Returns NULL if
+ * the connection can't be found.
+ */
+struct kdbus_conn *kdbus_bus_find_conn_by_id(struct kdbus_bus *bus, u64 id)
+{
+	struct kdbus_conn *conn, *found = NULL;
+
+	down_read(&bus->conn_rwlock);
+	hash_for_each_possible(bus->conn_hash, conn, hentry, id)
+		if (conn->id == id) {
+			found = kdbus_conn_ref(conn);
+			break;
+		}
+	up_read(&bus->conn_rwlock);
+
+	return found;
+}
+
+/**
+ * kdbus_bus_broadcast() - send a message to all subscribed connections
+ * @bus:	The bus the connections are connected to
+ * @conn_src:	The source connection, may be %NULL for kernel notifications
+ * @staging:	Staging object containing the message to send
+ *
+ * Send message to all connections that are currently active on the bus.
+ * Connections must still have matches installed in order to let the message
+ * pass.
+ *
+ * The caller must hold the name-registry lock of @bus.
+ */
+void kdbus_bus_broadcast(struct kdbus_bus *bus,
+			 struct kdbus_conn *conn_src,
+			 struct kdbus_staging *staging)
+{
+	struct kdbus_conn *conn_dst;
+	unsigned int i;
+	int ret;
+
+	lockdep_assert_held(&bus->name_registry->rwlock);
+
+	/*
+	 * Make sure broadcast are queued on monitors before we send it out to
+	 * anyone else. Otherwise, connections might react to broadcasts before
+	 * the monitor gets the broadcast queued. In the worst case, the
+	 * monitor sees a reaction to the broadcast before the broadcast itself.
+	 * We don't give ordering guarantees across connections (and monitors
+	 * can re-construct order via sequence numbers), but we should at least
+	 * try to avoid re-ordering for monitors.
+	 */
+	kdbus_bus_eavesdrop(bus, conn_src, staging);
+
+	down_read(&bus->conn_rwlock);
+	hash_for_each(bus->conn_hash, i, conn_dst, hentry) {
+		if (!kdbus_conn_is_ordinary(conn_dst))
+			continue;
+
+		/*
+		 * Check if there is a match for the kmsg object in
+		 * the destination connection match db
+		 */
+		if (!kdbus_match_db_match_msg(conn_dst->match_db, conn_src,
+					      staging))
+			continue;
+
+		if (conn_src) {
+			/*
+			 * Anyone can send broadcasts, as they have no
+			 * destination. But a receiver needs TALK access to
+			 * the sender in order to receive broadcasts.
+			 */
+			if (!kdbus_conn_policy_talk(conn_dst, NULL, conn_src))
+				continue;
+		} else {
+			/*
+			 * Check if there is a policy db that prevents the
+			 * destination connection from receiving this kernel
+			 * notification
+			 */
+			if (!kdbus_conn_policy_see_notification(conn_dst, NULL,
+								staging->msg))
+				continue;
+		}
+
+		ret = kdbus_conn_entry_insert(conn_src, conn_dst, staging,
+					      NULL, NULL);
+		if (ret < 0)
+			kdbus_conn_lost_message(conn_dst);
+	}
+	up_read(&bus->conn_rwlock);
+}
+
+/**
+ * kdbus_bus_eavesdrop() - send a message to all subscribed monitors
+ * @bus:	The bus the monitors are connected to
+ * @conn_src:	The source connection, may be %NULL for kernel notifications
+ * @staging:	Staging object containing the message to send
+ *
+ * Send message to all monitors that are currently active on the bus. Monitors
+ * must still have matches installed in order to let the message pass.
+ *
+ * The caller must hold the name-registry lock of @bus.
+ */
+void kdbus_bus_eavesdrop(struct kdbus_bus *bus,
+			 struct kdbus_conn *conn_src,
+			 struct kdbus_staging *staging)
+{
+	struct kdbus_conn *conn_dst;
+	int ret;
+
+	/*
+	 * Monitor connections get all messages; ignore possible errors
+	 * when sending messages to monitor connections.
+	 */
+
+	lockdep_assert_held(&bus->name_registry->rwlock);
+
+	down_read(&bus->conn_rwlock);
+	list_for_each_entry(conn_dst, &bus->monitors_list, monitor_entry) {
+		ret = kdbus_conn_entry_insert(conn_src, conn_dst, staging,
+					      NULL, NULL);
+		if (ret < 0)
+			kdbus_conn_lost_message(conn_dst);
+	}
+	up_read(&bus->conn_rwlock);
+}
+
+/**
+ * kdbus_cmd_bus_make() - handle KDBUS_CMD_BUS_MAKE
+ * @domain:		domain to operate on
+ * @argp:		command payload
+ *
+ * Return: NULL or newly created bus on success, ERR_PTR on failure.
+ */
+struct kdbus_bus *kdbus_cmd_bus_make(struct kdbus_domain *domain,
+				     void __user *argp)
+{
+	struct kdbus_bus *bus = NULL;
+	struct kdbus_cmd *cmd;
+	struct kdbus_ep *ep = NULL;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_MAKE_NAME, .mandatory = true },
+		{ .type = KDBUS_ITEM_BLOOM_PARAMETER, .mandatory = true },
+		{ .type = KDBUS_ITEM_ATTACH_FLAGS_SEND },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_MAKE_ACCESS_GROUP |
+				 KDBUS_MAKE_ACCESS_WORLD,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret > 0)
+		return NULL;
+
+	bus = kdbus_bus_new(domain,
+			    argv[1].item->str, &argv[2].item->bloom_parameter,
+			    argv[3].item ? argv[3].item->data64 : NULL,
+			    cmd->flags, current_euid(), current_egid());
+	if (IS_ERR(bus)) {
+		ret = PTR_ERR(bus);
+		bus = NULL;
+		goto exit;
+	}
+
+	if (atomic_inc_return(&bus->creator->buses) > KDBUS_USER_MAX_BUSES) {
+		atomic_dec(&bus->creator->buses);
+		ret = -EMFILE;
+		goto exit;
+	}
+
+	if (!kdbus_node_activate(&bus->node)) {
+		atomic_dec(&bus->creator->buses);
+		ret = -ESHUTDOWN;
+		goto exit;
+	}
+
+	ep = kdbus_ep_new(bus, "bus", cmd->flags, bus->node.uid, bus->node.gid,
+			  false);
+	if (IS_ERR(ep)) {
+		ret = PTR_ERR(ep);
+		ep = NULL;
+		goto exit;
+	}
+
+	if (!kdbus_node_activate(&ep->node)) {
+		ret = -ESHUTDOWN;
+		goto exit;
+	}
+
+	/*
+	 * Drop our own reference, effectively causing the endpoint to be
+	 * deactivated and released when the parent bus is.
+	 */
+	ep = kdbus_ep_unref(ep);
+
+exit:
+	ret = kdbus_args_clear(&args, ret);
+	if (ret < 0) {
+		if (ep) {
+			kdbus_node_deactivate(&ep->node);
+			kdbus_ep_unref(ep);
+		}
+		if (bus) {
+			kdbus_node_deactivate(&bus->node);
+			kdbus_bus_unref(bus);
+		}
+		return ERR_PTR(ret);
+	}
+	return bus;
+}
+
+/**
+ * kdbus_cmd_bus_creator_info() - handle KDBUS_CMD_BUS_CREATOR_INFO
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_bus_creator_info(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_cmd_info *cmd;
+	struct kdbus_bus *bus = conn->ep->bus;
+	struct kdbus_pool_slice *slice = NULL;
+	struct kdbus_item *meta_items = NULL;
+	struct kdbus_item_header item_hdr;
+	struct kdbus_info info = {};
+	size_t meta_size, name_len, cnt = 0;
+	struct kvec kvec[6];
+	u64 attach_flags, size = 0;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	ret = kdbus_sanitize_attach_flags(cmd->attach_flags, &attach_flags);
+	if (ret < 0)
+		goto exit;
+
+	attach_flags &= bus->attach_flags_owner;
+
+	ret = kdbus_meta_emit(bus->creator_meta, NULL, NULL, conn,
+			      attach_flags, &meta_items, &meta_size);
+	if (ret < 0)
+		goto exit;
+
+	name_len = strlen(bus->node.name) + 1;
+	info.id = bus->id;
+	info.flags = bus->bus_flags;
+	item_hdr.type = KDBUS_ITEM_MAKE_NAME;
+	item_hdr.size = KDBUS_ITEM_HEADER_SIZE + name_len;
+
+	kdbus_kvec_set(&kvec[cnt++], &info, sizeof(info), &size);
+	kdbus_kvec_set(&kvec[cnt++], &item_hdr, sizeof(item_hdr), &size);
+	kdbus_kvec_set(&kvec[cnt++], bus->node.name, name_len, &size);
+	cnt += !!kdbus_kvec_pad(&kvec[cnt], &size);
+	if (meta_size > 0) {
+		kdbus_kvec_set(&kvec[cnt++], meta_items, meta_size, &size);
+		cnt += !!kdbus_kvec_pad(&kvec[cnt], &size);
+	}
+
+	info.size = size;
+
+	slice = kdbus_pool_slice_alloc(conn->pool, size, false);
+	if (IS_ERR(slice)) {
+		ret = PTR_ERR(slice);
+		slice = NULL;
+		goto exit;
+	}
+
+	ret = kdbus_pool_slice_copy_kvec(slice, 0, kvec, cnt, size);
+	if (ret < 0)
+		goto exit;
+
+	kdbus_pool_slice_publish(slice, &cmd->offset, &cmd->info_size);
+
+	if (kdbus_member_set_user(&cmd->offset, argp, typeof(*cmd), offset) ||
+	    kdbus_member_set_user(&cmd->info_size, argp,
+				  typeof(*cmd), info_size))
+		ret = -EFAULT;
+
+exit:
+	kdbus_pool_slice_release(slice);
+	kfree(meta_items);
+	return kdbus_args_clear(&args, ret);
+}
diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
new file mode 100644
index 000000000000..8c2acaed6258
--- /dev/null
+++ b/ipc/kdbus/bus.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_BUS_H
+#define __KDBUS_BUS_H
+
+#include <linux/hashtable.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rwsem.h>
+#include <linux/spinlock.h>
+#include <uapi/linux/kdbus.h>
+
+#include "metadata.h"
+#include "names.h"
+#include "node.h"
+#include "policy.h"
+
+struct kdbus_conn;
+struct kdbus_domain;
+struct kdbus_staging;
+struct kdbus_user;
+
+/**
+ * struct kdbus_bus - bus in a domain
+ * @node:		kdbus_node
+ * @id:			ID of this bus in the domain
+ * @bus_flags:		Simple pass-through flags from userspace to userspace
+ * @attach_flags_owner:	KDBUS_ATTACH_* flags of bus creator that other
+ *			connections can see or query
+ * @id128:		Unique random 128 bit ID of this bus
+ * @bloom:		Bloom parameters
+ * @domain:		Domain of this bus
+ * @creator:		Creator of the bus
+ * @creator_meta:	Meta information about the bus creator
+ * @last_message_id:	Last used message id
+ * @policy_db:		Policy database for this bus
+ * @name_registry:	Name registry of this bus
+ * @conn_rwlock:	Read/Write lock for all lists of child connections
+ * @conn_hash:		Map of connection IDs
+ * @monitors_list:	Connections that monitor this bus
+ * @notify_list:	List of pending kernel-generated messages
+ * @notify_lock:	Notification list lock
+ * @notify_flush_lock:	Notification flushing lock
+ */
+struct kdbus_bus {
+	struct kdbus_node node;
+
+	/* static */
+	u64 id;
+	u64 bus_flags;
+	u64 attach_flags_owner;
+	u8 id128[16];
+	struct kdbus_bloom_parameter bloom;
+	struct kdbus_domain *domain;
+	struct kdbus_user *creator;
+	struct kdbus_meta_proc *creator_meta;
+
+	/* protected by own locks */
+	atomic64_t last_message_id;
+	struct kdbus_policy_db policy_db;
+	struct kdbus_name_registry *name_registry;
+
+	/* protected by conn_rwlock */
+	struct rw_semaphore conn_rwlock;
+	DECLARE_HASHTABLE(conn_hash, 8);
+	struct list_head monitors_list;
+
+	/* protected by notify_lock */
+	struct list_head notify_list;
+	spinlock_t notify_lock;
+	struct mutex notify_flush_lock;
+};
+
+struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
+struct kdbus_bus *kdbus_bus_unref(struct kdbus_bus *bus);
+
+struct kdbus_conn *kdbus_bus_find_conn_by_id(struct kdbus_bus *bus, u64 id);
+void kdbus_bus_broadcast(struct kdbus_bus *bus,
+			 struct kdbus_conn *conn_src,
+			 struct kdbus_staging *staging);
+void kdbus_bus_eavesdrop(struct kdbus_bus *bus,
+			 struct kdbus_conn *conn_src,
+			 struct kdbus_staging *staging);
+
+struct kdbus_bus *kdbus_cmd_bus_make(struct kdbus_domain *domain,
+				     void __user *argp);
+int kdbus_cmd_bus_creator_info(struct kdbus_conn *conn, void __user *argp);
+
+#endif
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
new file mode 100644
index 000000000000..ef63d6533273
--- /dev/null
+++ b/ipc/kdbus/connection.c
@@ -0,0 +1,2227 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/audit.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fs_struct.h>
+#include <linux/hashtable.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/math64.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/path.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/shmem_fs.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/uio.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "pool.h"
+#include "reply.h"
+#include "util.h"
+#include "queue.h"
+
+#define KDBUS_CONN_ACTIVE_BIAS	(INT_MIN + 2)
+#define KDBUS_CONN_ACTIVE_NEW	(INT_MIN + 1)
+
+static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep,
+					 struct file *file,
+					 struct kdbus_cmd_hello *hello,
+					 const char *name,
+					 const struct kdbus_creds *creds,
+					 const struct kdbus_pids *pids,
+					 const char *seclabel,
+					 const char *conn_description)
+{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	static struct lock_class_key __key;
+#endif
+	struct kdbus_pool_slice *slice = NULL;
+	struct kdbus_bus *bus = ep->bus;
+	struct kdbus_conn *conn;
+	u64 attach_flags_send;
+	u64 attach_flags_recv;
+	u64 items_size = 0;
+	bool is_policy_holder;
+	bool is_activator;
+	bool is_monitor;
+	bool privileged;
+	bool owner;
+	struct kvec kvec;
+	int ret;
+
+	struct {
+		u64 size;
+		u64 type;
+		struct kdbus_bloom_parameter bloom;
+	} bloom_item;
+
+	privileged = kdbus_ep_is_privileged(ep, file);
+	owner = kdbus_ep_is_owner(ep, file);
+
+	is_monitor = hello->flags & KDBUS_HELLO_MONITOR;
+	is_activator = hello->flags & KDBUS_HELLO_ACTIVATOR;
+	is_policy_holder = hello->flags & KDBUS_HELLO_POLICY_HOLDER;
+
+	if (!hello->pool_size || !IS_ALIGNED(hello->pool_size, PAGE_SIZE))
+		return ERR_PTR(-EINVAL);
+	if (is_monitor + is_activator + is_policy_holder > 1)
+		return ERR_PTR(-EINVAL);
+	if (name && !is_activator && !is_policy_holder)
+		return ERR_PTR(-EINVAL);
+	if (!name && (is_activator || is_policy_holder))
+		return ERR_PTR(-EINVAL);
+	if (name && !kdbus_name_is_valid(name, true))
+		return ERR_PTR(-EINVAL);
+	if (is_monitor && ep->user)
+		return ERR_PTR(-EOPNOTSUPP);
+	if (!owner && (is_activator || is_policy_holder || is_monitor))
+		return ERR_PTR(-EPERM);
+	if (!owner && (creds || pids || seclabel))
+		return ERR_PTR(-EPERM);
+
+	ret = kdbus_sanitize_attach_flags(hello->attach_flags_send,
+					  &attach_flags_send);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	ret = kdbus_sanitize_attach_flags(hello->attach_flags_recv,
+					  &attach_flags_recv);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
+	if (!conn)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&conn->kref);
+	atomic_set(&conn->active, KDBUS_CONN_ACTIVE_NEW);
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	lockdep_init_map(&conn->dep_map, "s_active", &__key, 0);
+#endif
+	mutex_init(&conn->lock);
+	INIT_LIST_HEAD(&conn->names_list);
+	INIT_LIST_HEAD(&conn->reply_list);
+	atomic_set(&conn->request_count, 0);
+	atomic_set(&conn->lost_count, 0);
+	INIT_DELAYED_WORK(&conn->work, kdbus_reply_list_scan_work);
+	conn->cred = get_cred(file->f_cred);
+	conn->pid = get_pid(task_pid(current));
+	get_fs_root(current->fs, &conn->root_path);
+	init_waitqueue_head(&conn->wait);
+	kdbus_queue_init(&conn->queue);
+	conn->privileged = privileged;
+	conn->owner = owner;
+	conn->ep = kdbus_ep_ref(ep);
+	conn->id = atomic64_inc_return(&bus->domain->last_id);
+	conn->flags = hello->flags;
+	atomic64_set(&conn->attach_flags_send, attach_flags_send);
+	atomic64_set(&conn->attach_flags_recv, attach_flags_recv);
+	INIT_LIST_HEAD(&conn->monitor_entry);
+
+	if (conn_description) {
+		conn->description = kstrdup(conn_description, GFP_KERNEL);
+		if (!conn->description) {
+			ret = -ENOMEM;
+			goto exit_unref;
+		}
+	}
+
+	conn->pool = kdbus_pool_new(conn->description, hello->pool_size);
+	if (IS_ERR(conn->pool)) {
+		ret = PTR_ERR(conn->pool);
+		conn->pool = NULL;
+		goto exit_unref;
+	}
+
+	conn->match_db = kdbus_match_db_new();
+	if (IS_ERR(conn->match_db)) {
+		ret = PTR_ERR(conn->match_db);
+		conn->match_db = NULL;
+		goto exit_unref;
+	}
+
+	/* return properties of this connection to the caller */
+	hello->bus_flags = bus->bus_flags;
+	hello->id = conn->id;
+
+	BUILD_BUG_ON(sizeof(bus->id128) != sizeof(hello->id128));
+	memcpy(hello->id128, bus->id128, sizeof(hello->id128));
+
+	/* privileged processes can impersonate somebody else */
+	if (creds || pids || seclabel) {
+		conn->meta_fake = kdbus_meta_fake_new();
+		if (IS_ERR(conn->meta_fake)) {
+			ret = PTR_ERR(conn->meta_fake);
+			conn->meta_fake = NULL;
+			goto exit_unref;
+		}
+
+		ret = kdbus_meta_fake_collect(conn->meta_fake,
+					      creds, pids, seclabel);
+		if (ret < 0)
+			goto exit_unref;
+	} else {
+		conn->meta_proc = kdbus_meta_proc_new();
+		if (IS_ERR(conn->meta_proc)) {
+			ret = PTR_ERR(conn->meta_proc);
+			conn->meta_proc = NULL;
+			goto exit_unref;
+		}
+
+		ret = kdbus_meta_proc_collect(conn->meta_proc,
+					      KDBUS_ATTACH_CREDS |
+					      KDBUS_ATTACH_PIDS |
+					      KDBUS_ATTACH_AUXGROUPS |
+					      KDBUS_ATTACH_TID_COMM |
+					      KDBUS_ATTACH_PID_COMM |
+					      KDBUS_ATTACH_EXE |
+					      KDBUS_ATTACH_CMDLINE |
+					      KDBUS_ATTACH_CGROUP |
+					      KDBUS_ATTACH_CAPS |
+					      KDBUS_ATTACH_SECLABEL |
+					      KDBUS_ATTACH_AUDIT);
+		if (ret < 0)
+			goto exit_unref;
+	}
+
+	/*
+	 * Account the connection against the current user (UID), or for
+	 * custom endpoints use the anonymous user assigned to the endpoint.
+	 * Note that limits are always accounted against the real UID, not
+	 * the effective UID (cred->user always points to the accounting of
+	 * cred->uid, not cred->euid).
+	 * In case the caller is privileged, we allow changing the accounting
+	 * to the faked user.
+	 */
+	if (ep->user) {
+		conn->user = kdbus_user_ref(ep->user);
+	} else {
+		kuid_t uid;
+
+		if (conn->meta_fake && uid_valid(conn->meta_fake->uid) &&
+		    conn->privileged)
+			uid = conn->meta_fake->uid;
+		else
+			uid = conn->cred->uid;
+
+		conn->user = kdbus_user_lookup(ep->bus->domain, uid);
+		if (IS_ERR(conn->user)) {
+			ret = PTR_ERR(conn->user);
+			conn->user = NULL;
+			goto exit_unref;
+		}
+	}
+
+	if (atomic_inc_return(&conn->user->connections) > KDBUS_USER_MAX_CONN) {
+		/* decremented by destructor as conn->user is valid */
+		ret = -EMFILE;
+		goto exit_unref;
+	}
+
+	bloom_item.size = sizeof(bloom_item);
+	bloom_item.type = KDBUS_ITEM_BLOOM_PARAMETER;
+	bloom_item.bloom = bus->bloom;
+	kdbus_kvec_set(&kvec, &bloom_item, bloom_item.size, &items_size);
+
+	slice = kdbus_pool_slice_alloc(conn->pool, items_size, false);
+	if (IS_ERR(slice)) {
+		ret = PTR_ERR(slice);
+		slice = NULL;
+		goto exit_unref;
+	}
+
+	ret = kdbus_pool_slice_copy_kvec(slice, 0, &kvec, 1, items_size);
+	if (ret < 0)
+		goto exit_unref;
+
+	kdbus_pool_slice_publish(slice, &hello->offset, &hello->items_size);
+	kdbus_pool_slice_release(slice);
+
+	return conn;
+
+exit_unref:
+	kdbus_pool_slice_release(slice);
+	kdbus_conn_unref(conn);
+	return ERR_PTR(ret);
+}
+
+static void __kdbus_conn_free(struct kref *kref)
+{
+	struct kdbus_conn *conn = container_of(kref, struct kdbus_conn, kref);
+
+	WARN_ON(kdbus_conn_active(conn));
+	WARN_ON(delayed_work_pending(&conn->work));
+	WARN_ON(!list_empty(&conn->queue.msg_list));
+	WARN_ON(!list_empty(&conn->names_list));
+	WARN_ON(!list_empty(&conn->reply_list));
+
+	if (conn->user) {
+		atomic_dec(&conn->user->connections);
+		kdbus_user_unref(conn->user);
+	}
+
+	kdbus_meta_fake_free(conn->meta_fake);
+	kdbus_meta_proc_unref(conn->meta_proc);
+	kdbus_match_db_free(conn->match_db);
+	kdbus_pool_free(conn->pool);
+	kdbus_ep_unref(conn->ep);
+	path_put(&conn->root_path);
+	put_pid(conn->pid);
+	put_cred(conn->cred);
+	kfree(conn->description);
+	kfree(conn->quota);
+	kfree(conn);
+}
+
+/**
+ * kdbus_conn_ref() - take a connection reference
+ * @conn:		Connection, may be %NULL
+ *
+ * Return: the connection itself
+ */
+struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn)
+{
+	if (conn)
+		kref_get(&conn->kref);
+	return conn;
+}
+
+/**
+ * kdbus_conn_unref() - drop a connection reference
+ * @conn:		Connection (may be NULL)
+ *
+ * When the last reference is dropped, the connection's internal structure
+ * is freed.
+ *
+ * Return: NULL
+ */
+struct kdbus_conn *kdbus_conn_unref(struct kdbus_conn *conn)
+{
+	if (conn)
+		kref_put(&conn->kref, __kdbus_conn_free);
+	return NULL;
+}
+
+/**
+ * kdbus_conn_active() - connection is not disconnected
+ * @conn:		Connection to check
+ *
+ * Return true if the connection was not disconnected, yet. Note that a
+ * connection might be disconnected asynchronously, unless you hold the
+ * connection lock. If that's not suitable for you, see kdbus_conn_acquire() to
+ * suppress connection shutdown for a short period.
+ *
+ * Return: true if the connection is still active
+ */
+bool kdbus_conn_active(const struct kdbus_conn *conn)
+{
+	return atomic_read(&conn->active) >= 0;
+}
+
+/**
+ * kdbus_conn_acquire() - acquire an active connection reference
+ * @conn:		Connection
+ *
+ * Users can close a connection via KDBUS_BYEBYE (or by destroying the
+ * endpoint/bus/...) at any time. Whenever this happens, we should deny any
+ * user-visible action on this connection and signal ECONNRESET instead.
+ * To avoid testing for connection availability everytime you take the
+ * connection-lock, you can acquire a connection for short periods.
+ *
+ * By calling kdbus_conn_acquire(), you gain an "active reference" to the
+ * connection. You must also hold a regular reference at any time! As long as
+ * you hold the active-ref, the connection will not be shut down. However, if
+ * the connection was shut down, you can never acquire an active-ref again.
+ *
+ * kdbus_conn_disconnect() disables the connection and then waits for all active
+ * references to be dropped. It will also wake up any pending operation.
+ * However, you must not sleep for an indefinite period while holding an
+ * active-reference. Otherwise, kdbus_conn_disconnect() might stall. If you need
+ * to sleep for an indefinite period, either release the reference and try to
+ * acquire it again after waking up, or make kdbus_conn_disconnect() wake up
+ * your wait-queue.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_conn_acquire(struct kdbus_conn *conn)
+{
+	if (!atomic_inc_unless_negative(&conn->active))
+		return -ECONNRESET;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	rwsem_acquire_read(&conn->dep_map, 0, 1, _RET_IP_);
+#endif
+
+	return 0;
+}
+
+/**
+ * kdbus_conn_release() - release an active connection reference
+ * @conn:		Connection
+ *
+ * This releases an active reference that has been acquired via
+ * kdbus_conn_acquire(). If the connection was already disabled and this is the
+ * last active-ref that is dropped, the disconnect-waiter will be woken up and
+ * properly close the connection.
+ */
+void kdbus_conn_release(struct kdbus_conn *conn)
+{
+	int v;
+
+	if (!conn)
+		return;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	rwsem_release(&conn->dep_map, 1, _RET_IP_);
+#endif
+
+	v = atomic_dec_return(&conn->active);
+	if (v != KDBUS_CONN_ACTIVE_BIAS)
+		return;
+
+	wake_up_all(&conn->wait);
+}
+
+static int kdbus_conn_connect(struct kdbus_conn *conn, const char *name)
+{
+	struct kdbus_ep *ep = conn->ep;
+	struct kdbus_bus *bus = ep->bus;
+	int ret;
+
+	if (WARN_ON(atomic_read(&conn->active) != KDBUS_CONN_ACTIVE_NEW))
+		return -EALREADY;
+
+	/* make sure the ep-node is active while we add our connection */
+	if (!kdbus_node_acquire(&ep->node))
+		return -ESHUTDOWN;
+
+	/* lock order: domain -> bus -> ep -> names -> conn */
+	mutex_lock(&ep->lock);
+	down_write(&bus->conn_rwlock);
+
+	/* link into monitor list */
+	if (kdbus_conn_is_monitor(conn))
+		list_add_tail(&conn->monitor_entry, &bus->monitors_list);
+
+	/* link into bus and endpoint */
+	list_add_tail(&conn->ep_entry, &ep->conn_list);
+	hash_add(bus->conn_hash, &conn->hentry, conn->id);
+
+	/* enable lookups and acquire active ref */
+	atomic_set(&conn->active, 1);
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	rwsem_acquire_read(&conn->dep_map, 0, 1, _RET_IP_);
+#endif
+
+	up_write(&bus->conn_rwlock);
+	mutex_unlock(&ep->lock);
+
+	kdbus_node_release(&ep->node);
+
+	/*
+	 * Notify subscribers about the new active connection, unless it is
+	 * a monitor. Monitors are invisible on the bus, can't be addressed
+	 * directly, and won't cause any notifications.
+	 */
+	if (!kdbus_conn_is_monitor(conn)) {
+		ret = kdbus_notify_id_change(bus, KDBUS_ITEM_ID_ADD,
+					     conn->id, conn->flags);
+		if (ret < 0)
+			goto exit_disconnect;
+	}
+
+	if (kdbus_conn_is_activator(conn)) {
+		u64 flags = KDBUS_NAME_ACTIVATOR;
+
+		if (WARN_ON(!name)) {
+			ret = -EINVAL;
+			goto exit_disconnect;
+		}
+
+		ret = kdbus_name_acquire(bus->name_registry, conn, name,
+					 flags, NULL);
+		if (ret < 0)
+			goto exit_disconnect;
+	}
+
+	kdbus_conn_release(conn);
+	kdbus_notify_flush(bus);
+	return 0;
+
+exit_disconnect:
+	kdbus_conn_release(conn);
+	kdbus_conn_disconnect(conn, false);
+	return ret;
+}
+
+/**
+ * kdbus_conn_disconnect() - disconnect a connection
+ * @conn:		The connection to disconnect
+ * @ensure_queue_empty:	Flag to indicate if the call should fail in
+ *			case the connection's message list is not
+ *			empty
+ *
+ * If @ensure_msg_list_empty is true, and the connection has pending messages,
+ * -EBUSY is returned.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty)
+{
+	struct kdbus_queue_entry *entry, *tmp;
+	struct kdbus_bus *bus = conn->ep->bus;
+	struct kdbus_reply *r, *r_tmp;
+	struct kdbus_conn *c;
+	int i, v;
+
+	mutex_lock(&conn->lock);
+	v = atomic_read(&conn->active);
+	if (v == KDBUS_CONN_ACTIVE_NEW) {
+		/* was never connected */
+		mutex_unlock(&conn->lock);
+		return 0;
+	}
+	if (v < 0) {
+		/* already dead */
+		mutex_unlock(&conn->lock);
+		return -ECONNRESET;
+	}
+	if (ensure_queue_empty && !list_empty(&conn->queue.msg_list)) {
+		/* still busy */
+		mutex_unlock(&conn->lock);
+		return -EBUSY;
+	}
+
+	atomic_add(KDBUS_CONN_ACTIVE_BIAS, &conn->active);
+	mutex_unlock(&conn->lock);
+
+	wake_up_interruptible(&conn->wait);
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	rwsem_acquire(&conn->dep_map, 0, 0, _RET_IP_);
+	if (atomic_read(&conn->active) != KDBUS_CONN_ACTIVE_BIAS)
+		lock_contended(&conn->dep_map, _RET_IP_);
+#endif
+
+	wait_event(conn->wait,
+		   atomic_read(&conn->active) == KDBUS_CONN_ACTIVE_BIAS);
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	lock_acquired(&conn->dep_map, _RET_IP_);
+	rwsem_release(&conn->dep_map, 1, _RET_IP_);
+#endif
+
+	cancel_delayed_work_sync(&conn->work);
+	kdbus_policy_remove_owner(&conn->ep->bus->policy_db, conn);
+
+	/* lock order: domain -> bus -> ep -> names -> conn */
+	mutex_lock(&conn->ep->lock);
+	down_write(&bus->conn_rwlock);
+
+	/* remove from bus and endpoint */
+	hash_del(&conn->hentry);
+	list_del(&conn->monitor_entry);
+	list_del(&conn->ep_entry);
+
+	up_write(&bus->conn_rwlock);
+	mutex_unlock(&conn->ep->lock);
+
+	/*
+	 * Remove all names associated with this connection; this possibly
+	 * moves queued messages back to the activator connection.
+	 */
+	kdbus_name_release_all(bus->name_registry, conn);
+
+	/* if we die while other connections wait for our reply, notify them */
+	mutex_lock(&conn->lock);
+	list_for_each_entry_safe(entry, tmp, &conn->queue.msg_list, entry) {
+		if (entry->reply)
+			kdbus_notify_reply_dead(bus,
+						entry->reply->reply_dst->id,
+						entry->reply->cookie);
+		kdbus_queue_entry_free(entry);
+	}
+
+	list_for_each_entry_safe(r, r_tmp, &conn->reply_list, entry)
+		kdbus_reply_unlink(r);
+	mutex_unlock(&conn->lock);
+
+	/* lock order: domain -> bus -> ep -> names -> conn */
+	down_read(&bus->conn_rwlock);
+	hash_for_each(bus->conn_hash, i, c, hentry) {
+		mutex_lock(&c->lock);
+		list_for_each_entry_safe(r, r_tmp, &c->reply_list, entry) {
+			if (r->reply_src != conn)
+				continue;
+
+			if (r->sync)
+				kdbus_sync_reply_wakeup(r, -EPIPE);
+			else
+				/* send a 'connection dead' notification */
+				kdbus_notify_reply_dead(bus, c->id, r->cookie);
+
+			kdbus_reply_unlink(r);
+		}
+		mutex_unlock(&c->lock);
+	}
+	up_read(&bus->conn_rwlock);
+
+	if (!kdbus_conn_is_monitor(conn))
+		kdbus_notify_id_change(bus, KDBUS_ITEM_ID_REMOVE,
+				       conn->id, conn->flags);
+
+	kdbus_notify_flush(bus);
+
+	return 0;
+}
+
+/**
+ * kdbus_conn_has_name() - check if a connection owns a name
+ * @conn:		Connection
+ * @name:		Well-know name to check for
+ *
+ * The caller must hold the registry lock of conn->ep->bus.
+ *
+ * Return: true if the name is currently owned by the connection
+ */
+bool kdbus_conn_has_name(struct kdbus_conn *conn, const char *name)
+{
+	struct kdbus_name_owner *owner;
+
+	lockdep_assert_held(&conn->ep->bus->name_registry->rwlock);
+
+	list_for_each_entry(owner, &conn->names_list, conn_entry)
+		if (!(owner->flags & KDBUS_NAME_IN_QUEUE) &&
+		    !strcmp(name, owner->name->name))
+			return true;
+
+	return false;
+}
+
+struct kdbus_quota {
+	u32 memory;
+	u16 msgs;
+	u8 fds;
+};
+
+/**
+ * kdbus_conn_quota_inc() - increase quota accounting
+ * @c:		connection owning the quota tracking
+ * @u:		user to account for (or NULL for kernel accounting)
+ * @memory:	size of memory to account for
+ * @fds:	number of FDs to account for
+ *
+ * This call manages the quotas on resource @c. That is, it's used if other
+ * users want to use the resources of connection @c, which so far only concerns
+ * the receive queue of the destination.
+ *
+ * This increases the quota-accounting for user @u by @memory bytes and @fds
+ * file descriptors. If the user has already reached the quota limits, this call
+ * will not do any accounting but return a negative error code indicating the
+ * failure.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_conn_quota_inc(struct kdbus_conn *c, struct kdbus_user *u,
+			 size_t memory, size_t fds)
+{
+	struct kdbus_quota *quota;
+	size_t available, accounted;
+	unsigned int id;
+
+	/*
+	 * Pool Layout:
+	 * 50% of a pool is always owned by the connection. It is reserved for
+	 * kernel queries, handling received messages and other tasks that are
+	 * under control of the pool owner. The other 50% of the pool are used
+	 * as incoming queue.
+	 * As we optionally support user-space based policies, we need fair
+	 * allocation schemes. Furthermore, resource utilization should be
+	 * maximized, so only minimal resources stay reserved. However, we need
+	 * to adapt to a dynamic number of users, as we cannot know how many
+	 * users will talk to a connection. Therefore, the current allocation
+	 * works like this:
+	 * We limit the number of bytes in a destination's pool per sending
+	 * user. The space available for a user is 33% of the unused pool space
+	 * (whereas the space used by the user itself is also treated as
+	 * 'unused'). This way, we favor users coming first, but keep enough
+	 * pool space available for any following users. Given that messages are
+	 * dequeued in FIFO order, this should balance nicely if the number of
+	 * users grows. At the same time, this algorithm guarantees that the
+	 * space available to a connection is reduced dynamically, the more
+	 * concurrent users talk to a connection.
+	 */
+
+	/* per user-accounting is expensive, so we keep state small */
+	BUILD_BUG_ON(sizeof(quota->memory) != 4);
+	BUILD_BUG_ON(sizeof(quota->msgs) != 2);
+	BUILD_BUG_ON(sizeof(quota->fds) != 1);
+	BUILD_BUG_ON(KDBUS_CONN_MAX_MSGS > U16_MAX);
+	BUILD_BUG_ON(KDBUS_CONN_MAX_FDS_PER_USER > U8_MAX);
+
+	id = u ? u->id : KDBUS_USER_KERNEL_ID;
+	if (id >= c->n_quota) {
+		unsigned int users;
+
+		users = max(KDBUS_ALIGN8(id) + 8, id);
+		quota = krealloc(c->quota, users * sizeof(*quota),
+				 GFP_KERNEL | __GFP_ZERO);
+		if (!quota)
+			return -ENOMEM;
+
+		c->n_quota = users;
+		c->quota = quota;
+	}
+
+	quota = &c->quota[id];
+	kdbus_pool_accounted(c->pool, &available, &accounted);
+
+	/* half the pool is _always_ reserved for the pool owner */
+	available /= 2;
+
+	/*
+	 * Pool owner slices are un-accounted slices; they can claim more
+	 * than 50% of the queue. However, the slices we're dealing with here
+	 * belong to the incoming queue, hence they are 'accounted' slices
+	 * to which the 50%-limit applies.
+	 */
+	if (available < accounted)
+		return -ENOBUFS;
+
+	/* 1/3 of the remaining space (including your own memory) */
+	available = (available - accounted + quota->memory) / 3;
+
+	if (available < quota->memory ||
+	    available - quota->memory < memory ||
+	    quota->memory + memory > U32_MAX)
+		return -ENOBUFS;
+	if (quota->msgs >= KDBUS_CONN_MAX_MSGS)
+		return -ENOBUFS;
+	if (quota->fds + fds < quota->fds ||
+	    quota->fds + fds > KDBUS_CONN_MAX_FDS_PER_USER)
+		return -EMFILE;
+
+	quota->memory += memory;
+	quota->fds += fds;
+	++quota->msgs;
+	return 0;
+}
+
+/**
+ * kdbus_conn_quota_dec() - decrease quota accounting
+ * @c:		connection owning the quota tracking
+ * @u:		user which was accounted for (or NULL for kernel accounting)
+ * @memory:	size of memory which was accounted for
+ * @fds:	number of FDs which were accounted for
+ *
+ * This does the reverse of kdbus_conn_quota_inc(). You have to release any
+ * accounted resources that you called kdbus_conn_quota_inc() for. However, you
+ * must not call kdbus_conn_quota_dec() if the accounting failed (that is,
+ * kdbus_conn_quota_inc() failed).
+ */
+void kdbus_conn_quota_dec(struct kdbus_conn *c, struct kdbus_user *u,
+			  size_t memory, size_t fds)
+{
+	struct kdbus_quota *quota;
+	unsigned int id;
+
+	id = u ? u->id : KDBUS_USER_KERNEL_ID;
+	if (WARN_ON(id >= c->n_quota))
+		return;
+
+	quota = &c->quota[id];
+
+	if (!WARN_ON(quota->msgs == 0))
+		--quota->msgs;
+	if (!WARN_ON(quota->memory < memory))
+		quota->memory -= memory;
+	if (!WARN_ON(quota->fds < fds))
+		quota->fds -= fds;
+}
+
+/**
+ * kdbus_conn_lost_message() - handle lost messages
+ * @c:		connection that lost a message
+ *
+ * kdbus is reliable. That means, we try hard to never lose messages. However,
+ * memory is limited, so we cannot rely on transmissions to never fail.
+ * Therefore, we use quota-limits to let callers know if their unicast message
+ * cannot be transmitted to a peer. This works fine for unicasts, but for
+ * broadcasts we cannot make the caller handle the transmission failure.
+ * Instead, we must let the destination know that it couldn't receive a
+ * broadcast.
+ * As this is an unlikely scenario, we keep it simple. A single lost-counter
+ * remembers the number of lost messages since the last call to RECV. The next
+ * message retrieval will notify the connection that it lost messages since the
+ * last message retrieval and thus should resync its state.
+ */
+void kdbus_conn_lost_message(struct kdbus_conn *c)
+{
+	if (atomic_inc_return(&c->lost_count) == 1)
+		wake_up_interruptible(&c->wait);
+}
+
+/* Callers should take the conn_dst lock */
+static struct kdbus_queue_entry *
+kdbus_conn_entry_make(struct kdbus_conn *conn_src,
+		      struct kdbus_conn *conn_dst,
+		      struct kdbus_staging *staging)
+{
+	/* The remote connection was disconnected */
+	if (!kdbus_conn_active(conn_dst))
+		return ERR_PTR(-ECONNRESET);
+
+	/*
+	 * If the connection does not accept file descriptors but the message
+	 * has some attached, refuse it.
+	 *
+	 * If this is a monitor connection, accept the message. In that
+	 * case, all file descriptors will be set to -1 at receive time.
+	 */
+	if (!kdbus_conn_is_monitor(conn_dst) &&
+	    !(conn_dst->flags & KDBUS_HELLO_ACCEPT_FD) &&
+	    staging->gaps && staging->gaps->n_fds > 0)
+		return ERR_PTR(-ECOMM);
+
+	return kdbus_queue_entry_new(conn_src, conn_dst, staging);
+}
+
+/*
+ * Synchronously responding to a message, allocate a queue entry
+ * and attach it to the reply tracking object.
+ * The connection's queue will never get to see it.
+ */
+static int kdbus_conn_entry_sync_attach(struct kdbus_conn *conn_dst,
+					struct kdbus_staging *staging,
+					struct kdbus_reply *reply_wake)
+{
+	struct kdbus_queue_entry *entry;
+	int remote_ret, ret = 0;
+
+	mutex_lock(&reply_wake->reply_dst->lock);
+
+	/*
+	 * If we are still waiting then proceed, allocate a queue
+	 * entry and attach it to the reply object
+	 */
+	if (reply_wake->waiting) {
+		entry = kdbus_conn_entry_make(reply_wake->reply_src, conn_dst,
+					      staging);
+		if (IS_ERR(entry))
+			ret = PTR_ERR(entry);
+		else
+			/* Attach the entry to the reply object */
+			reply_wake->queue_entry = entry;
+	} else {
+		ret = -ECONNRESET;
+	}
+
+	/*
+	 * Update the reply object and wake up remote peer only
+	 * on appropriate return codes
+	 *
+	 * * -ECOMM: if the replying connection failed with -ECOMM
+	 *           then wakeup remote peer with -EREMOTEIO
+	 *
+	 *           We do this to differenciate between -ECOMM errors
+	 *           from the original sender perspective:
+	 *           -ECOMM error during the sync send and
+	 *           -ECOMM error during the sync reply, this last
+	 *           one is rewritten to -EREMOTEIO
+	 *
+	 * * Wake up on all other return codes.
+	 */
+	remote_ret = ret;
+
+	if (ret == -ECOMM)
+		remote_ret = -EREMOTEIO;
+
+	kdbus_sync_reply_wakeup(reply_wake, remote_ret);
+	kdbus_reply_unlink(reply_wake);
+	mutex_unlock(&reply_wake->reply_dst->lock);
+
+	return ret;
+}
+
+/**
+ * kdbus_conn_entry_insert() - enqueue a message into the receiver's pool
+ * @conn_src:		The sending connection
+ * @conn_dst:		The connection to queue into
+ * @staging:		Message to send
+ * @reply:		The reply tracker to attach to the queue entry
+ * @name:		Destination name this msg is sent to, or NULL
+ *
+ * Return: 0 on success. negative error otherwise.
+ */
+int kdbus_conn_entry_insert(struct kdbus_conn *conn_src,
+			    struct kdbus_conn *conn_dst,
+			    struct kdbus_staging *staging,
+			    struct kdbus_reply *reply,
+			    const struct kdbus_name_entry *name)
+{
+	struct kdbus_queue_entry *entry;
+	int ret;
+
+	kdbus_conn_lock2(conn_src, conn_dst);
+
+	entry = kdbus_conn_entry_make(conn_src, conn_dst, staging);
+	if (IS_ERR(entry)) {
+		ret = PTR_ERR(entry);
+		goto exit_unlock;
+	}
+
+	if (reply) {
+		kdbus_reply_link(reply);
+		if (!reply->sync)
+			schedule_delayed_work(&conn_src->work, 0);
+	}
+
+	/*
+	 * Record the sequence number of the registered name; it will
+	 * be remembered by the queue, in case messages addressed to a
+	 * name need to be moved from or to an activator.
+	 */
+	if (name)
+		entry->dst_name_id = name->name_id;
+
+	kdbus_queue_entry_enqueue(entry, reply);
+	wake_up_interruptible(&conn_dst->wait);
+
+	ret = 0;
+
+exit_unlock:
+	kdbus_conn_unlock2(conn_src, conn_dst);
+	return ret;
+}
+
+static int kdbus_conn_wait_reply(struct kdbus_conn *conn_src,
+				 struct kdbus_cmd_send *cmd_send,
+				 struct file *ioctl_file,
+				 struct file *cancel_fd,
+				 struct kdbus_reply *reply_wait,
+				 ktime_t expire)
+{
+	struct kdbus_queue_entry *entry;
+	struct poll_wqueues pwq = {};
+	int ret;
+
+	if (WARN_ON(!reply_wait))
+		return -EIO;
+
+	/*
+	 * Block until the reply arrives. reply_wait is left untouched
+	 * by the timeout scans that might be conducted for other,
+	 * asynchronous replies of conn_src.
+	 */
+
+	poll_initwait(&pwq);
+	poll_wait(ioctl_file, &conn_src->wait, &pwq.pt);
+
+	for (;;) {
+		/*
+		 * Any of the following conditions will stop our synchronously
+		 * blocking SEND command:
+		 *
+		 * a) The origin sender closed its connection
+		 * b) The remote peer answered, setting reply_wait->waiting = 0
+		 * c) The cancel FD was written to
+		 * d) A signal was received
+		 * e) The specified timeout was reached, and none of the above
+		 *    conditions kicked in.
+		 */
+
+		/*
+		 * We have already acquired an active reference when
+		 * entering here, but another thread may call
+		 * KDBUS_CMD_BYEBYE which does not acquire an active
+		 * reference, therefore kdbus_conn_disconnect() will
+		 * not wait for us.
+		 */
+		if (!kdbus_conn_active(conn_src)) {
+			ret = -ECONNRESET;
+			break;
+		}
+
+		/*
+		 * After the replying peer unset the waiting variable
+		 * it will wake up us.
+		 */
+		if (!reply_wait->waiting) {
+			ret = reply_wait->err;
+			break;
+		}
+
+		if (cancel_fd) {
+			unsigned int r;
+
+			r = cancel_fd->f_op->poll(cancel_fd, &pwq.pt);
+			if (r & POLLIN) {
+				ret = -ECANCELED;
+				break;
+			}
+		}
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
+		if (!poll_schedule_timeout(&pwq, TASK_INTERRUPTIBLE,
+					   &expire, 0)) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		/*
+		 * Reset the poll worker func, so the waitqueues are not
+		 * added to the poll table again. We just reuse what we've
+		 * collected earlier for further iterations.
+		 */
+		init_poll_funcptr(&pwq.pt, NULL);
+	}
+
+	poll_freewait(&pwq);
+
+	if (ret == -EINTR) {
+		/*
+		 * Interrupted system call. Unref the reply object, and pass
+		 * the return value down the chain. Mark the reply as
+		 * interrupted, so the cleanup work can remove it, but do not
+		 * unlink it from the list. Once the syscall restarts, we'll
+		 * pick it up and wait on it again.
+		 */
+		mutex_lock(&conn_src->lock);
+		reply_wait->interrupted = true;
+		schedule_delayed_work(&conn_src->work, 0);
+		mutex_unlock(&conn_src->lock);
+
+		return -ERESTARTSYS;
+	}
+
+	mutex_lock(&conn_src->lock);
+	reply_wait->waiting = false;
+	entry = reply_wait->queue_entry;
+	if (entry) {
+		ret = kdbus_queue_entry_install(entry,
+						&cmd_send->reply.return_flags,
+						true);
+		kdbus_pool_slice_publish(entry->slice, &cmd_send->reply.offset,
+					 &cmd_send->reply.msg_size);
+		kdbus_queue_entry_free(entry);
+	}
+	kdbus_reply_unlink(reply_wait);
+	mutex_unlock(&conn_src->lock);
+
+	return ret;
+}
+
+static int kdbus_pin_dst(struct kdbus_bus *bus,
+			 struct kdbus_staging *staging,
+			 struct kdbus_name_entry **out_name,
+			 struct kdbus_conn **out_dst)
+{
+	const struct kdbus_msg *msg = staging->msg;
+	struct kdbus_name_owner *owner = NULL;
+	struct kdbus_name_entry *name = NULL;
+	struct kdbus_conn *dst = NULL;
+	int ret;
+
+	lockdep_assert_held(&bus->name_registry->rwlock);
+
+	if (!staging->dst_name) {
+		dst = kdbus_bus_find_conn_by_id(bus, msg->dst_id);
+		if (!dst)
+			return -ENXIO;
+
+		if (!kdbus_conn_is_ordinary(dst)) {
+			ret = -ENXIO;
+			goto error;
+		}
+	} else {
+		name = kdbus_name_lookup_unlocked(bus->name_registry,
+						  staging->dst_name);
+		if (name)
+			owner = kdbus_name_get_owner(name);
+		if (!owner)
+			return -ESRCH;
+
+		/*
+		 * If both a name and a connection ID are given as destination
+		 * of a message, check that the currently owning connection of
+		 * the name matches the specified ID.
+		 * This way, we allow userspace to send the message to a
+		 * specific connection by ID only if the connection currently
+		 * owns the given name.
+		 */
+		if (msg->dst_id != KDBUS_DST_ID_NAME &&
+		    msg->dst_id != owner->conn->id)
+			return -EREMCHG;
+
+		if ((msg->flags & KDBUS_MSG_NO_AUTO_START) &&
+		    kdbus_conn_is_activator(owner->conn))
+			return -EADDRNOTAVAIL;
+
+		dst = kdbus_conn_ref(owner->conn);
+	}
+
+	*out_name = name;
+	*out_dst = dst;
+	return 0;
+
+error:
+	kdbus_conn_unref(dst);
+	return ret;
+}
+
+static int kdbus_conn_reply(struct kdbus_conn *src,
+			    struct kdbus_staging *staging)
+{
+	const struct kdbus_msg *msg = staging->msg;
+	struct kdbus_name_entry *name = NULL;
+	struct kdbus_reply *reply, *wake = NULL;
+	struct kdbus_conn *dst = NULL;
+	struct kdbus_bus *bus = src->ep->bus;
+	int ret;
+
+	if (WARN_ON(msg->dst_id == KDBUS_DST_ID_BROADCAST) ||
+	    WARN_ON(msg->flags & KDBUS_MSG_EXPECT_REPLY) ||
+	    WARN_ON(msg->flags & KDBUS_MSG_SIGNAL))
+		return -EINVAL;
+
+	/* name-registry must be locked for lookup *and* collecting data */
+	down_read(&bus->name_registry->rwlock);
+
+	/* find and pin destination */
+
+	ret = kdbus_pin_dst(bus, staging, &name, &dst);
+	if (ret < 0)
+		goto exit;
+
+	mutex_lock(&dst->lock);
+	reply = kdbus_reply_find(src, dst, msg->cookie_reply);
+	if (reply) {
+		if (reply->sync)
+			wake = kdbus_reply_ref(reply);
+		kdbus_reply_unlink(reply);
+	}
+	mutex_unlock(&dst->lock);
+
+	if (!reply) {
+		ret = -EBADSLT;
+		goto exit;
+	}
+
+	/* send message */
+
+	kdbus_bus_eavesdrop(bus, src, staging);
+
+	if (wake)
+		ret = kdbus_conn_entry_sync_attach(dst, staging, wake);
+	else
+		ret = kdbus_conn_entry_insert(src, dst, staging, NULL, name);
+
+exit:
+	up_read(&bus->name_registry->rwlock);
+	kdbus_reply_unref(wake);
+	kdbus_conn_unref(dst);
+	return ret;
+}
+
+static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
+					   struct kdbus_staging *staging,
+					   ktime_t exp)
+{
+	const struct kdbus_msg *msg = staging->msg;
+	struct kdbus_name_entry *name = NULL;
+	struct kdbus_reply *wait = NULL;
+	struct kdbus_conn *dst = NULL;
+	struct kdbus_bus *bus = src->ep->bus;
+	int ret;
+
+	if (WARN_ON(msg->dst_id == KDBUS_DST_ID_BROADCAST) ||
+	    WARN_ON(msg->flags & KDBUS_MSG_SIGNAL) ||
+	    WARN_ON(!(msg->flags & KDBUS_MSG_EXPECT_REPLY)))
+		return ERR_PTR(-EINVAL);
+
+	/* resume previous wait-context, if available */
+
+	mutex_lock(&src->lock);
+	wait = kdbus_reply_find(NULL, src, msg->cookie);
+	if (wait) {
+		if (wait->interrupted) {
+			kdbus_reply_ref(wait);
+			wait->interrupted = false;
+		} else {
+			wait = NULL;
+		}
+	}
+	mutex_unlock(&src->lock);
+
+	if (wait)
+		return wait;
+
+	if (ktime_compare(ktime_get(), exp) >= 0)
+		return ERR_PTR(-ETIMEDOUT);
+
+	/* name-registry must be locked for lookup *and* collecting data */
+	down_read(&bus->name_registry->rwlock);
+
+	/* find and pin destination */
+
+	ret = kdbus_pin_dst(bus, staging, &name, &dst);
+	if (ret < 0)
+		goto exit;
+
+	if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
+		ret = -EPERM;
+		goto exit;
+	}
+
+	wait = kdbus_reply_new(dst, src, msg, name, true);
+	if (IS_ERR(wait)) {
+		ret = PTR_ERR(wait);
+		wait = NULL;
+		goto exit;
+	}
+
+	/* send message */
+
+	kdbus_bus_eavesdrop(bus, src, staging);
+
+	ret = kdbus_conn_entry_insert(src, dst, staging, wait, name);
+	if (ret < 0)
+		goto exit;
+
+	ret = 0;
+
+exit:
+	up_read(&bus->name_registry->rwlock);
+	if (ret < 0) {
+		kdbus_reply_unref(wait);
+		wait = ERR_PTR(ret);
+	}
+	kdbus_conn_unref(dst);
+	return wait;
+}
+
+static int kdbus_conn_unicast(struct kdbus_conn *src,
+			      struct kdbus_staging *staging)
+{
+	const struct kdbus_msg *msg = staging->msg;
+	struct kdbus_name_entry *name = NULL;
+	struct kdbus_reply *wait = NULL;
+	struct kdbus_conn *dst = NULL;
+	struct kdbus_bus *bus = src->ep->bus;
+	bool is_signal = (msg->flags & KDBUS_MSG_SIGNAL);
+	int ret = 0;
+
+	if (WARN_ON(msg->dst_id == KDBUS_DST_ID_BROADCAST) ||
+	    WARN_ON(!(msg->flags & KDBUS_MSG_EXPECT_REPLY) &&
+		    msg->cookie_reply != 0))
+		return -EINVAL;
+
+	/* name-registry must be locked for lookup *and* collecting data */
+	down_read(&bus->name_registry->rwlock);
+
+	/* find and pin destination */
+
+	ret = kdbus_pin_dst(bus, staging, &name, &dst);
+	if (ret < 0)
+		goto exit;
+
+	if (is_signal) {
+		/* like broadcasts we eavesdrop even if the msg is dropped */
+		kdbus_bus_eavesdrop(bus, src, staging);
+
+		/* drop silently if peer is not interested or not privileged */
+		if (!kdbus_match_db_match_msg(dst->match_db, src, staging) ||
+		    !kdbus_conn_policy_talk(dst, NULL, src))
+			goto exit;
+	} else if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
+		ret = -EPERM;
+		goto exit;
+	} else if (msg->flags & KDBUS_MSG_EXPECT_REPLY) {
+		wait = kdbus_reply_new(dst, src, msg, name, false);
+		if (IS_ERR(wait)) {
+			ret = PTR_ERR(wait);
+			wait = NULL;
+			goto exit;
+		}
+	}
+
+	/* send message */
+
+	if (!is_signal)
+		kdbus_bus_eavesdrop(bus, src, staging);
+
+	ret = kdbus_conn_entry_insert(src, dst, staging, wait, name);
+	if (ret < 0 && !is_signal)
+		goto exit;
+
+	/* signals are treated like broadcasts, recv-errors are ignored */
+	ret = 0;
+
+exit:
+	up_read(&bus->name_registry->rwlock);
+	kdbus_reply_unref(wait);
+	kdbus_conn_unref(dst);
+	return ret;
+}
+
+/**
+ * kdbus_conn_move_messages() - move messages from one connection to another
+ * @conn_dst:		Connection to copy to
+ * @conn_src:		Connection to copy from
+ * @name_id:		Filter for the sequence number of the registered
+ *			name, 0 means no filtering.
+ *
+ * Move all messages from one connection to another. This is used when
+ * an implementer connection is taking over/giving back a well-known name
+ * from/to an activator connection.
+ */
+void kdbus_conn_move_messages(struct kdbus_conn *conn_dst,
+			      struct kdbus_conn *conn_src,
+			      u64 name_id)
+{
+	struct kdbus_queue_entry *e, *e_tmp;
+	struct kdbus_reply *r, *r_tmp;
+	struct kdbus_bus *bus;
+	struct kdbus_conn *c;
+	LIST_HEAD(msg_list);
+	int i, ret = 0;
+
+	if (WARN_ON(conn_src == conn_dst))
+		return;
+
+	bus = conn_src->ep->bus;
+
+	/* lock order: domain -> bus -> ep -> names -> conn */
+	down_read(&bus->conn_rwlock);
+	hash_for_each(bus->conn_hash, i, c, hentry) {
+		if (c == conn_src || c == conn_dst)
+			continue;
+
+		mutex_lock(&c->lock);
+		list_for_each_entry_safe(r, r_tmp, &c->reply_list, entry) {
+			if (r->reply_src != conn_src)
+				continue;
+
+			/* filter messages for a specific name */
+			if (name_id > 0 && r->name_id != name_id)
+				continue;
+
+			kdbus_conn_unref(r->reply_src);
+			r->reply_src = kdbus_conn_ref(conn_dst);
+		}
+		mutex_unlock(&c->lock);
+	}
+	up_read(&bus->conn_rwlock);
+
+	kdbus_conn_lock2(conn_src, conn_dst);
+	list_for_each_entry_safe(e, e_tmp, &conn_src->queue.msg_list, entry) {
+		/* filter messages for a specific name */
+		if (name_id > 0 && e->dst_name_id != name_id)
+			continue;
+
+		if (!(conn_dst->flags & KDBUS_HELLO_ACCEPT_FD) &&
+		    e->gaps && e->gaps->n_fds > 0) {
+			kdbus_conn_lost_message(conn_dst);
+			kdbus_queue_entry_free(e);
+			continue;
+		}
+
+		ret = kdbus_queue_entry_move(e, conn_dst);
+		if (ret < 0) {
+			kdbus_conn_lost_message(conn_dst);
+			kdbus_queue_entry_free(e);
+			continue;
+		}
+	}
+	kdbus_conn_unlock2(conn_src, conn_dst);
+
+	/* wake up poll() */
+	wake_up_interruptible(&conn_dst->wait);
+}
+
+/* query the policy-database for all names of @whom */
+static bool kdbus_conn_policy_query_all(struct kdbus_conn *conn,
+					const struct cred *conn_creds,
+					struct kdbus_policy_db *db,
+					struct kdbus_conn *whom,
+					unsigned int access)
+{
+	struct kdbus_name_owner *owner;
+	bool pass = false;
+	int res;
+
+	lockdep_assert_held(&conn->ep->bus->name_registry->rwlock);
+
+	down_read(&db->entries_rwlock);
+	mutex_lock(&whom->lock);
+
+	list_for_each_entry(owner, &whom->names_list, conn_entry) {
+		if (owner->flags & KDBUS_NAME_IN_QUEUE)
+			continue;
+
+		res = kdbus_policy_query_unlocked(db,
+					conn_creds ? : conn->cred,
+					owner->name->name,
+					kdbus_strhash(owner->name->name));
+		if (res >= (int)access) {
+			pass = true;
+			break;
+		}
+	}
+
+	mutex_unlock(&whom->lock);
+	up_read(&db->entries_rwlock);
+
+	return pass;
+}
+
+/**
+ * kdbus_conn_policy_own_name() - verify a connection can own the given name
+ * @conn:		Connection
+ * @conn_creds:		Credentials of @conn to use for policy check
+ * @name:		Name
+ *
+ * This verifies that @conn is allowed to acquire the well-known name @name.
+ *
+ * Return: true if allowed, false if not.
+ */
+bool kdbus_conn_policy_own_name(struct kdbus_conn *conn,
+				const struct cred *conn_creds,
+				const char *name)
+{
+	unsigned int hash = kdbus_strhash(name);
+	int res;
+
+	if (!conn_creds)
+		conn_creds = conn->cred;
+
+	if (conn->ep->user) {
+		res = kdbus_policy_query(&conn->ep->policy_db, conn_creds,
+					 name, hash);
+		if (res < KDBUS_POLICY_OWN)
+			return false;
+	}
+
+	if (conn->owner)
+		return true;
+
+	res = kdbus_policy_query(&conn->ep->bus->policy_db, conn_creds,
+				 name, hash);
+	return res >= KDBUS_POLICY_OWN;
+}
+
+/**
+ * kdbus_conn_policy_talk() - verify a connection can talk to a given peer
+ * @conn:		Connection that tries to talk
+ * @conn_creds:		Credentials of @conn to use for policy check
+ * @to:			Connection that is talked to
+ *
+ * This verifies that @conn is allowed to talk to @to.
+ *
+ * Return: true if allowed, false if not.
+ */
+bool kdbus_conn_policy_talk(struct kdbus_conn *conn,
+			    const struct cred *conn_creds,
+			    struct kdbus_conn *to)
+{
+	if (!conn_creds)
+		conn_creds = conn->cred;
+
+	if (conn->ep->user &&
+	    !kdbus_conn_policy_query_all(conn, conn_creds, &conn->ep->policy_db,
+					 to, KDBUS_POLICY_TALK))
+		return false;
+
+	if (conn->owner)
+		return true;
+	if (uid_eq(conn_creds->euid, to->cred->uid))
+		return true;
+
+	return kdbus_conn_policy_query_all(conn, conn_creds,
+					   &conn->ep->bus->policy_db, to,
+					   KDBUS_POLICY_TALK);
+}
+
+/**
+ * kdbus_conn_policy_see_name_unlocked() - verify a connection can see a given
+ *					   name
+ * @conn:		Connection
+ * @conn_creds:		Credentials of @conn to use for policy check
+ * @name:		Name
+ *
+ * This verifies that @conn is allowed to see the well-known name @name. Caller
+ * must hold policy-lock.
+ *
+ * Return: true if allowed, false if not.
+ */
+bool kdbus_conn_policy_see_name_unlocked(struct kdbus_conn *conn,
+					 const struct cred *conn_creds,
+					 const char *name)
+{
+	int res;
+
+	/*
+	 * By default, all names are visible on a bus. SEE policies can only be
+	 * installed on custom endpoints, where by default no name is visible.
+	 */
+	if (!conn->ep->user)
+		return true;
+
+	res = kdbus_policy_query_unlocked(&conn->ep->policy_db,
+					  conn_creds ? : conn->cred,
+					  name, kdbus_strhash(name));
+	return res >= KDBUS_POLICY_SEE;
+}
+
+static bool kdbus_conn_policy_see_name(struct kdbus_conn *conn,
+				       const struct cred *conn_creds,
+				       const char *name)
+{
+	bool res;
+
+	down_read(&conn->ep->policy_db.entries_rwlock);
+	res = kdbus_conn_policy_see_name_unlocked(conn, conn_creds, name);
+	up_read(&conn->ep->policy_db.entries_rwlock);
+
+	return res;
+}
+
+static bool kdbus_conn_policy_see(struct kdbus_conn *conn,
+				  const struct cred *conn_creds,
+				  struct kdbus_conn *whom)
+{
+	/*
+	 * By default, all names are visible on a bus, so a connection can
+	 * always see other connections. SEE policies can only be installed on
+	 * custom endpoints, where by default no name is visible and we hide
+	 * peers from each other, unless you see at least _one_ name of the
+	 * peer.
+	 */
+	return !conn->ep->user ||
+	       kdbus_conn_policy_query_all(conn, conn_creds,
+					   &conn->ep->policy_db, whom,
+					   KDBUS_POLICY_SEE);
+}
+
+/**
+ * kdbus_conn_policy_see_notification() - verify a connection is allowed to
+ *					  receive a given kernel notification
+ * @conn:		Connection
+ * @conn_creds:		Credentials of @conn to use for policy check
+ * @msg:		Notification message
+ *
+ * This checks whether @conn is allowed to see the kernel notification.
+ *
+ * Return: true if allowed, false if not.
+ */
+bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
+					const struct cred *conn_creds,
+					const struct kdbus_msg *msg)
+{
+	/*
+	 * Depending on the notification type, broadcasted kernel notifications
+	 * have to be filtered:
+	 *
+	 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}: This notification is forwarded
+	 *     to a peer if, and only if, that peer can see the name this
+	 *     notification is for.
+	 *
+	 * KDBUS_ITEM_ID_{ADD,REMOVE}: Notifications for ID changes are
+	 *     broadcast to everyone, to allow tracking peers.
+	 */
+
+	switch (msg->items[0].type) {
+	case KDBUS_ITEM_NAME_ADD:
+	case KDBUS_ITEM_NAME_REMOVE:
+	case KDBUS_ITEM_NAME_CHANGE:
+		return kdbus_conn_policy_see_name(conn, conn_creds,
+					msg->items[0].name_change.name);
+
+	case KDBUS_ITEM_ID_ADD:
+	case KDBUS_ITEM_ID_REMOVE:
+		return true;
+
+	default:
+		WARN(1, "Invalid type for notification broadcast: %llu\n",
+		     (unsigned long long)msg->items[0].type);
+		return false;
+	}
+}
+
+/**
+ * kdbus_cmd_hello() - handle KDBUS_CMD_HELLO
+ * @ep:			Endpoint to operate on
+ * @file:		File this connection is opened on
+ * @argp:		Command payload
+ *
+ * Return: NULL or newly created connection on success, ERR_PTR on failure.
+ */
+struct kdbus_conn *kdbus_cmd_hello(struct kdbus_ep *ep, struct file *file,
+				   void __user *argp)
+{
+	struct kdbus_cmd_hello *cmd;
+	struct kdbus_conn *c = NULL;
+	const char *item_name;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_NAME },
+		{ .type = KDBUS_ITEM_CREDS },
+		{ .type = KDBUS_ITEM_PIDS },
+		{ .type = KDBUS_ITEM_SECLABEL },
+		{ .type = KDBUS_ITEM_CONN_DESCRIPTION },
+		{ .type = KDBUS_ITEM_POLICY_ACCESS, .multiple = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_HELLO_ACCEPT_FD |
+				 KDBUS_HELLO_ACTIVATOR |
+				 KDBUS_HELLO_POLICY_HOLDER |
+				 KDBUS_HELLO_MONITOR,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret > 0)
+		return NULL;
+
+	item_name = argv[1].item ? argv[1].item->str : NULL;
+
+	c = kdbus_conn_new(ep, file, cmd, item_name,
+			   argv[2].item ? &argv[2].item->creds : NULL,
+			   argv[3].item ? &argv[3].item->pids : NULL,
+			   argv[4].item ? argv[4].item->str : NULL,
+			   argv[5].item ? argv[5].item->str : NULL);
+	if (IS_ERR(c)) {
+		ret = PTR_ERR(c);
+		c = NULL;
+		goto exit;
+	}
+
+	ret = kdbus_conn_connect(c, item_name);
+	if (ret < 0)
+		goto exit;
+
+	if (kdbus_conn_is_activator(c) || kdbus_conn_is_policy_holder(c)) {
+		ret = kdbus_conn_acquire(c);
+		if (ret < 0)
+			goto exit;
+
+		ret = kdbus_policy_set(&c->ep->bus->policy_db, args.items,
+				       args.items_size, 1,
+				       kdbus_conn_is_policy_holder(c), c);
+		kdbus_conn_release(c);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (copy_to_user(argp, cmd, sizeof(*cmd)))
+		ret = -EFAULT;
+
+exit:
+	ret = kdbus_args_clear(&args, ret);
+	if (ret < 0) {
+		if (c) {
+			kdbus_conn_disconnect(c, false);
+			kdbus_conn_unref(c);
+		}
+		return ERR_PTR(ret);
+	}
+	return c;
+}
+
+/**
+ * kdbus_cmd_byebye_unlocked() - handle KDBUS_CMD_BYEBYE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * The caller must not hold any active reference to @conn or this will deadlock.
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_byebye_unlocked(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_cmd *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	ret = kdbus_conn_disconnect(conn, true);
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_conn_info() - handle KDBUS_CMD_CONN_INFO
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_conn_info(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_meta_conn *conn_meta = NULL;
+	struct kdbus_pool_slice *slice = NULL;
+	struct kdbus_name_entry *entry = NULL;
+	struct kdbus_name_owner *owner = NULL;
+	struct kdbus_conn *owner_conn = NULL;
+	struct kdbus_item *meta_items = NULL;
+	struct kdbus_info info = {};
+	struct kdbus_cmd_info *cmd;
+	struct kdbus_bus *bus = conn->ep->bus;
+	struct kvec kvec[3];
+	size_t meta_size, cnt = 0;
+	const char *name;
+	u64 attach_flags, size = 0;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_NAME },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	/* registry must be held throughout lookup *and* collecting data */
+	down_read(&bus->name_registry->rwlock);
+
+	ret = kdbus_sanitize_attach_flags(cmd->attach_flags, &attach_flags);
+	if (ret < 0)
+		goto exit;
+
+	name = argv[1].item ? argv[1].item->str : NULL;
+
+	if (name) {
+		entry = kdbus_name_lookup_unlocked(bus->name_registry, name);
+		if (entry)
+			owner = kdbus_name_get_owner(entry);
+		if (!owner ||
+		    !kdbus_conn_policy_see_name(conn, current_cred(), name) ||
+		    (cmd->id != 0 && owner->conn->id != cmd->id)) {
+			/* pretend a name doesn't exist if you cannot see it */
+			ret = -ESRCH;
+			goto exit;
+		}
+
+		owner_conn = kdbus_conn_ref(owner->conn);
+	} else if (cmd->id > 0) {
+		owner_conn = kdbus_bus_find_conn_by_id(bus, cmd->id);
+		if (!owner_conn || !kdbus_conn_policy_see(conn, current_cred(),
+							  owner_conn)) {
+			/* pretend an id doesn't exist if you cannot see it */
+			ret = -ENXIO;
+			goto exit;
+		}
+	} else {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	attach_flags &= atomic64_read(&owner_conn->attach_flags_send);
+
+	conn_meta = kdbus_meta_conn_new();
+	if (IS_ERR(conn_meta)) {
+		ret = PTR_ERR(conn_meta);
+		conn_meta = NULL;
+		goto exit;
+	}
+
+	ret = kdbus_meta_conn_collect(conn_meta, owner_conn, 0, attach_flags);
+	if (ret < 0)
+		goto exit;
+
+	ret = kdbus_meta_emit(owner_conn->meta_proc, owner_conn->meta_fake,
+			      conn_meta, conn, attach_flags,
+			      &meta_items, &meta_size);
+	if (ret < 0)
+		goto exit;
+
+	info.id = owner_conn->id;
+	info.flags = owner_conn->flags;
+
+	kdbus_kvec_set(&kvec[cnt++], &info, sizeof(info), &size);
+	if (meta_size > 0) {
+		kdbus_kvec_set(&kvec[cnt++], meta_items, meta_size, &size);
+		cnt += !!kdbus_kvec_pad(&kvec[cnt], &size);
+	}
+
+	info.size = size;
+
+	slice = kdbus_pool_slice_alloc(conn->pool, size, false);
+	if (IS_ERR(slice)) {
+		ret = PTR_ERR(slice);
+		slice = NULL;
+		goto exit;
+	}
+
+	ret = kdbus_pool_slice_copy_kvec(slice, 0, kvec, cnt, size);
+	if (ret < 0)
+		goto exit;
+
+	kdbus_pool_slice_publish(slice, &cmd->offset, &cmd->info_size);
+
+	if (kdbus_member_set_user(&cmd->offset, argp, typeof(*cmd), offset) ||
+	    kdbus_member_set_user(&cmd->info_size, argp,
+				  typeof(*cmd), info_size)) {
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	ret = 0;
+
+exit:
+	up_read(&bus->name_registry->rwlock);
+	kdbus_pool_slice_release(slice);
+	kfree(meta_items);
+	kdbus_meta_conn_unref(conn_meta);
+	kdbus_conn_unref(owner_conn);
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_update() - handle KDBUS_CMD_UPDATE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_update(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_item *item_policy;
+	u64 *item_attach_send = NULL;
+	u64 *item_attach_recv = NULL;
+	struct kdbus_cmd *cmd;
+	u64 attach_send;
+	u64 attach_recv;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_ATTACH_FLAGS_SEND },
+		{ .type = KDBUS_ITEM_ATTACH_FLAGS_RECV },
+		{ .type = KDBUS_ITEM_NAME, .multiple = true },
+		{ .type = KDBUS_ITEM_POLICY_ACCESS, .multiple = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	item_attach_send = argv[1].item ? &argv[1].item->data64[0] : NULL;
+	item_attach_recv = argv[2].item ? &argv[2].item->data64[0] : NULL;
+	item_policy = argv[3].item ? : argv[4].item;
+
+	if (item_attach_send) {
+		if (!kdbus_conn_is_ordinary(conn) &&
+		    !kdbus_conn_is_monitor(conn)) {
+			ret = -EOPNOTSUPP;
+			goto exit;
+		}
+
+		ret = kdbus_sanitize_attach_flags(*item_attach_send,
+						  &attach_send);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (item_attach_recv) {
+		if (!kdbus_conn_is_ordinary(conn) &&
+		    !kdbus_conn_is_monitor(conn) &&
+		    !kdbus_conn_is_activator(conn)) {
+			ret = -EOPNOTSUPP;
+			goto exit;
+		}
+
+		ret = kdbus_sanitize_attach_flags(*item_attach_recv,
+						  &attach_recv);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (item_policy && !kdbus_conn_is_policy_holder(conn)) {
+		ret = -EOPNOTSUPP;
+		goto exit;
+	}
+
+	/* now that we verified the input, update the connection */
+
+	if (item_policy) {
+		ret = kdbus_policy_set(&conn->ep->bus->policy_db, cmd->items,
+				       KDBUS_ITEMS_SIZE(cmd, items),
+				       1, true, conn);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (item_attach_send)
+		atomic64_set(&conn->attach_flags_send, attach_send);
+
+	if (item_attach_recv)
+		atomic64_set(&conn->attach_flags_recv, attach_recv);
+
+exit:
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_send() - handle KDBUS_CMD_SEND
+ * @conn:		connection to operate on
+ * @f:			file this command was called on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp)
+{
+	struct kdbus_cmd_send *cmd;
+	struct kdbus_staging *staging = NULL;
+	struct kdbus_msg *msg = NULL;
+	struct file *cancel_fd = NULL;
+	int ret, ret2;
+
+	/* command arguments */
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_CANCEL_FD },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_SEND_SYNC_REPLY,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	/* message arguments */
+	struct kdbus_arg msg_argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_PAYLOAD_VEC, .multiple = true },
+		{ .type = KDBUS_ITEM_PAYLOAD_MEMFD, .multiple = true },
+		{ .type = KDBUS_ITEM_FDS },
+		{ .type = KDBUS_ITEM_BLOOM_FILTER },
+		{ .type = KDBUS_ITEM_DST_NAME },
+	};
+	struct kdbus_args msg_args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_MSG_EXPECT_REPLY |
+				 KDBUS_MSG_NO_AUTO_START |
+				 KDBUS_MSG_SIGNAL,
+		.argv = msg_argv,
+		.argc = ARRAY_SIZE(msg_argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	/* make sure to parse both, @cmd and @msg on negotiation */
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret < 0)
+		goto exit;
+	else if (ret > 0 && !cmd->msg_address) /* negotiation without msg */
+		goto exit;
+
+	ret2 = kdbus_args_parse_msg(&msg_args, KDBUS_PTR(cmd->msg_address),
+				    &msg);
+	if (ret2 < 0) { /* cannot parse message */
+		ret = ret2;
+		goto exit;
+	} else if (ret2 > 0 && !ret) { /* msg-negot implies cmd-negot */
+		ret = -EINVAL;
+		goto exit;
+	} else if (ret > 0) { /* negotiation */
+		goto exit;
+	}
+
+	/* here we parsed both, @cmd and @msg, and neither wants negotiation */
+
+	cmd->reply.return_flags = 0;
+	kdbus_pool_publish_empty(conn->pool, &cmd->reply.offset,
+				 &cmd->reply.msg_size);
+
+	if (argv[1].item) {
+		cancel_fd = fget(argv[1].item->fds[0]);
+		if (!cancel_fd) {
+			ret = -EBADF;
+			goto exit;
+		}
+
+		if (!cancel_fd->f_op->poll) {
+			ret = -EINVAL;
+			goto exit;
+		}
+	}
+
+	/* patch-in the source of this message */
+	if (msg->src_id > 0 && msg->src_id != conn->id) {
+		ret = -EINVAL;
+		goto exit;
+	}
+	msg->src_id = conn->id;
+
+	staging = kdbus_staging_new_user(conn->ep->bus, cmd, msg);
+	if (IS_ERR(staging)) {
+		ret = PTR_ERR(staging);
+		staging = NULL;
+		goto exit;
+	}
+
+	if (msg->dst_id == KDBUS_DST_ID_BROADCAST) {
+		down_read(&conn->ep->bus->name_registry->rwlock);
+		kdbus_bus_broadcast(conn->ep->bus, conn, staging);
+		up_read(&conn->ep->bus->name_registry->rwlock);
+	} else if (cmd->flags & KDBUS_SEND_SYNC_REPLY) {
+		struct kdbus_reply *r;
+		ktime_t exp;
+
+		exp = ns_to_ktime(msg->timeout_ns);
+		r = kdbus_conn_call(conn, staging, exp);
+		if (IS_ERR(r)) {
+			ret = PTR_ERR(r);
+			goto exit;
+		}
+
+		ret = kdbus_conn_wait_reply(conn, cmd, f, cancel_fd, r, exp);
+		kdbus_reply_unref(r);
+		if (ret < 0)
+			goto exit;
+	} else if ((msg->flags & KDBUS_MSG_EXPECT_REPLY) ||
+		   msg->cookie_reply == 0) {
+		ret = kdbus_conn_unicast(conn, staging);
+		if (ret < 0)
+			goto exit;
+	} else {
+		ret = kdbus_conn_reply(conn, staging);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (kdbus_member_set_user(&cmd->reply, argp, typeof(*cmd), reply))
+		ret = -EFAULT;
+
+exit:
+	if (cancel_fd)
+		fput(cancel_fd);
+	kdbus_staging_free(staging);
+	ret = kdbus_args_clear(&msg_args, ret);
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_recv() - handle KDBUS_CMD_RECV
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_queue_entry *entry;
+	struct kdbus_cmd_recv *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_RECV_PEEK |
+				 KDBUS_RECV_DROP |
+				 KDBUS_RECV_USE_PRIORITY,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn) &&
+	    !kdbus_conn_is_monitor(conn) &&
+	    !kdbus_conn_is_activator(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	cmd->dropped_msgs = 0;
+	cmd->msg.return_flags = 0;
+	kdbus_pool_publish_empty(conn->pool, &cmd->msg.offset,
+				 &cmd->msg.msg_size);
+
+	/* DROP+priority is not realiably, so prevent it */
+	if ((cmd->flags & KDBUS_RECV_DROP) &&
+	    (cmd->flags & KDBUS_RECV_USE_PRIORITY)) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	mutex_lock(&conn->lock);
+
+	entry = kdbus_queue_peek(&conn->queue, cmd->priority,
+				 cmd->flags & KDBUS_RECV_USE_PRIORITY);
+	if (!entry) {
+		mutex_unlock(&conn->lock);
+		ret = -EAGAIN;
+	} else if (cmd->flags & KDBUS_RECV_DROP) {
+		struct kdbus_reply *reply = kdbus_reply_ref(entry->reply);
+
+		kdbus_queue_entry_free(entry);
+
+		mutex_unlock(&conn->lock);
+
+		if (reply) {
+			mutex_lock(&reply->reply_dst->lock);
+			if (!list_empty(&reply->entry)) {
+				kdbus_reply_unlink(reply);
+				if (reply->sync)
+					kdbus_sync_reply_wakeup(reply, -EPIPE);
+				else
+					kdbus_notify_reply_dead(conn->ep->bus,
+							reply->reply_dst->id,
+							reply->cookie);
+			}
+			mutex_unlock(&reply->reply_dst->lock);
+			kdbus_notify_flush(conn->ep->bus);
+		}
+
+		kdbus_reply_unref(reply);
+	} else {
+		bool install_fds;
+
+		/*
+		 * PEEK just returns the location of the next message. Do not
+		 * install FDs nor memfds nor anything else. The only
+		 * information of interest should be the message header and
+		 * metadata. Any FD numbers in the payload is undefined for
+		 * PEEK'ed messages.
+		 * Also make sure to never install fds into a connection that
+		 * has refused to receive any. Ordinary connections will not get
+		 * messages with FDs queued (the receiver will get -ECOMM), but
+		 * eavesdroppers might.
+		 */
+		install_fds = (conn->flags & KDBUS_HELLO_ACCEPT_FD) &&
+			      !(cmd->flags & KDBUS_RECV_PEEK);
+
+		ret = kdbus_queue_entry_install(entry,
+						&cmd->msg.return_flags,
+						install_fds);
+		if (ret < 0) {
+			mutex_unlock(&conn->lock);
+			goto exit;
+		}
+
+		kdbus_pool_slice_publish(entry->slice, &cmd->msg.offset,
+					 &cmd->msg.msg_size);
+
+		if (!(cmd->flags & KDBUS_RECV_PEEK))
+			kdbus_queue_entry_free(entry);
+
+		mutex_unlock(&conn->lock);
+	}
+
+	cmd->dropped_msgs = atomic_xchg(&conn->lost_count, 0);
+	if (cmd->dropped_msgs > 0)
+		cmd->return_flags |= KDBUS_RECV_RETURN_DROPPED_MSGS;
+
+	if (kdbus_member_set_user(&cmd->msg, argp, typeof(*cmd), msg) ||
+	    kdbus_member_set_user(&cmd->dropped_msgs, argp, typeof(*cmd),
+				  dropped_msgs))
+		ret = -EFAULT;
+
+exit:
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_free() - handle KDBUS_CMD_FREE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_free(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_cmd_free *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn) &&
+	    !kdbus_conn_is_monitor(conn) &&
+	    !kdbus_conn_is_activator(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	ret = kdbus_pool_release_offset(conn->pool, cmd->offset);
+
+	return kdbus_args_clear(&args, ret);
+}
diff --git a/ipc/kdbus/connection.h b/ipc/kdbus/connection.h
new file mode 100644
index 000000000000..1ad082014faa
--- /dev/null
+++ b/ipc/kdbus/connection.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_CONNECTION_H
+#define __KDBUS_CONNECTION_H
+
+#include <linux/atomic.h>
+#include <linux/kref.h>
+#include <linux/lockdep.h>
+#include <linux/path.h>
+
+#include "limits.h"
+#include "metadata.h"
+#include "pool.h"
+#include "queue.h"
+#include "util.h"
+
+#define KDBUS_HELLO_SPECIAL_CONN	(KDBUS_HELLO_ACTIVATOR | \
+					 KDBUS_HELLO_POLICY_HOLDER | \
+					 KDBUS_HELLO_MONITOR)
+
+struct kdbus_name_entry;
+struct kdbus_quota;
+struct kdbus_staging;
+
+/**
+ * struct kdbus_conn - connection to a bus
+ * @kref:		Reference count
+ * @active:		Active references to the connection
+ * @id:			Connection ID
+ * @flags:		KDBUS_HELLO_* flags
+ * @attach_flags_send:	KDBUS_ATTACH_* flags for sending
+ * @attach_flags_recv:	KDBUS_ATTACH_* flags for receiving
+ * @description:	Human-readable connection description, used for
+ *			debugging. This field is only set when the
+ *			connection is created.
+ * @ep:			The endpoint this connection belongs to
+ * @lock:		Connection data lock
+ * @hentry:		Entry in ID <-> connection map
+ * @ep_entry:		Entry in endpoint
+ * @monitor_entry:	Entry in monitor, if the connection is a monitor
+ * @reply_list:		List of connections this connection should
+ *			reply to
+ * @work:		Delayed work to handle timeouts
+ *			activator for
+ * @match_db:		Subscription filter to broadcast messages
+ * @meta_proc:		Process metadata of connection creator, or NULL
+ * @meta_fake:		Faked metadata, or NULL
+ * @pool:		The user's buffer to receive messages
+ * @user:		Owner of the connection
+ * @cred:		The credentials of the connection at creation time
+ * @pid:		Pid at creation time
+ * @root_path:		Root path at creation time
+ * @request_count:	Number of pending requests issued by this
+ *			connection that are waiting for replies from
+ *			other peers
+ * @lost_count:		Number of lost broadcast messages
+ * @wait:		Wake up this endpoint
+ * @queue:		The message queue associated with this connection
+ * @quota:		Array of per-user quota indexed by user->id
+ * @n_quota:		Number of elements in quota array
+ * @names_list:		List of well-known names
+ * @name_count:		Number of owned well-known names
+ * @privileged:		Whether this connection is privileged on the domain
+ * @owner:		Owned by the same user as the bus owner
+ */
+struct kdbus_conn {
+	struct kref kref;
+	atomic_t active;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	struct lockdep_map dep_map;
+#endif
+	u64 id;
+	u64 flags;
+	atomic64_t attach_flags_send;
+	atomic64_t attach_flags_recv;
+	const char *description;
+	struct kdbus_ep *ep;
+	struct mutex lock;
+	struct hlist_node hentry;
+	struct list_head ep_entry;
+	struct list_head monitor_entry;
+	struct list_head reply_list;
+	struct delayed_work work;
+	struct kdbus_match_db *match_db;
+	struct kdbus_meta_proc *meta_proc;
+	struct kdbus_meta_fake *meta_fake;
+	struct kdbus_pool *pool;
+	struct kdbus_user *user;
+	const struct cred *cred;
+	struct pid *pid;
+	struct path root_path;
+	atomic_t request_count;
+	atomic_t lost_count;
+	wait_queue_head_t wait;
+	struct kdbus_queue queue;
+
+	struct kdbus_quota *quota;
+	unsigned int n_quota;
+
+	/* protected by registry->rwlock */
+	struct list_head names_list;
+	unsigned int name_count;
+
+	bool privileged:1;
+	bool owner:1;
+};
+
+struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
+struct kdbus_conn *kdbus_conn_unref(struct kdbus_conn *conn);
+bool kdbus_conn_active(const struct kdbus_conn *conn);
+int kdbus_conn_acquire(struct kdbus_conn *conn);
+void kdbus_conn_release(struct kdbus_conn *conn);
+int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty);
+bool kdbus_conn_has_name(struct kdbus_conn *conn, const char *name);
+int kdbus_conn_quota_inc(struct kdbus_conn *c, struct kdbus_user *u,
+			 size_t memory, size_t fds);
+void kdbus_conn_quota_dec(struct kdbus_conn *c, struct kdbus_user *u,
+			  size_t memory, size_t fds);
+void kdbus_conn_lost_message(struct kdbus_conn *c);
+int kdbus_conn_entry_insert(struct kdbus_conn *conn_src,
+			    struct kdbus_conn *conn_dst,
+			    struct kdbus_staging *staging,
+			    struct kdbus_reply *reply,
+			    const struct kdbus_name_entry *name);
+void kdbus_conn_move_messages(struct kdbus_conn *conn_dst,
+			      struct kdbus_conn *conn_src,
+			      u64 name_id);
+
+/* policy */
+bool kdbus_conn_policy_own_name(struct kdbus_conn *conn,
+				const struct cred *conn_creds,
+				const char *name);
+bool kdbus_conn_policy_talk(struct kdbus_conn *conn,
+			    const struct cred *conn_creds,
+			    struct kdbus_conn *to);
+bool kdbus_conn_policy_see_name_unlocked(struct kdbus_conn *conn,
+					 const struct cred *curr_creds,
+					 const char *name);
+bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
+					const struct cred *curr_creds,
+					const struct kdbus_msg *msg);
+
+/* command dispatcher */
+struct kdbus_conn *kdbus_cmd_hello(struct kdbus_ep *ep, struct file *file,
+				   void __user *argp);
+int kdbus_cmd_byebye_unlocked(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_conn_info(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_update(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp);
+int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_free(struct kdbus_conn *conn, void __user *argp);
+
+/**
+ * kdbus_conn_is_ordinary() - Check if connection is ordinary
+ * @conn:		The connection to check
+ *
+ * Return: Non-zero if the connection is an ordinary connection
+ */
+static inline int kdbus_conn_is_ordinary(const struct kdbus_conn *conn)
+{
+	return !(conn->flags & KDBUS_HELLO_SPECIAL_CONN);
+}
+
+/**
+ * kdbus_conn_is_activator() - Check if connection is an activator
+ * @conn:		The connection to check
+ *
+ * Return: Non-zero if the connection is an activator
+ */
+static inline int kdbus_conn_is_activator(const struct kdbus_conn *conn)
+{
+	return conn->flags & KDBUS_HELLO_ACTIVATOR;
+}
+
+/**
+ * kdbus_conn_is_policy_holder() - Check if connection is a policy holder
+ * @conn:		The connection to check
+ *
+ * Return: Non-zero if the connection is a policy holder
+ */
+static inline int kdbus_conn_is_policy_holder(const struct kdbus_conn *conn)
+{
+	return conn->flags & KDBUS_HELLO_POLICY_HOLDER;
+}
+
+/**
+ * kdbus_conn_is_monitor() - Check if connection is a monitor
+ * @conn:		The connection to check
+ *
+ * Return: Non-zero if the connection is a monitor
+ */
+static inline int kdbus_conn_is_monitor(const struct kdbus_conn *conn)
+{
+	return conn->flags & KDBUS_HELLO_MONITOR;
+}
+
+/**
+ * kdbus_conn_lock2() - Lock two connections
+ * @a:		connection A to lock or NULL
+ * @b:		connection B to lock or NULL
+ *
+ * Lock two connections at once. As we need to have a stable locking order, we
+ * always lock the connection with lower memory address first.
+ */
+static inline void kdbus_conn_lock2(struct kdbus_conn *a, struct kdbus_conn *b)
+{
+	if (a < b) {
+		if (a)
+			mutex_lock(&a->lock);
+		if (b && b != a)
+			mutex_lock_nested(&b->lock, !!a);
+	} else {
+		if (b)
+			mutex_lock(&b->lock);
+		if (a && a != b)
+			mutex_lock_nested(&a->lock, !!b);
+	}
+}
+
+/**
+ * kdbus_conn_unlock2() - Unlock two connections
+ * @a:		connection A to unlock or NULL
+ * @b:		connection B to unlock or NULL
+ *
+ * Unlock two connections at once. See kdbus_conn_lock2().
+ */
+static inline void kdbus_conn_unlock2(struct kdbus_conn *a,
+				      struct kdbus_conn *b)
+{
+	if (a)
+		mutex_unlock(&a->lock);
+	if (b && b != a)
+		mutex_unlock(&b->lock);
+}
+
+/**
+ * kdbus_conn_assert_active() - lockdep assert on active lock
+ * @conn:	connection that shall be active
+ *
+ * This verifies via lockdep that the caller holds an active reference to the
+ * given connection.
+ */
+static inline void kdbus_conn_assert_active(struct kdbus_conn *conn)
+{
+	lockdep_assert_held(conn);
+}
+
+#endif
diff --git a/ipc/kdbus/domain.c b/ipc/kdbus/domain.c
new file mode 100644
index 000000000000..ac9f760c150d
--- /dev/null
+++ b/ipc/kdbus/domain.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "bus.h"
+#include "domain.h"
+#include "handle.h"
+#include "item.h"
+#include "limits.h"
+#include "util.h"
+
+static void kdbus_domain_control_free(struct kdbus_node *node)
+{
+	kfree(node);
+}
+
+static struct kdbus_node *kdbus_domain_control_new(struct kdbus_domain *domain,
+						   unsigned int access)
+{
+	struct kdbus_node *node;
+	int ret;
+
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (!node)
+		return ERR_PTR(-ENOMEM);
+
+	kdbus_node_init(node, KDBUS_NODE_CONTROL);
+
+	node->free_cb = kdbus_domain_control_free;
+	node->mode = domain->node.mode;
+	node->mode = S_IRUSR | S_IWUSR;
+	if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
+		node->mode |= S_IRGRP | S_IWGRP;
+	if (access & KDBUS_MAKE_ACCESS_WORLD)
+		node->mode |= S_IROTH | S_IWOTH;
+
+	ret = kdbus_node_link(node, &domain->node, "control");
+	if (ret < 0)
+		goto exit_free;
+
+	return node;
+
+exit_free:
+	kdbus_node_deactivate(node);
+	kdbus_node_unref(node);
+	return ERR_PTR(ret);
+}
+
+static void kdbus_domain_free(struct kdbus_node *node)
+{
+	struct kdbus_domain *domain =
+		container_of(node, struct kdbus_domain, node);
+
+	put_user_ns(domain->user_namespace);
+	ida_destroy(&domain->user_ida);
+	idr_destroy(&domain->user_idr);
+	kfree(domain);
+}
+
+/**
+ * kdbus_domain_new() - create a new domain
+ * @access:		The access mode for this node (KDBUS_MAKE_ACCESS_*)
+ *
+ * Return: a new kdbus_domain on success, ERR_PTR on failure
+ */
+struct kdbus_domain *kdbus_domain_new(unsigned int access)
+{
+	struct kdbus_domain *d;
+	int ret;
+
+	d = kzalloc(sizeof(*d), GFP_KERNEL);
+	if (!d)
+		return ERR_PTR(-ENOMEM);
+
+	kdbus_node_init(&d->node, KDBUS_NODE_DOMAIN);
+
+	d->node.free_cb = kdbus_domain_free;
+	d->node.mode = S_IRUSR | S_IXUSR;
+	if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
+		d->node.mode |= S_IRGRP | S_IXGRP;
+	if (access & KDBUS_MAKE_ACCESS_WORLD)
+		d->node.mode |= S_IROTH | S_IXOTH;
+
+	mutex_init(&d->lock);
+	idr_init(&d->user_idr);
+	ida_init(&d->user_ida);
+
+	/* Pin user namespace so we can guarantee domain-unique bus * names. */
+	d->user_namespace = get_user_ns(current_user_ns());
+
+	ret = kdbus_node_link(&d->node, NULL, NULL);
+	if (ret < 0)
+		goto exit_unref;
+
+	return d;
+
+exit_unref:
+	kdbus_node_deactivate(&d->node);
+	kdbus_node_unref(&d->node);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_domain_ref() - take a domain reference
+ * @domain:		Domain
+ *
+ * Return: the domain itself
+ */
+struct kdbus_domain *kdbus_domain_ref(struct kdbus_domain *domain)
+{
+	if (domain)
+		kdbus_node_ref(&domain->node);
+	return domain;
+}
+
+/**
+ * kdbus_domain_unref() - drop a domain reference
+ * @domain:		Domain
+ *
+ * When the last reference is dropped, the domain internal structure
+ * is freed.
+ *
+ * Return: NULL
+ */
+struct kdbus_domain *kdbus_domain_unref(struct kdbus_domain *domain)
+{
+	if (domain)
+		kdbus_node_unref(&domain->node);
+	return NULL;
+}
+
+/**
+ * kdbus_domain_populate() - populate static domain nodes
+ * @domain:	domain to populate
+ * @access:	KDBUS_MAKE_ACCESS_* access restrictions for new nodes
+ *
+ * Allocate and activate static sub-nodes of the given domain. This will fail if
+ * you call it on a non-active node or if the domain was already populated.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_domain_populate(struct kdbus_domain *domain, unsigned int access)
+{
+	struct kdbus_node *control;
+
+	/*
+	 * Create a control-node for this domain. We drop our own reference
+	 * immediately, effectively causing the node to be deactivated and
+	 * released when the parent domain is.
+	 */
+	control = kdbus_domain_control_new(domain, access);
+	if (IS_ERR(control))
+		return PTR_ERR(control);
+
+	kdbus_node_activate(control);
+	kdbus_node_unref(control);
+	return 0;
+}
+
+/**
+ * kdbus_user_lookup() - lookup a kdbus_user object
+ * @domain:		domain of the user
+ * @uid:		uid of the user; INVALID_UID for an anon user
+ *
+ * Lookup the kdbus user accounting object for the given domain. If INVALID_UID
+ * is passed, a new anonymous user is created which is private to the caller.
+ *
+ * Return: The user object is returned, ERR_PTR on failure.
+ */
+struct kdbus_user *kdbus_user_lookup(struct kdbus_domain *domain, kuid_t uid)
+{
+	struct kdbus_user *u = NULL, *old = NULL;
+	int ret;
+
+	mutex_lock(&domain->lock);
+
+	if (uid_valid(uid)) {
+		old = idr_find(&domain->user_idr, __kuid_val(uid));
+		/*
+		 * If the object is about to be destroyed, ignore it and
+		 * replace the slot in the IDR later on.
+		 */
+		if (old && kref_get_unless_zero(&old->kref)) {
+			mutex_unlock(&domain->lock);
+			return old;
+		}
+	}
+
+	u = kzalloc(sizeof(*u), GFP_KERNEL);
+	if (!u) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	kref_init(&u->kref);
+	u->domain = kdbus_domain_ref(domain);
+	u->uid = uid;
+	atomic_set(&u->buses, 0);
+	atomic_set(&u->connections, 0);
+
+	if (uid_valid(uid)) {
+		if (old) {
+			idr_replace(&domain->user_idr, u, __kuid_val(uid));
+			old->uid = INVALID_UID; /* mark old as removed */
+		} else {
+			ret = idr_alloc(&domain->user_idr, u, __kuid_val(uid),
+					__kuid_val(uid) + 1, GFP_KERNEL);
+			if (ret < 0)
+				goto exit;
+		}
+	}
+
+	/*
+	 * Allocate the smallest possible index for this user; used
+	 * in arrays for accounting user quota in receiver queues.
+	 */
+	ret = ida_simple_get(&domain->user_ida, 1, 0, GFP_KERNEL);
+	if (ret < 0)
+		goto exit;
+
+	u->id = ret;
+	mutex_unlock(&domain->lock);
+	return u;
+
+exit:
+	if (u) {
+		if (uid_valid(u->uid))
+			idr_remove(&domain->user_idr, __kuid_val(u->uid));
+		kdbus_domain_unref(u->domain);
+		kfree(u);
+	}
+	mutex_unlock(&domain->lock);
+	return ERR_PTR(ret);
+}
+
+static void __kdbus_user_free(struct kref *kref)
+{
+	struct kdbus_user *user = container_of(kref, struct kdbus_user, kref);
+
+	WARN_ON(atomic_read(&user->buses) > 0);
+	WARN_ON(atomic_read(&user->connections) > 0);
+
+	mutex_lock(&user->domain->lock);
+	ida_simple_remove(&user->domain->user_ida, user->id);
+	if (uid_valid(user->uid))
+		idr_remove(&user->domain->user_idr, __kuid_val(user->uid));
+	mutex_unlock(&user->domain->lock);
+
+	kdbus_domain_unref(user->domain);
+	kfree(user);
+}
+
+/**
+ * kdbus_user_ref() - take a user reference
+ * @u:		User
+ *
+ * Return: @u is returned
+ */
+struct kdbus_user *kdbus_user_ref(struct kdbus_user *u)
+{
+	if (u)
+		kref_get(&u->kref);
+	return u;
+}
+
+/**
+ * kdbus_user_unref() - drop a user reference
+ * @u:		User
+ *
+ * Return: NULL
+ */
+struct kdbus_user *kdbus_user_unref(struct kdbus_user *u)
+{
+	if (u)
+		kref_put(&u->kref, __kdbus_user_free);
+	return NULL;
+}
diff --git a/ipc/kdbus/domain.h b/ipc/kdbus/domain.h
new file mode 100644
index 000000000000..447a2bd4d972
--- /dev/null
+++ b/ipc/kdbus/domain.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_DOMAIN_H
+#define __KDBUS_DOMAIN_H
+
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/kref.h>
+#include <linux/user_namespace.h>
+
+#include "node.h"
+
+/**
+ * struct kdbus_domain - domain for buses
+ * @node:		Underlying API node
+ * @lock:		Domain data lock
+ * @last_id:		Last used object id
+ * @user_idr:		Set of all users indexed by UID
+ * @user_ida:		Set of all users to compute small indices
+ * @user_namespace:	User namespace, pinned at creation time
+ * @dentry:		Root dentry of VFS mount (don't use outside of kdbusfs)
+ */
+struct kdbus_domain {
+	struct kdbus_node node;
+	struct mutex lock;
+	atomic64_t last_id;
+	struct idr user_idr;
+	struct ida user_ida;
+	struct user_namespace *user_namespace;
+	struct dentry *dentry;
+};
+
+/**
+ * struct kdbus_user - resource accounting for users
+ * @kref:		Reference counter
+ * @domain:		Domain of the user
+ * @id:			Index of this user
+ * @uid:		UID of the user
+ * @buses:		Number of buses the user has created
+ * @connections:	Number of connections the user has created
+ */
+struct kdbus_user {
+	struct kref kref;
+	struct kdbus_domain *domain;
+	unsigned int id;
+	kuid_t uid;
+	atomic_t buses;
+	atomic_t connections;
+};
+
+#define kdbus_domain_from_node(_node) \
+	container_of((_node), struct kdbus_domain, node)
+
+struct kdbus_domain *kdbus_domain_new(unsigned int access);
+struct kdbus_domain *kdbus_domain_ref(struct kdbus_domain *domain);
+struct kdbus_domain *kdbus_domain_unref(struct kdbus_domain *domain);
+int kdbus_domain_populate(struct kdbus_domain *domain, unsigned int access);
+
+#define KDBUS_USER_KERNEL_ID 0 /* ID 0 is reserved for kernel accounting */
+
+struct kdbus_user *kdbus_user_lookup(struct kdbus_domain *domain, kuid_t uid);
+struct kdbus_user *kdbus_user_ref(struct kdbus_user *u);
+struct kdbus_user *kdbus_user_unref(struct kdbus_user *u);
+
+#endif
diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
new file mode 100644
index 000000000000..44e7a20de9c2
--- /dev/null
+++ b/ipc/kdbus/endpoint.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/uio.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "item.h"
+#include "message.h"
+#include "policy.h"
+
+static void kdbus_ep_free(struct kdbus_node *node)
+{
+	struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
+
+	WARN_ON(!list_empty(&ep->conn_list));
+
+	kdbus_policy_db_clear(&ep->policy_db);
+	kdbus_bus_unref(ep->bus);
+	kdbus_user_unref(ep->user);
+	kfree(ep);
+}
+
+static void kdbus_ep_release(struct kdbus_node *node, bool was_active)
+{
+	struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
+
+	/* disconnect all connections to this endpoint */
+	for (;;) {
+		struct kdbus_conn *conn;
+
+		mutex_lock(&ep->lock);
+		conn = list_first_entry_or_null(&ep->conn_list,
+						struct kdbus_conn,
+						ep_entry);
+		if (!conn) {
+			mutex_unlock(&ep->lock);
+			break;
+		}
+
+		/* take reference, release lock, disconnect without lock */
+		kdbus_conn_ref(conn);
+		mutex_unlock(&ep->lock);
+
+		kdbus_conn_disconnect(conn, false);
+		kdbus_conn_unref(conn);
+	}
+}
+
+/**
+ * kdbus_ep_new() - create a new endpoint
+ * @bus:		The bus this endpoint will be created for
+ * @name:		The name of the endpoint
+ * @access:		The access flags for this node (KDBUS_MAKE_ACCESS_*)
+ * @uid:		The uid of the node
+ * @gid:		The gid of the node
+ * @is_custom:		Whether this is a custom endpoint
+ *
+ * This function will create a new endpoint with the given
+ * name and properties for a given bus.
+ *
+ * Return: a new kdbus_ep on success, ERR_PTR on failure.
+ */
+struct kdbus_ep *kdbus_ep_new(struct kdbus_bus *bus, const char *name,
+			      unsigned int access, kuid_t uid, kgid_t gid,
+			      bool is_custom)
+{
+	struct kdbus_ep *e;
+	int ret;
+
+	/*
+	 * Validate only custom endpoints names, default endpoints
+	 * with a "bus" name are created when the bus is created
+	 */
+	if (is_custom) {
+		ret = kdbus_verify_uid_prefix(name, bus->domain->user_namespace,
+					      uid);
+		if (ret < 0)
+			return ERR_PTR(ret);
+	}
+
+	e = kzalloc(sizeof(*e), GFP_KERNEL);
+	if (!e)
+		return ERR_PTR(-ENOMEM);
+
+	kdbus_node_init(&e->node, KDBUS_NODE_ENDPOINT);
+
+	e->node.free_cb = kdbus_ep_free;
+	e->node.release_cb = kdbus_ep_release;
+	e->node.uid = uid;
+	e->node.gid = gid;
+	e->node.mode = S_IRUSR | S_IWUSR;
+	if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
+		e->node.mode |= S_IRGRP | S_IWGRP;
+	if (access & KDBUS_MAKE_ACCESS_WORLD)
+		e->node.mode |= S_IROTH | S_IWOTH;
+
+	mutex_init(&e->lock);
+	INIT_LIST_HEAD(&e->conn_list);
+	kdbus_policy_db_init(&e->policy_db);
+	e->bus = kdbus_bus_ref(bus);
+
+	ret = kdbus_node_link(&e->node, &bus->node, name);
+	if (ret < 0)
+		goto exit_unref;
+
+	/*
+	 * Transactions on custom endpoints are never accounted on the global
+	 * user limits. Instead, for each custom endpoint, we create a custom,
+	 * unique user, which all transactions are accounted on. Regardless of
+	 * the user using that endpoint, it is always accounted on the same
+	 * user-object. This budget is not shared with ordinary users on
+	 * non-custom endpoints.
+	 */
+	if (is_custom) {
+		e->user = kdbus_user_lookup(bus->domain, INVALID_UID);
+		if (IS_ERR(e->user)) {
+			ret = PTR_ERR(e->user);
+			e->user = NULL;
+			goto exit_unref;
+		}
+	}
+
+	return e;
+
+exit_unref:
+	kdbus_node_deactivate(&e->node);
+	kdbus_node_unref(&e->node);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_ep_ref() - increase the reference counter of a kdbus_ep
+ * @ep:			The endpoint to reference
+ *
+ * Every user of an endpoint, except for its creator, must add a reference to
+ * the kdbus_ep instance using this function.
+ *
+ * Return: the ep itself
+ */
+struct kdbus_ep *kdbus_ep_ref(struct kdbus_ep *ep)
+{
+	if (ep)
+		kdbus_node_ref(&ep->node);
+	return ep;
+}
+
+/**
+ * kdbus_ep_unref() - decrease the reference counter of a kdbus_ep
+ * @ep:		The ep to unref
+ *
+ * Release a reference. If the reference count drops to 0, the ep will be
+ * freed.
+ *
+ * Return: NULL
+ */
+struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep)
+{
+	if (ep)
+		kdbus_node_unref(&ep->node);
+	return NULL;
+}
+
+/**
+ * kdbus_ep_is_privileged() - check whether a file is privileged
+ * @ep:		endpoint to operate on
+ * @file:	file to test
+ *
+ * Return: True if @file is privileged in the domain of @ep.
+ */
+bool kdbus_ep_is_privileged(struct kdbus_ep *ep, struct file *file)
+{
+	return !ep->user &&
+		file_ns_capable(file, ep->bus->domain->user_namespace,
+				CAP_IPC_OWNER);
+}
+
+/**
+ * kdbus_ep_is_owner() - check whether a file should be treated as bus owner
+ * @ep:		endpoint to operate on
+ * @file:	file to test
+ *
+ * Return: True if @file should be treated as bus owner on @ep
+ */
+bool kdbus_ep_is_owner(struct kdbus_ep *ep, struct file *file)
+{
+	return !ep->user &&
+		(uid_eq(file->f_cred->euid, ep->bus->node.uid) ||
+		 kdbus_ep_is_privileged(ep, file));
+}
+
+/**
+ * kdbus_cmd_ep_make() - handle KDBUS_CMD_ENDPOINT_MAKE
+ * @bus:		bus to operate on
+ * @argp:		command payload
+ *
+ * Return: NULL or newly created endpoint on success, ERR_PTR on failure.
+ */
+struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp)
+{
+	const char *item_make_name;
+	struct kdbus_ep *ep = NULL;
+	struct kdbus_cmd *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_MAKE_NAME, .mandatory = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_MAKE_ACCESS_GROUP |
+				 KDBUS_MAKE_ACCESS_WORLD,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret > 0)
+		return NULL;
+
+	item_make_name = argv[1].item->str;
+
+	ep = kdbus_ep_new(bus, item_make_name, cmd->flags,
+			  current_euid(), current_egid(), true);
+	if (IS_ERR(ep)) {
+		ret = PTR_ERR(ep);
+		ep = NULL;
+		goto exit;
+	}
+
+	if (!kdbus_node_activate(&ep->node)) {
+		ret = -ESHUTDOWN;
+		goto exit;
+	}
+
+exit:
+	ret = kdbus_args_clear(&args, ret);
+	if (ret < 0) {
+		if (ep) {
+			kdbus_node_deactivate(&ep->node);
+			kdbus_ep_unref(ep);
+		}
+		return ERR_PTR(ret);
+	}
+	return ep;
+}
+
+/**
+ * kdbus_cmd_ep_update() - handle KDBUS_CMD_ENDPOINT_UPDATE
+ * @ep:			endpoint to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
+{
+	struct kdbus_cmd *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_NAME, .multiple = true },
+		{ .type = KDBUS_ITEM_POLICY_ACCESS, .multiple = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	ret = kdbus_policy_set(&ep->policy_db, args.items, args.items_size,
+			       0, true, ep);
+	return kdbus_args_clear(&args, ret);
+}
diff --git a/ipc/kdbus/endpoint.h b/ipc/kdbus/endpoint.h
new file mode 100644
index 000000000000..e0da59f01a7a
--- /dev/null
+++ b/ipc/kdbus/endpoint.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_ENDPOINT_H
+#define __KDBUS_ENDPOINT_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/uidgid.h>
+#include "node.h"
+#include "policy.h"
+
+struct kdbus_bus;
+struct kdbus_user;
+
+/**
+ * struct kdbus_ep - endpoint to access a bus
+ * @node:		The kdbus node
+ * @lock:		Endpoint data lock
+ * @bus:		Bus behind this endpoint
+ * @user:		Custom enpoints account against an anonymous user
+ * @policy_db:		Uploaded policy
+ * @conn_list:		Connections of this endpoint
+ *
+ * An endpoint offers access to a bus; the default endpoint node name is "bus".
+ * Additional custom endpoints to the same bus can be created and they can
+ * carry their own policies/filters.
+ */
+struct kdbus_ep {
+	struct kdbus_node node;
+	struct mutex lock;
+
+	/* static */
+	struct kdbus_bus *bus;
+	struct kdbus_user *user;
+
+	/* protected by own locks */
+	struct kdbus_policy_db policy_db;
+
+	/* protected by ep->lock */
+	struct list_head conn_list;
+};
+
+#define kdbus_ep_from_node(_node) \
+	container_of((_node), struct kdbus_ep, node)
+
+struct kdbus_ep *kdbus_ep_new(struct kdbus_bus *bus, const char *name,
+			      unsigned int access, kuid_t uid, kgid_t gid,
+			      bool policy);
+struct kdbus_ep *kdbus_ep_ref(struct kdbus_ep *ep);
+struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep);
+
+bool kdbus_ep_is_privileged(struct kdbus_ep *ep, struct file *file);
+bool kdbus_ep_is_owner(struct kdbus_ep *ep, struct file *file);
+
+struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp);
+int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp);
+
+#endif
diff --git a/ipc/kdbus/fs.c b/ipc/kdbus/fs.c
new file mode 100644
index 000000000000..09c480924b9e
--- /dev/null
+++ b/ipc/kdbus/fs.c
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/dcache.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/init.h>
+#include <linux/ipc_namespace.h>
+#include <linux/magic.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/mutex.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include "bus.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "fs.h"
+#include "handle.h"
+#include "node.h"
+
+#define kdbus_node_from_dentry(_dentry) \
+	((struct kdbus_node *)(_dentry)->d_fsdata)
+
+static struct inode *fs_inode_get(struct super_block *sb,
+				  struct kdbus_node *node);
+
+/*
+ * Directory Management
+ */
+
+static inline unsigned char kdbus_dt_type(struct kdbus_node *node)
+{
+	switch (node->type) {
+	case KDBUS_NODE_DOMAIN:
+	case KDBUS_NODE_BUS:
+		return DT_DIR;
+	case KDBUS_NODE_CONTROL:
+	case KDBUS_NODE_ENDPOINT:
+		return DT_REG;
+	}
+
+	return DT_UNKNOWN;
+}
+
+static int fs_dir_fop_iterate(struct file *file, struct dir_context *ctx)
+{
+	struct dentry *dentry = file->f_path.dentry;
+	struct kdbus_node *parent = kdbus_node_from_dentry(dentry);
+	struct kdbus_node *old, *next = file->private_data;
+
+	/*
+	 * kdbusfs directory iterator (modelled after sysfs/kernfs)
+	 * When iterating kdbusfs directories, we iterate all children of the
+	 * parent kdbus_node object. We use ctx->pos to store the hash of the
+	 * child and file->private_data to store a reference to the next node
+	 * object. If ctx->pos is not modified via llseek while you iterate a
+	 * directory, then we use the file->private_data node pointer to
+	 * directly access the next node in the tree.
+	 * However, if you directly seek on the directory, we have to find the
+	 * closest node to that position and cannot use our node pointer. This
+	 * means iterating the rb-tree to find the closest match and start over
+	 * from there.
+	 * Note that hash values are not necessarily unique. Therefore, llseek
+	 * is not guaranteed to seek to the same node that you got when you
+	 * retrieved the position. Seeking to 0, 1, 2 and >=INT_MAX is safe,
+	 * though. We could use the inode-number as position, but this would
+	 * require another rb-tree for fast access. Kernfs and others already
+	 * ignore those conflicts, so we should be fine, too.
+	 */
+
+	if (!dir_emit_dots(file, ctx))
+		return 0;
+
+	/* acquire @next; if deactivated, or seek detected, find next node */
+	old = next;
+	if (next && ctx->pos == next->hash) {
+		if (kdbus_node_acquire(next))
+			kdbus_node_ref(next);
+		else
+			next = kdbus_node_next_child(parent, next);
+	} else {
+		next = kdbus_node_find_closest(parent, ctx->pos);
+	}
+	kdbus_node_unref(old);
+
+	while (next) {
+		/* emit @next */
+		file->private_data = next;
+		ctx->pos = next->hash;
+
+		kdbus_node_release(next);
+
+		if (!dir_emit(ctx, next->name, strlen(next->name), next->id,
+			      kdbus_dt_type(next)))
+			return 0;
+
+		/* find next node after @next */
+		old = next;
+		next = kdbus_node_next_child(parent, next);
+		kdbus_node_unref(old);
+	}
+
+	file->private_data = NULL;
+	ctx->pos = INT_MAX;
+
+	return 0;
+}
+
+static loff_t fs_dir_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct inode *inode = file_inode(file);
+	loff_t ret;
+
+	/* protect f_off against fop_iterate */
+	mutex_lock(&inode->i_mutex);
+	ret = generic_file_llseek(file, offset, whence);
+	mutex_unlock(&inode->i_mutex);
+
+	return ret;
+}
+
+static int fs_dir_fop_release(struct inode *inode, struct file *file)
+{
+	kdbus_node_unref(file->private_data);
+	return 0;
+}
+
+static const struct file_operations fs_dir_fops = {
+	.read		= generic_read_dir,
+	.iterate	= fs_dir_fop_iterate,
+	.llseek		= fs_dir_fop_llseek,
+	.release	= fs_dir_fop_release,
+};
+
+static struct dentry *fs_dir_iop_lookup(struct inode *dir,
+					struct dentry *dentry,
+					unsigned int flags)
+{
+	struct dentry *dnew = NULL;
+	struct kdbus_node *parent;
+	struct kdbus_node *node;
+	struct inode *inode;
+
+	parent = kdbus_node_from_dentry(dentry->d_parent);
+	if (!kdbus_node_acquire(parent))
+		return NULL;
+
+	/* returns reference to _acquired_ child node */
+	node = kdbus_node_find_child(parent, dentry->d_name.name);
+	if (node) {
+		dentry->d_fsdata = node;
+		inode = fs_inode_get(dir->i_sb, node);
+		if (IS_ERR(inode))
+			dnew = ERR_CAST(inode);
+		else
+			dnew = d_splice_alias(inode, dentry);
+
+		kdbus_node_release(node);
+	}
+
+	kdbus_node_release(parent);
+	return dnew;
+}
+
+static const struct inode_operations fs_dir_iops = {
+	.permission	= generic_permission,
+	.lookup		= fs_dir_iop_lookup,
+};
+
+/*
+ * Inode Management
+ */
+
+static const struct inode_operations fs_inode_iops = {
+	.permission	= generic_permission,
+};
+
+static struct inode *fs_inode_get(struct super_block *sb,
+				  struct kdbus_node *node)
+{
+	struct inode *inode;
+
+	inode = iget_locked(sb, node->id);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+	if (!(inode->i_state & I_NEW))
+		return inode;
+
+	inode->i_private = kdbus_node_ref(node);
+	inode->i_mapping->a_ops = &empty_aops;
+	inode->i_mode = node->mode & S_IALLUGO;
+	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_uid = node->uid;
+	inode->i_gid = node->gid;
+
+	switch (node->type) {
+	case KDBUS_NODE_DOMAIN:
+	case KDBUS_NODE_BUS:
+		inode->i_mode |= S_IFDIR;
+		inode->i_op = &fs_dir_iops;
+		inode->i_fop = &fs_dir_fops;
+		set_nlink(inode, 2);
+		break;
+	case KDBUS_NODE_CONTROL:
+	case KDBUS_NODE_ENDPOINT:
+		inode->i_mode |= S_IFREG;
+		inode->i_op = &fs_inode_iops;
+		inode->i_fop = &kdbus_handle_ops;
+		break;
+	}
+
+	unlock_new_inode(inode);
+
+	return inode;
+}
+
+/*
+ * Superblock Management
+ */
+
+static int fs_super_dop_revalidate(struct dentry *dentry, unsigned int flags)
+{
+	struct kdbus_node *node;
+
+	/* Force lookup on negatives */
+	if (!dentry->d_inode)
+		return 0;
+
+	node = kdbus_node_from_dentry(dentry);
+
+	/* see whether the node has been removed */
+	if (!kdbus_node_is_active(node))
+		return 0;
+
+	return 1;
+}
+
+static void fs_super_dop_release(struct dentry *dentry)
+{
+	kdbus_node_unref(dentry->d_fsdata);
+}
+
+static const struct dentry_operations fs_super_dops = {
+	.d_revalidate	= fs_super_dop_revalidate,
+	.d_release	= fs_super_dop_release,
+};
+
+static void fs_super_sop_evict_inode(struct inode *inode)
+{
+	struct kdbus_node *node = kdbus_node_from_inode(inode);
+
+	truncate_inode_pages_final(&inode->i_data);
+	clear_inode(inode);
+	kdbus_node_unref(node);
+}
+
+static const struct super_operations fs_super_sops = {
+	.statfs		= simple_statfs,
+	.drop_inode	= generic_delete_inode,
+	.evict_inode	= fs_super_sop_evict_inode,
+};
+
+static int fs_super_fill(struct super_block *sb)
+{
+	struct kdbus_domain *domain = sb->s_fs_info;
+	struct inode *inode;
+	int ret;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = KDBUS_SUPER_MAGIC;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_op = &fs_super_sops;
+	sb->s_time_gran = 1;
+
+	inode = fs_inode_get(sb, &domain->node);
+	if (IS_ERR(inode))
+		return PTR_ERR(inode);
+
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root) {
+		/* d_make_root iput()s the inode on failure */
+		return -ENOMEM;
+	}
+
+	/* sb holds domain reference */
+	sb->s_root->d_fsdata = &domain->node;
+	sb->s_d_op = &fs_super_dops;
+
+	/* sb holds root reference */
+	domain->dentry = sb->s_root;
+
+	if (!kdbus_node_activate(&domain->node))
+		return -ESHUTDOWN;
+
+	ret = kdbus_domain_populate(domain, KDBUS_MAKE_ACCESS_WORLD);
+	if (ret < 0)
+		return ret;
+
+	sb->s_flags |= MS_ACTIVE;
+	return 0;
+}
+
+static void fs_super_kill(struct super_block *sb)
+{
+	struct kdbus_domain *domain = sb->s_fs_info;
+
+	if (domain) {
+		kdbus_node_deactivate(&domain->node);
+		domain->dentry = NULL;
+	}
+
+	kill_anon_super(sb);
+	kdbus_domain_unref(domain);
+}
+
+static int fs_super_set(struct super_block *sb, void *data)
+{
+	int ret;
+
+	ret = set_anon_super(sb, data);
+	if (!ret)
+		sb->s_fs_info = data;
+
+	return ret;
+}
+
+static struct dentry *fs_super_mount(struct file_system_type *fs_type,
+				     int flags, const char *dev_name,
+				     void *data)
+{
+	struct kdbus_domain *domain;
+	struct super_block *sb;
+	int ret;
+
+	domain = kdbus_domain_new(KDBUS_MAKE_ACCESS_WORLD);
+	if (IS_ERR(domain))
+		return ERR_CAST(domain);
+
+	sb = sget(fs_type, NULL, fs_super_set, flags, domain);
+	if (IS_ERR(sb)) {
+		kdbus_node_deactivate(&domain->node);
+		kdbus_domain_unref(domain);
+		return ERR_CAST(sb);
+	}
+
+	WARN_ON(sb->s_fs_info != domain);
+	WARN_ON(sb->s_root);
+
+	ret = fs_super_fill(sb);
+	if (ret < 0) {
+		/* calls into ->kill_sb() when done */
+		deactivate_locked_super(sb);
+		return ERR_PTR(ret);
+	}
+
+	return dget(sb->s_root);
+}
+
+static struct file_system_type fs_type = {
+	.name		= KBUILD_MODNAME "fs",
+	.owner		= THIS_MODULE,
+	.mount		= fs_super_mount,
+	.kill_sb	= fs_super_kill,
+	.fs_flags	= FS_USERNS_MOUNT,
+};
+
+/**
+ * kdbus_fs_init() - register kdbus filesystem
+ *
+ * This registers a filesystem with the VFS layer. The filesystem is called
+ * `KBUILD_MODNAME "fs"', which usually resolves to `kdbusfs'. The nameing
+ * scheme allows to set KBUILD_MODNAME to "kdbus2" and you will get an
+ * independent filesystem for developers.
+ *
+ * Each mount of the kdbusfs filesystem has an kdbus_domain attached.
+ * Operations on this mount will only affect the attached domain. On each mount
+ * a new domain is automatically created and used for this mount exclusively.
+ * If you want to share a domain across multiple mounts, you need to bind-mount
+ * it.
+ *
+ * Mounts of kdbusfs (with a different domain each) are unrelated to each other
+ * and will never have any effect on any domain but their own.
+ *
+ * Return: 0 on success, negative error otherwise.
+ */
+int kdbus_fs_init(void)
+{
+	return register_filesystem(&fs_type);
+}
+
+/**
+ * kdbus_fs_exit() - unregister kdbus filesystem
+ *
+ * This does the reverse to kdbus_fs_init(). It unregisters the kdbusfs
+ * filesystem from VFS and cleans up any allocated resources.
+ */
+void kdbus_fs_exit(void)
+{
+	unregister_filesystem(&fs_type);
+}
+
+/* acquire domain of @node, making sure all ancestors are active */
+static struct kdbus_domain *fs_acquire_domain(struct kdbus_node *node)
+{
+	struct kdbus_domain *domain;
+	struct kdbus_node *iter;
+
+	/* caller must guarantee that @node is linked */
+	for (iter = node; iter->parent; iter = iter->parent)
+		if (!kdbus_node_is_active(iter->parent))
+			return NULL;
+
+	/* root nodes are always domains */
+	if (WARN_ON(iter->type != KDBUS_NODE_DOMAIN))
+		return NULL;
+
+	domain = kdbus_domain_from_node(iter);
+	if (!kdbus_node_acquire(&domain->node))
+		return NULL;
+
+	return domain;
+}
+
+/**
+ * kdbus_fs_flush() - flush dcache entries of a node
+ * @node:		Node to flush entries of
+ *
+ * This flushes all VFS filesystem cache entries for a node and all its
+ * children. This should be called whenever a node is destroyed during
+ * runtime. It will flush the cache entries so the linked objects can be
+ * deallocated.
+ *
+ * This is a no-op if you call it on active nodes (they really should stay in
+ * cache) or on nodes with deactivated parents (flushing the parent is enough).
+ * Furthermore, there is no need to call it on nodes whose lifetime is bound to
+ * their parents'. In those cases, the parent-flush will always also flush the
+ * children.
+ */
+void kdbus_fs_flush(struct kdbus_node *node)
+{
+	struct dentry *dentry, *parent_dentry = NULL;
+	struct kdbus_domain *domain;
+	struct qstr name;
+
+	/* active nodes should remain in cache */
+	if (!kdbus_node_is_deactivated(node))
+		return;
+
+	/* nodes that were never linked were never instantiated */
+	if (!node->parent)
+		return;
+
+	/* acquire domain and verify all ancestors are active */
+	domain = fs_acquire_domain(node);
+	if (!domain)
+		return;
+
+	switch (node->type) {
+	case KDBUS_NODE_ENDPOINT:
+		if (WARN_ON(!node->parent || !node->parent->name))
+			goto exit;
+
+		name.name = node->parent->name;
+		name.len = strlen(node->parent->name);
+		parent_dentry = d_hash_and_lookup(domain->dentry, &name);
+		if (IS_ERR_OR_NULL(parent_dentry))
+			goto exit;
+
+		/* fallthrough */
+	case KDBUS_NODE_BUS:
+		if (WARN_ON(!node->name))
+			goto exit;
+
+		name.name = node->name;
+		name.len = strlen(node->name);
+		dentry = d_hash_and_lookup(parent_dentry ? : domain->dentry,
+					   &name);
+		if (!IS_ERR_OR_NULL(dentry)) {
+			d_invalidate(dentry);
+			dput(dentry);
+		}
+
+		dput(parent_dentry);
+		break;
+
+	default:
+		/* all other types are bound to their parent lifetime */
+		break;
+	}
+
+exit:
+	kdbus_node_release(&domain->node);
+}
diff --git a/ipc/kdbus/fs.h b/ipc/kdbus/fs.h
new file mode 100644
index 000000000000..62f7d6abf11e
--- /dev/null
+++ b/ipc/kdbus/fs.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUSFS_H
+#define __KDBUSFS_H
+
+#include <linux/kernel.h>
+
+struct kdbus_node;
+
+int kdbus_fs_init(void);
+void kdbus_fs_exit(void);
+void kdbus_fs_flush(struct kdbus_node *node);
+
+#define kdbus_node_from_inode(_inode) \
+	((struct kdbus_node *)(_inode)->i_private)
+
+#endif
diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
new file mode 100644
index 000000000000..fc60932d69c7
--- /dev/null
+++ b/ipc/kdbus/handle.c
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/syscalls.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "fs.h"
+#include "handle.h"
+#include "item.h"
+#include "match.h"
+#include "message.h"
+#include "names.h"
+#include "domain.h"
+#include "policy.h"
+
+static int kdbus_args_verify(struct kdbus_args *args)
+{
+	struct kdbus_item *item;
+	size_t i;
+	int ret;
+
+	KDBUS_ITEMS_FOREACH(item, args->items, args->items_size) {
+		struct kdbus_arg *arg = NULL;
+
+		if (!KDBUS_ITEM_VALID(item, args->items, args->items_size))
+			return -EINVAL;
+
+		for (i = 0; i < args->argc; ++i)
+			if (args->argv[i].type == item->type)
+				break;
+		if (i >= args->argc)
+			return -EINVAL;
+
+		arg = &args->argv[i];
+
+		ret = kdbus_item_validate(item);
+		if (ret < 0)
+			return ret;
+
+		if (arg->item && !arg->multiple)
+			return -EINVAL;
+
+		arg->item = item;
+	}
+
+	if (!KDBUS_ITEMS_END(item, args->items, args->items_size))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int kdbus_args_negotiate(struct kdbus_args *args)
+{
+	struct kdbus_item __user *user;
+	struct kdbus_item *negotiation;
+	size_t i, j, num;
+
+	/*
+	 * If KDBUS_FLAG_NEGOTIATE is set, we overwrite the flags field with
+	 * the set of supported flags. Furthermore, if an KDBUS_ITEM_NEGOTIATE
+	 * item is passed, we iterate its payload (array of u64, each set to an
+	 * item type) and clear all unsupported item-types to 0.
+	 * The caller might do this recursively, if other flags or objects are
+	 * embedded in the payload itself.
+	 */
+
+	if (args->cmd->flags & KDBUS_FLAG_NEGOTIATE) {
+		if (put_user(args->allowed_flags & ~KDBUS_FLAG_NEGOTIATE,
+			     &args->user->flags))
+			return -EFAULT;
+	}
+
+	if (args->argc < 1 || args->argv[0].type != KDBUS_ITEM_NEGOTIATE ||
+	    !args->argv[0].item)
+		return 0;
+
+	negotiation = args->argv[0].item;
+	user = (struct kdbus_item __user *)
+		((u8 __user *)args->user +
+		 ((u8 *)negotiation - (u8 *)args->cmd));
+	num = KDBUS_ITEM_PAYLOAD_SIZE(negotiation) / sizeof(u64);
+
+	for (i = 0; i < num; ++i) {
+		for (j = 0; j < args->argc; ++j)
+			if (negotiation->data64[i] == args->argv[j].type)
+				break;
+
+		if (j < args->argc)
+			continue;
+
+		/* this item is not supported, clear it out */
+		negotiation->data64[i] = 0;
+		if (put_user(negotiation->data64[i], &user->data64[i]))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ * __kdbus_args_parse() - parse payload of kdbus command
+ * @args:		object to parse data into
+ * @is_cmd:		whether this is a command or msg payload
+ * @argp:		user-space location of command payload to parse
+ * @type_size:		overall size of command payload to parse
+ * @items_offset:	offset of items array in command payload
+ * @out:		output variable to store pointer to copied payload
+ *
+ * This parses the ioctl payload at user-space location @argp into @args. @args
+ * must be pre-initialized by the caller to reflect the supported flags and
+ * items of this command. This parser will then copy the command payload into
+ * kernel-space, verify correctness and consistency and cache pointers to parsed
+ * items and other data in @args.
+ *
+ * If this function succeeded, you must call kdbus_args_clear() to release
+ * allocated resources before destroying @args.
+ *
+ * This can also be used to import kdbus_msg objects. In that case, @is_cmd must
+ * be set to 'false' and the 'return_flags' field will not be touched (as it
+ * doesn't exist on kdbus_msg).
+ *
+ * Return: On failure a negative error code is returned. Otherwise, 1 is
+ * returned if negotiation was requested, 0 if not.
+ */
+int __kdbus_args_parse(struct kdbus_args *args, bool is_cmd, void __user *argp,
+		       size_t type_size, size_t items_offset, void **out)
+{
+	u64 user_size;
+	int ret, i;
+
+	ret = kdbus_copy_from_user(&user_size, argp, sizeof(user_size));
+	if (ret < 0)
+		return ret;
+
+	if (user_size < type_size)
+		return -EINVAL;
+	if (user_size > KDBUS_CMD_MAX_SIZE)
+		return -EMSGSIZE;
+
+	if (user_size <= sizeof(args->cmd_buf)) {
+		if (copy_from_user(args->cmd_buf, argp, user_size))
+			return -EFAULT;
+		args->cmd = (void*)args->cmd_buf;
+	} else {
+		args->cmd = memdup_user(argp, user_size);
+		if (IS_ERR(args->cmd))
+			return PTR_ERR(args->cmd);
+	}
+
+	if (args->cmd->size != user_size) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (is_cmd)
+		args->cmd->return_flags = 0;
+	args->user = argp;
+	args->items = (void *)((u8 *)args->cmd + items_offset);
+	args->items_size = args->cmd->size - items_offset;
+	args->is_cmd = is_cmd;
+
+	if (args->cmd->flags & ~args->allowed_flags) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = kdbus_args_verify(args);
+	if (ret < 0)
+		goto error;
+
+	ret = kdbus_args_negotiate(args);
+	if (ret < 0)
+		goto error;
+
+	/* mandatory items must be given (but not on negotiation) */
+	if (!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE)) {
+		for (i = 0; i < args->argc; ++i)
+			if (args->argv[i].mandatory && !args->argv[i].item) {
+				ret = -EINVAL;
+				goto error;
+			}
+	}
+
+	*out = args->cmd;
+	return !!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE);
+
+error:
+	return kdbus_args_clear(args, ret);
+}
+
+/**
+ * kdbus_args_clear() - release allocated command resources
+ * @args:	object to release resources of
+ * @ret:	return value of this command
+ *
+ * This frees all allocated resources on @args and copies the command result
+ * flags into user-space. @ret is usually returned unchanged by this function,
+ * so it can be used in the final 'return' statement of the command handler.
+ *
+ * Return: -EFAULT if return values cannot be copied into user-space, otherwise
+ *         @ret is returned unchanged.
+ */
+int kdbus_args_clear(struct kdbus_args *args, int ret)
+{
+	if (!args)
+		return ret;
+
+	if (!IS_ERR_OR_NULL(args->cmd)) {
+		if (args->is_cmd && put_user(args->cmd->return_flags,
+					     &args->user->return_flags))
+			ret = -EFAULT;
+		if (args->cmd != (void*)args->cmd_buf)
+			kfree(args->cmd);
+		args->cmd = NULL;
+	}
+
+	return ret;
+}
+
+/**
+ * enum kdbus_handle_type - type an handle can be of
+ * @KDBUS_HANDLE_NONE:		no type set, yet
+ * @KDBUS_HANDLE_BUS_OWNER:	bus owner
+ * @KDBUS_HANDLE_EP_OWNER:	endpoint owner
+ * @KDBUS_HANDLE_CONNECTED:	endpoint connection after HELLO
+ */
+enum kdbus_handle_type {
+	KDBUS_HANDLE_NONE,
+	KDBUS_HANDLE_BUS_OWNER,
+	KDBUS_HANDLE_EP_OWNER,
+	KDBUS_HANDLE_CONNECTED,
+};
+
+/**
+ * struct kdbus_handle - handle to the kdbus system
+ * @lock:		handle lock
+ * @type:		type of this handle (KDBUS_HANDLE_*)
+ * @bus_owner:		bus this handle owns
+ * @ep_owner:		endpoint this handle owns
+ * @conn:		connection this handle owns
+ */
+struct kdbus_handle {
+	struct mutex lock;
+
+	enum kdbus_handle_type type;
+	union {
+		struct kdbus_bus *bus_owner;
+		struct kdbus_ep *ep_owner;
+		struct kdbus_conn *conn;
+	};
+};
+
+static int kdbus_handle_open(struct inode *inode, struct file *file)
+{
+	struct kdbus_handle *handle;
+	struct kdbus_node *node;
+	int ret;
+
+	node = kdbus_node_from_inode(inode);
+	if (!kdbus_node_acquire(node))
+		return -ESHUTDOWN;
+
+	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	mutex_init(&handle->lock);
+	handle->type = KDBUS_HANDLE_NONE;
+
+	file->private_data = handle;
+	ret = 0;
+
+exit:
+	kdbus_node_release(node);
+	return ret;
+}
+
+static int kdbus_handle_release(struct inode *inode, struct file *file)
+{
+	struct kdbus_handle *handle = file->private_data;
+
+	switch (handle->type) {
+	case KDBUS_HANDLE_BUS_OWNER:
+		if (handle->bus_owner) {
+			kdbus_node_deactivate(&handle->bus_owner->node);
+			kdbus_bus_unref(handle->bus_owner);
+		}
+		break;
+	case KDBUS_HANDLE_EP_OWNER:
+		if (handle->ep_owner) {
+			kdbus_node_deactivate(&handle->ep_owner->node);
+			kdbus_ep_unref(handle->ep_owner);
+		}
+		break;
+	case KDBUS_HANDLE_CONNECTED:
+		kdbus_conn_disconnect(handle->conn, false);
+		kdbus_conn_unref(handle->conn);
+		break;
+	case KDBUS_HANDLE_NONE:
+		/* nothing to clean up */
+		break;
+	}
+
+	kfree(handle);
+
+	return 0;
+}
+
+static long kdbus_handle_ioctl_control(struct file *file, unsigned int cmd,
+				       void __user *argp)
+{
+	struct kdbus_handle *handle = file->private_data;
+	struct kdbus_node *node = file_inode(file)->i_private;
+	struct kdbus_domain *domain;
+	int ret = 0;
+
+	if (!kdbus_node_acquire(node))
+		return -ESHUTDOWN;
+
+	/*
+	 * The parent of control-nodes is always a domain, make sure to pin it
+	 * so the parent is actually valid.
+	 */
+	domain = kdbus_domain_from_node(node->parent);
+	if (!kdbus_node_acquire(&domain->node)) {
+		kdbus_node_release(node);
+		return -ESHUTDOWN;
+	}
+
+	switch (cmd) {
+	case KDBUS_CMD_BUS_MAKE: {
+		struct kdbus_bus *bus;
+
+		bus = kdbus_cmd_bus_make(domain, argp);
+		if (IS_ERR_OR_NULL(bus)) {
+			ret = PTR_ERR_OR_ZERO(bus);
+			break;
+		}
+
+		handle->bus_owner = bus;
+		ret = KDBUS_HANDLE_BUS_OWNER;
+		break;
+	}
+
+	default:
+		ret = -EBADFD;
+		break;
+	}
+
+	kdbus_node_release(&domain->node);
+	kdbus_node_release(node);
+	return ret;
+}
+
+static long kdbus_handle_ioctl_ep(struct file *file, unsigned int cmd,
+				  void __user *buf)
+{
+	struct kdbus_handle *handle = file->private_data;
+	struct kdbus_node *node = file_inode(file)->i_private;
+	struct kdbus_ep *ep, *file_ep = kdbus_ep_from_node(node);
+	struct kdbus_bus *bus = file_ep->bus;
+	struct kdbus_conn *conn;
+	int ret = 0;
+
+	if (!kdbus_node_acquire(node))
+		return -ESHUTDOWN;
+
+	switch (cmd) {
+	case KDBUS_CMD_ENDPOINT_MAKE: {
+		/* creating custom endpoints is a privileged operation */
+		if (!kdbus_ep_is_owner(file_ep, file)) {
+			ret = -EPERM;
+			break;
+		}
+
+		ep = kdbus_cmd_ep_make(bus, buf);
+		if (IS_ERR_OR_NULL(ep)) {
+			ret = PTR_ERR_OR_ZERO(ep);
+			break;
+		}
+
+		handle->ep_owner = ep;
+		ret = KDBUS_HANDLE_EP_OWNER;
+		break;
+	}
+
+	case KDBUS_CMD_HELLO:
+		conn = kdbus_cmd_hello(file_ep, file, buf);
+		if (IS_ERR_OR_NULL(conn)) {
+			ret = PTR_ERR_OR_ZERO(conn);
+			break;
+		}
+
+		handle->conn = conn;
+		ret = KDBUS_HANDLE_CONNECTED;
+		break;
+
+	default:
+		ret = -EBADFD;
+		break;
+	}
+
+	kdbus_node_release(node);
+	return ret;
+}
+
+static long kdbus_handle_ioctl_ep_owner(struct file *file, unsigned int command,
+					void __user *buf)
+{
+	struct kdbus_handle *handle = file->private_data;
+	struct kdbus_ep *ep = handle->ep_owner;
+	int ret;
+
+	if (!kdbus_node_acquire(&ep->node))
+		return -ESHUTDOWN;
+
+	switch (command) {
+	case KDBUS_CMD_ENDPOINT_UPDATE:
+		ret = kdbus_cmd_ep_update(ep, buf);
+		break;
+	default:
+		ret = -EBADFD;
+		break;
+	}
+
+	kdbus_node_release(&ep->node);
+	return ret;
+}
+
+static long kdbus_handle_ioctl_connected(struct file *file,
+					 unsigned int command, void __user *buf)
+{
+	struct kdbus_handle *handle = file->private_data;
+	struct kdbus_conn *conn = handle->conn;
+	struct kdbus_conn *release_conn = NULL;
+	int ret;
+
+	release_conn = conn;
+	ret = kdbus_conn_acquire(release_conn);
+	if (ret < 0)
+		return ret;
+
+	switch (command) {
+	case KDBUS_CMD_BYEBYE:
+		/*
+		 * BYEBYE is special; we must not acquire a connection when
+		 * calling into kdbus_conn_disconnect() or we will deadlock,
+		 * because kdbus_conn_disconnect() will wait for all acquired
+		 * references to be dropped.
+		 */
+		kdbus_conn_release(release_conn);
+		release_conn = NULL;
+		ret = kdbus_cmd_byebye_unlocked(conn, buf);
+		break;
+	case KDBUS_CMD_NAME_ACQUIRE:
+		ret = kdbus_cmd_name_acquire(conn, buf);
+		break;
+	case KDBUS_CMD_NAME_RELEASE:
+		ret = kdbus_cmd_name_release(conn, buf);
+		break;
+	case KDBUS_CMD_LIST:
+		ret = kdbus_cmd_list(conn, buf);
+		break;
+	case KDBUS_CMD_CONN_INFO:
+		ret = kdbus_cmd_conn_info(conn, buf);
+		break;
+	case KDBUS_CMD_BUS_CREATOR_INFO:
+		ret = kdbus_cmd_bus_creator_info(conn, buf);
+		break;
+	case KDBUS_CMD_UPDATE:
+		ret = kdbus_cmd_update(conn, buf);
+		break;
+	case KDBUS_CMD_MATCH_ADD:
+		ret = kdbus_cmd_match_add(conn, buf);
+		break;
+	case KDBUS_CMD_MATCH_REMOVE:
+		ret = kdbus_cmd_match_remove(conn, buf);
+		break;
+	case KDBUS_CMD_SEND:
+		ret = kdbus_cmd_send(conn, file, buf);
+		break;
+	case KDBUS_CMD_RECV:
+		ret = kdbus_cmd_recv(conn, buf);
+		break;
+	case KDBUS_CMD_FREE:
+		ret = kdbus_cmd_free(conn, buf);
+		break;
+	default:
+		ret = -EBADFD;
+		break;
+	}
+
+	kdbus_conn_release(release_conn);
+	return ret;
+}
+
+static long kdbus_handle_ioctl(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	struct kdbus_handle *handle = file->private_data;
+	struct kdbus_node *node = kdbus_node_from_inode(file_inode(file));
+	void __user *argp = (void __user *)arg;
+	long ret = -EBADFD;
+
+	switch (cmd) {
+	case KDBUS_CMD_BUS_MAKE:
+	case KDBUS_CMD_ENDPOINT_MAKE:
+	case KDBUS_CMD_HELLO:
+		mutex_lock(&handle->lock);
+		if (handle->type == KDBUS_HANDLE_NONE) {
+			if (node->type == KDBUS_NODE_CONTROL)
+				ret = kdbus_handle_ioctl_control(file, cmd,
+								 argp);
+			else if (node->type == KDBUS_NODE_ENDPOINT)
+				ret = kdbus_handle_ioctl_ep(file, cmd, argp);
+
+			if (ret > 0) {
+				/*
+				 * The data given via open() is not sufficient
+				 * to setup a kdbus handle. Hence, we require
+				 * the user to perform a setup ioctl. This setup
+				 * can only be performed once and defines the
+				 * type of the handle. The different setup
+				 * ioctls are locked against each other so they
+				 * cannot race. Once the handle type is set,
+				 * the type-dependent ioctls are enabled. To
+				 * improve performance, we don't lock those via
+				 * handle->lock. Instead, we issue a
+				 * write-barrier before performing the
+				 * type-change, which pairs with smp_rmb() in
+				 * all handlers that access the type field. This
+				 * guarantees the handle is fully setup, if
+				 * handle->type is set. If handle->type is
+				 * unset, you must not make any assumptions
+				 * without taking handle->lock.
+				 * Note that handle->type is only set once. It
+				 * will never change afterwards.
+				 */
+				smp_wmb();
+				handle->type = ret;
+			}
+		}
+		mutex_unlock(&handle->lock);
+		break;
+
+	case KDBUS_CMD_ENDPOINT_UPDATE:
+	case KDBUS_CMD_BYEBYE:
+	case KDBUS_CMD_NAME_ACQUIRE:
+	case KDBUS_CMD_NAME_RELEASE:
+	case KDBUS_CMD_LIST:
+	case KDBUS_CMD_CONN_INFO:
+	case KDBUS_CMD_BUS_CREATOR_INFO:
+	case KDBUS_CMD_UPDATE:
+	case KDBUS_CMD_MATCH_ADD:
+	case KDBUS_CMD_MATCH_REMOVE:
+	case KDBUS_CMD_SEND:
+	case KDBUS_CMD_RECV:
+	case KDBUS_CMD_FREE: {
+		enum kdbus_handle_type type;
+
+		/*
+		 * This read-barrier pairs with smp_wmb() of the handle setup.
+		 * it guarantees the handle is fully written, in case the
+		 * type has been set. It allows us to access the handle without
+		 * taking handle->lock, given the guarantee that the type is
+		 * only ever set once, and stays constant afterwards.
+		 * Furthermore, the handle object itself is not modified in any
+		 * way after the type is set. That is, the type-field is the
+		 * last field that is written on any handle. If it has not been
+		 * set, we must not access the handle here.
+		 */
+		type = handle->type;
+		smp_rmb();
+
+		if (type == KDBUS_HANDLE_EP_OWNER)
+			ret = kdbus_handle_ioctl_ep_owner(file, cmd, argp);
+		else if (type == KDBUS_HANDLE_CONNECTED)
+			ret = kdbus_handle_ioctl_connected(file, cmd, argp);
+
+		break;
+	}
+	default:
+		ret = -ENOTTY;
+		break;
+	}
+
+	return ret < 0 ? ret : 0;
+}
+
+static unsigned int kdbus_handle_poll(struct file *file,
+				      struct poll_table_struct *wait)
+{
+	struct kdbus_handle *handle = file->private_data;
+	enum kdbus_handle_type type;
+	unsigned int mask = POLLOUT | POLLWRNORM;
+
+	/*
+	 * This pairs with smp_wmb() during handle setup. It guarantees that
+	 * _iff_ the handle type is set, handle->conn is valid. Furthermore,
+	 * _iff_ the type is set, the handle object is constant and never
+	 * changed again. If it's not set, we must not access the handle but
+	 * bail out. We also must assume no setup has taken place, yet.
+	 */
+	type = handle->type;
+	smp_rmb();
+
+	/* Only a connected endpoint can read/write data */
+	if (type != KDBUS_HANDLE_CONNECTED)
+		return POLLERR | POLLHUP;
+
+	poll_wait(file, &handle->conn->wait, wait);
+
+	/*
+	 * Verify the connection hasn't been deactivated _after_ adding the
+	 * wait-queue. This guarantees, that if the connection is deactivated
+	 * after we checked it, the waitqueue is signaled and we're called
+	 * again.
+	 */
+	if (!kdbus_conn_active(handle->conn))
+		return POLLERR | POLLHUP;
+
+	if (!list_empty(&handle->conn->queue.msg_list) ||
+	    atomic_read(&handle->conn->lost_count) > 0)
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+static int kdbus_handle_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct kdbus_handle *handle = file->private_data;
+	enum kdbus_handle_type type;
+	int ret = -EBADFD;
+
+	/*
+	 * This pairs with smp_wmb() during handle setup. It guarantees that
+	 * _iff_ the handle type is set, handle->conn is valid. Furthermore,
+	 * _iff_ the type is set, the handle object is constant and never
+	 * changed again. If it's not set, we must not access the handle but
+	 * bail out. We also must assume no setup has taken place, yet.
+	 */
+	type = handle->type;
+	smp_rmb();
+
+	/* Only connected handles have a pool we can map */
+	if (type == KDBUS_HANDLE_CONNECTED)
+		ret = kdbus_pool_mmap(handle->conn->pool, vma);
+
+	return ret;
+}
+
+const struct file_operations kdbus_handle_ops = {
+	.owner =		THIS_MODULE,
+	.open =			kdbus_handle_open,
+	.release =		kdbus_handle_release,
+	.poll =			kdbus_handle_poll,
+	.llseek =		noop_llseek,
+	.unlocked_ioctl =	kdbus_handle_ioctl,
+	.mmap =			kdbus_handle_mmap,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl =		kdbus_handle_ioctl,
+#endif
+};
diff --git a/ipc/kdbus/handle.h b/ipc/kdbus/handle.h
new file mode 100644
index 000000000000..5dde2c10bed4
--- /dev/null
+++ b/ipc/kdbus/handle.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_HANDLE_H
+#define __KDBUS_HANDLE_H
+
+#include <linux/fs.h>
+#include <uapi/linux/kdbus.h>
+
+extern const struct file_operations kdbus_handle_ops;
+
+/**
+ * kdbus_arg - information and state of a single ioctl command item
+ * @type:		item type
+ * @item:		set by the parser to the first found item of this type
+ * @multiple:		whether multiple items of this type are allowed
+ * @mandatory:		whether at least one item of this type is required
+ *
+ * This structure describes a single item in an ioctl command payload. The
+ * caller has to pre-fill the type and flags, the parser will then use this
+ * information to verify the ioctl payload. @item is set by the parser to point
+ * to the first occurrence of the item.
+ */
+struct kdbus_arg {
+	u64 type;
+	struct kdbus_item *item;
+	bool multiple : 1;
+	bool mandatory : 1;
+};
+
+/**
+ * kdbus_args - information and state of ioctl command parser
+ * @allowed_flags:	set of flags this command supports
+ * @argc:		number of items in @argv
+ * @argv:		array of items this command supports
+ * @user:		set by parser to user-space location of current command
+ * @cmd:		set by parser to kernel copy of command payload
+ * @cmd_buf:		inline buf to avoid kmalloc() on small cmds
+ * @items:		points to item array in @cmd
+ * @items_size:		size of @items in bytes
+ * @is_cmd:		whether this is a command-payload or msg-payload
+ *
+ * This structure is used to parse ioctl command payloads on each invocation.
+ * The ioctl handler has to pre-fill the flags and allowed items before passing
+ * the object to kdbus_args_parse(). The parser will copy the command payload
+ * into kernel-space and verify the correctness of the data.
+ *
+ * We use a 256 bytes buffer for small command payloads, to be allocated on
+ * stack on syscall entrance.
+ */
+struct kdbus_args {
+	u64 allowed_flags;
+	size_t argc;
+	struct kdbus_arg *argv;
+
+	struct kdbus_cmd __user *user;
+	struct kdbus_cmd *cmd;
+	u8 cmd_buf[256];
+
+	struct kdbus_item *items;
+	size_t items_size;
+	bool is_cmd : 1;
+};
+
+int __kdbus_args_parse(struct kdbus_args *args, bool is_cmd, void __user *argp,
+		       size_t type_size, size_t items_offset, void **out);
+int kdbus_args_clear(struct kdbus_args *args, int ret);
+
+#define kdbus_args_parse(_args, _argp, _v)                              \
+	({                                                              \
+		BUILD_BUG_ON(offsetof(typeof(**(_v)), size) !=          \
+			     offsetof(struct kdbus_cmd, size));         \
+		BUILD_BUG_ON(offsetof(typeof(**(_v)), flags) !=         \
+			     offsetof(struct kdbus_cmd, flags));        \
+		BUILD_BUG_ON(offsetof(typeof(**(_v)), return_flags) !=  \
+			     offsetof(struct kdbus_cmd, return_flags)); \
+		__kdbus_args_parse((_args), 1, (_argp), sizeof(**(_v)), \
+				   offsetof(typeof(**(_v)), items),     \
+				   (void **)(_v));                      \
+	})
+
+#define kdbus_args_parse_msg(_args, _argp, _v)                          \
+	({                                                              \
+		BUILD_BUG_ON(offsetof(typeof(**(_v)), size) !=          \
+			     offsetof(struct kdbus_cmd, size));         \
+		BUILD_BUG_ON(offsetof(typeof(**(_v)), flags) !=         \
+			     offsetof(struct kdbus_cmd, flags));        \
+		__kdbus_args_parse((_args), 0, (_argp), sizeof(**(_v)), \
+				   offsetof(typeof(**(_v)), items),     \
+				   (void **)(_v));                      \
+	})
+
+#endif
diff --git a/ipc/kdbus/item.c b/ipc/kdbus/item.c
new file mode 100644
index 000000000000..ce78dba03426
--- /dev/null
+++ b/ipc/kdbus/item.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/ctype.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+
+#include "item.h"
+#include "limits.h"
+#include "util.h"
+
+/*
+ * This verifies the string at position @str with size @size is properly
+ * zero-terminated and does not contain a 0-byte but at the end.
+ */
+static bool kdbus_str_valid(const char *str, size_t size)
+{
+	return size > 0 && memchr(str, '\0', size) == str + size - 1;
+}
+
+/**
+ * kdbus_item_validate_name() - validate an item containing a name
+ * @item:		Item to validate
+ *
+ * Return: zero on success or an negative error code on failure
+ */
+int kdbus_item_validate_name(const struct kdbus_item *item)
+{
+	const char *name = item->str;
+	unsigned int i;
+	size_t len;
+
+	if (item->size < KDBUS_ITEM_HEADER_SIZE + 2)
+		return -EINVAL;
+
+	if (item->size > KDBUS_ITEM_HEADER_SIZE +
+			 KDBUS_SYSNAME_MAX_LEN + 1)
+		return -ENAMETOOLONG;
+
+	if (!kdbus_str_valid(name, KDBUS_ITEM_PAYLOAD_SIZE(item)))
+		return -EINVAL;
+
+	len = strlen(name);
+	if (len == 0)
+		return -EINVAL;
+
+	for (i = 0; i < len; i++) {
+		if (isalpha(name[i]))
+			continue;
+		if (isdigit(name[i]))
+			continue;
+		if (name[i] == '_')
+			continue;
+		if (i > 0 && i + 1 < len && (name[i] == '-' || name[i] == '.'))
+			continue;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * kdbus_item_validate() - validate a single item
+ * @item:	item to validate
+ *
+ * Return: 0 if item is valid, negative error code if not.
+ */
+int kdbus_item_validate(const struct kdbus_item *item)
+{
+	size_t payload_size = KDBUS_ITEM_PAYLOAD_SIZE(item);
+	size_t l;
+	int ret;
+
+	BUILD_BUG_ON(KDBUS_ITEM_HEADER_SIZE !=
+		     sizeof(struct kdbus_item_header));
+
+	if (item->size < KDBUS_ITEM_HEADER_SIZE)
+		return -EINVAL;
+
+	switch (item->type) {
+	case KDBUS_ITEM_NEGOTIATE:
+		if (payload_size % sizeof(u64) != 0)
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_PAYLOAD_VEC:
+	case KDBUS_ITEM_PAYLOAD_OFF:
+		if (payload_size != sizeof(struct kdbus_vec))
+			return -EINVAL;
+		if (item->vec.size == 0 || item->vec.size > SIZE_MAX)
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_PAYLOAD_MEMFD:
+		if (payload_size != sizeof(struct kdbus_memfd))
+			return -EINVAL;
+		if (item->memfd.size == 0 || item->memfd.size > SIZE_MAX)
+			return -EINVAL;
+		if (item->memfd.fd < 0)
+			return -EBADF;
+		break;
+
+	case KDBUS_ITEM_FDS:
+		if (payload_size % sizeof(int) != 0)
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_CANCEL_FD:
+		if (payload_size != sizeof(int))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_BLOOM_PARAMETER:
+		if (payload_size != sizeof(struct kdbus_bloom_parameter))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_BLOOM_FILTER:
+		/* followed by the bloom-mask, depends on the bloom-size */
+		if (payload_size < sizeof(struct kdbus_bloom_filter))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_BLOOM_MASK:
+		/* size depends on bloom-size of bus */
+		break;
+
+	case KDBUS_ITEM_CONN_DESCRIPTION:
+	case KDBUS_ITEM_MAKE_NAME:
+		ret = kdbus_item_validate_name(item);
+		if (ret < 0)
+			return ret;
+		break;
+
+	case KDBUS_ITEM_ATTACH_FLAGS_SEND:
+	case KDBUS_ITEM_ATTACH_FLAGS_RECV:
+	case KDBUS_ITEM_ID:
+	case KDBUS_ITEM_DST_ID:
+		if (payload_size != sizeof(u64))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_TIMESTAMP:
+		if (payload_size != sizeof(struct kdbus_timestamp))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_CREDS:
+		if (payload_size != sizeof(struct kdbus_creds))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_AUXGROUPS:
+		if (payload_size % sizeof(u32) != 0)
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_NAME:
+	case KDBUS_ITEM_DST_NAME:
+	case KDBUS_ITEM_PID_COMM:
+	case KDBUS_ITEM_TID_COMM:
+	case KDBUS_ITEM_EXE:
+	case KDBUS_ITEM_CMDLINE:
+	case KDBUS_ITEM_CGROUP:
+	case KDBUS_ITEM_SECLABEL:
+		if (!kdbus_str_valid(item->str, payload_size))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_CAPS:
+		if (payload_size < sizeof(u32))
+			return -EINVAL;
+		if (payload_size < sizeof(u32) +
+		    4 * CAP_TO_INDEX(item->caps.last_cap) * sizeof(u32))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_AUDIT:
+		if (payload_size != sizeof(struct kdbus_audit))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_POLICY_ACCESS:
+		if (payload_size != sizeof(struct kdbus_policy_access))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_NAME_ADD:
+	case KDBUS_ITEM_NAME_REMOVE:
+	case KDBUS_ITEM_NAME_CHANGE:
+		if (payload_size < sizeof(struct kdbus_notify_name_change))
+			return -EINVAL;
+		l = payload_size - offsetof(struct kdbus_notify_name_change,
+					    name);
+		if (l > 0 && !kdbus_str_valid(item->name_change.name, l))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_ID_ADD:
+	case KDBUS_ITEM_ID_REMOVE:
+		if (payload_size != sizeof(struct kdbus_notify_id_change))
+			return -EINVAL;
+		break;
+
+	case KDBUS_ITEM_REPLY_TIMEOUT:
+	case KDBUS_ITEM_REPLY_DEAD:
+		if (payload_size != 0)
+			return -EINVAL;
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * kdbus_items_validate() - validate items passed by user-space
+ * @items:		items to validate
+ * @items_size:		number of items
+ *
+ * This verifies that the passed items pointer is consistent and valid.
+ * Furthermore, each item is checked for:
+ *  - valid "size" value
+ *  - payload is of expected type
+ *  - payload is fully included in the item
+ *  - string payloads are zero-terminated
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_items_validate(const struct kdbus_item *items, size_t items_size)
+{
+	const struct kdbus_item *item;
+	int ret;
+
+	KDBUS_ITEMS_FOREACH(item, items, items_size) {
+		if (!KDBUS_ITEM_VALID(item, items, items_size))
+			return -EINVAL;
+
+		ret = kdbus_item_validate(item);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!KDBUS_ITEMS_END(item, items, items_size))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * kdbus_item_set() - Set item content
+ * @item:	The item to modify
+ * @type:	The item type to set (KDBUS_ITEM_*)
+ * @data:	Data to copy to item->data, may be %NULL
+ * @len:	Number of bytes in @data
+ *
+ * This sets type, size and data fields of an item. If @data is NULL, the data
+ * memory is cleared.
+ *
+ * Note that you must align your @data memory to 8 bytes. Trailing padding (in
+ * case @len is not 8byte aligned) is cleared by this call.
+ *
+ * Returns: Pointer to the following item.
+ */
+struct kdbus_item *kdbus_item_set(struct kdbus_item *item, u64 type,
+				  const void *data, size_t len)
+{
+	item->type = type;
+	item->size = KDBUS_ITEM_HEADER_SIZE + len;
+
+	if (data) {
+		memcpy(item->data, data, len);
+		memset(item->data + len, 0, KDBUS_ALIGN8(len) - len);
+	} else {
+		memset(item->data, 0, KDBUS_ALIGN8(len));
+	}
+
+	return KDBUS_ITEM_NEXT(item);
+}
diff --git a/ipc/kdbus/item.h b/ipc/kdbus/item.h
new file mode 100644
index 000000000000..3a7e6ccc253c
--- /dev/null
+++ b/ipc/kdbus/item.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_ITEM_H
+#define __KDBUS_ITEM_H
+
+#include <linux/kernel.h>
+#include <uapi/linux/kdbus.h>
+
+#include "util.h"
+
+/* generic access and iterators over a stream of items */
+#define KDBUS_ITEM_NEXT(_i) (typeof(_i))((u8 *)(_i) + KDBUS_ALIGN8((_i)->size))
+#define KDBUS_ITEMS_SIZE(_h, _is) ((_h)->size - offsetof(typeof(*(_h)), _is))
+#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
+#define KDBUS_ITEM_SIZE(_s) KDBUS_ALIGN8(KDBUS_ITEM_HEADER_SIZE + (_s))
+#define KDBUS_ITEM_PAYLOAD_SIZE(_i) ((_i)->size - KDBUS_ITEM_HEADER_SIZE)
+
+#define KDBUS_ITEMS_FOREACH(_i, _is, _s)				\
+	for ((_i) = (_is);						\
+	     ((u8 *)(_i) < (u8 *)(_is) + (_s)) &&			\
+	       ((u8 *)(_i) >= (u8 *)(_is));				\
+	     (_i) = KDBUS_ITEM_NEXT(_i))
+
+#define KDBUS_ITEM_VALID(_i, _is, _s)					\
+	((_i)->size >= KDBUS_ITEM_HEADER_SIZE &&			\
+	 (u8 *)(_i) + (_i)->size > (u8 *)(_i) &&			\
+	 (u8 *)(_i) + (_i)->size <= (u8 *)(_is) + (_s) &&		\
+	 (u8 *)(_i) >= (u8 *)(_is))
+
+#define KDBUS_ITEMS_END(_i, _is, _s)					\
+	((u8 *)(_i) == ((u8 *)(_is) + KDBUS_ALIGN8(_s)))
+
+/**
+ * struct kdbus_item_header - Describes the fix part of an item
+ * @size:	The total size of the item
+ * @type:	The item type, one of KDBUS_ITEM_*
+ */
+struct kdbus_item_header {
+	u64 size;
+	u64 type;
+};
+
+int kdbus_item_validate_name(const struct kdbus_item *item);
+int kdbus_item_validate(const struct kdbus_item *item);
+int kdbus_items_validate(const struct kdbus_item *items, size_t items_size);
+struct kdbus_item *kdbus_item_set(struct kdbus_item *item, u64 type,
+				  const void *data, size_t len);
+
+#endif
diff --git a/ipc/kdbus/limits.h b/ipc/kdbus/limits.h
new file mode 100644
index 000000000000..c54925a25971
--- /dev/null
+++ b/ipc/kdbus/limits.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_DEFAULTS_H
+#define __KDBUS_DEFAULTS_H
+
+#include <linux/kernel.h>
+
+/* maximum size of message header and items */
+#define KDBUS_MSG_MAX_SIZE		SZ_8K
+
+/* maximum number of memfd items per message */
+#define KDBUS_MSG_MAX_MEMFD_ITEMS	16
+
+/* max size of ioctl command data */
+#define KDBUS_CMD_MAX_SIZE		SZ_32K
+
+/* maximum number of inflight fds in a target queue per user */
+#define KDBUS_CONN_MAX_FDS_PER_USER	16
+
+/* maximum message payload size */
+#define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE		SZ_2M
+
+/* maximum size of bloom bit field in bytes */
+#define KDBUS_BUS_BLOOM_MAX_SIZE		SZ_4K
+
+/* maximum length of well-known bus name */
+#define KDBUS_NAME_MAX_LEN			255
+
+/* maximum length of bus, domain, ep name */
+#define KDBUS_SYSNAME_MAX_LEN			63
+
+/* maximum number of matches per connection */
+#define KDBUS_MATCH_MAX				256
+
+/* maximum number of queued messages from the same individual user */
+#define KDBUS_CONN_MAX_MSGS			256
+
+/* maximum number of well-known names per connection */
+#define KDBUS_CONN_MAX_NAMES			256
+
+/* maximum number of queued requests waiting for a reply */
+#define KDBUS_CONN_MAX_REQUESTS_PENDING		128
+
+/* maximum number of connections per user in one domain */
+#define KDBUS_USER_MAX_CONN			1024
+
+/* maximum number of buses per user in one domain */
+#define KDBUS_USER_MAX_BUSES			16
+
+#endif
diff --git a/ipc/kdbus/main.c b/ipc/kdbus/main.c
new file mode 100644
index 000000000000..1ad4dc8dafa1
--- /dev/null
+++ b/ipc/kdbus/main.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "util.h"
+#include "fs.h"
+#include "handle.h"
+#include "metadata.h"
+#include "node.h"
+
+/*
+ * This is a simplified outline of the internal kdbus object relations, for
+ * those interested in the inner life of the driver implementation.
+ *
+ * From a mount point's (domain's) perspective:
+ *
+ * struct kdbus_domain
+ *   |» struct kdbus_user *user (many, owned)
+ *   '» struct kdbus_node node (embedded)
+ *       |» struct kdbus_node children (many, referenced)
+ *       |» struct kdbus_node *parent (pinned)
+ *       '» struct kdbus_bus (many, pinned)
+ *           |» struct kdbus_node node (embedded)
+ *           '» struct kdbus_ep (many, pinned)
+ *               |» struct kdbus_node node (embedded)
+ *               |» struct kdbus_bus *bus (pinned)
+ *               |» struct kdbus_conn conn_list (many, pinned)
+ *               |   |» struct kdbus_ep *ep (pinned)
+ *               |   |» struct kdbus_name_entry *activator_of (owned)
+ *               |   |» struct kdbus_match_db *match_db (owned)
+ *               |   |» struct kdbus_meta *meta (owned)
+ *               |   |» struct kdbus_match_db *match_db (owned)
+ *               |   |    '» struct kdbus_match_entry (many, owned)
+ *               |   |
+ *               |   |» struct kdbus_pool *pool (owned)
+ *               |   |    '» struct kdbus_pool_slice *slices (many, owned)
+ *               |   |       '» struct kdbus_pool *pool (pinned)
+ *               |   |
+ *               |   |» struct kdbus_user *user (pinned)
+ *               |   `» struct kdbus_queue_entry entries (many, embedded)
+ *               |        |» struct kdbus_pool_slice *slice (pinned)
+ *               |        |» struct kdbus_conn_reply *reply (owned)
+ *               |        '» struct kdbus_user *user (pinned)
+ *               |
+ *               '» struct kdbus_user *user (pinned)
+ *                   '» struct kdbus_policy_db policy_db (embedded)
+ *                        |» struct kdbus_policy_db_entry (many, owned)
+ *                        |   |» struct kdbus_conn (pinned)
+ *                        |   '» struct kdbus_ep (pinned)
+ *                        |
+ *                        '» struct kdbus_policy_db_cache_entry (many, owned)
+ *                            '» struct kdbus_conn (pinned)
+ *
+ * For the life-time of a file descriptor derived from calling open() on a file
+ * inside the mount point:
+ *
+ * struct kdbus_handle
+ *  |» struct kdbus_meta *meta (owned)
+ *  |» struct kdbus_ep *ep (pinned)
+ *  |» struct kdbus_conn *conn (owned)
+ *  '» struct kdbus_ep *ep (owned)
+ */
+
+/* kdbus mount-point /sys/fs/kdbus */
+static struct kobject *kdbus_dir;
+
+static int __init kdbus_init(void)
+{
+	int ret;
+
+	kdbus_dir = kobject_create_and_add(KBUILD_MODNAME, fs_kobj);
+	if (!kdbus_dir)
+		return -ENOMEM;
+
+	ret = kdbus_fs_init();
+	if (ret < 0) {
+		pr_err("cannot register filesystem: %d\n", ret);
+		goto exit_dir;
+	}
+
+	pr_info("initialized\n");
+	return 0;
+
+exit_dir:
+	kobject_put(kdbus_dir);
+	return ret;
+}
+
+static void __exit kdbus_exit(void)
+{
+	kdbus_fs_exit();
+	kobject_put(kdbus_dir);
+	ida_destroy(&kdbus_node_ida);
+}
+
+module_init(kdbus_init);
+module_exit(kdbus_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("D-Bus, powerful, easy to use interprocess communication");
+MODULE_ALIAS_FS(KBUILD_MODNAME "fs");
diff --git a/ipc/kdbus/match.c b/ipc/kdbus/match.c
new file mode 100644
index 000000000000..4ee6a1f2e1bc
--- /dev/null
+++ b/ipc/kdbus/match.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/hash.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "item.h"
+#include "match.h"
+#include "message.h"
+#include "names.h"
+
+/**
+ * struct kdbus_match_db - message filters
+ * @entries_list:	List of matches
+ * @mdb_rwlock:		Match data lock
+ * @entries_count:	Number of entries in database
+ */
+struct kdbus_match_db {
+	struct list_head entries_list;
+	struct rw_semaphore mdb_rwlock;
+	unsigned int entries_count;
+};
+
+/**
+ * struct kdbus_match_entry - a match database entry
+ * @cookie:		User-supplied cookie to lookup the entry
+ * @list_entry:		The list entry element for the db list
+ * @rules_list:		The list head for tracking rules of this entry
+ */
+struct kdbus_match_entry {
+	u64 cookie;
+	struct list_head list_entry;
+	struct list_head rules_list;
+};
+
+/**
+ * struct kdbus_bloom_mask - mask to match against filter
+ * @generations:	Number of generations carried
+ * @data:		Array of bloom bit fields
+ */
+struct kdbus_bloom_mask {
+	u64 generations;
+	u64 *data;
+};
+
+/**
+ * struct kdbus_match_rule - a rule appended to a match entry
+ * @type:		An item type to match against
+ * @bloom_mask:		Bloom mask to match a message's filter against, used
+ *			with KDBUS_ITEM_BLOOM_MASK
+ * @name:		Name to match against, used with KDBUS_ITEM_NAME,
+ *			KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
+ * @old_id:		ID to match against, used with
+ *			KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE},
+ *			KDBUS_ITEM_ID_REMOVE
+ * @new_id:		ID to match against, used with
+ *			KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE},
+ *			KDBUS_ITEM_ID_REMOVE
+ * @src_id:		ID to match against, used with KDBUS_ITEM_ID
+ * @dst_id:		Message destination ID, used with KDBUS_ITEM_DST_ID
+ * @rules_entry:	Entry in the entry's rules list
+ */
+struct kdbus_match_rule {
+	u64 type;
+	union {
+		struct kdbus_bloom_mask bloom_mask;
+		struct {
+			char *name;
+			u64 old_id;
+			u64 new_id;
+		};
+		u64 src_id;
+		u64 dst_id;
+	};
+	struct list_head rules_entry;
+};
+
+static void kdbus_match_rule_free(struct kdbus_match_rule *rule)
+{
+	if (!rule)
+		return;
+
+	switch (rule->type) {
+	case KDBUS_ITEM_BLOOM_MASK:
+		kfree(rule->bloom_mask.data);
+		break;
+
+	case KDBUS_ITEM_NAME:
+	case KDBUS_ITEM_NAME_ADD:
+	case KDBUS_ITEM_NAME_REMOVE:
+	case KDBUS_ITEM_NAME_CHANGE:
+		kfree(rule->name);
+		break;
+
+	case KDBUS_ITEM_ID:
+	case KDBUS_ITEM_DST_ID:
+	case KDBUS_ITEM_ID_ADD:
+	case KDBUS_ITEM_ID_REMOVE:
+		break;
+
+	default:
+		BUG();
+	}
+
+	list_del(&rule->rules_entry);
+	kfree(rule);
+}
+
+static void kdbus_match_entry_free(struct kdbus_match_entry *entry)
+{
+	struct kdbus_match_rule *r, *tmp;
+
+	if (!entry)
+		return;
+
+	list_for_each_entry_safe(r, tmp, &entry->rules_list, rules_entry)
+		kdbus_match_rule_free(r);
+
+	list_del(&entry->list_entry);
+	kfree(entry);
+}
+
+/**
+ * kdbus_match_db_free() - free match db resources
+ * @mdb:		The match database
+ */
+void kdbus_match_db_free(struct kdbus_match_db *mdb)
+{
+	struct kdbus_match_entry *entry, *tmp;
+
+	if (!mdb)
+		return;
+
+	list_for_each_entry_safe(entry, tmp, &mdb->entries_list, list_entry)
+		kdbus_match_entry_free(entry);
+
+	kfree(mdb);
+}
+
+/**
+ * kdbus_match_db_new() - create a new match database
+ *
+ * Return: a new kdbus_match_db on success, ERR_PTR on failure.
+ */
+struct kdbus_match_db *kdbus_match_db_new(void)
+{
+	struct kdbus_match_db *d;
+
+	d = kzalloc(sizeof(*d), GFP_KERNEL);
+	if (!d)
+		return ERR_PTR(-ENOMEM);
+
+	init_rwsem(&d->mdb_rwlock);
+	INIT_LIST_HEAD(&d->entries_list);
+
+	return d;
+}
+
+static bool kdbus_match_bloom(const struct kdbus_bloom_filter *filter,
+			      const struct kdbus_bloom_mask *mask,
+			      const struct kdbus_conn *conn)
+{
+	size_t n = conn->ep->bus->bloom.size / sizeof(u64);
+	const u64 *m;
+	size_t i;
+
+	/*
+	 * The message's filter carries a generation identifier, the
+	 * match's mask possibly carries an array of multiple generations
+	 * of the mask. Select the mask with the closest match of the
+	 * filter's generation.
+	 */
+	m = mask->data + (min(filter->generation, mask->generations - 1) * n);
+
+	/*
+	 * The message's filter contains the messages properties,
+	 * the match's mask contains the properties to look for in the
+	 * message. Check the mask bit field against the filter bit field,
+	 * if the message possibly carries the properties the connection
+	 * has subscribed to.
+	 */
+	for (i = 0; i < n; i++)
+		if ((filter->data[i] & m[i]) != m[i])
+			return false;
+
+	return true;
+}
+
+static bool kdbus_match_rule_conn(const struct kdbus_match_rule *r,
+				  struct kdbus_conn *c,
+				  const struct kdbus_staging *s)
+{
+	lockdep_assert_held(&c->ep->bus->name_registry->rwlock);
+
+	switch (r->type) {
+	case KDBUS_ITEM_BLOOM_MASK:
+		return kdbus_match_bloom(s->bloom_filter, &r->bloom_mask, c);
+	case KDBUS_ITEM_ID:
+		return r->src_id == c->id || r->src_id == KDBUS_MATCH_ID_ANY;
+	case KDBUS_ITEM_DST_ID:
+		return r->dst_id == s->msg->dst_id ||
+		       r->dst_id == KDBUS_MATCH_ID_ANY;
+	case KDBUS_ITEM_NAME:
+		return kdbus_conn_has_name(c, r->name);
+	default:
+		return false;
+	}
+}
+
+static bool kdbus_match_rule_kernel(const struct kdbus_match_rule *r,
+				    const struct kdbus_staging *s)
+{
+	struct kdbus_item *n = s->notify;
+
+	if (WARN_ON(!n) || n->type != r->type)
+		return false;
+
+	switch (r->type) {
+	case KDBUS_ITEM_ID_ADD:
+		return r->new_id == KDBUS_MATCH_ID_ANY ||
+		       r->new_id == n->id_change.id;
+	case KDBUS_ITEM_ID_REMOVE:
+		return r->old_id == KDBUS_MATCH_ID_ANY ||
+		       r->old_id == n->id_change.id;
+	case KDBUS_ITEM_NAME_ADD:
+	case KDBUS_ITEM_NAME_CHANGE:
+	case KDBUS_ITEM_NAME_REMOVE:
+		return (r->old_id == KDBUS_MATCH_ID_ANY ||
+		        r->old_id == n->name_change.old_id.id) &&
+		       (r->new_id == KDBUS_MATCH_ID_ANY ||
+		        r->new_id == n->name_change.new_id.id) &&
+		       (!r->name || !strcmp(r->name, n->name_change.name));
+	default:
+		return false;
+	}
+}
+
+static bool kdbus_match_rules(const struct kdbus_match_entry *entry,
+			      struct kdbus_conn *c,
+			      const struct kdbus_staging *s)
+{
+	struct kdbus_match_rule *r;
+
+	list_for_each_entry(r, &entry->rules_list, rules_entry)
+		if ((c && !kdbus_match_rule_conn(r, c, s)) ||
+		    (!c && !kdbus_match_rule_kernel(r, s)))
+			return false;
+
+	return true;
+}
+
+/**
+ * kdbus_match_db_match_msg() - match a msg object agains the database entries
+ * @mdb:		The match database
+ * @conn_src:		The connection object originating the message
+ * @staging:		Staging object containing the message to match against
+ *
+ * This function will walk through all the database entries previously uploaded
+ * with kdbus_match_db_add(). As soon as any of them has an all-satisfied rule
+ * set, this function will return true.
+ *
+ * The caller must hold the registry lock of conn_src->ep->bus, in case conn_src
+ * is non-NULL.
+ *
+ * Return: true if there was a matching database entry, false otherwise.
+ */
+bool kdbus_match_db_match_msg(struct kdbus_match_db *mdb,
+			      struct kdbus_conn *conn_src,
+			      const struct kdbus_staging *staging)
+{
+	struct kdbus_match_entry *entry;
+	bool matched = false;
+
+	down_read(&mdb->mdb_rwlock);
+	list_for_each_entry(entry, &mdb->entries_list, list_entry) {
+		matched = kdbus_match_rules(entry, conn_src, staging);
+		if (matched)
+			break;
+	}
+	up_read(&mdb->mdb_rwlock);
+
+	return matched;
+}
+
+static int kdbus_match_db_remove_unlocked(struct kdbus_match_db *mdb,
+					  u64 cookie)
+{
+	struct kdbus_match_entry *entry, *tmp;
+	bool found = false;
+
+	list_for_each_entry_safe(entry, tmp, &mdb->entries_list, list_entry)
+		if (entry->cookie == cookie) {
+			kdbus_match_entry_free(entry);
+			--mdb->entries_count;
+			found = true;
+		}
+
+	return found ? 0 : -EBADSLT;
+}
+
+/**
+ * kdbus_cmd_match_add() - handle KDBUS_CMD_MATCH_ADD
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * One call to this function (or one ioctl(KDBUS_CMD_MATCH_ADD), respectively,
+ * adds one new database entry with n rules attached to it. Each rule is
+ * described with an kdbus_item, and an entry is considered matching if all
+ * its rules are satisfied.
+ *
+ * The items attached to a kdbus_cmd_match struct have the following mapping:
+ *
+ * KDBUS_ITEM_BLOOM_MASK:	A bloom mask
+ * KDBUS_ITEM_NAME:		A connection's source name
+ * KDBUS_ITEM_ID:		A connection ID
+ * KDBUS_ITEM_DST_ID:		A connection ID
+ * KDBUS_ITEM_NAME_ADD:
+ * KDBUS_ITEM_NAME_REMOVE:
+ * KDBUS_ITEM_NAME_CHANGE:	Well-known name changes, carry
+ *				kdbus_notify_name_change
+ * KDBUS_ITEM_ID_ADD:
+ * KDBUS_ITEM_ID_REMOVE:	Connection ID changes, carry
+ *				kdbus_notify_id_change
+ *
+ * For kdbus_notify_{id,name}_change structs, only the ID and name fields
+ * are looked at when adding an entry. The flags are unused.
+ *
+ * Also note that KDBUS_ITEM_BLOOM_MASK, KDBUS_ITEM_NAME, KDBUS_ITEM_ID,
+ * and KDBUS_ITEM_DST_ID are used to match messages from userspace, while the
+ * others apply to kernel-generated notifications.
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_match_db *mdb = conn->match_db;
+	struct kdbus_match_entry *entry = NULL;
+	struct kdbus_cmd_match *cmd;
+	struct kdbus_item *item;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_BLOOM_MASK, .multiple = true },
+		{ .type = KDBUS_ITEM_NAME, .multiple = true },
+		{ .type = KDBUS_ITEM_ID, .multiple = true },
+		{ .type = KDBUS_ITEM_DST_ID, .multiple = true },
+		{ .type = KDBUS_ITEM_NAME_ADD, .multiple = true },
+		{ .type = KDBUS_ITEM_NAME_REMOVE, .multiple = true },
+		{ .type = KDBUS_ITEM_NAME_CHANGE, .multiple = true },
+		{ .type = KDBUS_ITEM_ID_ADD, .multiple = true },
+		{ .type = KDBUS_ITEM_ID_REMOVE, .multiple = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_MATCH_REPLACE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	entry->cookie = cmd->cookie;
+	INIT_LIST_HEAD(&entry->list_entry);
+	INIT_LIST_HEAD(&entry->rules_list);
+
+	KDBUS_ITEMS_FOREACH(item, cmd->items, KDBUS_ITEMS_SIZE(cmd, items)) {
+		struct kdbus_match_rule *rule;
+		size_t size = item->size - offsetof(struct kdbus_item, data);
+
+		rule = kzalloc(sizeof(*rule), GFP_KERNEL);
+		if (!rule) {
+			ret = -ENOMEM;
+			goto exit;
+		}
+
+		rule->type = item->type;
+		INIT_LIST_HEAD(&rule->rules_entry);
+
+		switch (item->type) {
+		case KDBUS_ITEM_BLOOM_MASK: {
+			u64 bsize = conn->ep->bus->bloom.size;
+			u64 generations;
+			u64 remainder;
+
+			generations = div64_u64_rem(size, bsize, &remainder);
+			if (size < bsize || remainder > 0) {
+				ret = -EDOM;
+				break;
+			}
+
+			rule->bloom_mask.data = kmemdup(item->data,
+							size, GFP_KERNEL);
+			if (!rule->bloom_mask.data) {
+				ret = -ENOMEM;
+				break;
+			}
+
+			rule->bloom_mask.generations = generations;
+			break;
+		}
+
+		case KDBUS_ITEM_NAME:
+			if (!kdbus_name_is_valid(item->str, false)) {
+				ret = -EINVAL;
+				break;
+			}
+
+			rule->name = kstrdup(item->str, GFP_KERNEL);
+			if (!rule->name)
+				ret = -ENOMEM;
+
+			break;
+
+		case KDBUS_ITEM_ID:
+			rule->src_id = item->id;
+			break;
+
+		case KDBUS_ITEM_DST_ID:
+			rule->dst_id = item->id;
+			break;
+
+		case KDBUS_ITEM_NAME_ADD:
+		case KDBUS_ITEM_NAME_REMOVE:
+		case KDBUS_ITEM_NAME_CHANGE:
+			rule->old_id = item->name_change.old_id.id;
+			rule->new_id = item->name_change.new_id.id;
+
+			if (size > sizeof(struct kdbus_notify_name_change)) {
+				rule->name = kstrdup(item->name_change.name,
+						     GFP_KERNEL);
+				if (!rule->name)
+					ret = -ENOMEM;
+			}
+
+			break;
+
+		case KDBUS_ITEM_ID_ADD:
+		case KDBUS_ITEM_ID_REMOVE:
+			if (item->type == KDBUS_ITEM_ID_ADD)
+				rule->new_id = item->id_change.id;
+			else
+				rule->old_id = item->id_change.id;
+
+			break;
+		}
+
+		if (ret < 0) {
+			kdbus_match_rule_free(rule);
+			goto exit;
+		}
+
+		list_add_tail(&rule->rules_entry, &entry->rules_list);
+	}
+
+	down_write(&mdb->mdb_rwlock);
+
+	/* Remove any entry that has the same cookie as the current one. */
+	if (cmd->flags & KDBUS_MATCH_REPLACE)
+		kdbus_match_db_remove_unlocked(mdb, entry->cookie);
+
+	/*
+	 * If the above removal caught any entry, there will be room for the
+	 * new one.
+	 */
+	if (++mdb->entries_count > KDBUS_MATCH_MAX) {
+		--mdb->entries_count;
+		ret = -EMFILE;
+	} else {
+		list_add_tail(&entry->list_entry, &mdb->entries_list);
+		entry = NULL;
+	}
+
+	up_write(&mdb->mdb_rwlock);
+
+exit:
+	kdbus_match_entry_free(entry);
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_match_remove() - handle KDBUS_CMD_MATCH_REMOVE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_cmd_match *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	down_write(&conn->match_db->mdb_rwlock);
+	ret = kdbus_match_db_remove_unlocked(conn->match_db, cmd->cookie);
+	up_write(&conn->match_db->mdb_rwlock);
+
+	return kdbus_args_clear(&args, ret);
+}
diff --git a/ipc/kdbus/match.h b/ipc/kdbus/match.h
new file mode 100644
index 000000000000..ceb492f8e51c
--- /dev/null
+++ b/ipc/kdbus/match.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_MATCH_H
+#define __KDBUS_MATCH_H
+
+struct kdbus_conn;
+struct kdbus_match_db;
+struct kdbus_staging;
+
+struct kdbus_match_db *kdbus_match_db_new(void);
+void kdbus_match_db_free(struct kdbus_match_db *db);
+int kdbus_match_db_add(struct kdbus_conn *conn,
+		       struct kdbus_cmd_match *cmd);
+int kdbus_match_db_remove(struct kdbus_conn *conn,
+			  struct kdbus_cmd_match *cmd);
+bool kdbus_match_db_match_msg(struct kdbus_match_db *db,
+			      struct kdbus_conn *conn_src,
+			      const struct kdbus_staging *staging);
+
+int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp);
+
+#endif
diff --git a/ipc/kdbus/message.c b/ipc/kdbus/message.c
new file mode 100644
index 000000000000..ae565cd343f8
--- /dev/null
+++ b/ipc/kdbus/message.c
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/capability.h>
+#include <linux/cgroup.h>
+#include <linux/cred.h>
+#include <linux/file.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/shmem_fs.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <net/sock.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "item.h"
+#include "match.h"
+#include "message.h"
+#include "names.h"
+#include "policy.h"
+
+static const char * const zeros = "\0\0\0\0\0\0\0";
+
+static struct kdbus_gaps *kdbus_gaps_new(size_t n_memfds, size_t n_fds)
+{
+	size_t size_offsets, size_memfds, size_fds, size;
+	struct kdbus_gaps *gaps;
+
+	size_offsets = n_memfds * sizeof(*gaps->memfd_offsets);
+	size_memfds = n_memfds * sizeof(*gaps->memfd_files);
+	size_fds = n_fds * sizeof(*gaps->fd_files);
+	size = sizeof(*gaps) + size_offsets + size_memfds + size_fds;
+
+	gaps = kzalloc(size, GFP_KERNEL);
+	if (!gaps)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&gaps->kref);
+	gaps->n_memfds = 0; /* we reserve n_memfds, but don't enforce them */
+	gaps->memfd_offsets = (void *)(gaps + 1);
+	gaps->memfd_files = (void *)((u8 *)gaps->memfd_offsets + size_offsets);
+	gaps->n_fds = 0; /* we reserve n_fds, but don't enforce them */
+	gaps->fd_files = (void *)((u8 *)gaps->memfd_files + size_memfds);
+
+	return gaps;
+}
+
+static void kdbus_gaps_free(struct kref *kref)
+{
+	struct kdbus_gaps *gaps = container_of(kref, struct kdbus_gaps, kref);
+	size_t i;
+
+	for (i = 0; i < gaps->n_fds; ++i)
+		if (gaps->fd_files[i])
+			fput(gaps->fd_files[i]);
+	for (i = 0; i < gaps->n_memfds; ++i)
+		if (gaps->memfd_files[i])
+			fput(gaps->memfd_files[i]);
+
+	kfree(gaps);
+}
+
+/**
+ * kdbus_gaps_ref() - gain reference
+ * @gaps:	gaps object
+ *
+ * Return: @gaps is returned
+ */
+struct kdbus_gaps *kdbus_gaps_ref(struct kdbus_gaps *gaps)
+{
+	if (gaps)
+		kref_get(&gaps->kref);
+	return gaps;
+}
+
+/**
+ * kdbus_gaps_unref() - drop reference
+ * @gaps:	gaps object
+ *
+ * Return: NULL
+ */
+struct kdbus_gaps *kdbus_gaps_unref(struct kdbus_gaps *gaps)
+{
+	if (gaps)
+		kref_put(&gaps->kref, kdbus_gaps_free);
+	return NULL;
+}
+
+/**
+ * kdbus_gaps_install() - install file-descriptors
+ * @gaps:		gaps object, or NULL
+ * @slice:		pool slice that contains the message
+ * @out_incomplete	output variable to note incomplete fds
+ *
+ * This function installs all file-descriptors of @gaps into the current
+ * process and copies the file-descriptor numbers into the target pool slice.
+ *
+ * If the file-descriptors were only partially installed, then @out_incomplete
+ * will be set to true. Otherwise, it's set to false.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int kdbus_gaps_install(struct kdbus_gaps *gaps, struct kdbus_pool_slice *slice,
+		       bool *out_incomplete)
+{
+	bool incomplete_fds = false;
+	struct kvec kvec;
+	size_t i, n_fds;
+	int ret, *fds;
+
+	if (!gaps) {
+		/* nothing to do */
+		*out_incomplete = incomplete_fds;
+		return 0;
+	}
+
+	n_fds = gaps->n_fds + gaps->n_memfds;
+	if (n_fds < 1) {
+		/* nothing to do */
+		*out_incomplete = incomplete_fds;
+		return 0;
+	}
+
+	fds = kmalloc_array(n_fds, sizeof(*fds), GFP_TEMPORARY);
+	n_fds = 0;
+	if (!fds)
+		return -ENOMEM;
+
+	/* 1) allocate fds and copy them over */
+
+	if (gaps->n_fds > 0) {
+		for (i = 0; i < gaps->n_fds; ++i) {
+			int fd;
+
+			fd = get_unused_fd_flags(O_CLOEXEC);
+			if (fd < 0)
+				incomplete_fds = true;
+
+			WARN_ON(!gaps->fd_files[i]);
+
+			fds[n_fds++] = fd < 0 ? -1 : fd;
+		}
+
+		/*
+		 * The file-descriptor array can only be present once per
+		 * message. Hence, prepare all fds and then copy them over with
+		 * a single kvec.
+		 */
+
+		WARN_ON(!gaps->fd_offset);
+
+		kvec.iov_base = fds;
+		kvec.iov_len = gaps->n_fds * sizeof(*fds);
+		ret = kdbus_pool_slice_copy_kvec(slice, gaps->fd_offset,
+						 &kvec, 1, kvec.iov_len);
+		if (ret < 0)
+			goto exit;
+	}
+
+	for (i = 0; i < gaps->n_memfds; ++i) {
+		int memfd;
+
+		memfd = get_unused_fd_flags(O_CLOEXEC);
+		if (memfd < 0) {
+			incomplete_fds = true;
+			/* memfds are initialized to -1, skip copying it */
+			continue;
+		}
+
+		fds[n_fds++] = memfd;
+
+		/*
+		 * memfds have to be copied individually as they each are put
+		 * into a separate item. This should not be an issue, though,
+		 * as usually there is no need to send more than one memfd per
+		 * message.
+		 */
+
+		WARN_ON(!gaps->memfd_offsets[i]);
+		WARN_ON(!gaps->memfd_files[i]);
+
+		kvec.iov_base = &memfd;
+		kvec.iov_len = sizeof(memfd);
+		ret = kdbus_pool_slice_copy_kvec(slice, gaps->memfd_offsets[i],
+						 &kvec, 1, kvec.iov_len);
+		if (ret < 0)
+			goto exit;
+	}
+
+	/* 2) install fds now that everything was successful */
+
+	for (i = 0; i < gaps->n_fds; ++i)
+		if (fds[i] >= 0)
+			fd_install(fds[i], get_file(gaps->fd_files[i]));
+	for (i = 0; i < gaps->n_memfds; ++i)
+		if (fds[gaps->n_fds + i] >= 0)
+			fd_install(fds[gaps->n_fds + i],
+				   get_file(gaps->memfd_files[i]));
+
+	ret = 0;
+
+exit:
+	if (ret < 0)
+		for (i = 0; i < n_fds; ++i)
+			put_unused_fd(fds[i]);
+	kfree(fds);
+	*out_incomplete = incomplete_fds;
+	return ret;
+}
+
+static struct file *kdbus_get_fd(int fd)
+{
+	struct file *f, *ret;
+	struct inode *inode;
+	struct socket *sock;
+
+	if (fd < 0)
+		return ERR_PTR(-EBADF);
+
+	f = fget_raw(fd);
+	if (!f)
+		return ERR_PTR(-EBADF);
+
+	inode = file_inode(f);
+	sock = S_ISSOCK(inode->i_mode) ? SOCKET_I(inode) : NULL;
+
+	if (f->f_mode & FMODE_PATH)
+		ret = f; /* O_PATH is always allowed */
+	else if (f->f_op == &kdbus_handle_ops)
+		ret = ERR_PTR(-EOPNOTSUPP); /* disallow kdbus-fd over kdbus */
+	else if (sock && sock->sk && sock->ops && sock->ops->family == PF_UNIX)
+		ret = ERR_PTR(-EOPNOTSUPP); /* disallow UDS over kdbus */
+	else
+		ret = f; /* all other are allowed */
+
+	if (f != ret)
+		fput(f);
+
+	return ret;
+}
+
+static struct file *kdbus_get_memfd(const struct kdbus_memfd *memfd)
+{
+	const int m = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL;
+	struct file *f, *ret;
+	int s;
+
+	if (memfd->fd < 0)
+		return ERR_PTR(-EBADF);
+
+	f = fget(memfd->fd);
+	if (!f)
+		return ERR_PTR(-EBADF);
+
+	s = shmem_get_seals(f);
+	if (s < 0)
+		ret = ERR_PTR(-EMEDIUMTYPE);
+	else if ((s & m) != m)
+		ret = ERR_PTR(-ETXTBSY);
+	else if (memfd->start + memfd->size > (u64)i_size_read(file_inode(f)))
+		ret = ERR_PTR(-EFAULT);
+	else
+		ret = f;
+
+	if (f != ret)
+		fput(f);
+
+	return ret;
+}
+
+static int kdbus_msg_examine(struct kdbus_msg *msg, struct kdbus_bus *bus,
+			     struct kdbus_cmd_send *cmd, size_t *out_n_memfds,
+			     size_t *out_n_fds, size_t *out_n_parts)
+{
+	struct kdbus_item *item, *fds = NULL, *bloom = NULL, *dstname = NULL;
+	u64 n_parts, n_memfds, n_fds, vec_size;
+
+	/*
+	 * Step 1:
+	 * Validate the message and command parameters.
+	 */
+
+	/* KDBUS_PAYLOAD_KERNEL is reserved to kernel messages */
+	if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
+		return -EINVAL;
+
+	if (msg->dst_id == KDBUS_DST_ID_BROADCAST) {
+		/* broadcasts must be marked as signals */
+		if (!(msg->flags & KDBUS_MSG_SIGNAL))
+			return -EBADMSG;
+		/* broadcasts cannot have timeouts */
+		if (msg->timeout_ns > 0)
+			return -ENOTUNIQ;
+	}
+
+	if (msg->flags & KDBUS_MSG_EXPECT_REPLY) {
+		/* if you expect a reply, you must specify a timeout */
+		if (msg->timeout_ns == 0)
+			return -EINVAL;
+		/* signals cannot have replies */
+		if (msg->flags & KDBUS_MSG_SIGNAL)
+			return -ENOTUNIQ;
+	} else {
+		/* must expect reply if sent as synchronous call */
+		if (cmd->flags & KDBUS_SEND_SYNC_REPLY)
+			return -EINVAL;
+		/* cannot mark replies as signal */
+		if (msg->cookie_reply && (msg->flags & KDBUS_MSG_SIGNAL))
+			return -EINVAL;
+	}
+
+	/*
+	 * Step 2:
+	 * Validate all passed items. While at it, select some statistics that
+	 * are required to allocate state objects later on.
+	 *
+	 * Generic item validation has already been done via
+	 * kdbus_item_validate(). Furthermore, the number of items is naturally
+	 * limited by the maximum message size. Hence, only non-generic item
+	 * checks are performed here (mainly integer overflow tests).
+	 */
+
+	n_parts = 0;
+	n_memfds = 0;
+	n_fds = 0;
+	vec_size = 0;
+
+	KDBUS_ITEMS_FOREACH(item, msg->items, KDBUS_ITEMS_SIZE(msg, items)) {
+		switch (item->type) {
+		case KDBUS_ITEM_PAYLOAD_VEC: {
+			void __force __user *ptr = KDBUS_PTR(item->vec.address);
+			u64 size = item->vec.size;
+
+			if (vec_size + size < vec_size)
+				return -EMSGSIZE;
+			if (vec_size + size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
+				return -EMSGSIZE;
+			if (ptr && unlikely(!access_ok(VERIFY_READ, ptr, size)))
+				return -EFAULT;
+
+			if (ptr || size % 8) /* data or padding */
+				++n_parts;
+			break;
+		}
+		case KDBUS_ITEM_PAYLOAD_MEMFD: {
+			u64 start = item->memfd.start;
+			u64 size = item->memfd.size;
+
+			if (start + size < start)
+				return -EMSGSIZE;
+			if (n_memfds >= KDBUS_MSG_MAX_MEMFD_ITEMS)
+				return -E2BIG;
+
+			++n_memfds;
+			if (size % 8) /* vec-padding required */
+				++n_parts;
+			break;
+		}
+		case KDBUS_ITEM_FDS: {
+			if (fds)
+				return -EEXIST;
+
+			fds = item;
+			n_fds = KDBUS_ITEM_PAYLOAD_SIZE(item) / sizeof(int);
+			if (n_fds > KDBUS_CONN_MAX_FDS_PER_USER)
+				return -EMFILE;
+
+			break;
+		}
+		case KDBUS_ITEM_BLOOM_FILTER: {
+			u64 bloom_size;
+
+			if (bloom)
+				return -EEXIST;
+
+			bloom = item;
+			bloom_size = KDBUS_ITEM_PAYLOAD_SIZE(item) -
+				     offsetof(struct kdbus_bloom_filter, data);
+			if (!KDBUS_IS_ALIGNED8(bloom_size))
+				return -EFAULT;
+			if (bloom_size != bus->bloom.size)
+				return -EDOM;
+
+			break;
+		}
+		case KDBUS_ITEM_DST_NAME: {
+			if (dstname)
+				return -EEXIST;
+
+			dstname = item;
+			if (!kdbus_name_is_valid(item->str, false))
+				return -EINVAL;
+			if (msg->dst_id == KDBUS_DST_ID_BROADCAST)
+				return -EBADMSG;
+
+			break;
+		}
+		default:
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * Step 3:
+	 * Validate that required items were actually passed, and that no item
+	 * contradicts the message flags.
+	 */
+
+	/* bloom filters must be attached _iff_ it's a signal */
+	if (!(msg->flags & KDBUS_MSG_SIGNAL) != !bloom)
+		return -EBADMSG;
+	/* destination name is required if no ID is given */
+	if (msg->dst_id == KDBUS_DST_ID_NAME && !dstname)
+		return -EDESTADDRREQ;
+	/* cannot send file-descriptors attached to broadcasts */
+	if (msg->dst_id == KDBUS_DST_ID_BROADCAST && fds)
+		return -ENOTUNIQ;
+
+	*out_n_memfds = n_memfds;
+	*out_n_fds = n_fds;
+	*out_n_parts = n_parts;
+
+	return 0;
+}
+
+static bool kdbus_staging_merge_vecs(struct kdbus_staging *staging,
+				     struct kdbus_item **prev_item,
+				     struct iovec **prev_vec,
+				     const struct kdbus_item *merge)
+{
+	void __user *ptr = (void __user *)KDBUS_PTR(merge->vec.address);
+	u64 padding = merge->vec.size % 8;
+	struct kdbus_item *prev = *prev_item;
+	struct iovec *vec = *prev_vec;
+
+	/* XXX: merging is disabled so far */
+	if (0 && prev && prev->type == KDBUS_ITEM_PAYLOAD_OFF &&
+	    !merge->vec.address == !prev->vec.address) {
+		/*
+		 * If we merge two VECs, we can always drop the second
+		 * PAYLOAD_VEC item. Hence, include its size in the previous
+		 * one.
+		 */
+		prev->vec.size += merge->vec.size;
+
+		if (ptr) {
+			/*
+			 * If we merge two data VECs, we need two iovecs to copy
+			 * the data. But the items can be easily merged by
+			 * summing their lengths.
+			 */
+			vec = &staging->parts[staging->n_parts++];
+			vec->iov_len = merge->vec.size;
+			vec->iov_base = ptr;
+			staging->n_payload += vec->iov_len;
+		} else if (padding) {
+			/*
+			 * If we merge two 0-vecs with the second 0-vec
+			 * requiring padding, we need to insert an iovec to copy
+			 * the 0-padding. We try merging it with the previous
+			 * 0-padding iovec. This might end up with an
+			 * iov_len==0, in which case we simply drop the iovec.
+			 */
+			if (vec) {
+				staging->n_payload -= vec->iov_len;
+				vec->iov_len = prev->vec.size % 8;
+				if (!vec->iov_len) {
+					--staging->n_parts;
+					vec = NULL;
+				} else {
+					staging->n_payload += vec->iov_len;
+				}
+			} else {
+				vec = &staging->parts[staging->n_parts++];
+				vec->iov_len = padding;
+				vec->iov_base = (char __user *)zeros;
+				staging->n_payload += vec->iov_len;
+			}
+		} else {
+			/*
+			 * If we merge two 0-vecs with the second 0-vec having
+			 * no padding, we know the padding of the first stays
+			 * the same. Hence, @vec needs no adjustment.
+			 */
+		}
+
+		/* successfully merged with previous item */
+		merge = prev;
+	} else {
+		/*
+		 * If we cannot merge the payload item with the previous one,
+		 * we simply insert a new iovec for the data/padding.
+		 */
+		if (ptr) {
+			vec = &staging->parts[staging->n_parts++];
+			vec->iov_len = merge->vec.size;
+			vec->iov_base = ptr;
+			staging->n_payload += vec->iov_len;
+		} else if (padding) {
+			vec = &staging->parts[staging->n_parts++];
+			vec->iov_len = padding;
+			vec->iov_base = (char __user *)zeros;
+			staging->n_payload += vec->iov_len;
+		} else {
+			vec = NULL;
+		}
+	}
+
+	*prev_item = (struct kdbus_item *)merge;
+	*prev_vec = vec;
+
+	return merge == prev;
+}
+
+static int kdbus_staging_import(struct kdbus_staging *staging)
+{
+	struct kdbus_item *it, *item, *last, *prev_payload;
+	struct kdbus_gaps *gaps = staging->gaps;
+	struct kdbus_msg *msg = staging->msg;
+	struct iovec *part, *prev_part;
+	bool drop_item;
+
+	drop_item = false;
+	last = NULL;
+	prev_payload = NULL;
+	prev_part = NULL;
+
+	/*
+	 * We modify msg->items along the way; make sure to use @item as offset
+	 * to the next item (instead of the iterator @it).
+	 */
+	for (it = item = msg->items;
+	     it >= msg->items &&
+	             (u8 *)it < (u8 *)msg + msg->size &&
+	             (u8 *)it + it->size <= (u8 *)msg + msg->size; ) {
+		/*
+		 * If we dropped items along the way, move current item to
+		 * front. We must not access @it afterwards, but use @item
+		 * instead!
+		 */
+		if (it != item)
+			memmove(item, it, it->size);
+		it = (void *)((u8 *)it + KDBUS_ALIGN8(item->size));
+
+		switch (item->type) {
+		case KDBUS_ITEM_PAYLOAD_VEC: {
+			size_t offset = staging->n_payload;
+
+			if (kdbus_staging_merge_vecs(staging, &prev_payload,
+						     &prev_part, item)) {
+				drop_item = true;
+			} else if (item->vec.address) {
+				/* real offset is patched later on */
+				item->type = KDBUS_ITEM_PAYLOAD_OFF;
+				item->vec.offset = offset;
+			} else {
+				item->type = KDBUS_ITEM_PAYLOAD_OFF;
+				item->vec.offset = ~0ULL;
+			}
+
+			break;
+		}
+		case KDBUS_ITEM_PAYLOAD_MEMFD: {
+			struct file *f;
+
+			f = kdbus_get_memfd(&item->memfd);
+			if (IS_ERR(f))
+				return PTR_ERR(f);
+
+			gaps->memfd_files[gaps->n_memfds] = f;
+			gaps->memfd_offsets[gaps->n_memfds] =
+					(u8 *)&item->memfd.fd - (u8 *)msg;
+			++gaps->n_memfds;
+
+			/* memfds cannot be merged */
+			prev_payload = item;
+			prev_part = NULL;
+
+			/* insert padding to make following VECs aligned */
+			if (item->memfd.size % 8) {
+				part = &staging->parts[staging->n_parts++];
+				part->iov_len = item->memfd.size % 8;
+				part->iov_base = (char __user *)zeros;
+				staging->n_payload += part->iov_len;
+			}
+
+			break;
+		}
+		case KDBUS_ITEM_FDS: {
+			size_t i, n_fds;
+
+			n_fds = KDBUS_ITEM_PAYLOAD_SIZE(item) / sizeof(int);
+			for (i = 0; i < n_fds; ++i) {
+				struct file *f;
+
+				f = kdbus_get_fd(item->fds[i]);
+				if (IS_ERR(f))
+					return PTR_ERR(f);
+
+				gaps->fd_files[gaps->n_fds++] = f;
+			}
+
+			gaps->fd_offset = (u8 *)item->fds - (u8 *)msg;
+
+			break;
+		}
+		case KDBUS_ITEM_BLOOM_FILTER:
+			staging->bloom_filter = &item->bloom_filter;
+			break;
+		case KDBUS_ITEM_DST_NAME:
+			staging->dst_name = item->str;
+			break;
+		}
+
+		/* drop item if we merged it with a previous one */
+		if (drop_item) {
+			drop_item = false;
+		} else {
+			last = item;
+			item = KDBUS_ITEM_NEXT(item);
+		}
+	}
+
+	/* adjust message size regarding dropped items */
+	msg->size = offsetof(struct kdbus_msg, items);
+	if (last)
+		msg->size += ((u8 *)last - (u8 *)msg->items) + last->size;
+
+	return 0;
+}
+
+static void kdbus_staging_reserve(struct kdbus_staging *staging)
+{
+	struct iovec *part;
+
+	part = &staging->parts[staging->n_parts++];
+	part->iov_base = (void __user *)zeros;
+	part->iov_len = 0;
+}
+
+static struct kdbus_staging *kdbus_staging_new(struct kdbus_bus *bus,
+					       size_t n_parts,
+					       size_t msg_extra_size)
+{
+	const size_t reserved_parts = 5; /* see below for explanation */
+	struct kdbus_staging *staging;
+	int ret;
+
+	n_parts += reserved_parts;
+
+	staging = kzalloc(sizeof(*staging) + n_parts * sizeof(*staging->parts) +
+			  msg_extra_size, GFP_TEMPORARY);
+	if (!staging)
+		return ERR_PTR(-ENOMEM);
+
+	staging->msg_seqnum = atomic64_inc_return(&bus->last_message_id);
+	staging->n_parts = 0; /* we reserve n_parts, but don't enforce them */
+	staging->parts = (void *)(staging + 1);
+
+	if (msg_extra_size) /* if requested, allocate message, too */
+		staging->msg = (void *)((u8 *)staging->parts +
+				        n_parts * sizeof(*staging->parts));
+
+	staging->meta_proc = kdbus_meta_proc_new();
+	if (IS_ERR(staging->meta_proc)) {
+		ret = PTR_ERR(staging->meta_proc);
+		staging->meta_proc = NULL;
+		goto error;
+	}
+
+	staging->meta_conn = kdbus_meta_conn_new();
+	if (IS_ERR(staging->meta_conn)) {
+		ret = PTR_ERR(staging->meta_conn);
+		staging->meta_conn = NULL;
+		goto error;
+	}
+
+	/*
+	 * Prepare iovecs to copy the message into the target pool. We use the
+	 * following iovecs:
+	 *   * iovec to copy "kdbus_msg.size"
+	 *   * iovec to copy "struct kdbus_msg" (minus size) plus items
+	 *   * iovec for possible padding after the items
+	 *   * iovec for metadata items
+	 *   * iovec for possible padding after the items
+	 *
+	 * Make sure to update @reserved_parts if you add more parts here.
+	 */
+
+	kdbus_staging_reserve(staging); /* msg.size */
+	kdbus_staging_reserve(staging); /* msg (minus msg.size) plus items */
+	kdbus_staging_reserve(staging); /* msg padding */
+	kdbus_staging_reserve(staging); /* meta */
+	kdbus_staging_reserve(staging); /* meta padding */
+
+	return staging;
+
+error:
+	kdbus_staging_free(staging);
+	return ERR_PTR(ret);
+}
+
+struct kdbus_staging *kdbus_staging_new_kernel(struct kdbus_bus *bus,
+					       u64 dst, u64 cookie_timeout,
+					       size_t it_size, size_t it_type)
+{
+	struct kdbus_staging *staging;
+	size_t size;
+
+	size = offsetof(struct kdbus_msg, items) +
+	       KDBUS_ITEM_HEADER_SIZE + it_size;
+
+	staging = kdbus_staging_new(bus, 0, KDBUS_ALIGN8(size));
+	if (IS_ERR(staging))
+		return ERR_CAST(staging);
+
+	staging->msg->size = size;
+	staging->msg->flags = (dst == KDBUS_DST_ID_BROADCAST) ?
+							KDBUS_MSG_SIGNAL : 0;
+	staging->msg->dst_id = dst;
+	staging->msg->src_id = KDBUS_SRC_ID_KERNEL;
+	staging->msg->payload_type = KDBUS_PAYLOAD_KERNEL;
+	staging->msg->cookie_reply = cookie_timeout;
+	staging->notify = staging->msg->items;
+	staging->notify->size = KDBUS_ITEM_HEADER_SIZE + it_size;
+	staging->notify->type = it_type;
+
+	return staging;
+}
+
+struct kdbus_staging *kdbus_staging_new_user(struct kdbus_bus *bus,
+					     struct kdbus_cmd_send *cmd,
+					     struct kdbus_msg *msg)
+{
+	const size_t reserved_parts = 1; /* see below for explanation */
+	size_t n_memfds, n_fds, n_parts;
+	struct kdbus_staging *staging;
+	int ret;
+
+	/*
+	 * Examine user-supplied message and figure out how many resources we
+	 * need to allocate in our staging area. This requires us to iterate
+	 * the message twice, but saves us from re-allocating our resources
+	 * all the time.
+	 */
+
+	ret = kdbus_msg_examine(msg, bus, cmd, &n_memfds, &n_fds, &n_parts);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	n_parts += reserved_parts;
+
+	/*
+	 * Allocate staging area with the number of required resources. Make
+	 * sure that we have enough iovecs for all required parts pre-allocated
+	 * so this will hopefully be the only memory allocation for this
+	 * message transaction.
+	 */
+
+	staging = kdbus_staging_new(bus, n_parts, 0);
+	if (IS_ERR(staging))
+		return ERR_CAST(staging);
+
+	staging->msg = msg;
+
+	/*
+	 * If the message contains memfds or fd items, we need to remember some
+	 * state so we can fill in the requested information at RECV time.
+	 * File-descriptors cannot be passed at SEND time. Hence, allocate a
+	 * gaps-object to remember that state. That gaps object is linked to
+	 * from the staging area, but will also be linked to from the message
+	 * queue of each peer. Hence, each receiver owns a reference to it, and
+	 * it will later be used to fill the 'gaps' in message that couldn't be
+	 * filled at SEND time.
+	 * Note that the 'gaps' object is read-only once the staging-allocator
+	 * returns. There might be connections receiving a queued message while
+	 * the sender still broadcasts the message to other receivers.
+	 */
+
+	if (n_memfds > 0 || n_fds > 0) {
+		staging->gaps = kdbus_gaps_new(n_memfds, n_fds);
+		if (IS_ERR(staging->gaps)) {
+			ret = PTR_ERR(staging->gaps);
+			staging->gaps = NULL;
+			kdbus_staging_free(staging);
+			return ERR_PTR(ret);
+		}
+	}
+
+	/*
+	 * kdbus_staging_new() already reserves parts for message setup. For
+	 * user-supplied messages, we add the following iovecs:
+	 *   ... variable number of iovecs for payload ...
+	 *   * final iovec for possible padding of payload
+	 *
+	 * Make sure to update @reserved_parts if you add more parts here.
+	 */
+
+	ret = kdbus_staging_import(staging); /* payload */
+	kdbus_staging_reserve(staging); /* payload padding */
+
+	if (ret < 0)
+		goto error;
+
+	return staging;
+
+error:
+	kdbus_staging_free(staging);
+	return ERR_PTR(ret);
+}
+
+struct kdbus_staging *kdbus_staging_free(struct kdbus_staging *staging)
+{
+	if (!staging)
+		return NULL;
+
+	kdbus_meta_conn_unref(staging->meta_conn);
+	kdbus_meta_proc_unref(staging->meta_proc);
+	kdbus_gaps_unref(staging->gaps);
+	kfree(staging);
+
+	return NULL;
+}
+
+static int kdbus_staging_collect_metadata(struct kdbus_staging *staging,
+					  struct kdbus_conn *src,
+					  struct kdbus_conn *dst,
+					  u64 *out_attach)
+{
+	u64 attach;
+	int ret;
+
+	if (src)
+		attach = kdbus_meta_msg_mask(src, dst);
+	else
+		attach = KDBUS_ATTACH_TIMESTAMP; /* metadata for kernel msgs */
+
+	if (src && !src->meta_fake) {
+		ret = kdbus_meta_proc_collect(staging->meta_proc, attach);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = kdbus_meta_conn_collect(staging->meta_conn, src,
+				      staging->msg_seqnum, attach);
+	if (ret < 0)
+		return ret;
+
+	*out_attach = attach;
+	return 0;
+}
+
+/**
+ * kdbus_staging_emit() - emit linearized message in target pool
+ * @staging:		staging object to create message from
+ * @src:		sender of the message (or NULL)
+ * @dst:		target connection to allocate message for
+ *
+ * This allocates a pool-slice for @dst and copies the message provided by
+ * @staging into it. The new slice is then returned to the caller for further
+ * processing. It's not linked into any queue, yet.
+ *
+ * Return: Newly allocated slice or ERR_PTR on failure.
+ */
+struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging,
+					    struct kdbus_conn *src,
+					    struct kdbus_conn *dst)
+{
+	struct kdbus_item *item, *meta_items = NULL;
+	struct kdbus_pool_slice *slice = NULL;
+	size_t off, size, meta_size;
+	struct iovec *v;
+	u64 attach, msg_size;
+	int ret;
+
+	/*
+	 * Step 1:
+	 * Collect metadata from @src depending on the attach-flags allowed for
+	 * @dst. Translate it into the namespaces pinned by @dst.
+	 */
+
+	ret = kdbus_staging_collect_metadata(staging, src, dst, &attach);
+	if (ret < 0)
+		goto error;
+
+	ret = kdbus_meta_emit(staging->meta_proc, NULL, staging->meta_conn,
+			      dst, attach, &meta_items, &meta_size);
+	if (ret < 0)
+		goto error;
+
+	/*
+	 * Step 2:
+	 * Setup iovecs for the message. See kdbus_staging_new() for allocation
+	 * of those iovecs. All reserved iovecs have been initialized with
+	 * iov_len=0 + iov_base=zeros. Furthermore, the iovecs to copy the
+	 * actual message payload have already been initialized and need not be
+	 * touched.
+	 */
+
+	v = staging->parts;
+	msg_size = staging->msg->size;
+
+	/* msg.size */
+	v->iov_len = sizeof(msg_size);
+	v->iov_base = (void __user *)&msg_size;
+	++v;
+
+	/* msg (after msg.size) plus items */
+	v->iov_len = staging->msg->size - sizeof(staging->msg->size);
+	v->iov_base = (void __user *)((u8 *)staging->msg +
+				      sizeof(staging->msg->size));
+	++v;
+
+	/* padding after msg */
+	v->iov_len = KDBUS_ALIGN8(staging->msg->size) - staging->msg->size;
+	v->iov_base = (void __user *)zeros;
+	++v;
+
+	if (meta_size > 0) {
+		/* metadata items */
+		v->iov_len = meta_size;
+		v->iov_base = (void __user *)meta_items;
+		++v;
+
+		/* padding after metadata */
+		v->iov_len = KDBUS_ALIGN8(meta_size) - meta_size;
+		v->iov_base = (void __user *)zeros;
+		++v;
+
+		msg_size = KDBUS_ALIGN8(msg_size) + meta_size;
+	} else {
+		/* metadata items */
+		v->iov_len = 0;
+		v->iov_base = (void __user *)zeros;
+		++v;
+
+		/* padding after metadata */
+		v->iov_len = 0;
+		v->iov_base = (void __user *)zeros;
+		++v;
+	}
+
+	/* ... payload iovecs are already filled in ... */
+
+	/* compute overall size and fill in padding after payload */
+	size = KDBUS_ALIGN8(msg_size);
+
+	if (staging->n_payload > 0) {
+		size += staging->n_payload;
+
+		v = &staging->parts[staging->n_parts - 1];
+		v->iov_len = KDBUS_ALIGN8(size) - size;
+		v->iov_base = (void __user *)zeros;
+
+		size = KDBUS_ALIGN8(size);
+	}
+
+	/*
+	 * Step 3:
+	 * The PAYLOAD_OFF items in the message contain a relative 'offset'
+	 * field that tells the receiver where to find the actual payload. This
+	 * offset is relative to the start of the message, and as such depends
+	 * on the size of the metadata items we inserted. This size is variable
+	 * and changes for each peer we send the message to. Hence, we remember
+	 * the last relative offset that was used to calculate the 'offset'
+	 * fields. For each message, we re-calculate it and patch all items, in
+	 * case it changed.
+	 */
+
+	off = KDBUS_ALIGN8(msg_size);
+
+	if (off != staging->i_payload) {
+		KDBUS_ITEMS_FOREACH(item, staging->msg->items,
+				    KDBUS_ITEMS_SIZE(staging->msg, items)) {
+			if (item->type != KDBUS_ITEM_PAYLOAD_OFF)
+				continue;
+
+			item->vec.offset -= staging->i_payload;
+			item->vec.offset += off;
+		}
+
+		staging->i_payload = off;
+	}
+
+	/*
+	 * Step 4:
+	 * Allocate pool slice and copy over all data. Make sure to properly
+	 * account on user quota.
+	 */
+
+	ret = kdbus_conn_quota_inc(dst, src ? src->user : NULL, size,
+				   staging->gaps ? staging->gaps->n_fds : 0);
+	if (ret < 0)
+		goto error;
+
+	slice = kdbus_pool_slice_alloc(dst->pool, size, true);
+	if (IS_ERR(slice)) {
+		ret = PTR_ERR(slice);
+		slice = NULL;
+		goto error;
+	}
+
+	WARN_ON(kdbus_pool_slice_size(slice) != size);
+
+	ret = kdbus_pool_slice_copy_iovec(slice, 0, staging->parts,
+					  staging->n_parts, size);
+	if (ret < 0)
+		goto error;
+
+	/* all done, return slice to caller */
+	goto exit;
+
+error:
+	if (slice)
+		kdbus_conn_quota_dec(dst, src ? src->user : NULL, size,
+				     staging->gaps ? staging->gaps->n_fds : 0);
+	kdbus_pool_slice_release(slice);
+	slice = ERR_PTR(ret);
+exit:
+	kfree(meta_items);
+	return slice;
+}
diff --git a/ipc/kdbus/message.h b/ipc/kdbus/message.h
new file mode 100644
index 000000000000..298f9c99dfcf
--- /dev/null
+++ b/ipc/kdbus/message.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_MESSAGE_H
+#define __KDBUS_MESSAGE_H
+
+#include <linux/fs.h>
+#include <linux/kref.h>
+#include <uapi/linux/kdbus.h>
+
+struct kdbus_bus;
+struct kdbus_conn;
+struct kdbus_meta_conn;
+struct kdbus_meta_proc;
+struct kdbus_pool_slice;
+
+/**
+ * struct kdbus_gaps - gaps in message to be filled later
+ * @kref:		Reference counter
+ * @n_memfd_offs:	Number of memfds
+ * @memfd_offs:		Offsets of kdbus_memfd items in target slice
+ * @n_fds:		Number of fds
+ * @fds:		Array of sent fds
+ * @fds_offset:		Offset of fd-array in target slice
+ *
+ * The 'gaps' object is used to track data that is needed to fill gaps in a
+ * message at RECV time. Usually, we try to compile the whole message at SEND
+ * time. This has the advantage, that we don't have to cache any information and
+ * can keep the memory consumption small. Furthermore, all copy operations can
+ * be combined into a single function call, which speeds up transactions
+ * considerably.
+ * However, things like file-descriptors can only be fully installed at RECV
+ * time. The gaps object tracks this data and pins it until a message is
+ * received. The gaps object is shared between all receivers of the same
+ * message.
+ */
+struct kdbus_gaps {
+	struct kref kref;
+
+	/* state tracking for KDBUS_ITEM_PAYLOAD_MEMFD entries */
+	size_t n_memfds;
+	u64 *memfd_offsets;
+	struct file **memfd_files;
+
+	/* state tracking for KDBUS_ITEM_FDS */
+	size_t n_fds;
+	struct file **fd_files;
+	u64 fd_offset;
+};
+
+struct kdbus_gaps *kdbus_gaps_ref(struct kdbus_gaps *gaps);
+struct kdbus_gaps *kdbus_gaps_unref(struct kdbus_gaps *gaps);
+int kdbus_gaps_install(struct kdbus_gaps *gaps, struct kdbus_pool_slice *slice,
+		       bool *out_incomplete);
+
+/**
+ * struct kdbus_staging - staging area to import messages
+ * @msg:		User-supplied message
+ * @gaps:		Gaps-object created during import (or NULL if empty)
+ * @msg_seqnum:		Message sequence number
+ * @notify_entry:	Entry into list of kernel-generated notifications
+ * @i_payload:		Current relative index of start of payload
+ * @n_payload:		Total number of bytes needed for payload
+ * @n_parts:		Number of parts
+ * @parts:		Array of iovecs that make up the whole message
+ * @meta_proc:		Process metadata of the sender (or NULL if empty)
+ * @meta_conn:		Connection metadata of the sender (or NULL if empty)
+ * @bloom_filter:	Pointer to the bloom-item in @msg, or NULL
+ * @dst_name:		Pointer to the dst-name-item in @msg, or NULL
+ * @notify:		Pointer to the notification item in @msg, or NULL
+ *
+ * The kdbus_staging object is a temporary staging area to import user-supplied
+ * messages into the kernel. It is only used during SEND and dropped once the
+ * message is queued. Any data that cannot be collected during SEND, is
+ * collected in a kdbus_gaps object and attached to the message queue.
+ */
+struct kdbus_staging {
+	struct kdbus_msg *msg;
+	struct kdbus_gaps *gaps;
+	u64 msg_seqnum;
+	struct list_head notify_entry;
+
+	/* crafted iovecs to copy the message */
+	size_t i_payload;
+	size_t n_payload;
+	size_t n_parts;
+	struct iovec *parts;
+
+	/* metadata state */
+	struct kdbus_meta_proc *meta_proc;
+	struct kdbus_meta_conn *meta_conn;
+
+	/* cached pointers into @msg */
+	const struct kdbus_bloom_filter *bloom_filter;
+	const char *dst_name;
+	struct kdbus_item *notify;
+};
+
+struct kdbus_staging *kdbus_staging_new_kernel(struct kdbus_bus *bus,
+					       u64 dst, u64 cookie_timeout,
+					       size_t it_size, size_t it_type);
+struct kdbus_staging *kdbus_staging_new_user(struct kdbus_bus *bus,
+					     struct kdbus_cmd_send *cmd,
+					     struct kdbus_msg *msg);
+struct kdbus_staging *kdbus_staging_free(struct kdbus_staging *staging);
+struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging,
+					    struct kdbus_conn *src,
+					    struct kdbus_conn *dst);
+
+#endif
diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
new file mode 100644
index 000000000000..71ca475a80d5
--- /dev/null
+++ b/ipc/kdbus/metadata.c
@@ -0,0 +1,1347 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/audit.h>
+#include <linux/capability.h>
+#include <linux/cgroup.h>
+#include <linux/cred.h>
+#include <linux/file.h>
+#include <linux/fs_struct.h>
+#include <linux/init.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/security.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/uidgid.h>
+#include <linux/uio.h>
+#include <linux/user_namespace.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "item.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+
+/**
+ * struct kdbus_meta_proc - Process metadata
+ * @kref:		Reference counting
+ * @lock:		Object lock
+ * @collected:		Bitmask of collected items
+ * @valid:		Bitmask of collected and valid items
+ * @cred:		Credentials
+ * @pid:		PID of process
+ * @tgid:		TGID of process
+ * @ppid:		PPID of process
+ * @tid_comm:		TID comm line
+ * @pid_comm:		PID comm line
+ * @exe_path:		Executable path
+ * @root_path:		Root-FS path
+ * @cmdline:		Command-line
+ * @cgroup:		Full cgroup path
+ * @seclabel:		Seclabel
+ * @audit_loginuid:	Audit login-UID
+ * @audit_sessionid:	Audit session-ID
+ */
+struct kdbus_meta_proc {
+	struct kref kref;
+	struct mutex lock;
+	u64 collected;
+	u64 valid;
+
+	/* KDBUS_ITEM_CREDS */
+	/* KDBUS_ITEM_AUXGROUPS */
+	/* KDBUS_ITEM_CAPS */
+	const struct cred *cred;
+
+	/* KDBUS_ITEM_PIDS */
+	struct pid *pid;
+	struct pid *tgid;
+	struct pid *ppid;
+
+	/* KDBUS_ITEM_TID_COMM */
+	char tid_comm[TASK_COMM_LEN];
+	/* KDBUS_ITEM_PID_COMM */
+	char pid_comm[TASK_COMM_LEN];
+
+	/* KDBUS_ITEM_EXE */
+	struct path exe_path;
+	struct path root_path;
+
+	/* KDBUS_ITEM_CMDLINE */
+	char *cmdline;
+
+	/* KDBUS_ITEM_CGROUP */
+	char *cgroup;
+
+	/* KDBUS_ITEM_SECLABEL */
+	char *seclabel;
+
+	/* KDBUS_ITEM_AUDIT */
+	kuid_t audit_loginuid;
+	unsigned int audit_sessionid;
+};
+
+/**
+ * struct kdbus_meta_conn
+ * @kref:		Reference counting
+ * @lock:		Object lock
+ * @collected:		Bitmask of collected items
+ * @valid:		Bitmask of collected and valid items
+ * @ts:			Timestamp values
+ * @owned_names_items:	Serialized items for owned names
+ * @owned_names_size:	Size of @owned_names_items
+ * @conn_description:	Connection description
+ */
+struct kdbus_meta_conn {
+	struct kref kref;
+	struct mutex lock;
+	u64 collected;
+	u64 valid;
+
+	/* KDBUS_ITEM_TIMESTAMP */
+	struct kdbus_timestamp ts;
+
+	/* KDBUS_ITEM_OWNED_NAME */
+	struct kdbus_item *owned_names_items;
+	size_t owned_names_size;
+
+	/* KDBUS_ITEM_CONN_DESCRIPTION */
+	char *conn_description;
+};
+
+/* fixed size equivalent of "kdbus_caps" */
+struct kdbus_meta_caps {
+	u32 last_cap;
+	struct {
+		u32 caps[_KERNEL_CAPABILITY_U32S];
+	} set[4];
+};
+
+/**
+ * kdbus_meta_proc_new() - Create process metadata object
+ *
+ * Return: Pointer to new object on success, ERR_PTR on failure.
+ */
+struct kdbus_meta_proc *kdbus_meta_proc_new(void)
+{
+	struct kdbus_meta_proc *mp;
+
+	mp = kzalloc(sizeof(*mp), GFP_KERNEL);
+	if (!mp)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&mp->kref);
+	mutex_init(&mp->lock);
+
+	return mp;
+}
+
+static void kdbus_meta_proc_free(struct kref *kref)
+{
+	struct kdbus_meta_proc *mp = container_of(kref, struct kdbus_meta_proc,
+						  kref);
+
+	path_put(&mp->exe_path);
+	path_put(&mp->root_path);
+	if (mp->cred)
+		put_cred(mp->cred);
+	put_pid(mp->ppid);
+	put_pid(mp->tgid);
+	put_pid(mp->pid);
+
+	kfree(mp->seclabel);
+	kfree(mp->cmdline);
+	kfree(mp->cgroup);
+	kfree(mp);
+}
+
+/**
+ * kdbus_meta_proc_ref() - Gain reference
+ * @mp:		Process metadata object
+ *
+ * Return: @mp is returned
+ */
+struct kdbus_meta_proc *kdbus_meta_proc_ref(struct kdbus_meta_proc *mp)
+{
+	if (mp)
+		kref_get(&mp->kref);
+	return mp;
+}
+
+/**
+ * kdbus_meta_proc_unref() - Drop reference
+ * @mp:		Process metadata object
+ *
+ * Return: NULL
+ */
+struct kdbus_meta_proc *kdbus_meta_proc_unref(struct kdbus_meta_proc *mp)
+{
+	if (mp)
+		kref_put(&mp->kref, kdbus_meta_proc_free);
+	return NULL;
+}
+
+static void kdbus_meta_proc_collect_pids(struct kdbus_meta_proc *mp)
+{
+	struct task_struct *parent;
+
+	mp->pid = get_pid(task_pid(current));
+	mp->tgid = get_pid(task_tgid(current));
+
+	rcu_read_lock();
+	parent = rcu_dereference(current->real_parent);
+	mp->ppid = get_pid(task_tgid(parent));
+	rcu_read_unlock();
+
+	mp->valid |= KDBUS_ATTACH_PIDS;
+}
+
+static void kdbus_meta_proc_collect_tid_comm(struct kdbus_meta_proc *mp)
+{
+	get_task_comm(mp->tid_comm, current);
+	mp->valid |= KDBUS_ATTACH_TID_COMM;
+}
+
+static void kdbus_meta_proc_collect_pid_comm(struct kdbus_meta_proc *mp)
+{
+	get_task_comm(mp->pid_comm, current->group_leader);
+	mp->valid |= KDBUS_ATTACH_PID_COMM;
+}
+
+static void kdbus_meta_proc_collect_exe(struct kdbus_meta_proc *mp)
+{
+	struct file *exe_file;
+
+	rcu_read_lock();
+	exe_file = rcu_dereference(current->mm->exe_file);
+	if (exe_file) {
+		mp->exe_path = exe_file->f_path;
+		path_get(&mp->exe_path);
+		get_fs_root(current->fs, &mp->root_path);
+		mp->valid |= KDBUS_ATTACH_EXE;
+	}
+	rcu_read_unlock();
+}
+
+static int kdbus_meta_proc_collect_cmdline(struct kdbus_meta_proc *mp)
+{
+	struct mm_struct *mm = current->mm;
+	char *cmdline;
+
+	if (!mm->arg_end)
+		return 0;
+
+	cmdline = strndup_user((const char __user *)mm->arg_start,
+			       mm->arg_end - mm->arg_start);
+	if (IS_ERR(cmdline))
+		return PTR_ERR(cmdline);
+
+	mp->cmdline = cmdline;
+	mp->valid |= KDBUS_ATTACH_CMDLINE;
+
+	return 0;
+}
+
+static int kdbus_meta_proc_collect_cgroup(struct kdbus_meta_proc *mp)
+{
+#ifdef CONFIG_CGROUPS
+	void *page;
+	char *s;
+
+	page = (void *)__get_free_page(GFP_TEMPORARY);
+	if (!page)
+		return -ENOMEM;
+
+	s = task_cgroup_path(current, page, PAGE_SIZE);
+	if (s) {
+		mp->cgroup = kstrdup(s, GFP_KERNEL);
+		if (!mp->cgroup) {
+			free_page((unsigned long)page);
+			return -ENOMEM;
+		}
+	}
+
+	free_page((unsigned long)page);
+	mp->valid |= KDBUS_ATTACH_CGROUP;
+#endif
+
+	return 0;
+}
+
+static int kdbus_meta_proc_collect_seclabel(struct kdbus_meta_proc *mp)
+{
+#ifdef CONFIG_SECURITY
+	char *ctx = NULL;
+	u32 sid, len;
+	int ret;
+
+	security_task_getsecid(current, &sid);
+	ret = security_secid_to_secctx(sid, &ctx, &len);
+	if (ret < 0) {
+		/*
+		 * EOPNOTSUPP means no security module is active,
+		 * lets skip adding the seclabel then. This effectively
+		 * drops the SECLABEL item.
+		 */
+		return (ret == -EOPNOTSUPP) ? 0 : ret;
+	}
+
+	mp->seclabel = kstrdup(ctx, GFP_KERNEL);
+	security_release_secctx(ctx, len);
+	if (!mp->seclabel)
+		return -ENOMEM;
+
+	mp->valid |= KDBUS_ATTACH_SECLABEL;
+#endif
+
+	return 0;
+}
+
+static void kdbus_meta_proc_collect_audit(struct kdbus_meta_proc *mp)
+{
+#ifdef CONFIG_AUDITSYSCALL
+	mp->audit_loginuid = audit_get_loginuid(current);
+	mp->audit_sessionid = audit_get_sessionid(current);
+	mp->valid |= KDBUS_ATTACH_AUDIT;
+#endif
+}
+
+/**
+ * kdbus_meta_proc_collect() - Collect process metadata
+ * @mp:		Process metadata object
+ * @what:	Attach flags to collect
+ *
+ * This collects process metadata from current and saves it in @mp.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_meta_proc_collect(struct kdbus_meta_proc *mp, u64 what)
+{
+	int ret;
+
+	if (!mp || !(what & (KDBUS_ATTACH_CREDS |
+			     KDBUS_ATTACH_PIDS |
+			     KDBUS_ATTACH_AUXGROUPS |
+			     KDBUS_ATTACH_TID_COMM |
+			     KDBUS_ATTACH_PID_COMM |
+			     KDBUS_ATTACH_EXE |
+			     KDBUS_ATTACH_CMDLINE |
+			     KDBUS_ATTACH_CGROUP |
+			     KDBUS_ATTACH_CAPS |
+			     KDBUS_ATTACH_SECLABEL |
+			     KDBUS_ATTACH_AUDIT)))
+		return 0;
+
+	mutex_lock(&mp->lock);
+
+	/* creds, auxgrps and caps share "struct cred" as context */
+	{
+		const u64 m_cred = KDBUS_ATTACH_CREDS |
+				   KDBUS_ATTACH_AUXGROUPS |
+				   KDBUS_ATTACH_CAPS;
+
+		if ((what & m_cred) && !(mp->collected & m_cred)) {
+			mp->cred = get_current_cred();
+			mp->valid |= m_cred;
+			mp->collected |= m_cred;
+		}
+	}
+
+	if ((what & KDBUS_ATTACH_PIDS) &&
+	    !(mp->collected & KDBUS_ATTACH_PIDS)) {
+		kdbus_meta_proc_collect_pids(mp);
+		mp->collected |= KDBUS_ATTACH_PIDS;
+	}
+
+	if ((what & KDBUS_ATTACH_TID_COMM) &&
+	    !(mp->collected & KDBUS_ATTACH_TID_COMM)) {
+		kdbus_meta_proc_collect_tid_comm(mp);
+		mp->collected |= KDBUS_ATTACH_TID_COMM;
+	}
+
+	if ((what & KDBUS_ATTACH_PID_COMM) &&
+	    !(mp->collected & KDBUS_ATTACH_PID_COMM)) {
+		kdbus_meta_proc_collect_pid_comm(mp);
+		mp->collected |= KDBUS_ATTACH_PID_COMM;
+	}
+
+	if ((what & KDBUS_ATTACH_EXE) &&
+	    !(mp->collected & KDBUS_ATTACH_EXE)) {
+		kdbus_meta_proc_collect_exe(mp);
+		mp->collected |= KDBUS_ATTACH_EXE;
+	}
+
+	if ((what & KDBUS_ATTACH_CMDLINE) &&
+	    !(mp->collected & KDBUS_ATTACH_CMDLINE)) {
+		ret = kdbus_meta_proc_collect_cmdline(mp);
+		if (ret < 0)
+			goto exit_unlock;
+		mp->collected |= KDBUS_ATTACH_CMDLINE;
+	}
+
+	if ((what & KDBUS_ATTACH_CGROUP) &&
+	    !(mp->collected & KDBUS_ATTACH_CGROUP)) {
+		ret = kdbus_meta_proc_collect_cgroup(mp);
+		if (ret < 0)
+			goto exit_unlock;
+		mp->collected |= KDBUS_ATTACH_CGROUP;
+	}
+
+	if ((what & KDBUS_ATTACH_SECLABEL) &&
+	    !(mp->collected & KDBUS_ATTACH_SECLABEL)) {
+		ret = kdbus_meta_proc_collect_seclabel(mp);
+		if (ret < 0)
+			goto exit_unlock;
+		mp->collected |= KDBUS_ATTACH_SECLABEL;
+	}
+
+	if ((what & KDBUS_ATTACH_AUDIT) &&
+	    !(mp->collected & KDBUS_ATTACH_AUDIT)) {
+		kdbus_meta_proc_collect_audit(mp);
+		mp->collected |= KDBUS_ATTACH_AUDIT;
+	}
+
+	ret = 0;
+
+exit_unlock:
+	mutex_unlock(&mp->lock);
+	return ret;
+}
+
+/**
+ * kdbus_meta_fake_new() - Create fake metadata object
+ *
+ * Return: Pointer to new object on success, ERR_PTR on failure.
+ */
+struct kdbus_meta_fake *kdbus_meta_fake_new(void)
+{
+	struct kdbus_meta_fake *mf;
+
+	mf = kzalloc(sizeof(*mf), GFP_KERNEL);
+	if (!mf)
+		return ERR_PTR(-ENOMEM);
+
+	return mf;
+}
+
+/**
+ * kdbus_meta_fake_free() - Free fake metadata object
+ * @mf:		Fake metadata object
+ *
+ * Return: NULL
+ */
+struct kdbus_meta_fake *kdbus_meta_fake_free(struct kdbus_meta_fake *mf)
+{
+	if (mf) {
+		put_pid(mf->ppid);
+		put_pid(mf->tgid);
+		put_pid(mf->pid);
+		kfree(mf->seclabel);
+		kfree(mf);
+	}
+
+	return NULL;
+}
+
+/**
+ * kdbus_meta_fake_collect() - Fill fake metadata from faked credentials
+ * @mf:		Fake metadata object
+ * @creds:	Creds to set, may be %NULL
+ * @pids:	PIDs to set, may be %NULL
+ * @seclabel:	Seclabel to set, may be %NULL
+ *
+ * This function takes information stored in @creds, @pids and @seclabel and
+ * resolves them to kernel-representations, if possible. This call uses the
+ * current task's namespaces to resolve the given information.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_meta_fake_collect(struct kdbus_meta_fake *mf,
+			    const struct kdbus_creds *creds,
+			    const struct kdbus_pids *pids,
+			    const char *seclabel)
+{
+	if (mf->valid)
+		return -EALREADY;
+
+	if (creds) {
+		struct user_namespace *ns = current_user_ns();
+
+		mf->uid		= make_kuid(ns, creds->uid);
+		mf->euid	= make_kuid(ns, creds->euid);
+		mf->suid	= make_kuid(ns, creds->suid);
+		mf->fsuid	= make_kuid(ns, creds->fsuid);
+
+		mf->gid		= make_kgid(ns, creds->gid);
+		mf->egid	= make_kgid(ns, creds->egid);
+		mf->sgid	= make_kgid(ns, creds->sgid);
+		mf->fsgid	= make_kgid(ns, creds->fsgid);
+
+		if ((creds->uid   != (uid_t)-1 && !uid_valid(mf->uid))   ||
+		    (creds->euid  != (uid_t)-1 && !uid_valid(mf->euid))  ||
+		    (creds->suid  != (uid_t)-1 && !uid_valid(mf->suid))  ||
+		    (creds->fsuid != (uid_t)-1 && !uid_valid(mf->fsuid)) ||
+		    (creds->gid   != (gid_t)-1 && !gid_valid(mf->gid))   ||
+		    (creds->egid  != (gid_t)-1 && !gid_valid(mf->egid))  ||
+		    (creds->sgid  != (gid_t)-1 && !gid_valid(mf->sgid))  ||
+		    (creds->fsgid != (gid_t)-1 && !gid_valid(mf->fsgid)))
+			return -EINVAL;
+
+		mf->valid |= KDBUS_ATTACH_CREDS;
+	}
+
+	if (pids) {
+		mf->pid = get_pid(find_vpid(pids->tid));
+		mf->tgid = get_pid(find_vpid(pids->pid));
+		mf->ppid = get_pid(find_vpid(pids->ppid));
+
+		if ((pids->tid != 0 && !mf->pid) ||
+		    (pids->pid != 0 && !mf->tgid) ||
+		    (pids->ppid != 0 && !mf->ppid)) {
+			put_pid(mf->pid);
+			put_pid(mf->tgid);
+			put_pid(mf->ppid);
+			mf->pid = NULL;
+			mf->tgid = NULL;
+			mf->ppid = NULL;
+			return -EINVAL;
+		}
+
+		mf->valid |= KDBUS_ATTACH_PIDS;
+	}
+
+	if (seclabel) {
+		mf->seclabel = kstrdup(seclabel, GFP_KERNEL);
+		if (!mf->seclabel)
+			return -ENOMEM;
+
+		mf->valid |= KDBUS_ATTACH_SECLABEL;
+	}
+
+	return 0;
+}
+
+/**
+ * kdbus_meta_conn_new() - Create connection metadata object
+ *
+ * Return: Pointer to new object on success, ERR_PTR on failure.
+ */
+struct kdbus_meta_conn *kdbus_meta_conn_new(void)
+{
+	struct kdbus_meta_conn *mc;
+
+	mc = kzalloc(sizeof(*mc), GFP_KERNEL);
+	if (!mc)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&mc->kref);
+	mutex_init(&mc->lock);
+
+	return mc;
+}
+
+static void kdbus_meta_conn_free(struct kref *kref)
+{
+	struct kdbus_meta_conn *mc =
+		container_of(kref, struct kdbus_meta_conn, kref);
+
+	kfree(mc->conn_description);
+	kfree(mc->owned_names_items);
+	kfree(mc);
+}
+
+/**
+ * kdbus_meta_conn_ref() - Gain reference
+ * @mc:		Connection metadata object
+ */
+struct kdbus_meta_conn *kdbus_meta_conn_ref(struct kdbus_meta_conn *mc)
+{
+	if (mc)
+		kref_get(&mc->kref);
+	return mc;
+}
+
+/**
+ * kdbus_meta_conn_unref() - Drop reference
+ * @mc:		Connection metadata object
+ */
+struct kdbus_meta_conn *kdbus_meta_conn_unref(struct kdbus_meta_conn *mc)
+{
+	if (mc)
+		kref_put(&mc->kref, kdbus_meta_conn_free);
+	return NULL;
+}
+
+static void kdbus_meta_conn_collect_timestamp(struct kdbus_meta_conn *mc,
+					      u64 msg_seqnum)
+{
+	mc->ts.monotonic_ns = ktime_get_ns();
+	mc->ts.realtime_ns = ktime_get_real_ns();
+
+	if (msg_seqnum)
+		mc->ts.seqnum = msg_seqnum;
+
+	mc->valid |= KDBUS_ATTACH_TIMESTAMP;
+}
+
+static int kdbus_meta_conn_collect_names(struct kdbus_meta_conn *mc,
+					 struct kdbus_conn *conn)
+{
+	const struct kdbus_name_owner *owner;
+	struct kdbus_item *item;
+	size_t slen, size;
+
+	lockdep_assert_held(&conn->ep->bus->name_registry->rwlock);
+
+	size = 0;
+	/* open-code length calculation to avoid final padding */
+	list_for_each_entry(owner, &conn->names_list, conn_entry)
+		if (!(owner->flags & KDBUS_NAME_IN_QUEUE))
+			size = KDBUS_ALIGN8(size) + KDBUS_ITEM_HEADER_SIZE +
+				sizeof(struct kdbus_name) +
+				strlen(owner->name->name) + 1;
+
+	if (!size)
+		return 0;
+
+	/* make sure we include zeroed padding for convenience helpers */
+	item = kmalloc(KDBUS_ALIGN8(size), GFP_KERNEL);
+	if (!item)
+		return -ENOMEM;
+
+	mc->owned_names_items = item;
+	mc->owned_names_size = size;
+
+	list_for_each_entry(owner, &conn->names_list, conn_entry) {
+		if (owner->flags & KDBUS_NAME_IN_QUEUE)
+			continue;
+
+		slen = strlen(owner->name->name) + 1;
+		kdbus_item_set(item, KDBUS_ITEM_OWNED_NAME, NULL,
+			       sizeof(struct kdbus_name) + slen);
+		item->name.flags = owner->flags;
+		memcpy(item->name.name, owner->name->name, slen);
+		item = KDBUS_ITEM_NEXT(item);
+	}
+
+	/* sanity check: the buffer should be completely written now */
+	WARN_ON((u8 *)item !=
+			(u8 *)mc->owned_names_items + KDBUS_ALIGN8(size));
+
+	mc->valid |= KDBUS_ATTACH_NAMES;
+	return 0;
+}
+
+static int kdbus_meta_conn_collect_description(struct kdbus_meta_conn *mc,
+					       struct kdbus_conn *conn)
+{
+	if (!conn->description)
+		return 0;
+
+	mc->conn_description = kstrdup(conn->description, GFP_KERNEL);
+	if (!mc->conn_description)
+		return -ENOMEM;
+
+	mc->valid |= KDBUS_ATTACH_CONN_DESCRIPTION;
+	return 0;
+}
+
+/**
+ * kdbus_meta_conn_collect() - Collect connection metadata
+ * @mc:		Message metadata object
+ * @conn:	Connection to collect data from
+ * @msg_seqnum:	Sequence number of the message to send
+ * @what:	Attach flags to collect
+ *
+ * This collects connection metadata from @msg_seqnum and @conn and saves it
+ * in @mc.
+ *
+ * If KDBUS_ATTACH_NAMES is set in @what and @conn is non-NULL, the caller must
+ * hold the name-registry read-lock of conn->ep->bus->registry.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_meta_conn_collect(struct kdbus_meta_conn *mc,
+			    struct kdbus_conn *conn,
+			    u64 msg_seqnum, u64 what)
+{
+	int ret;
+
+	if (!mc || !(what & (KDBUS_ATTACH_TIMESTAMP |
+			     KDBUS_ATTACH_NAMES |
+			     KDBUS_ATTACH_CONN_DESCRIPTION)))
+		return 0;
+
+	mutex_lock(&mc->lock);
+
+	if (msg_seqnum && (what & KDBUS_ATTACH_TIMESTAMP) &&
+	    !(mc->collected & KDBUS_ATTACH_TIMESTAMP)) {
+		kdbus_meta_conn_collect_timestamp(mc, msg_seqnum);
+		mc->collected |= KDBUS_ATTACH_TIMESTAMP;
+	}
+
+	if (conn && (what & KDBUS_ATTACH_NAMES) &&
+	    !(mc->collected & KDBUS_ATTACH_NAMES)) {
+		ret = kdbus_meta_conn_collect_names(mc, conn);
+		if (ret < 0)
+			goto exit_unlock;
+		mc->collected |= KDBUS_ATTACH_NAMES;
+	}
+
+	if (conn && (what & KDBUS_ATTACH_CONN_DESCRIPTION) &&
+	    !(mc->collected & KDBUS_ATTACH_CONN_DESCRIPTION)) {
+		ret = kdbus_meta_conn_collect_description(mc, conn);
+		if (ret < 0)
+			goto exit_unlock;
+		mc->collected |= KDBUS_ATTACH_CONN_DESCRIPTION;
+	}
+
+	ret = 0;
+
+exit_unlock:
+	mutex_unlock(&mc->lock);
+	return ret;
+}
+
+static void kdbus_meta_export_caps(struct kdbus_meta_caps *out,
+				   const struct kdbus_meta_proc *mp,
+				   struct user_namespace *user_ns)
+{
+	struct user_namespace *iter;
+	const struct cred *cred = mp->cred;
+	bool parent = false, owner = false;
+	int i;
+
+	/*
+	 * This translates the effective capabilities of 'cred' into the given
+	 * user-namespace. If the given user-namespace is a child-namespace of
+	 * the user-namespace of 'cred', the mask can be copied verbatim. If
+	 * not, the mask is cleared.
+	 * There's one exception: If 'cred' is the owner of any user-namespace
+	 * in the path between the given user-namespace and the user-namespace
+	 * of 'cred', then it has all effective capabilities set. This means,
+	 * the user who created a user-namespace always has all effective
+	 * capabilities in any child namespaces. Note that this is based on the
+	 * uid of the namespace creator, not the task hierarchy.
+	 */
+	for (iter = user_ns; iter; iter = iter->parent) {
+		if (iter == cred->user_ns) {
+			parent = true;
+			break;
+		}
+
+		if (iter == &init_user_ns)
+			break;
+
+		if ((iter->parent == cred->user_ns) &&
+		    uid_eq(iter->owner, cred->euid)) {
+			owner = true;
+			break;
+		}
+	}
+
+	out->last_cap = CAP_LAST_CAP;
+
+	CAP_FOR_EACH_U32(i) {
+		if (parent) {
+			out->set[0].caps[i] = cred->cap_inheritable.cap[i];
+			out->set[1].caps[i] = cred->cap_permitted.cap[i];
+			out->set[2].caps[i] = cred->cap_effective.cap[i];
+			out->set[3].caps[i] = cred->cap_bset.cap[i];
+		} else if (owner) {
+			out->set[0].caps[i] = 0U;
+			out->set[1].caps[i] = ~0U;
+			out->set[2].caps[i] = ~0U;
+			out->set[3].caps[i] = ~0U;
+		} else {
+			out->set[0].caps[i] = 0U;
+			out->set[1].caps[i] = 0U;
+			out->set[2].caps[i] = 0U;
+			out->set[3].caps[i] = 0U;
+		}
+	}
+
+	/* clear unused bits */
+	for (i = 0; i < 4; i++)
+		out->set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
+					CAP_LAST_U32_VALID_MASK;
+}
+
+/* This is equivalent to from_kuid_munged(), but maps INVALID_UID to itself */
+static uid_t kdbus_from_kuid_keep(struct user_namespace *ns, kuid_t uid)
+{
+	return uid_valid(uid) ? from_kuid_munged(ns, uid) : ((uid_t)-1);
+}
+
+/* This is equivalent to from_kgid_munged(), but maps INVALID_GID to itself */
+static gid_t kdbus_from_kgid_keep(struct user_namespace *ns, kgid_t gid)
+{
+	return gid_valid(gid) ? from_kgid_munged(ns, gid) : ((gid_t)-1);
+}
+
+struct kdbus_meta_staging {
+	const struct kdbus_meta_proc *mp;
+	const struct kdbus_meta_fake *mf;
+	const struct kdbus_meta_conn *mc;
+	const struct kdbus_conn *conn;
+	u64 mask;
+
+	void *exe;
+	const char *exe_path;
+};
+
+static size_t kdbus_meta_measure(struct kdbus_meta_staging *staging)
+{
+	const struct kdbus_meta_proc *mp = staging->mp;
+	const struct kdbus_meta_fake *mf = staging->mf;
+	const struct kdbus_meta_conn *mc = staging->mc;
+	const u64 mask = staging->mask;
+	size_t size = 0;
+
+	/* process metadata */
+
+	if (mf && (mask & KDBUS_ATTACH_CREDS))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_creds));
+	else if (mp && (mask & KDBUS_ATTACH_CREDS))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_creds));
+
+	if (mf && (mask & KDBUS_ATTACH_PIDS))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_pids));
+	else if (mp && (mask & KDBUS_ATTACH_PIDS))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_pids));
+
+	if (mp && (mask & KDBUS_ATTACH_AUXGROUPS))
+		size += KDBUS_ITEM_SIZE(mp->cred->group_info->ngroups *
+					sizeof(u64));
+
+	if (mp && (mask & KDBUS_ATTACH_TID_COMM))
+		size += KDBUS_ITEM_SIZE(strlen(mp->tid_comm) + 1);
+
+	if (mp && (mask & KDBUS_ATTACH_PID_COMM))
+		size += KDBUS_ITEM_SIZE(strlen(mp->pid_comm) + 1);
+
+	if (staging->exe_path && (mask & KDBUS_ATTACH_EXE))
+		size += KDBUS_ITEM_SIZE(strlen(staging->exe_path) + 1);
+
+	if (mp && (mask & KDBUS_ATTACH_CMDLINE))
+		size += KDBUS_ITEM_SIZE(strlen(mp->cmdline) + 1);
+
+	if (mp && (mask & KDBUS_ATTACH_CGROUP))
+		size += KDBUS_ITEM_SIZE(strlen(mp->cgroup) + 1);
+
+	if (mp && (mask & KDBUS_ATTACH_CAPS))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_meta_caps));
+
+	if (mf && (mask & KDBUS_ATTACH_SECLABEL))
+		size += KDBUS_ITEM_SIZE(strlen(mf->seclabel) + 1);
+	else if (mp && (mask & KDBUS_ATTACH_SECLABEL))
+		size += KDBUS_ITEM_SIZE(strlen(mp->seclabel) + 1);
+
+	if (mp && (mask & KDBUS_ATTACH_AUDIT))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_audit));
+
+	/* connection metadata */
+
+	if (mc && (mask & KDBUS_ATTACH_NAMES))
+		size += KDBUS_ALIGN8(mc->owned_names_size);
+
+	if (mc && (mask & KDBUS_ATTACH_CONN_DESCRIPTION))
+		size += KDBUS_ITEM_SIZE(strlen(mc->conn_description) + 1);
+
+	if (mc && (mask & KDBUS_ATTACH_TIMESTAMP))
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_timestamp));
+
+	return size;
+}
+
+static struct kdbus_item *kdbus_write_head(struct kdbus_item **iter,
+					   u64 type, u64 size)
+{
+	struct kdbus_item *item = *iter;
+	size_t padding;
+
+	item->type = type;
+	item->size = KDBUS_ITEM_HEADER_SIZE + size;
+
+	/* clear padding */
+	padding = KDBUS_ALIGN8(item->size) - item->size;
+	if (padding)
+		memset(item->data + size, 0, padding);
+
+	*iter = KDBUS_ITEM_NEXT(item);
+	return item;
+}
+
+static struct kdbus_item *kdbus_write_full(struct kdbus_item **iter,
+					   u64 type, u64 size, const void *data)
+{
+	struct kdbus_item *item;
+
+	item = kdbus_write_head(iter, type, size);
+	memcpy(item->data, data, size);
+	return item;
+}
+
+static size_t kdbus_meta_write(struct kdbus_meta_staging *staging, void *mem,
+			       size_t size)
+{
+	struct user_namespace *user_ns = staging->conn->cred->user_ns;
+	struct pid_namespace *pid_ns = ns_of_pid(staging->conn->pid);
+	struct kdbus_item *item = NULL, *items = mem;
+	u8 *end, *owned_names_end = NULL;
+
+	/* process metadata */
+
+	if (staging->mf && (staging->mask & KDBUS_ATTACH_CREDS)) {
+		const struct kdbus_meta_fake *mf = staging->mf;
+
+		item = kdbus_write_head(&items, KDBUS_ITEM_CREDS,
+					sizeof(struct kdbus_creds));
+		item->creds = (struct kdbus_creds){
+			.uid	= kdbus_from_kuid_keep(user_ns, mf->uid),
+			.euid	= kdbus_from_kuid_keep(user_ns, mf->euid),
+			.suid	= kdbus_from_kuid_keep(user_ns, mf->suid),
+			.fsuid	= kdbus_from_kuid_keep(user_ns, mf->fsuid),
+			.gid	= kdbus_from_kgid_keep(user_ns, mf->gid),
+			.egid	= kdbus_from_kgid_keep(user_ns, mf->egid),
+			.sgid	= kdbus_from_kgid_keep(user_ns, mf->sgid),
+			.fsgid	= kdbus_from_kgid_keep(user_ns, mf->fsgid),
+		};
+	} else if (staging->mp && (staging->mask & KDBUS_ATTACH_CREDS)) {
+		const struct cred *c = staging->mp->cred;
+
+		item = kdbus_write_head(&items, KDBUS_ITEM_CREDS,
+					sizeof(struct kdbus_creds));
+		item->creds = (struct kdbus_creds){
+			.uid	= kdbus_from_kuid_keep(user_ns, c->uid),
+			.euid	= kdbus_from_kuid_keep(user_ns, c->euid),
+			.suid	= kdbus_from_kuid_keep(user_ns, c->suid),
+			.fsuid	= kdbus_from_kuid_keep(user_ns, c->fsuid),
+			.gid	= kdbus_from_kgid_keep(user_ns, c->gid),
+			.egid	= kdbus_from_kgid_keep(user_ns, c->egid),
+			.sgid	= kdbus_from_kgid_keep(user_ns, c->sgid),
+			.fsgid	= kdbus_from_kgid_keep(user_ns, c->fsgid),
+		};
+	}
+
+	if (staging->mf && (staging->mask & KDBUS_ATTACH_PIDS)) {
+		item = kdbus_write_head(&items, KDBUS_ITEM_PIDS,
+					sizeof(struct kdbus_pids));
+		item->pids = (struct kdbus_pids){
+			.pid = pid_nr_ns(staging->mf->tgid, pid_ns),
+			.tid = pid_nr_ns(staging->mf->pid, pid_ns),
+			.ppid = pid_nr_ns(staging->mf->ppid, pid_ns),
+		};
+	} else if (staging->mp && (staging->mask & KDBUS_ATTACH_PIDS)) {
+		item = kdbus_write_head(&items, KDBUS_ITEM_PIDS,
+					sizeof(struct kdbus_pids));
+		item->pids = (struct kdbus_pids){
+			.pid = pid_nr_ns(staging->mp->tgid, pid_ns),
+			.tid = pid_nr_ns(staging->mp->pid, pid_ns),
+			.ppid = pid_nr_ns(staging->mp->ppid, pid_ns),
+		};
+	}
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_AUXGROUPS)) {
+		const struct group_info *info = staging->mp->cred->group_info;
+		size_t i;
+
+		item = kdbus_write_head(&items, KDBUS_ITEM_AUXGROUPS,
+					info->ngroups * sizeof(u64));
+		for (i = 0; i < info->ngroups; ++i)
+			item->data64[i] = from_kgid_munged(user_ns,
+							   GROUP_AT(info, i));
+	}
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_TID_COMM))
+		item = kdbus_write_full(&items, KDBUS_ITEM_TID_COMM,
+					strlen(staging->mp->tid_comm) + 1,
+					staging->mp->tid_comm);
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_PID_COMM))
+		item = kdbus_write_full(&items, KDBUS_ITEM_PID_COMM,
+					strlen(staging->mp->pid_comm) + 1,
+					staging->mp->pid_comm);
+
+	if (staging->exe_path && (staging->mask & KDBUS_ATTACH_EXE))
+		item = kdbus_write_full(&items, KDBUS_ITEM_EXE,
+					strlen(staging->exe_path) + 1,
+					staging->exe_path);
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_CMDLINE))
+		item = kdbus_write_full(&items, KDBUS_ITEM_CMDLINE,
+					strlen(staging->mp->cmdline) + 1,
+					staging->mp->cmdline);
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_CGROUP))
+		item = kdbus_write_full(&items, KDBUS_ITEM_CGROUP,
+					strlen(staging->mp->cgroup) + 1,
+					staging->mp->cgroup);
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_CAPS)) {
+		item = kdbus_write_head(&items, KDBUS_ITEM_CAPS,
+					sizeof(struct kdbus_meta_caps));
+		kdbus_meta_export_caps((void*)&item->caps, staging->mp,
+				       user_ns);
+	}
+
+	if (staging->mf && (staging->mask & KDBUS_ATTACH_SECLABEL))
+		item = kdbus_write_full(&items, KDBUS_ITEM_SECLABEL,
+					strlen(staging->mf->seclabel) + 1,
+					staging->mf->seclabel);
+	else if (staging->mp && (staging->mask & KDBUS_ATTACH_SECLABEL))
+		item = kdbus_write_full(&items, KDBUS_ITEM_SECLABEL,
+					strlen(staging->mp->seclabel) + 1,
+					staging->mp->seclabel);
+
+	if (staging->mp && (staging->mask & KDBUS_ATTACH_AUDIT)) {
+		item = kdbus_write_head(&items, KDBUS_ITEM_AUDIT,
+					sizeof(struct kdbus_audit));
+		item->audit = (struct kdbus_audit){
+			.loginuid = from_kuid(user_ns,
+					      staging->mp->audit_loginuid),
+			.sessionid = staging->mp->audit_sessionid,
+		};
+	}
+
+	/* connection metadata */
+
+	if (staging->mc && (staging->mask & KDBUS_ATTACH_NAMES)) {
+		memcpy(items, staging->mc->owned_names_items,
+		       KDBUS_ALIGN8(staging->mc->owned_names_size));
+		owned_names_end = (u8 *)items + staging->mc->owned_names_size;
+		items = (void *)KDBUS_ALIGN8((unsigned long)owned_names_end);
+	}
+
+	if (staging->mc && (staging->mask & KDBUS_ATTACH_CONN_DESCRIPTION))
+		item = kdbus_write_full(&items, KDBUS_ITEM_CONN_DESCRIPTION,
+				strlen(staging->mc->conn_description) + 1,
+				staging->mc->conn_description);
+
+	if (staging->mc && (staging->mask & KDBUS_ATTACH_TIMESTAMP))
+		item = kdbus_write_full(&items, KDBUS_ITEM_TIMESTAMP,
+					sizeof(staging->mc->ts),
+					&staging->mc->ts);
+
+	/*
+	 * Return real size (minus trailing padding). In case of 'owned_names'
+	 * we cannot deduce it from item->size, so treat it special.
+	 */
+
+	if (items == (void *)KDBUS_ALIGN8((unsigned long)owned_names_end))
+		end = owned_names_end;
+	else if (item)
+		end = (u8 *)item + item->size;
+	else
+		end = mem;
+
+	WARN_ON((u8 *)items - (u8 *)mem != size);
+	WARN_ON((void *)KDBUS_ALIGN8((unsigned long)end) != (void *)items);
+
+	return end - (u8 *)mem;
+}
+
+int kdbus_meta_emit(struct kdbus_meta_proc *mp,
+		    struct kdbus_meta_fake *mf,
+		    struct kdbus_meta_conn *mc,
+		    struct kdbus_conn *conn,
+		    u64 mask,
+		    struct kdbus_item **out_items,
+		    size_t *out_size)
+{
+	struct kdbus_meta_staging staging = {};
+	struct kdbus_item *items = NULL;
+	size_t size = 0;
+	int ret;
+
+	if (WARN_ON(mf && mp))
+		mp = NULL;
+
+	staging.mp = mp;
+	staging.mf = mf;
+	staging.mc = mc;
+	staging.conn = conn;
+
+	/* get mask of valid items */
+	if (mf)
+		staging.mask |= mf->valid;
+	if (mp) {
+		mutex_lock(&mp->lock);
+		staging.mask |= mp->valid;
+		mutex_unlock(&mp->lock);
+	}
+	if (mc) {
+		mutex_lock(&mc->lock);
+		staging.mask |= mc->valid;
+		mutex_unlock(&mc->lock);
+	}
+
+	staging.mask &= mask;
+
+	if (!staging.mask) { /* bail out if nothing to do */
+		ret = 0;
+		goto exit;
+	}
+
+	/* EXE is special as it needs a temporary page to assemble */
+	if (mp && (staging.mask & KDBUS_ATTACH_EXE)) {
+		struct path p;
+
+		/*
+		 * XXX: We need access to __d_path() so we can write the path
+		 * relative to conn->root_path. Once upstream, we need
+		 * EXPORT_SYMBOL(__d_path) or an equivalent of d_path() that
+		 * takes the root path directly. Until then, we drop this item
+		 * if the root-paths differ.
+		 */
+
+		get_fs_root(current->fs, &p);
+		if (path_equal(&p, &conn->root_path)) {
+			staging.exe = (void *)__get_free_page(GFP_TEMPORARY);
+			if (!staging.exe) {
+				path_put(&p);
+				ret = -ENOMEM;
+				goto exit;
+			}
+
+			staging.exe_path = d_path(&mp->exe_path, staging.exe,
+						  PAGE_SIZE);
+			if (IS_ERR(staging.exe_path)) {
+				path_put(&p);
+				ret = PTR_ERR(staging.exe_path);
+				goto exit;
+			}
+		}
+		path_put(&p);
+	}
+
+	size = kdbus_meta_measure(&staging);
+	if (!size) { /* bail out if nothing to do */
+		ret = 0;
+		goto exit;
+	}
+
+	items = kmalloc(size, GFP_KERNEL);
+	if (!items) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	size = kdbus_meta_write(&staging, items, size);
+	if (!size) {
+		kfree(items);
+		items = NULL;
+	}
+
+	ret = 0;
+
+exit:
+	if (staging.exe)
+		free_page((unsigned long)staging.exe);
+	if (ret >= 0) {
+		*out_items = items;
+		*out_size = size;
+	}
+	return ret;
+}
+
+enum {
+	KDBUS_META_PROC_NONE,
+	KDBUS_META_PROC_NORMAL,
+};
+
+/**
+ * kdbus_proc_permission() - check /proc permissions on target pid
+ * @pid_ns:		namespace we operate in
+ * @cred:		credentials of requestor
+ * @target:		target process
+ *
+ * This checks whether a process with credentials @cred can access information
+ * of @target in the namespace @pid_ns. This tries to follow /proc permissions,
+ * but is slightly more restrictive.
+ *
+ * Return: The /proc access level (KDBUS_META_PROC_*) is returned.
+ */
+static unsigned int kdbus_proc_permission(const struct pid_namespace *pid_ns,
+					  const struct cred *cred,
+					  struct pid *target)
+{
+	if (pid_ns->hide_pid < 1)
+		return KDBUS_META_PROC_NORMAL;
+
+	/* XXX: we need groups_search() exported for aux-groups */
+	if (gid_eq(cred->egid, pid_ns->pid_gid))
+		return KDBUS_META_PROC_NORMAL;
+
+	/*
+	 * XXX: If ptrace_may_access(PTRACE_MODE_READ) is granted, you can
+	 * overwrite hide_pid. However, ptrace_may_access() only supports
+	 * checking 'current', hence, we cannot use this here. But we
+	 * simply decide to not support this override, so no need to worry.
+	 */
+
+	return KDBUS_META_PROC_NONE;
+}
+
+/**
+ * kdbus_meta_proc_mask() - calculate which metadata would be visible to
+ *			    a connection via /proc
+ * @prv_pid:		pid of metadata provider
+ * @req_pid:		pid of metadata requestor
+ * @req_cred:		credentials of metadata reqeuestor
+ * @wanted:		metadata that is requested
+ *
+ * This checks which metadata items of @prv_pid can be read via /proc by the
+ * requestor @req_pid.
+ *
+ * Return: Set of metadata flags the requestor can see (limited by @wanted).
+ */
+static u64 kdbus_meta_proc_mask(struct pid *prv_pid,
+				struct pid *req_pid,
+				const struct cred *req_cred,
+				u64 wanted)
+{
+	struct pid_namespace *prv_ns, *req_ns;
+	unsigned int proc;
+
+	prv_ns = ns_of_pid(prv_pid);
+	req_ns = ns_of_pid(req_pid);
+
+	/*
+	 * If the sender is not visible in the receiver namespace, then the
+	 * receiver cannot access the sender via its own procfs. Hence, we do
+	 * not attach any additional metadata.
+	 */
+	if (!pid_nr_ns(prv_pid, req_ns))
+		return 0;
+
+	/*
+	 * If the pid-namespace of the receiver has hide_pid set, it cannot see
+	 * any process but its own. We shortcut this /proc permission check if
+	 * provider and requestor are the same. If not, we perform rather
+	 * expensive /proc permission checks.
+	 */
+	if (prv_pid == req_pid)
+		proc = KDBUS_META_PROC_NORMAL;
+	else
+		proc = kdbus_proc_permission(req_ns, req_cred, prv_pid);
+
+	/* you need /proc access to read standard process attributes */
+	if (proc < KDBUS_META_PROC_NORMAL)
+		wanted &= ~(KDBUS_ATTACH_TID_COMM |
+			    KDBUS_ATTACH_PID_COMM |
+			    KDBUS_ATTACH_SECLABEL |
+			    KDBUS_ATTACH_CMDLINE |
+			    KDBUS_ATTACH_CGROUP |
+			    KDBUS_ATTACH_AUDIT |
+			    KDBUS_ATTACH_CAPS |
+			    KDBUS_ATTACH_EXE);
+
+	/* clear all non-/proc flags */
+	return wanted & (KDBUS_ATTACH_TID_COMM |
+			 KDBUS_ATTACH_PID_COMM |
+			 KDBUS_ATTACH_SECLABEL |
+			 KDBUS_ATTACH_CMDLINE |
+			 KDBUS_ATTACH_CGROUP |
+			 KDBUS_ATTACH_AUDIT |
+			 KDBUS_ATTACH_CAPS |
+			 KDBUS_ATTACH_EXE);
+}
+
+/**
+ * kdbus_meta_get_mask() - calculate attach flags mask for metadata request
+ * @prv_pid:		pid of metadata provider
+ * @prv_mask:		mask of metadata the provide grants unchecked
+ * @req_pid:		pid of metadata requestor
+ * @req_cred:		credentials of metadata requestor
+ * @req_mask:		mask of metadata that is requested
+ *
+ * This calculates the metadata items that the requestor @req_pid can access
+ * from the metadata provider @prv_pid. This permission check consists of
+ * several different parts:
+ *  - Providers can grant metadata items unchecked. Regardless of their type,
+ *    they're always granted to the requestor. This mask is passed as @prv_mask.
+ *  - Basic items (credentials and connection metadata) are granted implicitly
+ *    to everyone. They're publicly available to any bus-user that can see the
+ *    provider.
+ *  - Process credentials that are not granted implicitly follow the same
+ *    permission checks as /proc. This means, we always assume a requestor
+ *    process has access to their *own* /proc mount, if they have access to
+ *    kdbusfs.
+ *
+ * Return: Mask of metadata that is granted.
+ */
+static u64 kdbus_meta_get_mask(struct pid *prv_pid, u64 prv_mask,
+			       struct pid *req_pid,
+			       const struct cred *req_cred, u64 req_mask)
+{
+	u64 missing, impl_mask, proc_mask = 0;
+
+	/*
+	 * Connection metadata and basic unix process credentials are
+	 * transmitted implicitly, and cannot be suppressed. Both are required
+	 * to perform user-space policies on the receiver-side. Furthermore,
+	 * connection metadata is public state, anyway, and unix credentials
+	 * are needed for UDS-compatibility. We extend them slightly by
+	 * auxiliary groups and additional uids/gids/pids.
+	 */
+	impl_mask = /* connection metadata */
+		    KDBUS_ATTACH_CONN_DESCRIPTION |
+		    KDBUS_ATTACH_TIMESTAMP |
+		    KDBUS_ATTACH_NAMES |
+		    /* credentials and pids */
+		    KDBUS_ATTACH_AUXGROUPS |
+		    KDBUS_ATTACH_CREDS |
+		    KDBUS_ATTACH_PIDS;
+
+	/*
+	 * Calculate the set of metadata that is not granted implicitly nor by
+	 * the sender, but still requested by the receiver. If any are left,
+	 * perform rather expensive /proc access checks for them.
+	 */
+	missing = req_mask & ~((prv_mask | impl_mask) & req_mask);
+	if (missing)
+		proc_mask = kdbus_meta_proc_mask(prv_pid, req_pid, req_cred,
+						 missing);
+
+	return (prv_mask | impl_mask | proc_mask) & req_mask;
+}
+
+/**
+ */
+u64 kdbus_meta_info_mask(const struct kdbus_conn *conn, u64 mask)
+{
+	return kdbus_meta_get_mask(conn->pid,
+				   atomic64_read(&conn->attach_flags_send),
+				   task_pid(current),
+				   current_cred(),
+				   mask);
+}
+
+/**
+ */
+u64 kdbus_meta_msg_mask(const struct kdbus_conn *snd,
+			const struct kdbus_conn *rcv)
+{
+	return kdbus_meta_get_mask(task_pid(current),
+				   atomic64_read(&snd->attach_flags_send),
+				   rcv->pid,
+				   rcv->cred,
+				   atomic64_read(&rcv->attach_flags_recv));
+}
diff --git a/ipc/kdbus/metadata.h b/ipc/kdbus/metadata.h
new file mode 100644
index 000000000000..dba7cc7fdbcb
--- /dev/null
+++ b/ipc/kdbus/metadata.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_METADATA_H
+#define __KDBUS_METADATA_H
+
+#include <linux/kernel.h>
+
+struct kdbus_conn;
+struct kdbus_pool_slice;
+
+struct kdbus_meta_proc;
+struct kdbus_meta_conn;
+
+/**
+ * struct kdbus_meta_fake - Fake metadata
+ * @valid:		Bitmask of collected and valid items
+ * @uid:		UID of process
+ * @euid:		EUID of process
+ * @suid:		SUID of process
+ * @fsuid:		FSUID of process
+ * @gid:		GID of process
+ * @egid:		EGID of process
+ * @sgid:		SGID of process
+ * @fsgid:		FSGID of process
+ * @pid:		PID of process
+ * @tgid:		TGID of process
+ * @ppid:		PPID of process
+ * @seclabel:		Seclabel
+ */
+struct kdbus_meta_fake {
+	u64 valid;
+
+	/* KDBUS_ITEM_CREDS */
+	kuid_t uid, euid, suid, fsuid;
+	kgid_t gid, egid, sgid, fsgid;
+
+	/* KDBUS_ITEM_PIDS */
+	struct pid *pid, *tgid, *ppid;
+
+	/* KDBUS_ITEM_SECLABEL */
+	char *seclabel;
+};
+
+struct kdbus_meta_proc *kdbus_meta_proc_new(void);
+struct kdbus_meta_proc *kdbus_meta_proc_ref(struct kdbus_meta_proc *mp);
+struct kdbus_meta_proc *kdbus_meta_proc_unref(struct kdbus_meta_proc *mp);
+int kdbus_meta_proc_collect(struct kdbus_meta_proc *mp, u64 what);
+
+struct kdbus_meta_fake *kdbus_meta_fake_new(void);
+struct kdbus_meta_fake *kdbus_meta_fake_free(struct kdbus_meta_fake *mf);
+int kdbus_meta_fake_collect(struct kdbus_meta_fake *mf,
+			    const struct kdbus_creds *creds,
+			    const struct kdbus_pids *pids,
+			    const char *seclabel);
+
+struct kdbus_meta_conn *kdbus_meta_conn_new(void);
+struct kdbus_meta_conn *kdbus_meta_conn_ref(struct kdbus_meta_conn *mc);
+struct kdbus_meta_conn *kdbus_meta_conn_unref(struct kdbus_meta_conn *mc);
+int kdbus_meta_conn_collect(struct kdbus_meta_conn *mc,
+			    struct kdbus_conn *conn,
+			    u64 msg_seqnum, u64 what);
+
+int kdbus_meta_emit(struct kdbus_meta_proc *mp,
+		    struct kdbus_meta_fake *mf,
+		    struct kdbus_meta_conn *mc,
+		    struct kdbus_conn *conn,
+		    u64 mask,
+		    struct kdbus_item **out_items,
+		    size_t *out_size);
+u64 kdbus_meta_info_mask(const struct kdbus_conn *conn, u64 mask);
+u64 kdbus_meta_msg_mask(const struct kdbus_conn *snd,
+			const struct kdbus_conn *rcv);
+
+#endif
diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
new file mode 100644
index 000000000000..bf44ca3f12b6
--- /dev/null
+++ b/ipc/kdbus/names.c
@@ -0,0 +1,854 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/ctype.h>
+#include <linux/fs.h>
+#include <linux/hash.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/uio.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "item.h"
+#include "names.h"
+#include "notify.h"
+#include "policy.h"
+
+#define KDBUS_NAME_SAVED_MASK (KDBUS_NAME_ALLOW_REPLACEMENT |	\
+			       KDBUS_NAME_QUEUE)
+
+static bool kdbus_name_owner_is_used(struct kdbus_name_owner *owner)
+{
+	return !list_empty(&owner->name_entry) ||
+	       owner == owner->name->activator;
+}
+
+static struct kdbus_name_owner *
+kdbus_name_owner_new(struct kdbus_conn *conn, struct kdbus_name_entry *name,
+		     u64 flags)
+{
+	struct kdbus_name_owner *owner;
+
+	kdbus_conn_assert_active(conn);
+
+	if (conn->name_count >= KDBUS_CONN_MAX_NAMES)
+		return ERR_PTR(-E2BIG);
+
+	owner = kmalloc(sizeof(*owner), GFP_KERNEL);
+	if (!owner)
+		return ERR_PTR(-ENOMEM);
+
+	owner->flags = flags & KDBUS_NAME_SAVED_MASK;
+	owner->conn = conn;
+	owner->name = name;
+	list_add_tail(&owner->conn_entry, &conn->names_list);
+	INIT_LIST_HEAD(&owner->name_entry);
+
+	++conn->name_count;
+	return owner;
+}
+
+static void kdbus_name_owner_free(struct kdbus_name_owner *owner)
+{
+	if (!owner)
+		return;
+
+	WARN_ON(kdbus_name_owner_is_used(owner));
+	--owner->conn->name_count;
+	list_del(&owner->conn_entry);
+	kfree(owner);
+}
+
+static struct kdbus_name_owner *
+kdbus_name_owner_find(struct kdbus_name_entry *name, struct kdbus_conn *conn)
+{
+	struct kdbus_name_owner *owner;
+
+	/*
+	 * Use conn->names_list over name->queue to make sure boundaries of
+	 * this linear search are controlled by the connection itself.
+	 * Furthermore, this will find normal owners as well as activators
+	 * without any additional code.
+	 */
+	list_for_each_entry(owner, &conn->names_list, conn_entry)
+		if (owner->name == name)
+			return owner;
+
+	return NULL;
+}
+
+static bool kdbus_name_entry_is_used(struct kdbus_name_entry *name)
+{
+	return !list_empty(&name->queue) || name->activator;
+}
+
+static struct kdbus_name_owner *
+kdbus_name_entry_first(struct kdbus_name_entry *name)
+{
+	return list_first_entry_or_null(&name->queue, struct kdbus_name_owner,
+					name_entry);
+}
+
+static struct kdbus_name_entry *
+kdbus_name_entry_new(struct kdbus_name_registry *r, u32 hash,
+		     const char *name_str)
+{
+	struct kdbus_name_entry *name;
+	size_t namelen;
+
+	lockdep_assert_held(&r->rwlock);
+
+	namelen = strlen(name_str);
+
+	name = kmalloc(sizeof(*name) + namelen + 1, GFP_KERNEL);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
+
+	name->name_id = ++r->name_seq_last;
+	name->activator = NULL;
+	INIT_LIST_HEAD(&name->queue);
+	hash_add(r->entries_hash, &name->hentry, hash);
+	memcpy(name->name, name_str, namelen + 1);
+
+	return name;
+}
+
+static void kdbus_name_entry_free(struct kdbus_name_entry *name)
+{
+	if (!name)
+		return;
+
+	WARN_ON(kdbus_name_entry_is_used(name));
+	hash_del(&name->hentry);
+	kfree(name);
+}
+
+static struct kdbus_name_entry *
+kdbus_name_entry_find(struct kdbus_name_registry *r, u32 hash,
+		      const char *name_str)
+{
+	struct kdbus_name_entry *name;
+
+	lockdep_assert_held(&r->rwlock);
+
+	hash_for_each_possible(r->entries_hash, name, hentry, hash)
+		if (!strcmp(name->name, name_str))
+			return name;
+
+	return NULL;
+}
+
+/**
+ * kdbus_name_registry_new() - create a new name registry
+ *
+ * Return: a new kdbus_name_registry on success, ERR_PTR on failure.
+ */
+struct kdbus_name_registry *kdbus_name_registry_new(void)
+{
+	struct kdbus_name_registry *r;
+
+	r = kmalloc(sizeof(*r), GFP_KERNEL);
+	if (!r)
+		return ERR_PTR(-ENOMEM);
+
+	hash_init(r->entries_hash);
+	init_rwsem(&r->rwlock);
+	r->name_seq_last = 0;
+
+	return r;
+}
+
+/**
+ * kdbus_name_registry_free() - free name registry
+ * @r:		name registry to free, or NULL
+ *
+ * Free a name registry and cleanup all internal objects. This is a no-op if
+ * you pass NULL as registry.
+ */
+void kdbus_name_registry_free(struct kdbus_name_registry *r)
+{
+	if (!r)
+		return;
+
+	WARN_ON(!hash_empty(r->entries_hash));
+	kfree(r);
+}
+
+/**
+ * kdbus_name_lookup_unlocked() - lookup name in registry
+ * @reg:		name registry
+ * @name:		name to lookup
+ *
+ * This looks up @name in the given name-registry and returns the
+ * kdbus_name_entry object. The caller must hold the registry-lock and must not
+ * access the returned object after releasing the lock.
+ *
+ * Return: Pointer to name-entry, or NULL if not found.
+ */
+struct kdbus_name_entry *
+kdbus_name_lookup_unlocked(struct kdbus_name_registry *reg, const char *name)
+{
+	return kdbus_name_entry_find(reg, kdbus_strhash(name), name);
+}
+
+static int kdbus_name_become_activator(struct kdbus_name_owner *owner,
+				       u64 *return_flags)
+{
+	if (kdbus_name_owner_is_used(owner))
+		return -EALREADY;
+	if (owner->name->activator)
+		return -EEXIST;
+
+	owner->name->activator = owner;
+	owner->flags |= KDBUS_NAME_ACTIVATOR;
+
+	if (kdbus_name_entry_first(owner->name)) {
+		owner->flags |= KDBUS_NAME_IN_QUEUE;
+	} else {
+		owner->flags |= KDBUS_NAME_PRIMARY;
+		kdbus_notify_name_change(owner->conn->ep->bus,
+					 KDBUS_ITEM_NAME_ADD,
+					 0, owner->conn->id,
+					 0, owner->flags,
+					 owner->name->name);
+	}
+
+	if (return_flags)
+		*return_flags = owner->flags | KDBUS_NAME_ACQUIRED;
+
+	return 0;
+}
+
+static int kdbus_name_update(struct kdbus_name_owner *owner, u64 flags,
+			     u64 *return_flags)
+{
+	struct kdbus_name_owner *primary, *activator;
+	struct kdbus_name_entry *name;
+	struct kdbus_bus *bus;
+	u64 nflags = 0;
+	int ret = 0;
+
+	name = owner->name;
+	bus = owner->conn->ep->bus;
+	primary = kdbus_name_entry_first(name);
+	activator = name->activator;
+
+	/* cannot be activator and acquire a name */
+	if (owner == activator)
+		return -EUCLEAN;
+
+	/* update saved flags */
+	owner->flags = flags & KDBUS_NAME_SAVED_MASK;
+
+	if (!primary) {
+		/*
+		 * No primary owner (but maybe an activator). Take over the
+		 * name.
+		 */
+
+		list_add(&owner->name_entry, &name->queue);
+		owner->flags |= KDBUS_NAME_PRIMARY;
+		nflags |= KDBUS_NAME_ACQUIRED;
+
+		/* move messages to new owner on activation */
+		if (activator) {
+			kdbus_conn_move_messages(owner->conn, activator->conn,
+						 name->name_id);
+			kdbus_notify_name_change(bus, KDBUS_ITEM_NAME_CHANGE,
+					activator->conn->id, owner->conn->id,
+					activator->flags, owner->flags,
+					name->name);
+			activator->flags &= ~KDBUS_NAME_PRIMARY;
+			activator->flags |= KDBUS_NAME_IN_QUEUE;
+		} else {
+			kdbus_notify_name_change(bus, KDBUS_ITEM_NAME_ADD,
+						 0, owner->conn->id,
+						 0, owner->flags,
+						 name->name);
+		}
+
+	} else if (owner == primary) {
+		/*
+		 * Already the primary owner of the name, flags were already
+		 * updated. Nothing to do.
+		 */
+
+		owner->flags |= KDBUS_NAME_PRIMARY;
+
+	} else if ((primary->flags & KDBUS_NAME_ALLOW_REPLACEMENT) &&
+		   (flags & KDBUS_NAME_REPLACE_EXISTING)) {
+		/*
+		 * We're not the primary owner but can replace it. Move us
+		 * ahead of the primary owner and acquire the name (possibly
+		 * skipping queued owners ahead of us).
+		 */
+
+		list_del_init(&owner->name_entry);
+		list_add(&owner->name_entry, &name->queue);
+		owner->flags |= KDBUS_NAME_PRIMARY;
+		nflags |= KDBUS_NAME_ACQUIRED;
+
+		kdbus_notify_name_change(bus, KDBUS_ITEM_NAME_CHANGE,
+					 primary->conn->id, owner->conn->id,
+					 primary->flags, owner->flags,
+					 name->name);
+
+		/* requeue old primary, or drop if queueing not wanted */
+		if (primary->flags & KDBUS_NAME_QUEUE) {
+			primary->flags &= ~KDBUS_NAME_PRIMARY;
+			primary->flags |= KDBUS_NAME_IN_QUEUE;
+		} else {
+			list_del_init(&primary->name_entry);
+			kdbus_name_owner_free(primary);
+		}
+
+	} else if (flags & KDBUS_NAME_QUEUE) {
+		/*
+		 * Name is already occupied and we cannot take it over, but
+		 * queuing is allowed. Put us silently on the queue, if not
+		 * already there.
+		 */
+
+		owner->flags |= KDBUS_NAME_IN_QUEUE;
+		if (!kdbus_name_owner_is_used(owner)) {
+			list_add_tail(&owner->name_entry, &name->queue);
+			nflags |= KDBUS_NAME_ACQUIRED;
+		}
+	} else if (kdbus_name_owner_is_used(owner)) {
+		/*
+		 * Already queued on name, but re-queueing was not requested.
+		 * Make sure to unlink it from the name, the caller is
+		 * responsible for releasing it.
+		 */
+
+		list_del_init(&owner->name_entry);
+	} else {
+		/*
+		 * Name is already claimed and queueing is not requested.
+		 * Return error to the caller.
+		 */
+
+		ret = -EEXIST;
+	}
+
+	if (return_flags)
+		*return_flags = owner->flags | nflags;
+
+	return ret;
+}
+
+int kdbus_name_acquire(struct kdbus_name_registry *reg,
+		       struct kdbus_conn *conn, const char *name_str,
+		       u64 flags, u64 *return_flags)
+{
+	struct kdbus_name_entry *name = NULL;
+	struct kdbus_name_owner *owner = NULL;
+	u32 hash;
+	int ret;
+
+	kdbus_conn_assert_active(conn);
+
+	down_write(&reg->rwlock);
+
+	/*
+	 * Verify the connection has access to the name. Do this before testing
+	 * for double-acquisitions and other errors to make sure we do not leak
+	 * information about this name through possible custom endpoints.
+	 */
+	if (!kdbus_conn_policy_own_name(conn, current_cred(), name_str)) {
+		ret = -EPERM;
+		goto exit;
+	}
+
+	/*
+	 * Lookup the name entry. If it already exists, search for an owner
+	 * entry as we might already own that name. If either does not exist,
+	 * we will allocate a fresh one.
+	 */
+	hash = kdbus_strhash(name_str);
+	name = kdbus_name_entry_find(reg, hash, name_str);
+	if (name) {
+		owner = kdbus_name_owner_find(name, conn);
+	} else {
+		name = kdbus_name_entry_new(reg, hash, name_str);
+		if (IS_ERR(name)) {
+			ret = PTR_ERR(name);
+			name = NULL;
+			goto exit;
+		}
+	}
+
+	/* create name owner object if not already queued */
+	if (!owner) {
+		owner = kdbus_name_owner_new(conn, name, flags);
+		if (IS_ERR(owner)) {
+			ret = PTR_ERR(owner);
+			owner = NULL;
+			goto exit;
+		}
+	}
+
+	if (flags & KDBUS_NAME_ACTIVATOR)
+		ret = kdbus_name_become_activator(owner, return_flags);
+	else
+		ret = kdbus_name_update(owner, flags, return_flags);
+	if (ret < 0)
+		goto exit;
+
+exit:
+	if (owner && !kdbus_name_owner_is_used(owner))
+		kdbus_name_owner_free(owner);
+	if (name && !kdbus_name_entry_is_used(name))
+		kdbus_name_entry_free(name);
+	up_write(&reg->rwlock);
+	kdbus_notify_flush(conn->ep->bus);
+	return ret;
+}
+
+static void kdbus_name_release_unlocked(struct kdbus_name_owner *owner)
+{
+	struct kdbus_name_owner *primary, *next;
+	struct kdbus_name_entry *name;
+
+	name = owner->name;
+	primary = kdbus_name_entry_first(name);
+
+	list_del_init(&owner->name_entry);
+	if (owner == name->activator)
+		name->activator = NULL;
+
+	if (!primary || owner == primary) {
+		next = kdbus_name_entry_first(name);
+		if (!next)
+			next = name->activator;
+
+		if (next) {
+			/* hand to next in queue */
+			next->flags &= ~KDBUS_NAME_IN_QUEUE;
+			next->flags |= KDBUS_NAME_PRIMARY;
+			if (next == name->activator)
+				kdbus_conn_move_messages(next->conn,
+							 owner->conn,
+							 name->name_id);
+
+			kdbus_notify_name_change(owner->conn->ep->bus,
+					KDBUS_ITEM_NAME_CHANGE,
+					owner->conn->id, next->conn->id,
+					owner->flags, next->flags,
+					name->name);
+		} else {
+			kdbus_notify_name_change(owner->conn->ep->bus,
+						 KDBUS_ITEM_NAME_REMOVE,
+						 owner->conn->id, 0,
+						 owner->flags, 0,
+						 name->name);
+		}
+	}
+
+	kdbus_name_owner_free(owner);
+	if (!kdbus_name_entry_is_used(name))
+		kdbus_name_entry_free(name);
+}
+
+static int kdbus_name_release(struct kdbus_name_registry *reg,
+			      struct kdbus_conn *conn,
+			      const char *name_str)
+{
+	struct kdbus_name_owner *owner;
+	struct kdbus_name_entry *name;
+	int ret = 0;
+
+	down_write(&reg->rwlock);
+	name = kdbus_name_entry_find(reg, kdbus_strhash(name_str), name_str);
+	if (name) {
+		owner = kdbus_name_owner_find(name, conn);
+		if (owner)
+			kdbus_name_release_unlocked(owner);
+		else
+			ret = -EADDRINUSE;
+	} else {
+		ret = -ESRCH;
+	}
+	up_write(&reg->rwlock);
+
+	kdbus_notify_flush(conn->ep->bus);
+	return ret;
+}
+
+/**
+ * kdbus_name_release_all() - remove all name entries of a given connection
+ * @reg:		name registry
+ * @conn:		connection
+ */
+void kdbus_name_release_all(struct kdbus_name_registry *reg,
+			    struct kdbus_conn *conn)
+{
+	struct kdbus_name_owner *owner;
+
+	down_write(&reg->rwlock);
+
+	while ((owner = list_first_entry_or_null(&conn->names_list,
+						 struct kdbus_name_owner,
+						 conn_entry)))
+		kdbus_name_release_unlocked(owner);
+
+	up_write(&reg->rwlock);
+
+	kdbus_notify_flush(conn->ep->bus);
+}
+
+/**
+ * kdbus_name_is_valid() - check if a name is valid
+ * @p:			The name to check
+ * @allow_wildcard:	Whether or not to allow a wildcard name
+ *
+ * A name is valid if all of the following criterias are met:
+ *
+ *  - The name has two or more elements separated by a period ('.') character.
+ *  - All elements must contain at least one character.
+ *  - Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_-"
+ *    and must not begin with a digit.
+ *  - The name must not exceed KDBUS_NAME_MAX_LEN.
+ *  - If @allow_wildcard is true, the name may end on '.*'
+ */
+bool kdbus_name_is_valid(const char *p, bool allow_wildcard)
+{
+	bool dot, found_dot = false;
+	const char *q;
+
+	for (dot = true, q = p; *q; q++) {
+		if (*q == '.') {
+			if (dot)
+				return false;
+
+			found_dot = true;
+			dot = true;
+		} else {
+			bool good;
+
+			good = isalpha(*q) || (!dot && isdigit(*q)) ||
+				*q == '_' || *q == '-' ||
+				(allow_wildcard && dot &&
+					*q == '*' && *(q + 1) == '\0');
+
+			if (!good)
+				return false;
+
+			dot = false;
+		}
+	}
+
+	if (q - p > KDBUS_NAME_MAX_LEN)
+		return false;
+
+	if (dot)
+		return false;
+
+	if (!found_dot)
+		return false;
+
+	return true;
+}
+
+/**
+ * kdbus_cmd_name_acquire() - handle KDBUS_CMD_NAME_ACQUIRE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
+{
+	const char *item_name;
+	struct kdbus_cmd *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_NAME, .mandatory = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_NAME_REPLACE_EXISTING |
+				 KDBUS_NAME_ALLOW_REPLACEMENT |
+				 KDBUS_NAME_QUEUE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	item_name = argv[1].item->str;
+	if (!kdbus_name_is_valid(item_name, false)) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = kdbus_name_acquire(conn->ep->bus->name_registry, conn, item_name,
+				 cmd->flags, &cmd->return_flags);
+
+exit:
+	return kdbus_args_clear(&args, ret);
+}
+
+/**
+ * kdbus_cmd_name_release() - handle KDBUS_CMD_NAME_RELEASE
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_cmd *cmd;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+		{ .type = KDBUS_ITEM_NAME, .mandatory = true },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	if (!kdbus_conn_is_ordinary(conn))
+		return -EOPNOTSUPP;
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	ret = kdbus_name_release(conn->ep->bus->name_registry, conn,
+				 argv[1].item->str);
+	return kdbus_args_clear(&args, ret);
+}
+
+static int kdbus_list_write(struct kdbus_conn *conn,
+			    struct kdbus_conn *c,
+			    struct kdbus_pool_slice *slice,
+			    size_t *pos,
+			    struct kdbus_name_owner *o,
+			    bool write)
+{
+	struct kvec kvec[4];
+	size_t cnt = 0;
+	int ret;
+
+	/* info header */
+	struct kdbus_info info = {
+		.size = 0,
+		.id = c->id,
+		.flags = c->flags,
+	};
+
+	/* fake the header of a kdbus_name item */
+	struct {
+		u64 size;
+		u64 type;
+		u64 flags;
+	} h = {};
+
+	if (o && !kdbus_conn_policy_see_name_unlocked(conn, current_cred(),
+						      o->name->name))
+		return 0;
+
+	kdbus_kvec_set(&kvec[cnt++], &info, sizeof(info), &info.size);
+
+	/* append name */
+	if (o) {
+		size_t slen = strlen(o->name->name) + 1;
+
+		h.size = offsetof(struct kdbus_item, name.name) + slen;
+		h.type = KDBUS_ITEM_OWNED_NAME;
+		h.flags = o->flags;
+
+		kdbus_kvec_set(&kvec[cnt++], &h, sizeof(h), &info.size);
+		kdbus_kvec_set(&kvec[cnt++], o->name->name, slen, &info.size);
+		cnt += !!kdbus_kvec_pad(&kvec[cnt], &info.size);
+	}
+
+	if (write) {
+		ret = kdbus_pool_slice_copy_kvec(slice, *pos, kvec,
+						 cnt, info.size);
+		if (ret < 0)
+			return ret;
+	}
+
+	*pos += info.size;
+	return 0;
+}
+
+static int kdbus_list_all(struct kdbus_conn *conn, u64 flags,
+			  struct kdbus_pool_slice *slice,
+			  size_t *pos, bool write)
+{
+	struct kdbus_conn *c;
+	size_t p = *pos;
+	int ret, i;
+
+	hash_for_each(conn->ep->bus->conn_hash, i, c, hentry) {
+		bool added = false;
+
+		/* skip monitors */
+		if (kdbus_conn_is_monitor(c))
+			continue;
+
+		/* all names the connection owns */
+		if (flags & (KDBUS_LIST_NAMES |
+			     KDBUS_LIST_ACTIVATORS |
+			     KDBUS_LIST_QUEUED)) {
+			struct kdbus_name_owner *o;
+
+			list_for_each_entry(o, &c->names_list, conn_entry) {
+				if (o->flags & KDBUS_NAME_ACTIVATOR) {
+					if (!(flags & KDBUS_LIST_ACTIVATORS))
+						continue;
+
+					ret = kdbus_list_write(conn, c, slice,
+							       &p, o, write);
+					if (ret < 0) {
+						mutex_unlock(&c->lock);
+						return ret;
+					}
+
+					added = true;
+				} else if (o->flags & KDBUS_NAME_IN_QUEUE) {
+					if (!(flags & KDBUS_LIST_QUEUED))
+						continue;
+
+					ret = kdbus_list_write(conn, c, slice,
+							       &p, o, write);
+					if (ret < 0) {
+						mutex_unlock(&c->lock);
+						return ret;
+					}
+
+					added = true;
+				} else if (flags & KDBUS_LIST_NAMES) {
+					ret = kdbus_list_write(conn, c, slice,
+							       &p, o, write);
+					if (ret < 0) {
+						mutex_unlock(&c->lock);
+						return ret;
+					}
+
+					added = true;
+				}
+			}
+		}
+
+		/* nothing added so far, just add the unique ID */
+		if (!added && (flags & KDBUS_LIST_UNIQUE)) {
+			ret = kdbus_list_write(conn, c, slice, &p, NULL, write);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	*pos = p;
+	return 0;
+}
+
+/**
+ * kdbus_cmd_list() - handle KDBUS_CMD_LIST
+ * @conn:		connection to operate on
+ * @argp:		command payload
+ *
+ * Return: >=0 on success, negative error code on failure.
+ */
+int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp)
+{
+	struct kdbus_name_registry *reg = conn->ep->bus->name_registry;
+	struct kdbus_pool_slice *slice = NULL;
+	struct kdbus_cmd_list *cmd;
+	size_t pos, size;
+	int ret;
+
+	struct kdbus_arg argv[] = {
+		{ .type = KDBUS_ITEM_NEGOTIATE },
+	};
+	struct kdbus_args args = {
+		.allowed_flags = KDBUS_FLAG_NEGOTIATE |
+				 KDBUS_LIST_UNIQUE |
+				 KDBUS_LIST_NAMES |
+				 KDBUS_LIST_ACTIVATORS |
+				 KDBUS_LIST_QUEUED,
+		.argv = argv,
+		.argc = ARRAY_SIZE(argv),
+	};
+
+	ret = kdbus_args_parse(&args, argp, &cmd);
+	if (ret != 0)
+		return ret;
+
+	/* lock order: domain -> bus -> ep -> names -> conn */
+	down_read(&reg->rwlock);
+	down_read(&conn->ep->bus->conn_rwlock);
+	down_read(&conn->ep->policy_db.entries_rwlock);
+
+	/* size of records */
+	size = 0;
+	ret = kdbus_list_all(conn, cmd->flags, NULL, &size, false);
+	if (ret < 0)
+		goto exit_unlock;
+
+	if (size == 0) {
+		kdbus_pool_publish_empty(conn->pool, &cmd->offset,
+					 &cmd->list_size);
+	} else {
+		slice = kdbus_pool_slice_alloc(conn->pool, size, false);
+		if (IS_ERR(slice)) {
+			ret = PTR_ERR(slice);
+			slice = NULL;
+			goto exit_unlock;
+		}
+
+		/* copy the records */
+		pos = 0;
+		ret = kdbus_list_all(conn, cmd->flags, slice, &pos, true);
+		if (ret < 0)
+			goto exit_unlock;
+
+		WARN_ON(pos != size);
+		kdbus_pool_slice_publish(slice, &cmd->offset, &cmd->list_size);
+	}
+
+	if (kdbus_member_set_user(&cmd->offset, argp, typeof(*cmd), offset) ||
+	    kdbus_member_set_user(&cmd->list_size, argp,
+				  typeof(*cmd), list_size))
+		ret = -EFAULT;
+
+exit_unlock:
+	up_read(&conn->ep->policy_db.entries_rwlock);
+	up_read(&conn->ep->bus->conn_rwlock);
+	up_read(&reg->rwlock);
+	kdbus_pool_slice_release(slice);
+	return kdbus_args_clear(&args, ret);
+}
diff --git a/ipc/kdbus/names.h b/ipc/kdbus/names.h
new file mode 100644
index 000000000000..edac59ddd8ee
--- /dev/null
+++ b/ipc/kdbus/names.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_NAMES_H
+#define __KDBUS_NAMES_H
+
+#include <linux/hashtable.h>
+#include <linux/rwsem.h>
+
+struct kdbus_name_entry;
+struct kdbus_name_owner;
+struct kdbus_name_registry;
+
+/**
+ * struct kdbus_name_registry - names registered for a bus
+ * @entries_hash:	Map of entries
+ * @lock:		Registry data lock
+ * @name_seq_last:	Last used sequence number to assign to a name entry
+ */
+struct kdbus_name_registry {
+	DECLARE_HASHTABLE(entries_hash, 8);
+	struct rw_semaphore rwlock;
+	u64 name_seq_last;
+};
+
+/**
+ * struct kdbus_name_entry - well-know name entry
+ * @name_id:		sequence number of name entry to be able to uniquely
+ *			identify a name over its registration lifetime
+ * @activator:		activator of this name, or NULL
+ * @queue:		list of queued owners
+ * @hentry:		entry in registry map
+ * @name:		well-known name
+ */
+struct kdbus_name_entry {
+	u64 name_id;
+	struct kdbus_name_owner *activator;
+	struct list_head queue;
+	struct hlist_node hentry;
+	char name[];
+};
+
+/**
+ * struct kdbus_name_owner - owner of a well-known name
+ * @flags:		KDBUS_NAME_* flags of this owner
+ * @conn:		connection owning the name
+ * @name:		name that is owned
+ * @conn_entry:		link into @conn
+ * @name_entry:		link into @name
+ */
+struct kdbus_name_owner {
+	u64 flags;
+	struct kdbus_conn *conn;
+	struct kdbus_name_entry *name;
+	struct list_head conn_entry;
+	struct list_head name_entry;
+};
+
+bool kdbus_name_is_valid(const char *p, bool allow_wildcard);
+
+struct kdbus_name_registry *kdbus_name_registry_new(void);
+void kdbus_name_registry_free(struct kdbus_name_registry *reg);
+
+struct kdbus_name_entry *
+kdbus_name_lookup_unlocked(struct kdbus_name_registry *reg, const char *name);
+
+int kdbus_name_acquire(struct kdbus_name_registry *reg,
+		       struct kdbus_conn *conn, const char *name,
+		       u64 flags, u64 *return_flags);
+void kdbus_name_release_all(struct kdbus_name_registry *reg,
+			    struct kdbus_conn *conn);
+
+int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp);
+int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp);
+
+/**
+ * kdbus_name_get_owner() - get current owner of a name
+ * @name:	name to get current owner of
+ *
+ * This returns a pointer to the current owner of a name (or its activator if
+ * there is no owner). The caller must make sure @name is valid and does not
+ * vanish.
+ *
+ * Return: Pointer to current owner or NULL if there is none.
+ */
+static inline struct kdbus_name_owner *
+kdbus_name_get_owner(struct kdbus_name_entry *name)
+{
+	return list_first_entry_or_null(&name->queue, struct kdbus_name_owner,
+					name_entry) ? : name->activator;
+}
+
+#endif
diff --git a/ipc/kdbus/node.c b/ipc/kdbus/node.c
new file mode 100644
index 000000000000..89f58bc85433
--- /dev/null
+++ b/ipc/kdbus/node.c
@@ -0,0 +1,897 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/atomic.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/kdev_t.h>
+#include <linux/rbtree.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+
+#include "bus.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "fs.h"
+#include "handle.h"
+#include "node.h"
+#include "util.h"
+
+/**
+ * DOC: kdbus nodes
+ *
+ * Nodes unify lifetime management across exposed kdbus objects and provide a
+ * hierarchy. Each kdbus object, that might be exposed to user-space, has a
+ * kdbus_node object embedded and is linked into the hierarchy. Each node can
+ * have any number (0-n) of child nodes linked. Each child retains a reference
+ * to its parent node. For root-nodes, the parent is NULL.
+ *
+ * Each node object goes through a bunch of states during it's lifetime:
+ *     * NEW
+ *       * LINKED    (can be skipped by NEW->FREED transition)
+ *         * ACTIVE  (can be skipped by LINKED->INACTIVE transition)
+ *       * INACTIVE
+ *       * DRAINED
+ *     * FREED
+ *
+ * Each node is allocated by the caller and initialized via kdbus_node_init().
+ * This never fails and sets the object into state NEW. From now on, ref-counts
+ * on the node manage its lifetime. During init, the ref-count is set to 1. Once
+ * it drops to 0, the node goes to state FREED and the node->free_cb() callback
+ * is called to deallocate any memory.
+ *
+ * After initializing a node, you usually link it into the hierarchy. You need
+ * to provide a parent node and a name. The node will be linked as child to the
+ * parent and a globally unique ID is assigned to the child. The name of the
+ * child must be unique for all children of this parent. Otherwise, linking the
+ * child will fail with -EEXIST.
+ * Note that the child is not marked active, yet. Admittedly, it prevents any
+ * other node from being linked with the same name (thus, it reserves that
+ * name), but any child-lookup (via name or unique ID) will never return this
+ * child unless it has been marked active.
+ *
+ * Once successfully linked, you can use kdbus_node_activate() to activate a
+ * child. This will mark the child active. This state can be skipped by directly
+ * deactivating the child via kdbus_node_deactivate() (see below).
+ * By activating a child, you enable any lookups on this child to succeed from
+ * now on. Furthermore, any code that got its hands on a reference to the node,
+ * can from now on "acquire" the node.
+ *
+ *     Active References (or: 'acquiring' and 'releasing' a node)
+ *     Additionally to normal object references, nodes support something we call
+ *     "active references". An active reference can be acquired via
+ *     kdbus_node_acquire() and released via kdbus_node_release(). A caller
+ *     _must_ own a normal object reference whenever calling those functions.
+ *     Unlike object references, acquiring an active reference can fail (by
+ *     returning 'false' from kdbus_node_acquire()). An active reference can
+ *     only be acquired if the node is marked active. If it is not marked
+ *     active, yet, or if it was already deactivated, no more active references
+ *     can be acquired, ever!
+ *     Active references are used to track tasks working on a node. Whenever a
+ *     task enters kernel-space to perform an action on a node, it acquires an
+ *     active reference, performs the action and releases the reference again.
+ *     While holding an active reference, the node is guaranteed to stay active.
+ *     If the node is deactivated in parallel, the node is marked as
+ *     deactivated, then we wait for all active references to be dropped, before
+ *     we finally proceed with any cleanups. That is, if you hold an active
+ *     reference to a node, any resources that are bound to the "active" state
+ *     are guaranteed to stay accessible until you release your reference.
+ *
+ *     Active-references are very similar to rw-locks, where acquiring a node is
+ *     equal to try-read-lock and releasing to read-unlock. Deactivating a node
+ *     means write-lock and never releasing it again.
+ *     Unlike rw-locks, the 'active reference' concept is more versatile and
+ *     avoids unusual rw-lock usage (never releasing a write-lock..).
+ *
+ *     It is safe to acquire multiple active-references recursively. But you
+ *     need to check the return value of kdbus_node_acquire() on _each_ call. It
+ *     may stop granting references at _any_ time.
+ *
+ *     You're free to perform any operations you want while holding an active
+ *     reference, except sleeping for an indefinite period. Sleeping for a fixed
+ *     amount of time is fine, but you usually should not wait on wait-queues
+ *     without a timeout.
+ *     For example, if you wait for I/O to happen, you should gather all data
+ *     and schedule the I/O operation, then release your active reference and
+ *     wait for it to complete. Then try to acquire a new reference. If it
+ *     fails, perform any cleanup (the node is now dead). Otherwise, you can
+ *     finish your operation.
+ *
+ * All nodes can be deactivated via kdbus_node_deactivate() at any time. You can
+ * call this multiple times, even in parallel or on nodes that were never
+ * linked, and it will just work. The only restriction is, you must not hold an
+ * active reference when calling kdbus_node_deactivate().
+ * By deactivating a node, it is immediately marked inactive. Then, we wait for
+ * all active references to be released (called 'draining' the node). This
+ * shouldn't take very long as we don't perform long-lasting operations while
+ * holding an active reference. Note that once the node is marked inactive, no
+ * new active references can be acquired.
+ * Once all active references are dropped, the node is considered 'drained'. Now
+ * kdbus_node_deactivate() is called on each child of the node before we
+ * continue deactivating our node. That is, once all children are entirely
+ * deactivated, we call ->release_cb() of our node. ->release_cb() can release
+ * any resources on that node which are bound to the "active" state of a node.
+ * When done, we unlink the node from its parent rb-tree, mark it as
+ * 'released' and return.
+ * If kdbus_node_deactivate() is called multiple times (even in parallel), all
+ * but one caller will just wait until the node is fully deactivated. That is,
+ * one random caller of kdbus_node_deactivate() is selected to call
+ * ->release_cb() and cleanup the node. Only once all this is done, all other
+ * callers will return from kdbus_node_deactivate(). That is, it doesn't matter
+ * whether you're the selected caller or not, it will only return after
+ * everything is fully done.
+ *
+ * When a node is activated, we acquire a normal object reference to the node.
+ * This reference is dropped after deactivation is fully done (and only iff the
+ * node really was activated). This allows callers to link+activate a child node
+ * and then drop all refs. The node will be deactivated together with the
+ * parent, and then be freed when this reference is dropped.
+ *
+ * Currently, nodes provide a bunch of resources that external code can use
+ * directly. This includes:
+ *
+ *     * node->waitq: Each node has its own wait-queue that is used to manage
+ *                    the 'active' state. When a node is deactivated, we wait on
+ *                    this queue until all active refs are dropped. Analogously,
+ *                    when you release an active reference on a deactivated
+ *                    node, and the active ref-count drops to 0, we wake up a
+ *                    single thread on this queue. Furthermore, once the
+ *                    ->release_cb() callback finished, we wake up all waiters.
+ *                    The node-owner is free to re-use this wait-queue for other
+ *                    purposes. As node-management uses this queue only during
+ *                    deactivation, it is usually totally fine to re-use the
+ *                    queue for other, preferably low-overhead, use-cases.
+ *
+ *     * node->type: This field defines the type of the owner of this node. It
+ *                   must be set during node initialization and must remain
+ *                   constant. The node management never looks at this value,
+ *                   but external users might use to gain access to the owner
+ *                   object of a node.
+ *                   It is totally up to the owner of the node to define what
+ *                   their type means. Usually it means you can access the
+ *                   parent structure via container_of(), as long as you hold an
+ *                   active reference to the node.
+ *
+ *     * node->free_cb:    callback after all references are dropped
+ *       node->release_cb: callback during node deactivation
+ *                         These fields must be set by the node owner during
+ *                         node initialization. They must remain constant. If
+ *                         NULL, they're skipped.
+ *
+ *     * node->mode: filesystem access modes
+ *       node->uid:  filesystem owner uid
+ *       node->gid:  filesystem owner gid
+ *                   These fields must be set by the node owner during node
+ *                   initialization. They must remain constant and may be
+ *                   accessed by other callers to properly initialize
+ *                   filesystem nodes.
+ *
+ *     * node->id: This is an unsigned 32bit integer allocated by an IDA. It is
+ *                 always kept as small as possible during allocation and is
+ *                 globally unique across all nodes allocated by this module. 0
+ *                 is reserved as "not assigned" and is the default.
+ *                 The ID is assigned during kdbus_node_link() and is kept until
+ *                 the object is freed. Thus, the ID surpasses the active
+ *                 lifetime of a node. As long as you hold an object reference
+ *                 to a node (and the node was linked once), the ID is valid and
+ *                 unique.
+ *
+ *     * node->name: name of this node
+ *       node->hash: 31bit hash-value of @name (range [2..INT_MAX-1])
+ *                   These values follow the same lifetime rules as node->id.
+ *                   They're initialized when the node is linked and then remain
+ *                   constant until the last object reference is dropped.
+ *                   Unlike the id, the name is only unique across all siblings
+ *                   and only until the node is deactivated. Currently, the name
+ *                   is even unique if linked but not activated, yet. This might
+ *                   change in the future, though. Code should not rely on this.
+ *
+ *     * node->lock:     lock to protect node->children, node->rb, node->parent
+ *     * node->parent: Reference to parent node. This is set during LINK time
+ *                     and is dropped during destruction. You must not access
+ *                     it unless you hold an active reference to the node or if
+ *                     you know the node is dead.
+ *     * node->children: rb-tree of all linked children of this node. You must
+ *                       not access this directly, but use one of the iterator
+ *                       or lookup helpers.
+ */
+
+/*
+ * Bias values track states of "active references". They're all negative. If a
+ * node is active, its active-ref-counter is >=0 and tracks all active
+ * references. Once a node is deactivaed, we subtract NODE_BIAS. This means, the
+ * counter is now negative but still counts the active references. Once it drops
+ * to exactly NODE_BIAS, we know all active references were dropped. Exactly one
+ * thread will change it to NODE_RELEASE now, perform cleanup and then put it
+ * into NODE_DRAINED. Once drained, all other threads that tried deactivating
+ * the node will now be woken up (thus, they wait until the node is fully done).
+ * The initial state during node-setup is NODE_NEW. If a node is directly
+ * deactivated without having ever been active, it is put into
+ * NODE_RELEASE_DIRECT instead of NODE_BIAS. This tracks this one-bit state
+ * across node-deactivation. The task putting it into NODE_RELEASE now knows
+ * whether the node was active before or not.
+ *
+ * Some archs implement atomic_sub(v) with atomic_add(-v), so reserve INT_MIN
+ * to avoid overflows if multiplied by -1.
+ */
+#define KDBUS_NODE_BIAS			(INT_MIN + 5)
+#define KDBUS_NODE_RELEASE_DIRECT	(KDBUS_NODE_BIAS - 1)
+#define KDBUS_NODE_RELEASE		(KDBUS_NODE_BIAS - 2)
+#define KDBUS_NODE_DRAINED		(KDBUS_NODE_BIAS - 3)
+#define KDBUS_NODE_NEW			(KDBUS_NODE_BIAS - 4)
+
+/* global unique ID mapping for kdbus nodes */
+DEFINE_IDA(kdbus_node_ida);
+
+/**
+ * kdbus_node_name_hash() - hash a name
+ * @name:	The string to hash
+ *
+ * This computes the hash of @name. It is guaranteed to be in the range
+ * [2..INT_MAX-1]. The values 1, 2 and INT_MAX are unused as they are reserved
+ * for the filesystem code.
+ *
+ * Return: hash value of the passed string
+ */
+static unsigned int kdbus_node_name_hash(const char *name)
+{
+	unsigned int hash;
+
+	/* reserve hash numbers 0, 1 and >=INT_MAX for magic directories */
+	hash = kdbus_strhash(name) & INT_MAX;
+	if (hash < 2)
+		hash += 2;
+	if (hash >= INT_MAX)
+		hash = INT_MAX - 1;
+
+	return hash;
+}
+
+/**
+ * kdbus_node_name_compare() - compare a name with a node's name
+ * @hash:	hash of the string to compare the node with
+ * @name:	name to compare the node with
+ * @node:	node to compare the name with
+ *
+ * Return: 0 if @name and @hash exactly match the information in @node, or
+ * an integer less than or greater than zero if @name is found, respectively,
+ * to be less than or be greater than the string stored in @node.
+ */
+static int kdbus_node_name_compare(unsigned int hash, const char *name,
+				   const struct kdbus_node *node)
+{
+	if (hash != node->hash)
+		return hash - node->hash;
+
+	return strcmp(name, node->name);
+}
+
+/**
+ * kdbus_node_init() - initialize a kdbus_node
+ * @node:	Pointer to the node to initialize
+ * @type:	The type the node will have (KDBUS_NODE_*)
+ *
+ * The caller is responsible of allocating @node and initializating it to zero.
+ * Once this call returns, you must use the node_ref() and node_unref()
+ * functions to manage this node.
+ */
+void kdbus_node_init(struct kdbus_node *node, unsigned int type)
+{
+	atomic_set(&node->refcnt, 1);
+	mutex_init(&node->lock);
+	node->id = 0;
+	node->type = type;
+	RB_CLEAR_NODE(&node->rb);
+	node->children = RB_ROOT;
+	init_waitqueue_head(&node->waitq);
+	atomic_set(&node->active, KDBUS_NODE_NEW);
+}
+
+/**
+ * kdbus_node_link() - link a node into the nodes system
+ * @node:	Pointer to the node to initialize
+ * @parent:	Pointer to a parent node, may be %NULL
+ * @name:	The name of the node (or NULL if root node)
+ *
+ * This links a node into the hierarchy. This must not be called multiple times.
+ * If @parent is NULL, the node becomes a new root node.
+ *
+ * This call will fail if @name is not unique across all its siblings or if no
+ * ID could be allocated. You must not activate a node if linking failed! It is
+ * safe to deactivate it, though.
+ *
+ * Once you linked a node, you must call kdbus_node_deactivate() before you drop
+ * the last reference (even if you never activate the node).
+ *
+ * Return: 0 on success. negative error otherwise.
+ */
+int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
+		    const char *name)
+{
+	int ret;
+
+	if (WARN_ON(node->type != KDBUS_NODE_DOMAIN && !parent))
+		return -EINVAL;
+
+	if (WARN_ON(parent && !name))
+		return -EINVAL;
+
+	if (name) {
+		node->name = kstrdup(name, GFP_KERNEL);
+		if (!node->name)
+			return -ENOMEM;
+
+		node->hash = kdbus_node_name_hash(name);
+	}
+
+	ret = ida_simple_get(&kdbus_node_ida, 1, 0, GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+
+	node->id = ret;
+	ret = 0;
+
+	if (parent) {
+		struct rb_node **n, *prev;
+
+		if (!kdbus_node_acquire(parent))
+			return -ESHUTDOWN;
+
+		mutex_lock(&parent->lock);
+
+		n = &parent->children.rb_node;
+		prev = NULL;
+
+		while (*n) {
+			struct kdbus_node *pos;
+			int result;
+
+			pos = kdbus_node_from_rb(*n);
+			prev = *n;
+			result = kdbus_node_name_compare(node->hash,
+							 node->name,
+							 pos);
+			if (result == 0) {
+				ret = -EEXIST;
+				goto exit_unlock;
+			}
+
+			if (result < 0)
+				n = &pos->rb.rb_left;
+			else
+				n = &pos->rb.rb_right;
+		}
+
+		/* add new node and rebalance the tree */
+		rb_link_node(&node->rb, prev, n);
+		rb_insert_color(&node->rb, &parent->children);
+		node->parent = kdbus_node_ref(parent);
+
+exit_unlock:
+		mutex_unlock(&parent->lock);
+		kdbus_node_release(parent);
+	}
+
+	return ret;
+}
+
+/**
+ * kdbus_node_ref() - Acquire object reference
+ * @node:	node to acquire reference to (or NULL)
+ *
+ * This acquires a new reference to @node. You must already own a reference when
+ * calling this!
+ * If @node is NULL, this is a no-op.
+ *
+ * Return: @node is returned
+ */
+struct kdbus_node *kdbus_node_ref(struct kdbus_node *node)
+{
+	if (node)
+		atomic_inc(&node->refcnt);
+	return node;
+}
+
+/**
+ * kdbus_node_unref() - Drop object reference
+ * @node:	node to drop reference to (or NULL)
+ *
+ * This drops an object reference to @node. You must not access the node if you
+ * no longer own a reference.
+ * If the ref-count drops to 0, the object will be destroyed (->free_cb will be
+ * called).
+ *
+ * If you linked or activated the node, you must deactivate the node before you
+ * drop your last reference! If you didn't link or activate the node, you can
+ * drop any reference you want.
+ *
+ * Note that this calls into ->free_cb() and thus _might_ sleep. The ->free_cb()
+ * callbacks must not acquire any outer locks, though. So you can safely drop
+ * references while holding locks.
+ *
+ * If @node is NULL, this is a no-op.
+ *
+ * Return: This always returns NULL
+ */
+struct kdbus_node *kdbus_node_unref(struct kdbus_node *node)
+{
+	if (node && atomic_dec_and_test(&node->refcnt)) {
+		struct kdbus_node safe = *node;
+
+		WARN_ON(atomic_read(&node->active) != KDBUS_NODE_DRAINED);
+		WARN_ON(!RB_EMPTY_NODE(&node->rb));
+
+		if (node->free_cb)
+			node->free_cb(node);
+		if (safe.id > 0)
+			ida_simple_remove(&kdbus_node_ida, safe.id);
+
+		kfree(safe.name);
+
+		/*
+		 * kdbusfs relies on the parent to be available even after the
+		 * node was deactivated and unlinked. Therefore, we pin it
+		 * until a node is destroyed.
+		 */
+		kdbus_node_unref(safe.parent);
+	}
+
+	return NULL;
+}
+
+/**
+ * kdbus_node_is_active() - test whether a node is active
+ * @node:	node to test
+ *
+ * This checks whether @node is active. That means, @node was linked and
+ * activated by the node owner and hasn't been deactivated, yet. If, and only
+ * if, a node is active, kdbus_node_acquire() will be able to acquire active
+ * references.
+ *
+ * Note that this function does not give any lifetime guarantees. After this
+ * call returns, the node might be deactivated immediately. Normally, what you
+ * want is to acquire a real active reference via kdbus_node_acquire().
+ *
+ * Return: true if @node is active, false otherwise
+ */
+bool kdbus_node_is_active(struct kdbus_node *node)
+{
+	return atomic_read(&node->active) >= 0;
+}
+
+/**
+ * kdbus_node_is_deactivated() - test whether a node was already deactivated
+ * @node:	node to test
+ *
+ * This checks whether kdbus_node_deactivate() was called on @node. Note that
+ * this might be true even if you never deactivated the node directly, but only
+ * one of its ancestors.
+ *
+ * Note that even if this returns 'false', the node might get deactivated
+ * immediately after the call returns.
+ *
+ * Return: true if @node was already deactivated, false if not
+ */
+bool kdbus_node_is_deactivated(struct kdbus_node *node)
+{
+	int v;
+
+	v = atomic_read(&node->active);
+	return v != KDBUS_NODE_NEW && v < 0;
+}
+
+/**
+ * kdbus_node_activate() - activate a node
+ * @node:	node to activate
+ *
+ * This marks @node as active if, and only if, the node wasn't activated nor
+ * deactivated, yet, and the parent is still active. Any but the first call to
+ * kdbus_node_activate() is a no-op.
+ * If you called kdbus_node_deactivate() before, then even the first call to
+ * kdbus_node_activate() will be a no-op.
+ *
+ * This call doesn't give any lifetime guarantees. The node might get
+ * deactivated immediately after this call returns. Or the parent might already
+ * be deactivated, which will make this call a no-op.
+ *
+ * If this call successfully activated a node, it will take an object reference
+ * to it. This reference is dropped after the node is deactivated. Therefore,
+ * the object owner can safely drop their reference to @node iff they know that
+ * its parent node will get deactivated at some point. Once the parent node is
+ * deactivated, it will deactivate all its child and thus drop this reference
+ * again.
+ *
+ * Return: True if this call successfully activated the node, otherwise false.
+ *         Note that this might return false, even if the node is still active
+ *         (eg., if you called this a second time).
+ */
+bool kdbus_node_activate(struct kdbus_node *node)
+{
+	bool res = false;
+
+	mutex_lock(&node->lock);
+	if (atomic_read(&node->active) == KDBUS_NODE_NEW) {
+		atomic_sub(KDBUS_NODE_NEW, &node->active);
+		/* activated nodes have ref +1 */
+		kdbus_node_ref(node);
+		res = true;
+	}
+	mutex_unlock(&node->lock);
+
+	return res;
+}
+
+/**
+ * kdbus_node_deactivate() - deactivate a node
+ * @node:	The node to deactivate.
+ *
+ * This function recursively deactivates this node and all its children. It
+ * returns only once all children and the node itself were recursively disabled
+ * (even if you call this function multiple times in parallel).
+ *
+ * It is safe to call this function on _any_ node that was initialized _any_
+ * number of times.
+ *
+ * This call may sleep, as it waits for all active references to be dropped.
+ */
+void kdbus_node_deactivate(struct kdbus_node *node)
+{
+	struct kdbus_node *pos, *child;
+	struct rb_node *rb;
+	int v_pre, v_post;
+
+	pos = node;
+
+	/*
+	 * To avoid recursion, we perform back-tracking while deactivating
+	 * nodes. For each node we enter, we first mark the active-counter as
+	 * deactivated by adding BIAS. If the node as children, we set the first
+	 * child as current position and start over. If the node has no
+	 * children, we drain the node by waiting for all active refs to be
+	 * dropped and then releasing the node.
+	 *
+	 * After the node is released, we set its parent as current position
+	 * and start over. If the current position was the initial node, we're
+	 * done.
+	 *
+	 * Note that this function can be called in parallel by multiple
+	 * callers. We make sure that each node is only released once, and any
+	 * racing caller will wait until the other thread fully released that
+	 * node.
+	 */
+
+	for (;;) {
+		/*
+		 * Add BIAS to node->active to mark it as inactive. If it was
+		 * never active before, immediately mark it as RELEASE_INACTIVE
+		 * so we remember this state.
+		 * We cannot remember v_pre as we might iterate into the
+		 * children, overwriting v_pre, before we can release our node.
+		 */
+		mutex_lock(&pos->lock);
+		v_pre = atomic_read(&pos->active);
+		if (v_pre >= 0)
+			atomic_add_return(KDBUS_NODE_BIAS, &pos->active);
+		else if (v_pre == KDBUS_NODE_NEW)
+			atomic_set(&pos->active, KDBUS_NODE_RELEASE_DIRECT);
+		mutex_unlock(&pos->lock);
+
+		/* wait until all active references were dropped */
+		wait_event(pos->waitq,
+			   atomic_read(&pos->active) <= KDBUS_NODE_BIAS);
+
+		mutex_lock(&pos->lock);
+		/* recurse into first child if any */
+		rb = rb_first(&pos->children);
+		if (rb) {
+			child = kdbus_node_ref(kdbus_node_from_rb(rb));
+			mutex_unlock(&pos->lock);
+			pos = child;
+			continue;
+		}
+
+		/* mark object as RELEASE */
+		v_post = atomic_read(&pos->active);
+		if (v_post == KDBUS_NODE_BIAS ||
+		    v_post == KDBUS_NODE_RELEASE_DIRECT)
+			atomic_set(&pos->active, KDBUS_NODE_RELEASE);
+		mutex_unlock(&pos->lock);
+
+		/*
+		 * If this is the thread that marked the object as RELEASE, we
+		 * perform the actual release. Otherwise, we wait until the
+		 * release is done and the node is marked as DRAINED.
+		 */
+		if (v_post == KDBUS_NODE_BIAS ||
+		    v_post == KDBUS_NODE_RELEASE_DIRECT) {
+			if (pos->release_cb)
+				pos->release_cb(pos, v_post == KDBUS_NODE_BIAS);
+
+			if (pos->parent) {
+				mutex_lock(&pos->parent->lock);
+				if (!RB_EMPTY_NODE(&pos->rb)) {
+					rb_erase(&pos->rb,
+						 &pos->parent->children);
+					RB_CLEAR_NODE(&pos->rb);
+				}
+				mutex_unlock(&pos->parent->lock);
+			}
+
+			/* mark as DRAINED */
+			atomic_set(&pos->active, KDBUS_NODE_DRAINED);
+			wake_up_all(&pos->waitq);
+
+			/* drop VFS cache */
+			kdbus_fs_flush(pos);
+
+			/*
+			 * If the node was activated and someone subtracted BIAS
+			 * from it to deactivate it, we, and only us, are
+			 * responsible to release the extra ref-count that was
+			 * taken once in kdbus_node_activate().
+			 * If the node was never activated, no-one ever
+			 * subtracted BIAS, but instead skipped that state and
+			 * immediately went to NODE_RELEASE_DIRECT. In that case
+			 * we must not drop the reference.
+			 */
+			if (v_post == KDBUS_NODE_BIAS)
+				kdbus_node_unref(pos);
+		} else {
+			/* wait until object is DRAINED */
+			wait_event(pos->waitq,
+			    atomic_read(&pos->active) == KDBUS_NODE_DRAINED);
+		}
+
+		/*
+		 * We're done with the current node. Continue on its parent
+		 * again, which will try deactivating its next child, or itself
+		 * if no child is left.
+		 * If we've reached our initial node again, we are done and
+		 * can safely return.
+		 */
+		if (pos == node)
+			break;
+
+		child = pos;
+		pos = pos->parent;
+		kdbus_node_unref(child);
+	}
+}
+
+/**
+ * kdbus_node_acquire() - Acquire an active ref on a node
+ * @node:	The node
+ *
+ * This acquires an active-reference to @node. This will only succeed if the
+ * node is active. You must release this active reference via
+ * kdbus_node_release() again.
+ *
+ * See the introduction to "active references" for more details.
+ *
+ * Return: %true if @node was non-NULL and active
+ */
+bool kdbus_node_acquire(struct kdbus_node *node)
+{
+	return node && atomic_inc_unless_negative(&node->active);
+}
+
+/**
+ * kdbus_node_release() - Release an active ref on a node
+ * @node:	The node
+ *
+ * This releases an active reference that was previously acquired via
+ * kdbus_node_acquire(). See kdbus_node_acquire() for details.
+ */
+void kdbus_node_release(struct kdbus_node *node)
+{
+	if (node && atomic_dec_return(&node->active) == KDBUS_NODE_BIAS)
+		wake_up(&node->waitq);
+}
+
+/**
+ * kdbus_node_find_child() - Find child by name
+ * @node:	parent node to search through
+ * @name:	name of child node
+ *
+ * This searches through all children of @node for a child-node with name @name.
+ * If not found, or if the child is deactivated, NULL is returned. Otherwise,
+ * the child is acquired and a new reference is returned.
+ *
+ * If you're done with the child, you need to release it and drop your
+ * reference.
+ *
+ * This function does not acquire the parent node. However, if the parent was
+ * already deactivated, then kdbus_node_deactivate() will, at some point, also
+ * deactivate the child. Therefore, we can rely on the explicit ordering during
+ * deactivation.
+ *
+ * Return: Reference to acquired child node, or NULL if not found / not active.
+ */
+struct kdbus_node *kdbus_node_find_child(struct kdbus_node *node,
+					 const char *name)
+{
+	struct kdbus_node *child;
+	struct rb_node *rb;
+	unsigned int hash;
+	int ret;
+
+	hash = kdbus_node_name_hash(name);
+
+	mutex_lock(&node->lock);
+	rb = node->children.rb_node;
+	while (rb) {
+		child = kdbus_node_from_rb(rb);
+		ret = kdbus_node_name_compare(hash, name, child);
+		if (ret < 0)
+			rb = rb->rb_left;
+		else if (ret > 0)
+			rb = rb->rb_right;
+		else
+			break;
+	}
+	if (rb && kdbus_node_acquire(child))
+		kdbus_node_ref(child);
+	else
+		child = NULL;
+	mutex_unlock(&node->lock);
+
+	return child;
+}
+
+static struct kdbus_node *node_find_closest_unlocked(struct kdbus_node *node,
+						     unsigned int hash,
+						     const char *name)
+{
+	struct kdbus_node *n, *pos = NULL;
+	struct rb_node *rb;
+	int res;
+
+	/*
+	 * Find the closest child with ``node->hash >= hash'', or, if @name is
+	 * valid, ``node->name >= name'' (where '>=' is the lex. order).
+	 */
+
+	rb = node->children.rb_node;
+	while (rb) {
+		n = kdbus_node_from_rb(rb);
+
+		if (name)
+			res = kdbus_node_name_compare(hash, name, n);
+		else
+			res = hash - n->hash;
+
+		if (res <= 0) {
+			rb = rb->rb_left;
+			pos = n;
+		} else { /* ``hash > n->hash'', ``name > n->name'' */
+			rb = rb->rb_right;
+		}
+	}
+
+	return pos;
+}
+
+/**
+ * kdbus_node_find_closest() - Find closest child-match
+ * @node:	parent node to search through
+ * @hash:	hash value to find closest match for
+ *
+ * Find the closest child of @node with a hash greater than or equal to @hash.
+ * The closest match is the left-most child of @node with this property. Which
+ * means, it is the first child with that hash returned by
+ * kdbus_node_next_child(), if you'd iterate the whole parent node.
+ *
+ * Return: Reference to acquired child, or NULL if none found.
+ */
+struct kdbus_node *kdbus_node_find_closest(struct kdbus_node *node,
+					   unsigned int hash)
+{
+	struct kdbus_node *child;
+	struct rb_node *rb;
+
+	mutex_lock(&node->lock);
+
+	child = node_find_closest_unlocked(node, hash, NULL);
+	while (child && !kdbus_node_acquire(child)) {
+		rb = rb_next(&child->rb);
+		if (rb)
+			child = kdbus_node_from_rb(rb);
+		else
+			child = NULL;
+	}
+	kdbus_node_ref(child);
+
+	mutex_unlock(&node->lock);
+
+	return child;
+}
+
+/**
+ * kdbus_node_next_child() - Acquire next child
+ * @node:	parent node
+ * @prev:	previous child-node position or NULL
+ *
+ * This function returns a reference to the next active child of @node, after
+ * the passed position @prev. If @prev is NULL, a reference to the first active
+ * child is returned. If no more active children are found, NULL is returned.
+ *
+ * This function acquires the next child it returns. If you're done with the
+ * returned pointer, you need to release _and_ unref it.
+ *
+ * The passed in pointer @prev is not modified by this function, and it does
+ * *not* have to be active. If @prev was acquired via different means, or if it
+ * was unlinked from its parent before you pass it in, then this iterator will
+ * still return the next active child (it will have to search through the
+ * rb-tree based on the node-name, though).
+ * However, @prev must not be linked to a different parent than @node!
+ *
+ * Return: Reference to next acquired child, or NULL if at the end.
+ */
+struct kdbus_node *kdbus_node_next_child(struct kdbus_node *node,
+					 struct kdbus_node *prev)
+{
+	struct kdbus_node *pos = NULL;
+	struct rb_node *rb;
+
+	mutex_lock(&node->lock);
+
+	if (!prev) {
+		/*
+		 * New iteration; find first node in rb-tree and try to acquire
+		 * it. If we got it, directly return it as first element.
+		 * Otherwise, the loop below will find the next active node.
+		 */
+		rb = rb_first(&node->children);
+		if (!rb)
+			goto exit;
+		pos = kdbus_node_from_rb(rb);
+		if (kdbus_node_acquire(pos))
+			goto exit;
+	} else if (RB_EMPTY_NODE(&prev->rb)) {
+		/*
+		 * The current iterator is no longer linked to the rb-tree. Use
+		 * its hash value and name to find the next _higher_ node and
+		 * acquire it. If we got it, return it as next element.
+		 * Otherwise, the loop below will find the next active node.
+		 */
+		pos = node_find_closest_unlocked(node, prev->hash, prev->name);
+		if (!pos)
+			goto exit;
+		if (kdbus_node_acquire(pos))
+			goto exit;
+	} else {
+		/*
+		 * The current iterator is still linked to the parent. Set it
+		 * as current position and use the loop below to find the next
+		 * active element.
+		 */
+		pos = prev;
+	}
+
+	/* @pos was already returned or is inactive; find next active node */
+	do {
+		rb = rb_next(&pos->rb);
+		if (rb)
+			pos = kdbus_node_from_rb(rb);
+		else
+			pos = NULL;
+	} while (pos && !kdbus_node_acquire(pos));
+
+exit:
+	/* @pos is NULL or acquired. Take ref if non-NULL and return it */
+	kdbus_node_ref(pos);
+	mutex_unlock(&node->lock);
+	return pos;
+}
diff --git a/ipc/kdbus/node.h b/ipc/kdbus/node.h
new file mode 100644
index 000000000000..970e02b08e9f
--- /dev/null
+++ b/ipc/kdbus/node.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_NODE_H
+#define __KDBUS_NODE_H
+
+#include <linux/atomic.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+struct kdbus_node;
+
+enum kdbus_node_type {
+	KDBUS_NODE_DOMAIN,
+	KDBUS_NODE_CONTROL,
+	KDBUS_NODE_BUS,
+	KDBUS_NODE_ENDPOINT,
+};
+
+typedef void (*kdbus_node_free_t) (struct kdbus_node *node);
+typedef void (*kdbus_node_release_t) (struct kdbus_node *node, bool was_active);
+
+struct kdbus_node {
+	atomic_t refcnt;
+	atomic_t active;
+	wait_queue_head_t waitq;
+
+	/* static members */
+	unsigned int type;
+	kdbus_node_free_t free_cb;
+	kdbus_node_release_t release_cb;
+	umode_t mode;
+	kuid_t uid;
+	kgid_t gid;
+
+	/* valid once linked */
+	char *name;
+	unsigned int hash;
+	unsigned int id;
+	struct kdbus_node *parent; /* may be NULL */
+
+	/* valid iff active */
+	struct mutex lock;
+	struct rb_node rb;
+	struct rb_root children;
+};
+
+#define kdbus_node_from_rb(_node) rb_entry((_node), struct kdbus_node, rb)
+
+extern struct ida kdbus_node_ida;
+
+void kdbus_node_init(struct kdbus_node *node, unsigned int type);
+
+int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
+		    const char *name);
+
+struct kdbus_node *kdbus_node_ref(struct kdbus_node *node);
+struct kdbus_node *kdbus_node_unref(struct kdbus_node *node);
+
+bool kdbus_node_is_active(struct kdbus_node *node);
+bool kdbus_node_is_deactivated(struct kdbus_node *node);
+bool kdbus_node_activate(struct kdbus_node *node);
+void kdbus_node_deactivate(struct kdbus_node *node);
+
+bool kdbus_node_acquire(struct kdbus_node *node);
+void kdbus_node_release(struct kdbus_node *node);
+
+struct kdbus_node *kdbus_node_find_child(struct kdbus_node *node,
+					 const char *name);
+struct kdbus_node *kdbus_node_find_closest(struct kdbus_node *node,
+					   unsigned int hash);
+struct kdbus_node *kdbus_node_next_child(struct kdbus_node *node,
+					 struct kdbus_node *prev);
+
+#endif
diff --git a/ipc/kdbus/notify.c b/ipc/kdbus/notify.c
new file mode 100644
index 000000000000..375758c4896a
--- /dev/null
+++ b/ipc/kdbus/notify.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "domain.h"
+#include "endpoint.h"
+#include "item.h"
+#include "message.h"
+#include "notify.h"
+
+static inline void kdbus_notify_add_tail(struct kdbus_staging *staging,
+					 struct kdbus_bus *bus)
+{
+	spin_lock(&bus->notify_lock);
+	list_add_tail(&staging->notify_entry, &bus->notify_list);
+	spin_unlock(&bus->notify_lock);
+}
+
+static int kdbus_notify_reply(struct kdbus_bus *bus, u64 id,
+			      u64 cookie, u64 msg_type)
+{
+	struct kdbus_staging *s;
+
+	s = kdbus_staging_new_kernel(bus, id, cookie, 0, msg_type);
+	if (IS_ERR(s))
+		return PTR_ERR(s);
+
+	kdbus_notify_add_tail(s, bus);
+	return 0;
+}
+
+/**
+ * kdbus_notify_reply_timeout() - queue a timeout reply
+ * @bus:		Bus which queues the messages
+ * @id:			The destination's connection ID
+ * @cookie:		The cookie to set in the reply.
+ *
+ * Queues a message that has a KDBUS_ITEM_REPLY_TIMEOUT item attached.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int kdbus_notify_reply_timeout(struct kdbus_bus *bus, u64 id, u64 cookie)
+{
+	return kdbus_notify_reply(bus, id, cookie, KDBUS_ITEM_REPLY_TIMEOUT);
+}
+
+/**
+ * kdbus_notify_reply_dead() - queue a 'dead' reply
+ * @bus:		Bus which queues the messages
+ * @id:			The destination's connection ID
+ * @cookie:		The cookie to set in the reply.
+ *
+ * Queues a message that has a KDBUS_ITEM_REPLY_DEAD item attached.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int kdbus_notify_reply_dead(struct kdbus_bus *bus, u64 id, u64 cookie)
+{
+	return kdbus_notify_reply(bus, id, cookie, KDBUS_ITEM_REPLY_DEAD);
+}
+
+/**
+ * kdbus_notify_name_change() - queue a notification about a name owner change
+ * @bus:		Bus which queues the messages
+ * @type:		The type if the notification; KDBUS_ITEM_NAME_ADD,
+ *			KDBUS_ITEM_NAME_CHANGE or KDBUS_ITEM_NAME_REMOVE
+ * @old_id:		The id of the connection that used to own the name
+ * @new_id:		The id of the new owner connection
+ * @old_flags:		The flags to pass in the KDBUS_ITEM flags field for
+ *			the old owner
+ * @new_flags:		The flags to pass in the KDBUS_ITEM flags field for
+ *			the new owner
+ * @name:		The name that was removed or assigned to a new owner
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int kdbus_notify_name_change(struct kdbus_bus *bus, u64 type,
+			     u64 old_id, u64 new_id,
+			     u64 old_flags, u64 new_flags,
+			     const char *name)
+{
+	size_t name_len, extra_size;
+	struct kdbus_staging *s;
+
+	name_len = strlen(name) + 1;
+	extra_size = sizeof(struct kdbus_notify_name_change) + name_len;
+
+	s = kdbus_staging_new_kernel(bus, KDBUS_DST_ID_BROADCAST, 0,
+				     extra_size, type);
+	if (IS_ERR(s))
+		return PTR_ERR(s);
+
+	s->notify->name_change.old_id.id = old_id;
+	s->notify->name_change.old_id.flags = old_flags;
+	s->notify->name_change.new_id.id = new_id;
+	s->notify->name_change.new_id.flags = new_flags;
+	memcpy(s->notify->name_change.name, name, name_len);
+
+	kdbus_notify_add_tail(s, bus);
+	return 0;
+}
+
+/**
+ * kdbus_notify_id_change() - queue a notification about a unique ID change
+ * @bus:		Bus which queues the messages
+ * @type:		The type if the notification; KDBUS_ITEM_ID_ADD or
+ *			KDBUS_ITEM_ID_REMOVE
+ * @id:			The id of the connection that was added or removed
+ * @flags:		The flags to pass in the KDBUS_ITEM flags field
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int kdbus_notify_id_change(struct kdbus_bus *bus, u64 type, u64 id, u64 flags)
+{
+	struct kdbus_staging *s;
+	size_t extra_size;
+
+	extra_size = sizeof(struct kdbus_notify_id_change);
+	s = kdbus_staging_new_kernel(bus, KDBUS_DST_ID_BROADCAST, 0,
+				     extra_size, type);
+	if (IS_ERR(s))
+		return PTR_ERR(s);
+
+	s->notify->id_change.id = id;
+	s->notify->id_change.flags = flags;
+
+	kdbus_notify_add_tail(s, bus);
+	return 0;
+}
+
+/**
+ * kdbus_notify_flush() - send a list of collected messages
+ * @bus:		Bus which queues the messages
+ *
+ * The list is empty after sending the messages.
+ */
+void kdbus_notify_flush(struct kdbus_bus *bus)
+{
+	LIST_HEAD(notify_list);
+	struct kdbus_staging *s, *tmp;
+
+	mutex_lock(&bus->notify_flush_lock);
+	down_read(&bus->name_registry->rwlock);
+
+	spin_lock(&bus->notify_lock);
+	list_splice_init(&bus->notify_list, &notify_list);
+	spin_unlock(&bus->notify_lock);
+
+	list_for_each_entry_safe(s, tmp, &notify_list, notify_entry) {
+		if (s->msg->dst_id != KDBUS_DST_ID_BROADCAST) {
+			struct kdbus_conn *conn;
+
+			conn = kdbus_bus_find_conn_by_id(bus, s->msg->dst_id);
+			if (conn) {
+				kdbus_bus_eavesdrop(bus, NULL, s);
+				kdbus_conn_entry_insert(NULL, conn, s, NULL,
+							NULL);
+				kdbus_conn_unref(conn);
+			}
+		} else {
+			kdbus_bus_broadcast(bus, NULL, s);
+		}
+
+		list_del(&s->notify_entry);
+		kdbus_staging_free(s);
+	}
+
+	up_read(&bus->name_registry->rwlock);
+	mutex_unlock(&bus->notify_flush_lock);
+}
+
+/**
+ * kdbus_notify_free() - free a list of collected messages
+ * @bus:		Bus which queues the messages
+ */
+void kdbus_notify_free(struct kdbus_bus *bus)
+{
+	struct kdbus_staging *s, *tmp;
+
+	list_for_each_entry_safe(s, tmp, &bus->notify_list, notify_entry) {
+		list_del(&s->notify_entry);
+		kdbus_staging_free(s);
+	}
+}
diff --git a/ipc/kdbus/notify.h b/ipc/kdbus/notify.h
new file mode 100644
index 000000000000..03df464cb735
--- /dev/null
+++ b/ipc/kdbus/notify.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_NOTIFY_H
+#define __KDBUS_NOTIFY_H
+
+struct kdbus_bus;
+
+int kdbus_notify_id_change(struct kdbus_bus *bus, u64 type, u64 id, u64 flags);
+int kdbus_notify_reply_timeout(struct kdbus_bus *bus, u64 id, u64 cookie);
+int kdbus_notify_reply_dead(struct kdbus_bus *bus, u64 id, u64 cookie);
+int kdbus_notify_name_change(struct kdbus_bus *bus, u64 type,
+			     u64 old_id, u64 new_id,
+			     u64 old_flags, u64 new_flags,
+			     const char *name);
+void kdbus_notify_flush(struct kdbus_bus *bus);
+void kdbus_notify_free(struct kdbus_bus *bus);
+
+#endif
diff --git a/ipc/kdbus/policy.c b/ipc/kdbus/policy.c
new file mode 100644
index 000000000000..f2618e15e78d
--- /dev/null
+++ b/ipc/kdbus/policy.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/dcache.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "domain.h"
+#include "item.h"
+#include "names.h"
+#include "policy.h"
+
+#define KDBUS_POLICY_HASH_SIZE	64
+
+/**
+ * struct kdbus_policy_db_entry_access - a database entry access item
+ * @type:		One of KDBUS_POLICY_ACCESS_* types
+ * @access:		Access to grant. One of KDBUS_POLICY_*
+ * @uid:		For KDBUS_POLICY_ACCESS_USER, the global uid
+ * @gid:		For KDBUS_POLICY_ACCESS_GROUP, the global gid
+ * @list:		List entry item for the entry's list
+ *
+ * This is the internal version of struct kdbus_policy_db_access.
+ */
+struct kdbus_policy_db_entry_access {
+	u8 type;		/* USER, GROUP, WORLD */
+	u8 access;		/* OWN, TALK, SEE */
+	union {
+		kuid_t uid;	/* global uid */
+		kgid_t gid;	/* global gid */
+	};
+	struct list_head list;
+};
+
+/**
+ * struct kdbus_policy_db_entry - a policy database entry
+ * @name:		The name to match the policy entry against
+ * @hentry:		The hash entry for the database's entries_hash
+ * @access_list:	List head for keeping tracks of the entry's
+ *			access items.
+ * @owner:		The owner of this entry. Can be a kdbus_conn or
+ *			a kdbus_ep object.
+ * @wildcard:		The name is a wildcard, such as ending on '.*'
+ */
+struct kdbus_policy_db_entry {
+	char *name;
+	struct hlist_node hentry;
+	struct list_head access_list;
+	const void *owner;
+	bool wildcard:1;
+};
+
+static void kdbus_policy_entry_free(struct kdbus_policy_db_entry *e)
+{
+	struct kdbus_policy_db_entry_access *a, *tmp;
+
+	list_for_each_entry_safe(a, tmp, &e->access_list, list) {
+		list_del(&a->list);
+		kfree(a);
+	}
+
+	kfree(e->name);
+	kfree(e);
+}
+
+static unsigned int kdbus_strnhash(const char *str, size_t len)
+{
+	unsigned long hash = init_name_hash();
+
+	while (len--)
+		hash = partial_name_hash(*str++, hash);
+
+	return end_name_hash(hash);
+}
+
+static const struct kdbus_policy_db_entry *
+kdbus_policy_lookup(struct kdbus_policy_db *db, const char *name, u32 hash)
+{
+	struct kdbus_policy_db_entry *e;
+	const char *dot;
+	size_t len;
+
+	/* find exact match */
+	hash_for_each_possible(db->entries_hash, e, hentry, hash)
+		if (strcmp(e->name, name) == 0 && !e->wildcard)
+			return e;
+
+	/* find wildcard match */
+
+	dot = strrchr(name, '.');
+	if (!dot)
+		return NULL;
+
+	len = dot - name;
+	hash = kdbus_strnhash(name, len);
+
+	hash_for_each_possible(db->entries_hash, e, hentry, hash)
+		if (e->wildcard && !strncmp(e->name, name, len) &&
+		    !e->name[len])
+			return e;
+
+	return NULL;
+}
+
+/**
+ * kdbus_policy_db_clear - release all memory from a policy db
+ * @db:		The policy database
+ */
+void kdbus_policy_db_clear(struct kdbus_policy_db *db)
+{
+	struct kdbus_policy_db_entry *e;
+	struct hlist_node *tmp;
+	unsigned int i;
+
+	/* purge entries */
+	down_write(&db->entries_rwlock);
+	hash_for_each_safe(db->entries_hash, i, tmp, e, hentry) {
+		hash_del(&e->hentry);
+		kdbus_policy_entry_free(e);
+	}
+	up_write(&db->entries_rwlock);
+}
+
+/**
+ * kdbus_policy_db_init() - initialize a new policy database
+ * @db:		The location of the database
+ *
+ * This initializes a new policy-db. The underlying memory must have been
+ * cleared to zero by the caller.
+ */
+void kdbus_policy_db_init(struct kdbus_policy_db *db)
+{
+	hash_init(db->entries_hash);
+	init_rwsem(&db->entries_rwlock);
+}
+
+/**
+ * kdbus_policy_query_unlocked() - Query the policy database
+ * @db:		Policy database
+ * @cred:	Credentials to test against
+ * @name:	Name to query
+ * @hash:	Hash value of @name
+ *
+ * Same as kdbus_policy_query() but requires the caller to lock the policy
+ * database against concurrent writes.
+ *
+ * Return: The highest KDBUS_POLICY_* access type found, or -EPERM if none.
+ */
+int kdbus_policy_query_unlocked(struct kdbus_policy_db *db,
+				const struct cred *cred, const char *name,
+				unsigned int hash)
+{
+	struct kdbus_policy_db_entry_access *a;
+	const struct kdbus_policy_db_entry *e;
+	int i, highest = -EPERM;
+
+	e = kdbus_policy_lookup(db, name, hash);
+	if (!e)
+		return -EPERM;
+
+	list_for_each_entry(a, &e->access_list, list) {
+		if ((int)a->access <= highest)
+			continue;
+
+		switch (a->type) {
+		case KDBUS_POLICY_ACCESS_USER:
+			if (uid_eq(cred->euid, a->uid))
+				highest = a->access;
+			break;
+		case KDBUS_POLICY_ACCESS_GROUP:
+			if (gid_eq(cred->egid, a->gid)) {
+				highest = a->access;
+				break;
+			}
+
+			for (i = 0; i < cred->group_info->ngroups; i++) {
+				kgid_t gid = GROUP_AT(cred->group_info, i);
+
+				if (gid_eq(gid, a->gid)) {
+					highest = a->access;
+					break;
+				}
+			}
+
+			break;
+		case KDBUS_POLICY_ACCESS_WORLD:
+			highest = a->access;
+			break;
+		}
+
+		/* OWN is the highest possible policy */
+		if (highest >= KDBUS_POLICY_OWN)
+			break;
+	}
+
+	return highest;
+}
+
+/**
+ * kdbus_policy_query() - Query the policy database
+ * @db:		Policy database
+ * @cred:	Credentials to test against
+ * @name:	Name to query
+ * @hash:	Hash value of @name
+ *
+ * Query the policy database @db for the access rights of @cred to the name
+ * @name. The access rights of @cred are returned, or -EPERM if no access is
+ * granted.
+ *
+ * This call effectively searches for the highest access-right granted to
+ * @cred. The caller should really cache those as policy lookups are rather
+ * expensive.
+ *
+ * Return: The highest KDBUS_POLICY_* access type found, or -EPERM if none.
+ */
+int kdbus_policy_query(struct kdbus_policy_db *db, const struct cred *cred,
+		       const char *name, unsigned int hash)
+{
+	int ret;
+
+	down_read(&db->entries_rwlock);
+	ret = kdbus_policy_query_unlocked(db, cred, name, hash);
+	up_read(&db->entries_rwlock);
+
+	return ret;
+}
+
+static void __kdbus_policy_remove_owner(struct kdbus_policy_db *db,
+					const void *owner)
+{
+	struct kdbus_policy_db_entry *e;
+	struct hlist_node *tmp;
+	int i;
+
+	hash_for_each_safe(db->entries_hash, i, tmp, e, hentry)
+		if (e->owner == owner) {
+			hash_del(&e->hentry);
+			kdbus_policy_entry_free(e);
+		}
+}
+
+/**
+ * kdbus_policy_remove_owner() - remove all entries related to a connection
+ * @db:		The policy database
+ * @owner:	The connection which items to remove
+ */
+void kdbus_policy_remove_owner(struct kdbus_policy_db *db,
+			       const void *owner)
+{
+	down_write(&db->entries_rwlock);
+	__kdbus_policy_remove_owner(db, owner);
+	up_write(&db->entries_rwlock);
+}
+
+/*
+ * Convert user provided policy access to internal kdbus policy
+ * access
+ */
+static struct kdbus_policy_db_entry_access *
+kdbus_policy_make_access(const struct kdbus_policy_access *uaccess)
+{
+	int ret;
+	struct kdbus_policy_db_entry_access *a;
+
+	a = kzalloc(sizeof(*a), GFP_KERNEL);
+	if (!a)
+		return ERR_PTR(-ENOMEM);
+
+	ret = -EINVAL;
+	switch (uaccess->access) {
+	case KDBUS_POLICY_SEE:
+	case KDBUS_POLICY_TALK:
+	case KDBUS_POLICY_OWN:
+		a->access = uaccess->access;
+		break;
+	default:
+		goto err;
+	}
+
+	switch (uaccess->type) {
+	case KDBUS_POLICY_ACCESS_USER:
+		a->uid = make_kuid(current_user_ns(), uaccess->id);
+		if (!uid_valid(a->uid))
+			goto err;
+
+		break;
+	case KDBUS_POLICY_ACCESS_GROUP:
+		a->gid = make_kgid(current_user_ns(), uaccess->id);
+		if (!gid_valid(a->gid))
+			goto err;
+
+		break;
+	case KDBUS_POLICY_ACCESS_WORLD:
+		break;
+	default:
+		goto err;
+	}
+
+	a->type = uaccess->type;
+
+	return a;
+
+err:
+	kfree(a);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_policy_set() - set a connection's policy rules
+ * @db:				The policy database
+ * @items:			A list of kdbus_item elements that contain both
+ *				names and access rules to set.
+ * @items_size:			The total size of the items.
+ * @max_policies:		The maximum number of policy entries to allow.
+ *				Pass 0 for no limit.
+ * @allow_wildcards:		Boolean value whether wildcard entries (such
+ *				ending on '.*') should be allowed.
+ * @owner:			The owner of the new policy items.
+ *
+ * This function sets a new set of policies for a given owner. The names and
+ * access rules are gathered by walking the list of items passed in as
+ * argument. An item of type KDBUS_ITEM_NAME is expected before any number of
+ * KDBUS_ITEM_POLICY_ACCESS items. If there are more repetitions of this
+ * pattern than denoted in @max_policies, -EINVAL is returned.
+ *
+ * In order to allow atomic replacement of rules, the function first removes
+ * all entries that have been created for the given owner previously.
+ *
+ * Callers to this function must make sure that the owner is a custom
+ * endpoint, or if the endpoint is a default endpoint, then it must be
+ * either a policy holder or an activator.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int kdbus_policy_set(struct kdbus_policy_db *db,
+		     const struct kdbus_item *items,
+		     size_t items_size,
+		     size_t max_policies,
+		     bool allow_wildcards,
+		     const void *owner)
+{
+	struct kdbus_policy_db_entry_access *a;
+	struct kdbus_policy_db_entry *e, *p;
+	const struct kdbus_item *item;
+	struct hlist_node *tmp;
+	HLIST_HEAD(entries);
+	HLIST_HEAD(restore);
+	size_t count = 0;
+	int i, ret = 0;
+	u32 hash;
+
+	/* Walk the list of items and look for new policies */
+	e = NULL;
+	KDBUS_ITEMS_FOREACH(item, items, items_size) {
+		switch (item->type) {
+		case KDBUS_ITEM_NAME: {
+			size_t len;
+
+			if (max_policies && ++count > max_policies) {
+				ret = -E2BIG;
+				goto exit;
+			}
+
+			if (!kdbus_name_is_valid(item->str, true)) {
+				ret = -EINVAL;
+				goto exit;
+			}
+
+			e = kzalloc(sizeof(*e), GFP_KERNEL);
+			if (!e) {
+				ret = -ENOMEM;
+				goto exit;
+			}
+
+			INIT_LIST_HEAD(&e->access_list);
+			e->owner = owner;
+			hlist_add_head(&e->hentry, &entries);
+
+			e->name = kstrdup(item->str, GFP_KERNEL);
+			if (!e->name) {
+				ret = -ENOMEM;
+				goto exit;
+			}
+
+			/*
+			 * If a supplied name ends with an '.*', cut off that
+			 * part, only store anything before it, and mark the
+			 * entry as wildcard.
+			 */
+			len = strlen(e->name);
+			if (len > 2 &&
+			    e->name[len - 3] == '.' &&
+			    e->name[len - 2] == '*') {
+				if (!allow_wildcards) {
+					ret = -EINVAL;
+					goto exit;
+				}
+
+				e->name[len - 3] = '\0';
+				e->wildcard = true;
+			}
+
+			break;
+		}
+
+		case KDBUS_ITEM_POLICY_ACCESS:
+			if (!e) {
+				ret = -EINVAL;
+				goto exit;
+			}
+
+			a = kdbus_policy_make_access(&item->policy_access);
+			if (IS_ERR(a)) {
+				ret = PTR_ERR(a);
+				goto exit;
+			}
+
+			list_add_tail(&a->list, &e->access_list);
+			break;
+		}
+	}
+
+	down_write(&db->entries_rwlock);
+
+	/* remember previous entries to restore in case of failure */
+	hash_for_each_safe(db->entries_hash, i, tmp, e, hentry)
+		if (e->owner == owner) {
+			hash_del(&e->hentry);
+			hlist_add_head(&e->hentry, &restore);
+		}
+
+	hlist_for_each_entry_safe(e, tmp, &entries, hentry) {
+		/* prevent duplicates */
+		hash = kdbus_strhash(e->name);
+		hash_for_each_possible(db->entries_hash, p, hentry, hash)
+			if (strcmp(e->name, p->name) == 0 &&
+			    e->wildcard == p->wildcard) {
+				ret = -EEXIST;
+				goto restore;
+			}
+
+		hlist_del(&e->hentry);
+		hash_add(db->entries_hash, &e->hentry, hash);
+	}
+
+restore:
+	/* if we failed, flush all entries we added so far */
+	if (ret < 0)
+		__kdbus_policy_remove_owner(db, owner);
+
+	/* if we failed, restore entries, otherwise release them */
+	hlist_for_each_entry_safe(e, tmp, &restore, hentry) {
+		hlist_del(&e->hentry);
+		if (ret < 0) {
+			hash = kdbus_strhash(e->name);
+			hash_add(db->entries_hash, &e->hentry, hash);
+		} else {
+			kdbus_policy_entry_free(e);
+		}
+	}
+
+	up_write(&db->entries_rwlock);
+
+exit:
+	hlist_for_each_entry_safe(e, tmp, &entries, hentry) {
+		hlist_del(&e->hentry);
+		kdbus_policy_entry_free(e);
+	}
+
+	return ret;
+}
diff --git a/ipc/kdbus/policy.h b/ipc/kdbus/policy.h
new file mode 100644
index 000000000000..15dd7bc12068
--- /dev/null
+++ b/ipc/kdbus/policy.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_POLICY_H
+#define __KDBUS_POLICY_H
+
+#include <linux/hashtable.h>
+#include <linux/rwsem.h>
+
+struct kdbus_conn;
+struct kdbus_item;
+
+/**
+ * struct kdbus_policy_db - policy database
+ * @entries_hash:	Hashtable of entries
+ * @entries_rwlock:	Mutex to protect the database's access entries
+ */
+struct kdbus_policy_db {
+	DECLARE_HASHTABLE(entries_hash, 6);
+	struct rw_semaphore entries_rwlock;
+};
+
+void kdbus_policy_db_init(struct kdbus_policy_db *db);
+void kdbus_policy_db_clear(struct kdbus_policy_db *db);
+
+int kdbus_policy_query_unlocked(struct kdbus_policy_db *db,
+				const struct cred *cred, const char *name,
+				unsigned int hash);
+int kdbus_policy_query(struct kdbus_policy_db *db, const struct cred *cred,
+		       const char *name, unsigned int hash);
+
+void kdbus_policy_remove_owner(struct kdbus_policy_db *db,
+			       const void *owner);
+int kdbus_policy_set(struct kdbus_policy_db *db,
+		     const struct kdbus_item *items,
+		     size_t items_size,
+		     size_t max_policies,
+		     bool allow_wildcards,
+		     const void *owner);
+
+#endif
diff --git a/ipc/kdbus/pool.c b/ipc/kdbus/pool.c
new file mode 100644
index 000000000000..63ccd55713c7
--- /dev/null
+++ b/ipc/kdbus/pool.c
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/aio.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/rbtree.h>
+#include <linux/sched.h>
+#include <linux/shmem_fs.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/uio.h>
+
+#include "pool.h"
+#include "util.h"
+
+/**
+ * struct kdbus_pool - the receiver's buffer
+ * @f:			The backing shmem file
+ * @size:		The size of the file
+ * @accounted_size:	Currently accounted memory in bytes
+ * @lock:		Pool data lock
+ * @slices:		All slices sorted by address
+ * @slices_busy:	Tree of allocated slices
+ * @slices_free:	Tree of free slices
+ *
+ * The receiver's buffer, managed as a pool of allocated and free
+ * slices containing the queued messages.
+ *
+ * Messages sent with KDBUS_CMD_SEND are copied directly by the
+ * sending process into the receiver's pool.
+ *
+ * Messages received with KDBUS_CMD_RECV just return the offset
+ * to the data placed in the pool.
+ *
+ * The internally allocated memory needs to be returned by the receiver
+ * with KDBUS_CMD_FREE.
+ */
+struct kdbus_pool {
+	struct file *f;
+	size_t size;
+	size_t accounted_size;
+	struct mutex lock;
+
+	struct list_head slices;
+	struct rb_root slices_busy;
+	struct rb_root slices_free;
+};
+
+/**
+ * struct kdbus_pool_slice - allocated element in kdbus_pool
+ * @pool:		Pool this slice belongs to
+ * @off:		Offset of slice in the shmem file
+ * @size:		Size of slice
+ * @entry:		Entry in "all slices" list
+ * @rb_node:		Entry in free or busy list
+ * @free:		Unused slice
+ * @accounted:		Accounted as queue slice
+ * @ref_kernel:		Kernel holds a reference
+ * @ref_user:		Userspace holds a reference
+ *
+ * The pool has one or more slices, always spanning the entire size of the
+ * pool.
+ *
+ * Every slice is an element in a list sorted by the buffer address, to
+ * provide access to the next neighbor slice.
+ *
+ * Every slice is member in either the busy or the free tree. The free
+ * tree is organized by slice size, the busy tree organized by buffer
+ * offset.
+ */
+struct kdbus_pool_slice {
+	struct kdbus_pool *pool;
+	size_t off;
+	size_t size;
+
+	struct list_head entry;
+	struct rb_node rb_node;
+
+	bool free:1;
+	bool accounted:1;
+	bool ref_kernel:1;
+	bool ref_user:1;
+};
+
+static struct kdbus_pool_slice *kdbus_pool_slice_new(struct kdbus_pool *pool,
+						     size_t off, size_t size)
+{
+	struct kdbus_pool_slice *slice;
+
+	slice = kzalloc(sizeof(*slice), GFP_KERNEL);
+	if (!slice)
+		return NULL;
+
+	slice->pool = pool;
+	slice->off = off;
+	slice->size = size;
+	slice->free = true;
+	return slice;
+}
+
+/* insert a slice into the free tree */
+static void kdbus_pool_add_free_slice(struct kdbus_pool *pool,
+				      struct kdbus_pool_slice *slice)
+{
+	struct rb_node **n;
+	struct rb_node *pn = NULL;
+
+	n = &pool->slices_free.rb_node;
+	while (*n) {
+		struct kdbus_pool_slice *pslice;
+
+		pn = *n;
+		pslice = rb_entry(pn, struct kdbus_pool_slice, rb_node);
+		if (slice->size < pslice->size)
+			n = &pn->rb_left;
+		else
+			n = &pn->rb_right;
+	}
+
+	rb_link_node(&slice->rb_node, pn, n);
+	rb_insert_color(&slice->rb_node, &pool->slices_free);
+}
+
+/* insert a slice into the busy tree */
+static void kdbus_pool_add_busy_slice(struct kdbus_pool *pool,
+				      struct kdbus_pool_slice *slice)
+{
+	struct rb_node **n;
+	struct rb_node *pn = NULL;
+
+	n = &pool->slices_busy.rb_node;
+	while (*n) {
+		struct kdbus_pool_slice *pslice;
+
+		pn = *n;
+		pslice = rb_entry(pn, struct kdbus_pool_slice, rb_node);
+		if (slice->off < pslice->off)
+			n = &pn->rb_left;
+		else if (slice->off > pslice->off)
+			n = &pn->rb_right;
+		else
+			BUG();
+	}
+
+	rb_link_node(&slice->rb_node, pn, n);
+	rb_insert_color(&slice->rb_node, &pool->slices_busy);
+}
+
+static struct kdbus_pool_slice *kdbus_pool_find_slice(struct kdbus_pool *pool,
+						      size_t off)
+{
+	struct rb_node *n;
+
+	n = pool->slices_busy.rb_node;
+	while (n) {
+		struct kdbus_pool_slice *s;
+
+		s = rb_entry(n, struct kdbus_pool_slice, rb_node);
+		if (off < s->off)
+			n = n->rb_left;
+		else if (off > s->off)
+			n = n->rb_right;
+		else
+			return s;
+	}
+
+	return NULL;
+}
+
+/**
+ * kdbus_pool_slice_alloc() - allocate memory from a pool
+ * @pool:	The receiver's pool
+ * @size:	The number of bytes to allocate
+ * @accounted:	Whether this slice should be accounted for
+ *
+ * The returned slice is used for kdbus_pool_slice_release() to
+ * free the allocated memory. If either @kvec or @iovec is non-NULL, the data
+ * will be copied from kernel or userspace memory into the new slice at
+ * offset 0.
+ *
+ * Return: the allocated slice on success, ERR_PTR on failure.
+ */
+struct kdbus_pool_slice *kdbus_pool_slice_alloc(struct kdbus_pool *pool,
+						size_t size, bool accounted)
+{
+	size_t slice_size = KDBUS_ALIGN8(size);
+	struct rb_node *n, *found = NULL;
+	struct kdbus_pool_slice *s;
+	int ret = 0;
+
+	if (WARN_ON(!size))
+		return ERR_PTR(-EINVAL);
+
+	/* search a free slice with the closest matching size */
+	mutex_lock(&pool->lock);
+	n = pool->slices_free.rb_node;
+	while (n) {
+		s = rb_entry(n, struct kdbus_pool_slice, rb_node);
+		if (slice_size < s->size) {
+			found = n;
+			n = n->rb_left;
+		} else if (slice_size > s->size) {
+			n = n->rb_right;
+		} else {
+			found = n;
+			break;
+		}
+	}
+
+	/* no slice with the minimum size found in the pool */
+	if (!found) {
+		ret = -EXFULL;
+		goto exit_unlock;
+	}
+
+	/* no exact match, use the closest one */
+	if (!n) {
+		struct kdbus_pool_slice *s_new;
+
+		s = rb_entry(found, struct kdbus_pool_slice, rb_node);
+
+		/* split-off the remainder of the size to its own slice */
+		s_new = kdbus_pool_slice_new(pool, s->off + slice_size,
+					     s->size - slice_size);
+		if (!s_new) {
+			ret = -ENOMEM;
+			goto exit_unlock;
+		}
+
+		list_add(&s_new->entry, &s->entry);
+		kdbus_pool_add_free_slice(pool, s_new);
+
+		/* adjust our size now that we split-off another slice */
+		s->size = slice_size;
+	}
+
+	/* move slice from free to the busy tree */
+	rb_erase(found, &pool->slices_free);
+	kdbus_pool_add_busy_slice(pool, s);
+
+	WARN_ON(s->ref_kernel || s->ref_user);
+
+	s->ref_kernel = true;
+	s->free = false;
+	s->accounted = accounted;
+	if (accounted)
+		pool->accounted_size += s->size;
+	mutex_unlock(&pool->lock);
+
+	return s;
+
+exit_unlock:
+	mutex_unlock(&pool->lock);
+	return ERR_PTR(ret);
+}
+
+static void __kdbus_pool_slice_release(struct kdbus_pool_slice *slice)
+{
+	struct kdbus_pool *pool = slice->pool;
+
+	/* don't free the slice if either has a reference */
+	if (slice->ref_kernel || slice->ref_user)
+		return;
+
+	if (WARN_ON(slice->free))
+		return;
+
+	rb_erase(&slice->rb_node, &pool->slices_busy);
+
+	/* merge with the next free slice */
+	if (!list_is_last(&slice->entry, &pool->slices)) {
+		struct kdbus_pool_slice *s;
+
+		s = list_entry(slice->entry.next,
+			       struct kdbus_pool_slice, entry);
+		if (s->free) {
+			rb_erase(&s->rb_node, &pool->slices_free);
+			list_del(&s->entry);
+			slice->size += s->size;
+			kfree(s);
+		}
+	}
+
+	/* merge with previous free slice */
+	if (pool->slices.next != &slice->entry) {
+		struct kdbus_pool_slice *s;
+
+		s = list_entry(slice->entry.prev,
+			       struct kdbus_pool_slice, entry);
+		if (s->free) {
+			rb_erase(&s->rb_node, &pool->slices_free);
+			list_del(&slice->entry);
+			s->size += slice->size;
+			kfree(slice);
+			slice = s;
+		}
+	}
+
+	slice->free = true;
+	kdbus_pool_add_free_slice(pool, slice);
+}
+
+/**
+ * kdbus_pool_slice_release() - drop kernel-reference on allocated slice
+ * @slice:		Slice allocated from the pool
+ *
+ * This releases the kernel-reference on the given slice. If the
+ * kernel-reference and the user-reference on a slice are dropped, the slice is
+ * returned to the pool.
+ *
+ * So far, we do not implement full ref-counting on slices. Each, kernel and
+ * user-space can have exactly one reference to a slice. If both are dropped at
+ * the same time, the slice is released.
+ */
+void kdbus_pool_slice_release(struct kdbus_pool_slice *slice)
+{
+	struct kdbus_pool *pool;
+
+	if (!slice)
+		return;
+
+	/* @slice may be freed, so keep local ptr to @pool */
+	pool = slice->pool;
+
+	mutex_lock(&pool->lock);
+	/* kernel must own a ref to @slice to drop it */
+	WARN_ON(!slice->ref_kernel);
+	slice->ref_kernel = false;
+	/* no longer kernel-owned, de-account slice */
+	if (slice->accounted && !WARN_ON(pool->accounted_size < slice->size))
+		pool->accounted_size -= slice->size;
+	__kdbus_pool_slice_release(slice);
+	mutex_unlock(&pool->lock);
+}
+
+/**
+ * kdbus_pool_release_offset() - release a public offset
+ * @pool:		pool to operate on
+ * @off:		offset to release
+ *
+ * This should be called whenever user-space frees a slice given to them. It
+ * verifies the slice is available and public, and then drops it. It ensures
+ * correct locking and barriers against queues.
+ *
+ * Return: 0 on success, ENXIO if the offset is invalid or not public.
+ */
+int kdbus_pool_release_offset(struct kdbus_pool *pool, size_t off)
+{
+	struct kdbus_pool_slice *slice;
+	int ret = 0;
+
+	/* 'pool->size' is used as dummy offset for empty slices */
+	if (off == pool->size)
+		return 0;
+
+	mutex_lock(&pool->lock);
+	slice = kdbus_pool_find_slice(pool, off);
+	if (slice && slice->ref_user) {
+		slice->ref_user = false;
+		__kdbus_pool_slice_release(slice);
+	} else {
+		ret = -ENXIO;
+	}
+	mutex_unlock(&pool->lock);
+
+	return ret;
+}
+
+/**
+ * kdbus_pool_publish_empty() - publish empty slice to user-space
+ * @pool:		pool to operate on
+ * @off:		output storage for offset, or NULL
+ * @size:		output storage for size, or NULL
+ *
+ * This is the same as kdbus_pool_slice_publish(), but uses a dummy slice with
+ * size 0. The returned offset points to the end of the pool and is never
+ * returned on real slices.
+ */
+void kdbus_pool_publish_empty(struct kdbus_pool *pool, u64 *off, u64 *size)
+{
+	if (off)
+		*off = pool->size;
+	if (size)
+		*size = 0;
+}
+
+/**
+ * kdbus_pool_slice_publish() - publish slice to user-space
+ * @slice:		The slice
+ * @out_offset:		Output storage for offset, or NULL
+ * @out_size:		Output storage for size, or NULL
+ *
+ * This prepares a slice to be published to user-space.
+ *
+ * This call combines the following operations:
+ *   * the memory region is flushed so the user's memory view is consistent
+ *   * the slice is marked as referenced by user-space, so user-space has to
+ *     call KDBUS_CMD_FREE to release it
+ *   * the offset and size of the slice are written to the given output
+ *     arguments, if non-NULL
+ */
+void kdbus_pool_slice_publish(struct kdbus_pool_slice *slice,
+			      u64 *out_offset, u64 *out_size)
+{
+	mutex_lock(&slice->pool->lock);
+	/* kernel must own a ref to @slice to gain a user-space ref */
+	WARN_ON(!slice->ref_kernel);
+	slice->ref_user = true;
+	mutex_unlock(&slice->pool->lock);
+
+	if (out_offset)
+		*out_offset = slice->off;
+	if (out_size)
+		*out_size = slice->size;
+}
+
+/**
+ * kdbus_pool_slice_offset() - Get a slice's offset inside the pool
+ * @slice:	Slice to return the offset of
+ *
+ * Return: The internal offset @slice inside the pool.
+ */
+off_t kdbus_pool_slice_offset(const struct kdbus_pool_slice *slice)
+{
+	return slice->off;
+}
+
+/**
+ * kdbus_pool_slice_size() - get size of a pool slice
+ * @slice:	slice to query
+ *
+ * Return: size of the given slice
+ */
+size_t kdbus_pool_slice_size(const struct kdbus_pool_slice *slice)
+{
+	return slice->size;
+}
+
+/**
+ * kdbus_pool_new() - create a new pool
+ * @name:		Name of the (deleted) file which shows up in
+ *			/proc, used for debugging
+ * @size:		Maximum size of the pool
+ *
+ * Return: a new kdbus_pool on success, ERR_PTR on failure.
+ */
+struct kdbus_pool *kdbus_pool_new(const char *name, size_t size)
+{
+	struct kdbus_pool_slice *s;
+	struct kdbus_pool *p;
+	struct file *f;
+	char *n = NULL;
+	int ret;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return ERR_PTR(-ENOMEM);
+
+	if (name) {
+		n = kasprintf(GFP_KERNEL, KBUILD_MODNAME "-conn:%s", name);
+		if (!n) {
+			ret = -ENOMEM;
+			goto exit_free;
+		}
+	}
+
+	f = shmem_file_setup(n ?: KBUILD_MODNAME "-conn", size, 0);
+	kfree(n);
+
+	if (IS_ERR(f)) {
+		ret = PTR_ERR(f);
+		goto exit_free;
+	}
+
+	ret = get_write_access(file_inode(f));
+	if (ret < 0)
+		goto exit_put_shmem;
+
+	/* allocate first slice spanning the entire pool */
+	s = kdbus_pool_slice_new(p, 0, size);
+	if (!s) {
+		ret = -ENOMEM;
+		goto exit_put_write;
+	}
+
+	p->f = f;
+	p->size = size;
+	p->slices_free = RB_ROOT;
+	p->slices_busy = RB_ROOT;
+	mutex_init(&p->lock);
+
+	INIT_LIST_HEAD(&p->slices);
+	list_add(&s->entry, &p->slices);
+
+	kdbus_pool_add_free_slice(p, s);
+	return p;
+
+exit_put_write:
+	put_write_access(file_inode(f));
+exit_put_shmem:
+	fput(f);
+exit_free:
+	kfree(p);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_pool_free() - destroy pool
+ * @pool:		The receiver's pool
+ */
+void kdbus_pool_free(struct kdbus_pool *pool)
+{
+	struct kdbus_pool_slice *s, *tmp;
+
+	if (!pool)
+		return;
+
+	list_for_each_entry_safe(s, tmp, &pool->slices, entry) {
+		list_del(&s->entry);
+		kfree(s);
+	}
+
+	put_write_access(file_inode(pool->f));
+	fput(pool->f);
+	kfree(pool);
+}
+
+/**
+ * kdbus_pool_accounted() - retrieve accounting information
+ * @pool:		pool to query
+ * @size:		output for overall pool size
+ * @acc:		output for currently accounted size
+ *
+ * This returns accounting information of the pool. Note that the data might
+ * change after the function returns, as the pool lock is dropped. You need to
+ * protect the data via other means, if you need reliable accounting.
+ */
+void kdbus_pool_accounted(struct kdbus_pool *pool, size_t *size, size_t *acc)
+{
+	mutex_lock(&pool->lock);
+	if (size)
+		*size = pool->size;
+	if (acc)
+		*acc = pool->accounted_size;
+	mutex_unlock(&pool->lock);
+}
+
+/**
+ * kdbus_pool_slice_copy_iovec() - copy user memory to a slice
+ * @slice:		The slice to write to
+ * @off:		Offset in the slice to write to
+ * @iov:		iovec array, pointing to data to copy
+ * @iov_len:		Number of elements in @iov
+ * @total_len:		Total number of bytes described in members of @iov
+ *
+ * User memory referenced by @iov will be copied into @slice at offset @off.
+ *
+ * Return: the numbers of bytes copied, negative errno on failure.
+ */
+ssize_t
+kdbus_pool_slice_copy_iovec(const struct kdbus_pool_slice *slice, loff_t off,
+			    struct iovec *iov, size_t iov_len, size_t total_len)
+{
+	struct iov_iter iter;
+	ssize_t len;
+
+	if (WARN_ON(off + total_len > slice->size))
+		return -EFAULT;
+
+	off += slice->off;
+	iov_iter_init(&iter, WRITE, iov, iov_len, total_len);
+	len = vfs_iter_write(slice->pool->f, &iter, &off);
+
+	return (len >= 0 && len != total_len) ? -EFAULT : len;
+}
+
+/**
+ * kdbus_pool_slice_copy_kvec() - copy kernel memory to a slice
+ * @slice:		The slice to write to
+ * @off:		Offset in the slice to write to
+ * @kvec:		kvec array, pointing to data to copy
+ * @kvec_len:		Number of elements in @kvec
+ * @total_len:		Total number of bytes described in members of @kvec
+ *
+ * Kernel memory referenced by @kvec will be copied into @slice at offset @off.
+ *
+ * Return: the numbers of bytes copied, negative errno on failure.
+ */
+ssize_t kdbus_pool_slice_copy_kvec(const struct kdbus_pool_slice *slice,
+				   loff_t off, struct kvec *kvec,
+				   size_t kvec_len, size_t total_len)
+{
+	struct iov_iter iter;
+	mm_segment_t old_fs;
+	ssize_t len;
+
+	if (WARN_ON(off + total_len > slice->size))
+		return -EFAULT;
+
+	off += slice->off;
+	iov_iter_kvec(&iter, WRITE | ITER_KVEC, kvec, kvec_len, total_len);
+
+	old_fs = get_fs();
+	set_fs(get_ds());
+	len = vfs_iter_write(slice->pool->f, &iter, &off);
+	set_fs(old_fs);
+
+	return (len >= 0 && len != total_len) ? -EFAULT : len;
+}
+
+/**
+ * kdbus_pool_slice_copy() - copy data from one slice into another
+ * @slice_dst:		destination slice
+ * @slice_src:		source slice
+ *
+ * Return: 0 on success, negative error number on failure.
+ */
+int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
+			  const struct kdbus_pool_slice *slice_src)
+{
+	struct file *f_src = slice_src->pool->f;
+	struct file *f_dst = slice_dst->pool->f;
+	struct inode *i_dst = file_inode(f_dst);
+	struct address_space *mapping_dst = f_dst->f_mapping;
+	const struct address_space_operations *aops = mapping_dst->a_ops;
+	unsigned long len = slice_src->size;
+	loff_t off_src = slice_src->off;
+	loff_t off_dst = slice_dst->off;
+	mm_segment_t old_fs;
+	int ret = 0;
+
+	if (WARN_ON(slice_src->size != slice_dst->size) ||
+	    WARN_ON(slice_src->free || slice_dst->free))
+		return -EINVAL;
+
+	mutex_lock(&i_dst->i_mutex);
+	old_fs = get_fs();
+	set_fs(get_ds());
+	while (len > 0) {
+		unsigned long page_off;
+		unsigned long copy_len;
+		char __user *kaddr;
+		struct page *page;
+		ssize_t n_read;
+		void *fsdata;
+		long status;
+
+		page_off = off_dst & (PAGE_CACHE_SIZE - 1);
+		copy_len = min_t(unsigned long,
+				 PAGE_CACHE_SIZE - page_off, len);
+
+		status = aops->write_begin(f_dst, mapping_dst, off_dst,
+					   copy_len, 0, &page, &fsdata);
+		if (unlikely(status < 0)) {
+			ret = status;
+			break;
+		}
+
+		kaddr = (char __force __user *)kmap(page) + page_off;
+		n_read = __vfs_read(f_src, kaddr, copy_len, &off_src);
+		kunmap(page);
+		mark_page_accessed(page);
+		flush_dcache_page(page);
+
+		if (unlikely(n_read != copy_len)) {
+			ret = -EFAULT;
+			break;
+		}
+
+		status = aops->write_end(f_dst, mapping_dst, off_dst,
+					 copy_len, copy_len, page, fsdata);
+		if (unlikely(status != copy_len)) {
+			ret = -EFAULT;
+			break;
+		}
+
+		off_dst += copy_len;
+		len -= copy_len;
+	}
+	set_fs(old_fs);
+	mutex_unlock(&i_dst->i_mutex);
+
+	return ret;
+}
+
+/**
+ * kdbus_pool_mmap() -  map the pool into the process
+ * @pool:		The receiver's pool
+ * @vma:		passed by mmap() syscall
+ *
+ * Return: the result of the mmap() call, negative errno on failure.
+ */
+int kdbus_pool_mmap(const struct kdbus_pool *pool, struct vm_area_struct *vma)
+{
+	/* deny write access to the pool */
+	if (vma->vm_flags & VM_WRITE)
+		return -EPERM;
+	vma->vm_flags &= ~VM_MAYWRITE;
+
+	/* do not allow to map more than the size of the file */
+	if ((vma->vm_end - vma->vm_start) > pool->size)
+		return -EFAULT;
+
+	/* replace the connection file with our shmem file */
+	if (vma->vm_file)
+		fput(vma->vm_file);
+	vma->vm_file = get_file(pool->f);
+
+	return pool->f->f_op->mmap(pool->f, vma);
+}
diff --git a/ipc/kdbus/pool.h b/ipc/kdbus/pool.h
new file mode 100644
index 000000000000..a9038213aa4d
--- /dev/null
+++ b/ipc/kdbus/pool.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_POOL_H
+#define __KDBUS_POOL_H
+
+#include <linux/uio.h>
+
+struct kdbus_pool;
+struct kdbus_pool_slice;
+
+struct kdbus_pool *kdbus_pool_new(const char *name, size_t size);
+void kdbus_pool_free(struct kdbus_pool *pool);
+void kdbus_pool_accounted(struct kdbus_pool *pool, size_t *size, size_t *acc);
+int kdbus_pool_mmap(const struct kdbus_pool *pool, struct vm_area_struct *vma);
+int kdbus_pool_release_offset(struct kdbus_pool *pool, size_t off);
+void kdbus_pool_publish_empty(struct kdbus_pool *pool, u64 *off, u64 *size);
+
+struct kdbus_pool_slice *kdbus_pool_slice_alloc(struct kdbus_pool *pool,
+						size_t size, bool accounted);
+void kdbus_pool_slice_release(struct kdbus_pool_slice *slice);
+void kdbus_pool_slice_publish(struct kdbus_pool_slice *slice,
+			      u64 *out_offset, u64 *out_size);
+off_t kdbus_pool_slice_offset(const struct kdbus_pool_slice *slice);
+size_t kdbus_pool_slice_size(const struct kdbus_pool_slice *slice);
+int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
+			  const struct kdbus_pool_slice *slice_src);
+ssize_t kdbus_pool_slice_copy_kvec(const struct kdbus_pool_slice *slice,
+				   loff_t off, struct kvec *kvec,
+				   size_t kvec_count, size_t total_len);
+ssize_t kdbus_pool_slice_copy_iovec(const struct kdbus_pool_slice *slice,
+				    loff_t off, struct iovec *iov,
+				    size_t iov_count, size_t total_len);
+
+#endif
diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
new file mode 100644
index 000000000000..f9c44d7bae6d
--- /dev/null
+++ b/ipc/kdbus/queue.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/audit.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/hashtable.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/math64.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/uio.h>
+
+#include "util.h"
+#include "domain.h"
+#include "connection.h"
+#include "item.h"
+#include "message.h"
+#include "metadata.h"
+#include "queue.h"
+#include "reply.h"
+
+/**
+ * kdbus_queue_init() - initialize data structure related to a queue
+ * @queue:	The queue to initialize
+ */
+void kdbus_queue_init(struct kdbus_queue *queue)
+{
+	INIT_LIST_HEAD(&queue->msg_list);
+	queue->msg_prio_queue = RB_ROOT;
+}
+
+/**
+ * kdbus_queue_peek() - Retrieves an entry from a queue
+ * @queue:		The queue
+ * @priority:		The minimum priority of the entry to peek
+ * @use_priority:	Boolean flag whether or not to peek by priority
+ *
+ * Look for a entry in a queue, either by priority, or the oldest one (FIFO).
+ * The entry is not freed, put off the queue's lists or anything else.
+ *
+ * Return: the peeked queue entry on success, NULL if no suitable msg is found
+ */
+struct kdbus_queue_entry *kdbus_queue_peek(struct kdbus_queue *queue,
+					   s64 priority, bool use_priority)
+{
+	struct kdbus_queue_entry *e;
+
+	if (list_empty(&queue->msg_list))
+		return NULL;
+
+	if (use_priority) {
+		/* get next entry with highest priority */
+		e = rb_entry(queue->msg_prio_highest,
+			     struct kdbus_queue_entry, prio_node);
+
+		/* no entry with the requested priority */
+		if (e->priority > priority)
+			return NULL;
+	} else {
+		/* ignore the priority, return the next entry in the entry */
+		e = list_first_entry(&queue->msg_list,
+				     struct kdbus_queue_entry, entry);
+	}
+
+	return e;
+}
+
+static void kdbus_queue_entry_link(struct kdbus_queue_entry *entry)
+{
+	struct kdbus_queue *queue = &entry->conn->queue;
+	struct rb_node **n, *pn = NULL;
+	bool highest = true;
+
+	lockdep_assert_held(&entry->conn->lock);
+	if (WARN_ON(!list_empty(&entry->entry)))
+		return;
+
+	/* sort into priority entry tree */
+	n = &queue->msg_prio_queue.rb_node;
+	while (*n) {
+		struct kdbus_queue_entry *e;
+
+		pn = *n;
+		e = rb_entry(pn, struct kdbus_queue_entry, prio_node);
+
+		/* existing node for this priority, add to its list */
+		if (likely(entry->priority == e->priority)) {
+			list_add_tail(&entry->prio_entry, &e->prio_entry);
+			goto prio_done;
+		}
+
+		if (entry->priority < e->priority) {
+			n = &pn->rb_left;
+		} else {
+			n = &pn->rb_right;
+			highest = false;
+		}
+	}
+
+	/* cache highest-priority entry */
+	if (highest)
+		queue->msg_prio_highest = &entry->prio_node;
+
+	/* new node for this priority */
+	rb_link_node(&entry->prio_node, pn, n);
+	rb_insert_color(&entry->prio_node, &queue->msg_prio_queue);
+	INIT_LIST_HEAD(&entry->prio_entry);
+
+prio_done:
+	/* add to unsorted fifo list */
+	list_add_tail(&entry->entry, &queue->msg_list);
+}
+
+static void kdbus_queue_entry_unlink(struct kdbus_queue_entry *entry)
+{
+	struct kdbus_queue *queue = &entry->conn->queue;
+
+	lockdep_assert_held(&entry->conn->lock);
+	if (list_empty(&entry->entry))
+		return;
+
+	list_del_init(&entry->entry);
+
+	if (list_empty(&entry->prio_entry)) {
+		/*
+		 * Single entry for this priority, update cached
+		 * highest-priority entry, remove the tree node.
+		 */
+		if (queue->msg_prio_highest == &entry->prio_node)
+			queue->msg_prio_highest = rb_next(&entry->prio_node);
+
+		rb_erase(&entry->prio_node, &queue->msg_prio_queue);
+	} else {
+		struct kdbus_queue_entry *q;
+
+		/*
+		 * Multiple entries for this priority entry, get next one in
+		 * the list. Update cached highest-priority entry, store the
+		 * new one as the tree node.
+		 */
+		q = list_first_entry(&entry->prio_entry,
+				     struct kdbus_queue_entry, prio_entry);
+		list_del(&entry->prio_entry);
+
+		if (queue->msg_prio_highest == &entry->prio_node)
+			queue->msg_prio_highest = &q->prio_node;
+
+		rb_replace_node(&entry->prio_node, &q->prio_node,
+				&queue->msg_prio_queue);
+	}
+}
+
+/**
+ * kdbus_queue_entry_new() - allocate a queue entry
+ * @src:	source connection, or NULL
+ * @dst:	destination connection
+ * @s:		staging object carrying the message
+ *
+ * Allocates a queue entry based on a given msg and allocate space for
+ * the message payload and the requested metadata in the connection's pool.
+ * The entry is not actually added to the queue's lists at this point.
+ *
+ * Return: the allocated entry on success, or an ERR_PTR on failures.
+ */
+struct kdbus_queue_entry *kdbus_queue_entry_new(struct kdbus_conn *src,
+						struct kdbus_conn *dst,
+						struct kdbus_staging *s)
+{
+	struct kdbus_queue_entry *entry;
+	int ret;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&entry->entry);
+	entry->priority = s->msg->priority;
+	entry->conn = kdbus_conn_ref(dst);
+	entry->gaps = kdbus_gaps_ref(s->gaps);
+
+	entry->slice = kdbus_staging_emit(s, src, dst);
+	if (IS_ERR(entry->slice)) {
+		ret = PTR_ERR(entry->slice);
+		entry->slice = NULL;
+		goto error;
+	}
+
+	entry->user = src ? kdbus_user_ref(src->user) : NULL;
+	return entry;
+
+error:
+	kdbus_queue_entry_free(entry);
+	return ERR_PTR(ret);
+}
+
+/**
+ * kdbus_queue_entry_free() - free resources of an entry
+ * @entry:	The entry to free
+ *
+ * Removes resources allocated by a queue entry, along with the entry itself.
+ * Note that the entry's slice is not freed at this point.
+ */
+void kdbus_queue_entry_free(struct kdbus_queue_entry *entry)
+{
+	if (!entry)
+		return;
+
+	lockdep_assert_held(&entry->conn->lock);
+
+	kdbus_queue_entry_unlink(entry);
+	kdbus_reply_unref(entry->reply);
+
+	if (entry->slice) {
+		kdbus_conn_quota_dec(entry->conn, entry->user,
+				     kdbus_pool_slice_size(entry->slice),
+				     entry->gaps ? entry->gaps->n_fds : 0);
+		kdbus_pool_slice_release(entry->slice);
+	}
+
+	kdbus_user_unref(entry->user);
+	kdbus_gaps_unref(entry->gaps);
+	kdbus_conn_unref(entry->conn);
+	kfree(entry);
+}
+
+/**
+ * kdbus_queue_entry_install() - install message components into the
+ *				 receiver's process
+ * @entry:		The queue entry to install
+ * @return_flags:	Pointer to store the return flags for userspace
+ * @install_fds:	Whether or not to install associated file descriptors
+ *
+ * Return: 0 on success.
+ */
+int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
+			      u64 *return_flags, bool install_fds)
+{
+	bool incomplete_fds = false;
+	int ret;
+
+	lockdep_assert_held(&entry->conn->lock);
+
+	ret = kdbus_gaps_install(entry->gaps, entry->slice, &incomplete_fds);
+	if (ret < 0)
+		return ret;
+
+	if (incomplete_fds)
+		*return_flags |= KDBUS_RECV_RETURN_INCOMPLETE_FDS;
+	return 0;
+}
+
+/**
+ * kdbus_queue_entry_enqueue() - enqueue an entry
+ * @entry:		entry to enqueue
+ * @reply:		reply to link to this entry (or NULL if none)
+ *
+ * This enqueues an unqueued entry into the message queue of the linked
+ * connection. It also binds a reply object to the entry so we can remember it
+ * when the message is moved.
+ *
+ * Once this call returns (and the connection lock is released), this entry can
+ * be dequeued by the target connection. Note that the entry will not be removed
+ * from the queue until it is destroyed.
+ */
+void kdbus_queue_entry_enqueue(struct kdbus_queue_entry *entry,
+			       struct kdbus_reply *reply)
+{
+	lockdep_assert_held(&entry->conn->lock);
+
+	if (WARN_ON(entry->reply) || WARN_ON(!list_empty(&entry->entry)))
+		return;
+
+	entry->reply = kdbus_reply_ref(reply);
+	kdbus_queue_entry_link(entry);
+}
+
+/**
+ * kdbus_queue_entry_move() - move queue entry
+ * @e:		queue entry to move
+ * @dst:	destination connection to queue the entry on
+ *
+ * This moves a queue entry onto a different connection. It allocates a new
+ * slice on the target connection and copies the message over. If the copy
+ * succeeded, we move the entry from @src to @dst.
+ *
+ * On failure, the entry is left untouched.
+ *
+ * The queue entry must be queued right now, and after the call succeeds it will
+ * be queued on the destination, but no longer on the source.
+ *
+ * The caller must hold the connection lock of the source *and* destination.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_queue_entry_move(struct kdbus_queue_entry *e,
+			   struct kdbus_conn *dst)
+{
+	struct kdbus_pool_slice *slice = NULL;
+	struct kdbus_conn *src = e->conn;
+	size_t size, fds;
+	int ret;
+
+	lockdep_assert_held(&src->lock);
+	lockdep_assert_held(&dst->lock);
+
+	if (WARN_ON(list_empty(&e->entry)))
+		return -EINVAL;
+	if (src == dst)
+		return 0;
+
+	size = kdbus_pool_slice_size(e->slice);
+	fds = e->gaps ? e->gaps->n_fds : 0;
+
+	ret = kdbus_conn_quota_inc(dst, e->user, size, fds);
+	if (ret < 0)
+		return ret;
+
+	slice = kdbus_pool_slice_alloc(dst->pool, size, true);
+	if (IS_ERR(slice)) {
+		ret = PTR_ERR(slice);
+		slice = NULL;
+		goto error;
+	}
+
+	ret = kdbus_pool_slice_copy(slice, e->slice);
+	if (ret < 0)
+		goto error;
+
+	kdbus_queue_entry_unlink(e);
+	kdbus_conn_quota_dec(src, e->user, size, fds);
+	kdbus_pool_slice_release(e->slice);
+	kdbus_conn_unref(e->conn);
+
+	e->slice = slice;
+	e->conn = kdbus_conn_ref(dst);
+	kdbus_queue_entry_link(e);
+
+	return 0;
+
+error:
+	kdbus_pool_slice_release(slice);
+	kdbus_conn_quota_dec(dst, e->user, size, fds);
+	return ret;
+}
diff --git a/ipc/kdbus/queue.h b/ipc/kdbus/queue.h
new file mode 100644
index 000000000000..bf686d182ce1
--- /dev/null
+++ b/ipc/kdbus/queue.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_QUEUE_H
+#define __KDBUS_QUEUE_H
+
+#include <linux/list.h>
+#include <linux/rbtree.h>
+
+struct kdbus_conn;
+struct kdbus_pool_slice;
+struct kdbus_reply;
+struct kdbus_staging;
+struct kdbus_user;
+
+/**
+ * struct kdbus_queue - a connection's message queue
+ * @msg_list:		List head for kdbus_queue_entry objects
+ * @msg_prio_queue:	RB tree root for messages, sorted by priority
+ * @msg_prio_highest:	Link to the RB node referencing the message with the
+ *			highest priority in the tree.
+ */
+struct kdbus_queue {
+	struct list_head msg_list;
+	struct rb_root msg_prio_queue;
+	struct rb_node *msg_prio_highest;
+};
+
+/**
+ * struct kdbus_queue_entry - messages waiting to be read
+ * @entry:		Entry in the connection's list
+ * @prio_node:		Entry in the priority queue tree
+ * @prio_entry:		Queue tree node entry in the list of one priority
+ * @priority:		Message priority
+ * @dst_name_id:	The sequence number of the name this message is
+ *			addressed to, 0 for messages sent to an ID
+ * @conn:		Connection this entry is queued on
+ * @gaps:		Gaps object to fill message gaps at RECV time
+ * @user:		User used for accounting
+ * @slice:		Slice in the receiver's pool for the message
+ * @reply:		The reply block if a reply to this message is expected
+ */
+struct kdbus_queue_entry {
+	struct list_head entry;
+	struct rb_node prio_node;
+	struct list_head prio_entry;
+
+	s64 priority;
+	u64 dst_name_id;
+
+	struct kdbus_conn *conn;
+	struct kdbus_gaps *gaps;
+	struct kdbus_user *user;
+	struct kdbus_pool_slice *slice;
+	struct kdbus_reply *reply;
+};
+
+void kdbus_queue_init(struct kdbus_queue *queue);
+struct kdbus_queue_entry *kdbus_queue_peek(struct kdbus_queue *queue,
+					   s64 priority, bool use_priority);
+
+struct kdbus_queue_entry *kdbus_queue_entry_new(struct kdbus_conn *src,
+						struct kdbus_conn *dst,
+						struct kdbus_staging *s);
+void kdbus_queue_entry_free(struct kdbus_queue_entry *entry);
+int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
+			      u64 *return_flags, bool install_fds);
+void kdbus_queue_entry_enqueue(struct kdbus_queue_entry *entry,
+			       struct kdbus_reply *reply);
+int kdbus_queue_entry_move(struct kdbus_queue_entry *entry,
+			   struct kdbus_conn *dst);
+
+#endif /* __KDBUS_QUEUE_H */
diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
new file mode 100644
index 000000000000..e6791d86ec92
--- /dev/null
+++ b/ipc/kdbus/reply.c
@@ -0,0 +1,252 @@
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/uio.h>
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "reply.h"
+#include "util.h"
+
+/**
+ * kdbus_reply_new() - Allocate and set up a new kdbus_reply object
+ * @reply_src:		The connection a reply is expected from
+ * @reply_dst:		The connection this reply object belongs to
+ * @msg:		Message associated with the reply
+ * @name_entry:		Name entry used to send the message
+ * @sync:		Whether or not to make this reply synchronous
+ *
+ * Allocate and fill a new kdbus_reply object.
+ *
+ * Return: New kdbus_conn object on success, ERR_PTR on error.
+ */
+struct kdbus_reply *kdbus_reply_new(struct kdbus_conn *reply_src,
+				    struct kdbus_conn *reply_dst,
+				    const struct kdbus_msg *msg,
+				    struct kdbus_name_entry *name_entry,
+				    bool sync)
+{
+	struct kdbus_reply *r;
+	int ret;
+
+	if (atomic_inc_return(&reply_dst->request_count) >
+	    KDBUS_CONN_MAX_REQUESTS_PENDING) {
+		ret = -EMLINK;
+		goto exit_dec_request_count;
+	}
+
+	r = kzalloc(sizeof(*r), GFP_KERNEL);
+	if (!r) {
+		ret = -ENOMEM;
+		goto exit_dec_request_count;
+	}
+
+	kref_init(&r->kref);
+	INIT_LIST_HEAD(&r->entry);
+	r->reply_src = kdbus_conn_ref(reply_src);
+	r->reply_dst = kdbus_conn_ref(reply_dst);
+	r->cookie = msg->cookie;
+	r->name_id = name_entry ? name_entry->name_id : 0;
+	r->deadline_ns = msg->timeout_ns;
+
+	if (sync) {
+		r->sync = true;
+		r->waiting = true;
+	}
+
+	return r;
+
+exit_dec_request_count:
+	atomic_dec(&reply_dst->request_count);
+	return ERR_PTR(ret);
+}
+
+static void __kdbus_reply_free(struct kref *kref)
+{
+	struct kdbus_reply *reply =
+		container_of(kref, struct kdbus_reply, kref);
+
+	atomic_dec(&reply->reply_dst->request_count);
+	kdbus_conn_unref(reply->reply_src);
+	kdbus_conn_unref(reply->reply_dst);
+	kfree(reply);
+}
+
+/**
+ * kdbus_reply_ref() - Increase reference on kdbus_reply
+ * @r:		The reply, may be %NULL
+ *
+ * Return: The reply object with an extra reference
+ */
+struct kdbus_reply *kdbus_reply_ref(struct kdbus_reply *r)
+{
+	if (r)
+		kref_get(&r->kref);
+	return r;
+}
+
+/**
+ * kdbus_reply_unref() - Decrease reference on kdbus_reply
+ * @r:		The reply, may be %NULL
+ *
+ * Return: NULL
+ */
+struct kdbus_reply *kdbus_reply_unref(struct kdbus_reply *r)
+{
+	if (r)
+		kref_put(&r->kref, __kdbus_reply_free);
+	return NULL;
+}
+
+/**
+ * kdbus_reply_link() - Link reply object into target connection
+ * @r:		Reply to link
+ */
+void kdbus_reply_link(struct kdbus_reply *r)
+{
+	if (WARN_ON(!list_empty(&r->entry)))
+		return;
+
+	list_add(&r->entry, &r->reply_dst->reply_list);
+	kdbus_reply_ref(r);
+}
+
+/**
+ * kdbus_reply_unlink() - Unlink reply object from target connection
+ * @r:		Reply to unlink
+ */
+void kdbus_reply_unlink(struct kdbus_reply *r)
+{
+	if (!list_empty(&r->entry)) {
+		list_del_init(&r->entry);
+		kdbus_reply_unref(r);
+	}
+}
+
+/**
+ * kdbus_sync_reply_wakeup() - Wake a synchronously blocking reply
+ * @reply:	The reply object
+ * @err:	Error code to set on the remote side
+ *
+ * Wake up remote peer (method origin) with the appropriate synchronous reply
+ * code.
+ */
+void kdbus_sync_reply_wakeup(struct kdbus_reply *reply, int err)
+{
+	if (WARN_ON(!reply->sync))
+		return;
+
+	reply->waiting = false;
+	reply->err = err;
+	wake_up_interruptible(&reply->reply_dst->wait);
+}
+
+/**
+ * kdbus_reply_find() - Find the corresponding reply object
+ * @replying:	The replying connection or NULL
+ * @reply_dst:	The connection the reply will be sent to
+ *		(method origin)
+ * @cookie:	The cookie of the requesting message
+ *
+ * Lookup a reply object that should be sent as a reply by
+ * @replying to @reply_dst with the given cookie.
+ *
+ * Callers must take the @reply_dst lock.
+ *
+ * Return: the corresponding reply object or NULL if not found
+ */
+struct kdbus_reply *kdbus_reply_find(struct kdbus_conn *replying,
+				     struct kdbus_conn *reply_dst,
+				     u64 cookie)
+{
+	struct kdbus_reply *r;
+
+	list_for_each_entry(r, &reply_dst->reply_list, entry) {
+		if (r->cookie == cookie &&
+		    (!replying || r->reply_src == replying))
+			return r;
+	}
+
+	return NULL;
+}
+
+/**
+ * kdbus_reply_list_scan_work() - Worker callback to scan the replies of a
+ *				  connection for exceeded timeouts
+ * @work:		Work struct of the connection to scan
+ *
+ * Walk the list of replies stored with a connection and look for entries
+ * that have exceeded their timeout. If such an entry is found, a timeout
+ * notification is sent to the waiting peer, and the reply is removed from
+ * the list.
+ *
+ * The work is rescheduled to the nearest timeout found during the list
+ * iteration.
+ */
+void kdbus_reply_list_scan_work(struct work_struct *work)
+{
+	struct kdbus_conn *conn =
+		container_of(work, struct kdbus_conn, work.work);
+	struct kdbus_reply *reply, *reply_tmp;
+	u64 deadline = ~0ULL;
+	u64 now;
+
+	now = ktime_get_ns();
+
+	mutex_lock(&conn->lock);
+	if (!kdbus_conn_active(conn)) {
+		mutex_unlock(&conn->lock);
+		return;
+	}
+
+	list_for_each_entry_safe(reply, reply_tmp, &conn->reply_list, entry) {
+		/*
+		 * If the reply block is waiting for synchronous I/O,
+		 * the timeout is handled by wait_event_*_timeout(),
+		 * so we don't have to care for it here.
+		 */
+		if (reply->sync && !reply->interrupted)
+			continue;
+
+		WARN_ON(reply->reply_dst != conn);
+
+		if (reply->deadline_ns > now) {
+			/* remember next timeout */
+			if (deadline > reply->deadline_ns)
+				deadline = reply->deadline_ns;
+
+			continue;
+		}
+
+		/*
+		 * A zero deadline means the connection died, was
+		 * cleaned up already and the notification was sent.
+		 * Don't send notifications for reply trackers that were
+		 * left in an interrupted syscall state.
+		 */
+		if (reply->deadline_ns != 0 && !reply->interrupted)
+			kdbus_notify_reply_timeout(conn->ep->bus, conn->id,
+						   reply->cookie);
+
+		kdbus_reply_unlink(reply);
+	}
+
+	/* rearm delayed work with next timeout */
+	if (deadline != ~0ULL)
+		schedule_delayed_work(&conn->work,
+				      nsecs_to_jiffies(deadline - now));
+
+	mutex_unlock(&conn->lock);
+
+	kdbus_notify_flush(conn->ep->bus);
+}
diff --git a/ipc/kdbus/reply.h b/ipc/kdbus/reply.h
new file mode 100644
index 000000000000..68d52321a917
--- /dev/null
+++ b/ipc/kdbus/reply.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_REPLY_H
+#define __KDBUS_REPLY_H
+
+/**
+ * struct kdbus_reply - an entry of kdbus_conn's list of replies
+ * @kref:		Ref-count of this object
+ * @entry:		The entry of the connection's reply_list
+ * @reply_src:		The connection the reply will be sent from
+ * @reply_dst:		The connection the reply will be sent to
+ * @queue_entry:	The queue entry item that is prepared by the replying
+ *			connection
+ * @deadline_ns:	The deadline of the reply, in nanoseconds
+ * @cookie:		The cookie of the requesting message
+ * @name_id:		ID of the well-known name the original msg was sent to
+ * @sync:		The reply block is waiting for synchronous I/O
+ * @waiting:		The condition to synchronously wait for
+ * @interrupted:	The sync reply was left in an interrupted state
+ * @err:		The error code for the synchronous reply
+ */
+struct kdbus_reply {
+	struct kref kref;
+	struct list_head entry;
+	struct kdbus_conn *reply_src;
+	struct kdbus_conn *reply_dst;
+	struct kdbus_queue_entry *queue_entry;
+	u64 deadline_ns;
+	u64 cookie;
+	u64 name_id;
+	bool sync:1;
+	bool waiting:1;
+	bool interrupted:1;
+	int err;
+};
+
+struct kdbus_reply *kdbus_reply_new(struct kdbus_conn *reply_src,
+				    struct kdbus_conn *reply_dst,
+				    const struct kdbus_msg *msg,
+				    struct kdbus_name_entry *name_entry,
+				    bool sync);
+
+struct kdbus_reply *kdbus_reply_ref(struct kdbus_reply *r);
+struct kdbus_reply *kdbus_reply_unref(struct kdbus_reply *r);
+
+void kdbus_reply_link(struct kdbus_reply *r);
+void kdbus_reply_unlink(struct kdbus_reply *r);
+
+struct kdbus_reply *kdbus_reply_find(struct kdbus_conn *replying,
+				     struct kdbus_conn *reply_dst,
+				     u64 cookie);
+
+void kdbus_sync_reply_wakeup(struct kdbus_reply *reply, int err);
+void kdbus_reply_list_scan_work(struct work_struct *work);
+
+#endif /* __KDBUS_REPLY_H */
diff --git a/ipc/kdbus/util.c b/ipc/kdbus/util.c
new file mode 100644
index 000000000000..72b188330896
--- /dev/null
+++ b/ipc/kdbus/util.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/capability.h>
+#include <linux/cred.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/uio.h>
+#include <linux/user_namespace.h>
+
+#include "limits.h"
+#include "util.h"
+
+/**
+ * kdbus_copy_from_user() - copy aligned data from user-space
+ * @dest:	target buffer in kernel memory
+ * @user_ptr:	user-provided source buffer
+ * @size:	memory size to copy from user
+ *
+ * This copies @size bytes from @user_ptr into the kernel, just like
+ * copy_from_user() does. But we enforce an 8-byte alignment and reject any
+ * unaligned user-space pointers.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kdbus_copy_from_user(void *dest, void __user *user_ptr, size_t size)
+{
+	if (!KDBUS_IS_ALIGNED8((uintptr_t)user_ptr))
+		return -EFAULT;
+
+	if (copy_from_user(dest, user_ptr, size))
+		return -EFAULT;
+
+	return 0;
+}
+
+/**
+ * kdbus_verify_uid_prefix() - verify UID prefix of a user-supplied name
+ * @name:	user-supplied name to verify
+ * @user_ns:	user-namespace to act in
+ * @kuid:	Kernel internal uid of user
+ *
+ * This verifies that the user-supplied name @name has their UID as prefix. This
+ * is the default name-spacing policy we enforce on user-supplied names for
+ * public kdbus entities like buses and endpoints.
+ *
+ * The user must supply names prefixed with "<UID>-", whereas the UID is
+ * interpreted in the user-namespace of the domain. If the user fails to supply
+ * such a prefixed name, we reject it.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int kdbus_verify_uid_prefix(const char *name, struct user_namespace *user_ns,
+			    kuid_t kuid)
+{
+	uid_t uid;
+	char prefix[16];
+
+	/*
+	 * The kuid must have a mapping into the userns of the domain
+	 * otherwise do not allow creation of buses nor endpoints.
+	 */
+	uid = from_kuid(user_ns, kuid);
+	if (uid == (uid_t) -1)
+		return -EINVAL;
+
+	snprintf(prefix, sizeof(prefix), "%u-", uid);
+	if (strncmp(name, prefix, strlen(prefix)) != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * kdbus_sanitize_attach_flags() - Sanitize attach flags from user-space
+ * @flags:		Attach flags provided by userspace
+ * @attach_flags:	A pointer where to store the valid attach flags
+ *
+ * Convert attach-flags provided by user-space into a valid mask. If the mask
+ * is invalid, an error is returned. The sanitized attach flags are stored in
+ * the output parameter.
+ *
+ * Return: 0 on success, negative error on failure.
+ */
+int kdbus_sanitize_attach_flags(u64 flags, u64 *attach_flags)
+{
+	/* 'any' degrades to 'all' for compatibility */
+	if (flags == _KDBUS_ATTACH_ANY)
+		flags = _KDBUS_ATTACH_ALL;
+
+	/* reject unknown attach flags */
+	if (flags & ~_KDBUS_ATTACH_ALL)
+		return -EINVAL;
+
+	*attach_flags = flags;
+	return 0;
+}
+
+/**
+ * kdbus_kvec_set - helper utility to assemble kvec arrays
+ * @kvec:	kvec entry to use
+ * @src:	Source address to set in @kvec
+ * @len:	Number of bytes in @src
+ * @total_len:	Pointer to total length variable
+ *
+ * Set @src and @len in @kvec, and increase @total_len by @len.
+ */
+void kdbus_kvec_set(struct kvec *kvec, void *src, size_t len, u64 *total_len)
+{
+	kvec->iov_base = src;
+	kvec->iov_len = len;
+	*total_len += len;
+}
+
+static const char * const zeros = "\0\0\0\0\0\0\0";
+
+/**
+ * kdbus_kvec_pad - conditionally write a padding kvec
+ * @kvec:	kvec entry to use
+ * @len:	Total length used for kvec array
+ *
+ * Check if the current total byte length of the array in @len is aligned to
+ * 8 bytes. If it isn't, fill @kvec with padding information and increase @len
+ * by the number of bytes stored in @kvec.
+ *
+ * Return: the number of added padding bytes.
+ */
+size_t kdbus_kvec_pad(struct kvec *kvec, u64 *len)
+{
+	size_t pad = KDBUS_ALIGN8(*len) - *len;
+
+	if (!pad)
+		return 0;
+
+	kvec->iov_base = (void *)zeros;
+	kvec->iov_len = pad;
+
+	*len += pad;
+
+	return pad;
+}
diff --git a/ipc/kdbus/util.h b/ipc/kdbus/util.h
new file mode 100644
index 000000000000..529716669fe7
--- /dev/null
+++ b/ipc/kdbus/util.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __KDBUS_UTIL_H
+#define __KDBUS_UTIL_H
+
+#include <linux/dcache.h>
+#include <linux/ioctl.h>
+
+#include <uapi/linux/kdbus.h>
+
+/* all exported addresses are 64 bit */
+#define KDBUS_PTR(addr) ((void __user *)(uintptr_t)(addr))
+
+/* all exported sizes are 64 bit and data aligned to 64 bit */
+#define KDBUS_ALIGN8(s) ALIGN((s), 8)
+#define KDBUS_IS_ALIGNED8(s) (IS_ALIGNED(s, 8))
+
+/**
+ * kdbus_member_set_user - write a structure member to user memory
+ * @_s:		Variable to copy from
+ * @_b:		Buffer to write to
+ * @_t:		Structure type
+ * @_m:		Member name in the passed structure
+ *
+ * Return: the result of copy_to_user()
+ */
+#define kdbus_member_set_user(_s, _b, _t, _m)				\
+({									\
+	u64 __user *_sz =						\
+		(void __user *)((u8 __user *)(_b) + offsetof(_t, _m));	\
+	copy_to_user(_sz, _s, FIELD_SIZEOF(_t, _m));			\
+})
+
+/**
+ * kdbus_strhash - calculate a hash
+ * @str:	String
+ *
+ * Return: hash value
+ */
+static inline unsigned int kdbus_strhash(const char *str)
+{
+	unsigned long hash = init_name_hash();
+
+	while (*str)
+		hash = partial_name_hash(*str++, hash);
+
+	return end_name_hash(hash);
+}
+
+int kdbus_verify_uid_prefix(const char *name, struct user_namespace *user_ns,
+			    kuid_t kuid);
+int kdbus_sanitize_attach_flags(u64 flags, u64 *attach_flags);
+
+int kdbus_copy_from_user(void *dest, void __user *user_ptr, size_t size);
+
+struct kvec;
+
+void kdbus_kvec_set(struct kvec *kvec, void *src, size_t len, u64 *total_len);
+size_t kdbus_kvec_pad(struct kvec *kvec, u64 *len);
+
+#endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 82cf9dff4295..050c63472f03 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -304,8 +304,8 @@ static inline void check_for_tasks(int dead_cpu)
 {
 	struct task_struct *g, *p;
 
-	read_lock_irq(&tasklist_lock);
-	do_each_thread(g, p) {
+	read_lock(&tasklist_lock);
+	for_each_process_thread(g, p) {
 		if (!p->on_rq)
 			continue;
 		/*
@@ -320,8 +320,8 @@ static inline void check_for_tasks(int dead_cpu)
 
 		pr_warn("Task %s (pid=%d) is on cpu %d (state=%ld, flags=%x)\n",
 			p->comm, task_pid_nr(p), dead_cpu, p->state, p->flags);
-	} while_each_thread(g, p);
-	read_unlock_irq(&tasklist_lock);
+	}
+	read_unlock(&tasklist_lock);
 }
 
 struct take_cpu_down_param {
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index f0acff0f66c9..e414ae9c6b66 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -51,6 +51,7 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/time.h>
+#include <linux/time64.h>
 #include <linux/backing-dev.h>
 #include <linux/sort.h>
 
@@ -68,7 +69,7 @@ struct static_key cpusets_enabled_key __read_mostly = STATIC_KEY_INIT_FALSE;
 struct fmeter {
 	int cnt;		/* unprocessed events count */
 	int val;		/* most recent output value */
-	time_t time;		/* clock (secs) when val computed */
+	time64_t time;		/* clock (secs) when val computed */
 	spinlock_t lock;	/* guards read or write of above */
 };
 
@@ -1371,7 +1372,7 @@ out:
  */
 
 #define FM_COEF 933		/* coefficient for half-life of 10 secs */
-#define FM_MAXTICKS ((time_t)99) /* useless computing more ticks than this */
+#define FM_MAXTICKS ((u32)99)   /* useless computing more ticks than this */
 #define FM_MAXCNT 1000000	/* limit cnt to avoid overflow */
 #define FM_SCALE 1000		/* faux fixed point scale */
 
@@ -1387,8 +1388,11 @@ static void fmeter_init(struct fmeter *fmp)
 /* Internal meter update - process cnt events and update value */
 static void fmeter_update(struct fmeter *fmp)
 {
-	time_t now = get_seconds();
-	time_t ticks = now - fmp->time;
+	time64_t now;
+	u32 ticks;
+
+	now = ktime_get_seconds();
+	ticks = now - fmp->time;
 
 	if (ticks == 0)
 		return;
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index fc1ef736253c..77777d918676 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -349,7 +349,7 @@ poll_again:
 			}
 			kdb_printf("\n");
 			for (i = 0; i < count; i++) {
-				if (kallsyms_symbol_next(p_tmp, i) < 0)
+				if (WARN_ON(!kallsyms_symbol_next(p_tmp, i)))
 					break;
 				kdb_printf("%s ", p_tmp);
 				*(p_tmp + len) = '\0';
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f548f69c4299..55b0f7cf2614 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1914,7 +1914,7 @@ group_sched_in(struct perf_event *group_event,
 	if (group_event->state == PERF_EVENT_STATE_OFF)
 		return 0;
 
-	pmu->start_txn(pmu);
+	pmu->start_txn(pmu, PERF_PMU_TXN_ADD);
 
 	if (event_sched_in(group_event, cpuctx, ctx)) {
 		pmu->cancel_txn(pmu);
@@ -3184,14 +3184,22 @@ void perf_event_exec(void)
 	rcu_read_unlock();
 }
 
+struct perf_read_data {
+	struct perf_event *event;
+	bool group;
+	int ret;
+};
+
 /*
  * Cross CPU call to read the hardware event
  */
 static void __perf_event_read(void *info)
 {
-	struct perf_event *event = info;
+	struct perf_read_data *data = info;
+	struct perf_event *sub, *event = data->event;
 	struct perf_event_context *ctx = event->ctx;
 	struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
+	struct pmu *pmu = event->pmu;
 
 	/*
 	 * If this is a task context, we need to check whether it is
@@ -3208,9 +3216,35 @@ static void __perf_event_read(void *info)
 		update_context_time(ctx);
 		update_cgrp_time_from_event(event);
 	}
+
 	update_event_times(event);
-	if (event->state == PERF_EVENT_STATE_ACTIVE)
-		event->pmu->read(event);
+	if (event->state != PERF_EVENT_STATE_ACTIVE)
+		goto unlock;
+
+	if (!data->group) {
+		pmu->read(event);
+		data->ret = 0;
+		goto unlock;
+	}
+
+	pmu->start_txn(pmu, PERF_PMU_TXN_READ);
+
+	pmu->read(event);
+
+	list_for_each_entry(sub, &event->sibling_list, group_entry) {
+		update_event_times(sub);
+		if (sub->state == PERF_EVENT_STATE_ACTIVE) {
+			/*
+			 * Use sibling's PMU rather than @event's since
+			 * sibling could be on different (eg: software) PMU.
+			 */
+			sub->pmu->read(sub);
+		}
+	}
+
+	data->ret = pmu->commit_txn(pmu);
+
+unlock:
 	raw_spin_unlock(&ctx->lock);
 }
 
@@ -3275,15 +3309,23 @@ u64 perf_event_read_local(struct perf_event *event)
 	return val;
 }
 
-static u64 perf_event_read(struct perf_event *event)
+static int perf_event_read(struct perf_event *event, bool group)
 {
+	int ret = 0;
+
 	/*
 	 * If event is enabled and currently active on a CPU, update the
 	 * value in the event structure:
 	 */
 	if (event->state == PERF_EVENT_STATE_ACTIVE) {
+		struct perf_read_data data = {
+			.event = event,
+			.group = group,
+			.ret = 0,
+		};
 		smp_call_function_single(event->oncpu,
-					 __perf_event_read, event, 1);
+					 __perf_event_read, &data, 1);
+		ret = data.ret;
 	} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
 		struct perf_event_context *ctx = event->ctx;
 		unsigned long flags;
@@ -3298,11 +3340,14 @@ static u64 perf_event_read(struct perf_event *event)
 			update_context_time(ctx);
 			update_cgrp_time_from_event(event);
 		}
-		update_event_times(event);
+		if (group)
+			update_group_times(event);
+		else
+			update_event_times(event);
 		raw_spin_unlock_irqrestore(&ctx->lock, flags);
 	}
 
-	return perf_event_count(event);
+	return ret;
 }
 
 /*
@@ -3744,7 +3789,7 @@ static void put_event(struct perf_event *event)
 	 *     see the comment there.
 	 *
 	 *  2) there is a lock-inversion with mmap_sem through
-	 *     perf_event_read_group(), which takes faults while
+	 *     perf_read_group(), which takes faults while
 	 *     holding ctx->mutex, however this is called after
 	 *     the last filedesc died, so there is no possibility
 	 *     to trigger the AB-BA case.
@@ -3818,14 +3863,18 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
 	*running = 0;
 
 	mutex_lock(&event->child_mutex);
-	total += perf_event_read(event);
+
+	(void)perf_event_read(event, false);
+	total += perf_event_count(event);
+
 	*enabled += event->total_time_enabled +
 			atomic64_read(&event->child_total_time_enabled);
 	*running += event->total_time_running +
 			atomic64_read(&event->child_total_time_running);
 
 	list_for_each_entry(child, &event->child_list, child_list) {
-		total += perf_event_read(child);
+		(void)perf_event_read(child, false);
+		total += perf_event_count(child);
 		*enabled += child->total_time_enabled;
 		*running += child->total_time_running;
 	}
@@ -3835,55 +3884,95 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
 }
 EXPORT_SYMBOL_GPL(perf_event_read_value);
 
-static int perf_event_read_group(struct perf_event *event,
-				   u64 read_format, char __user *buf)
+static int __perf_read_group_add(struct perf_event *leader,
+					u64 read_format, u64 *values)
 {
-	struct perf_event *leader = event->group_leader, *sub;
-	struct perf_event_context *ctx = leader->ctx;
-	int n = 0, size = 0, ret;
-	u64 count, enabled, running;
-	u64 values[5];
+	struct perf_event *sub;
+	int n = 1; /* skip @nr */
+	int ret;
 
-	lockdep_assert_held(&ctx->mutex);
+	ret = perf_event_read(leader, true);
+	if (ret)
+		return ret;
 
-	count = perf_event_read_value(leader, &enabled, &running);
+	/*
+	 * Since we co-schedule groups, {enabled,running} times of siblings
+	 * will be identical to those of the leader, so we only publish one
+	 * set.
+	 */
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+		values[n++] += leader->total_time_enabled +
+			atomic64_read(&leader->child_total_time_enabled);
+	}
 
-	values[n++] = 1 + leader->nr_siblings;
-	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
-		values[n++] = enabled;
-	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
-		values[n++] = running;
-	values[n++] = count;
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+		values[n++] += leader->total_time_running +
+			atomic64_read(&leader->child_total_time_running);
+	}
+
+	/*
+	 * Write {count,id} tuples for every sibling.
+	 */
+	values[n++] += perf_event_count(leader);
 	if (read_format & PERF_FORMAT_ID)
 		values[n++] = primary_event_id(leader);
 
-	size = n * sizeof(u64);
+	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+		values[n++] += perf_event_count(sub);
+		if (read_format & PERF_FORMAT_ID)
+			values[n++] = primary_event_id(sub);
+	}
 
-	if (copy_to_user(buf, values, size))
-		return -EFAULT;
+	return 0;
+}
+
+static int perf_read_group(struct perf_event *event,
+				   u64 read_format, char __user *buf)
+{
+	struct perf_event *leader = event->group_leader, *child;
+	struct perf_event_context *ctx = leader->ctx;
+	int ret;
+	u64 *values;
 
-	ret = size;
+	lockdep_assert_held(&ctx->mutex);
 
-	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
-		n = 0;
+	values = kzalloc(event->read_size, GFP_KERNEL);
+	if (!values)
+		return -ENOMEM;
 
-		values[n++] = perf_event_read_value(sub, &enabled, &running);
-		if (read_format & PERF_FORMAT_ID)
-			values[n++] = primary_event_id(sub);
+	values[0] = 1 + leader->nr_siblings;
 
-		size = n * sizeof(u64);
+	/*
+	 * By locking the child_mutex of the leader we effectively
+	 * lock the child list of all siblings.. XXX explain how.
+	 */
+	mutex_lock(&leader->child_mutex);
 
-		if (copy_to_user(buf + ret, values, size)) {
-			return -EFAULT;
-		}
+	ret = __perf_read_group_add(leader, read_format, values);
+	if (ret)
+		goto unlock;
 
-		ret += size;
+	list_for_each_entry(child, &leader->child_list, child_list) {
+		ret = __perf_read_group_add(child, read_format, values);
+		if (ret)
+			goto unlock;
 	}
 
+	mutex_unlock(&leader->child_mutex);
+
+	ret = event->read_size;
+	if (copy_to_user(buf, values, event->read_size))
+		ret = -EFAULT;
+	goto out;
+
+unlock:
+	mutex_unlock(&leader->child_mutex);
+out:
+	kfree(values);
 	return ret;
 }
 
-static int perf_event_read_one(struct perf_event *event,
+static int perf_read_one(struct perf_event *event,
 				 u64 read_format, char __user *buf)
 {
 	u64 enabled, running;
@@ -3921,7 +4010,7 @@ static bool is_event_hup(struct perf_event *event)
  * Read the performance event - simple non blocking version for now
  */
 static ssize_t
-perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
+__perf_read(struct perf_event *event, char __user *buf, size_t count)
 {
 	u64 read_format = event->attr.read_format;
 	int ret;
@@ -3939,9 +4028,9 @@ perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
 
 	WARN_ON_ONCE(event->ctx->parent_ctx);
 	if (read_format & PERF_FORMAT_GROUP)
-		ret = perf_event_read_group(event, read_format, buf);
+		ret = perf_read_group(event, read_format, buf);
 	else
-		ret = perf_event_read_one(event, read_format, buf);
+		ret = perf_read_one(event, read_format, buf);
 
 	return ret;
 }
@@ -3954,7 +4043,7 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 	int ret;
 
 	ctx = perf_event_ctx_lock(event);
-	ret = perf_read_hw(event, buf, count);
+	ret = __perf_read(event, buf, count);
 	perf_event_ctx_unlock(event, ctx);
 
 	return ret;
@@ -3985,7 +4074,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
 
 static void _perf_event_reset(struct perf_event *event)
 {
-	(void)perf_event_read(event);
+	(void)perf_event_read(event, false);
 	local64_set(&event->count, 0);
 	perf_event_update_userpage(event);
 }
@@ -7267,24 +7356,49 @@ static void perf_pmu_nop_void(struct pmu *pmu)
 {
 }
 
+static void perf_pmu_nop_txn(struct pmu *pmu, unsigned int flags)
+{
+}
+
 static int perf_pmu_nop_int(struct pmu *pmu)
 {
 	return 0;
 }
 
-static void perf_pmu_start_txn(struct pmu *pmu)
+DEFINE_PER_CPU(unsigned int, nop_txn_flags);
+
+static void perf_pmu_start_txn(struct pmu *pmu, unsigned int flags)
 {
+	__this_cpu_write(nop_txn_flags, flags);
+
+	if (flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_disable(pmu);
 }
 
 static int perf_pmu_commit_txn(struct pmu *pmu)
 {
+	unsigned int flags = __this_cpu_read(nop_txn_flags);
+
+	__this_cpu_write(nop_txn_flags, 0);
+
+	if (flags & ~PERF_PMU_TXN_ADD)
+		return 0;
+
 	perf_pmu_enable(pmu);
 	return 0;
 }
 
 static void perf_pmu_cancel_txn(struct pmu *pmu)
 {
+	unsigned int flags =  __this_cpu_read(nop_txn_flags);
+
+	__this_cpu_write(nop_txn_flags, 0);
+
+	if (flags & ~PERF_PMU_TXN_ADD)
+		return;
+
 	perf_pmu_enable(pmu);
 }
 
@@ -7523,7 +7637,7 @@ got_cpu_context:
 			pmu->commit_txn = perf_pmu_commit_txn;
 			pmu->cancel_txn = perf_pmu_cancel_txn;
 		} else {
-			pmu->start_txn  = perf_pmu_nop_void;
+			pmu->start_txn  = perf_pmu_nop_txn;
 			pmu->commit_txn = perf_pmu_nop_int;
 			pmu->cancel_txn = perf_pmu_nop_void;
 		}
@@ -9297,14 +9411,6 @@ static void perf_cgroup_exit(struct cgroup_subsys_state *css,
 			     struct cgroup_subsys_state *old_css,
 			     struct task_struct *task)
 {
-	/*
-	 * cgroup_exit() is called in the copy_process() failure path.
-	 * Ignore this case since the task hasn't ran yet, this avoids
-	 * trying to poke a half freed task state from generic code.
-	 */
-	if (!(task->flags & PF_EXITING))
-		return;
-
 	task_function_call(task, __perf_cgroup_move, task);
 }
 
diff --git a/kernel/gcov/Kconfig b/kernel/gcov/Kconfig
index c92e44855ddd..6ca0b99e5f0a 100644
--- a/kernel/gcov/Kconfig
+++ b/kernel/gcov/Kconfig
@@ -2,7 +2,7 @@ menu "GCOV-based kernel profiling"
 
 config GCOV_KERNEL
 	bool "Enable gcov-based kernel profiling"
-	depends on DEBUG_FS
+	depends on DEBUG_FS && !LTO
 	select CONSTRUCTORS if !UML
 	default n
 	---help---
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
index 337c8818541d..87e9ce6a63c5 100644
--- a/kernel/locking/qspinlock.c
+++ b/kernel/locking/qspinlock.c
@@ -289,7 +289,7 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
 	if (pv_enabled())
 		goto queue;
 
-	if (virt_queued_spin_lock(lock))
+	if (virt_spin_lock(lock))
 		return;
 
 	/*
diff --git a/kernel/module.c b/kernel/module.c
index b86b7bf1be38..8f051a106676 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1063,11 +1063,15 @@ void symbol_put_addr(void *addr)
 	if (core_kernel_text(a))
 		return;
 
-	/* module_text_address is safe here: we're supposed to have reference
-	 * to module from symbol_get, so it can't go away. */
+	/*
+	 * Even though we hold a reference on the module; we still need to
+	 * disable preemption in order to safely traverse the data structure.
+	 */
+	preempt_disable();
 	modaddr = __module_text_address(a);
 	BUG_ON(!modaddr);
 	module_put(modaddr);
+	preempt_enable();
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3595403921bd..6ab415aa15c4 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -621,18 +621,21 @@ int get_nohz_timer_target(void)
 	int i, cpu = smp_processor_id();
 	struct sched_domain *sd;
 
-	if (!idle_cpu(cpu))
+	if (!idle_cpu(cpu) && is_housekeeping_cpu(cpu))
 		return cpu;
 
 	rcu_read_lock();
 	for_each_domain(cpu, sd) {
 		for_each_cpu(i, sched_domain_span(sd)) {
-			if (!idle_cpu(i)) {
+			if (!idle_cpu(i) && is_housekeeping_cpu(cpu)) {
 				cpu = i;
 				goto unlock;
 			}
 		}
 	}
+
+	if (!is_housekeeping_cpu(cpu))
+		cpu = housekeeping_any_cpu();
 unlock:
 	rcu_read_unlock();
 	return cpu;
@@ -2111,23 +2114,17 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
 #endif /* CONFIG_NUMA_BALANCING */
 }
 
+DEFINE_STATIC_KEY_FALSE(sched_numa_balancing);
+
 #ifdef CONFIG_NUMA_BALANCING
-#ifdef CONFIG_SCHED_DEBUG
+
 void set_numabalancing_state(bool enabled)
 {
 	if (enabled)
-		sched_feat_set("NUMA");
+		static_branch_enable(&sched_numa_balancing);
 	else
-		sched_feat_set("NO_NUMA");
-}
-#else
-__read_mostly bool numabalancing_enabled;
-
-void set_numabalancing_state(bool enabled)
-{
-	numabalancing_enabled = enabled;
+		static_branch_disable(&sched_numa_balancing);
 }
-#endif /* CONFIG_SCHED_DEBUG */
 
 #ifdef CONFIG_PROC_SYSCTL
 int sysctl_numa_balancing(struct ctl_table *table, int write,
@@ -2135,7 +2132,7 @@ int sysctl_numa_balancing(struct ctl_table *table, int write,
 {
 	struct ctl_table t;
 	int err;
-	int state = numabalancing_enabled;
+	int state = static_branch_likely(&sched_numa_balancing);
 
 	if (write && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -2346,6 +2343,8 @@ void wake_up_new_task(struct task_struct *p)
 	struct rq *rq;
 
 	raw_spin_lock_irqsave(&p->pi_lock, flags);
+	/* Initialize new task's runnable average */
+	init_entity_runnable_average(&p->se);
 #ifdef CONFIG_SMP
 	/*
 	 * Fork balancing, do it here and not earlier because:
@@ -2355,8 +2354,6 @@ void wake_up_new_task(struct task_struct *p)
 	set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));
 #endif
 
-	/* Initialize new task's runnable average */
-	init_entity_runnable_average(&p->se);
 	rq = __task_rq_lock(p);
 	activate_task(rq, p, 0);
 	p->on_rq = TASK_ON_RQ_QUEUED;
@@ -5178,24 +5175,47 @@ static void migrate_tasks(struct rq *dead_rq)
 			break;
 
 		/*
-		 * Ensure rq->lock covers the entire task selection
-		 * until the migration.
+		 * pick_next_task assumes pinned rq->lock.
 		 */
 		lockdep_pin_lock(&rq->lock);
 		next = pick_next_task(rq, &fake_task);
 		BUG_ON(!next);
 		next->sched_class->put_prev_task(rq, next);
 
+		/*
+		 * Rules for changing task_struct::cpus_allowed are holding
+		 * both pi_lock and rq->lock, such that holding either
+		 * stabilizes the mask.
+		 *
+		 * Drop rq->lock is not quite as disastrous as it usually is
+		 * because !cpu_active at this point, which means load-balance
+		 * will not interfere. Also, stop-machine.
+		 */
+		lockdep_unpin_lock(&rq->lock);
+		raw_spin_unlock(&rq->lock);
+		raw_spin_lock(&next->pi_lock);
+		raw_spin_lock(&rq->lock);
+
+		/*
+		 * Since we're inside stop-machine, _nothing_ should have
+		 * changed the task, WARN if weird stuff happened, because in
+		 * that case the above rq->lock drop is a fail too.
+		 */
+		if (WARN_ON(task_rq(next) != rq || !task_on_rq_queued(next))) {
+			raw_spin_unlock(&next->pi_lock);
+			continue;
+		}
+
 		/* Find suitable destination for @next, with force if needed. */
 		dest_cpu = select_fallback_rq(dead_rq->cpu, next);
 
-		lockdep_unpin_lock(&rq->lock);
 		rq = __migrate_task(rq, next, dest_cpu);
 		if (rq != dead_rq) {
 			raw_spin_unlock(&rq->lock);
 			rq = dead_rq;
 			raw_spin_lock(&rq->lock);
 		}
+		raw_spin_unlock(&next->pi_lock);
 	}
 
 	rq->stop = stop;
@@ -7695,7 +7715,7 @@ void sched_move_task(struct task_struct *tsk)
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	if (tsk->sched_class->task_move_group)
-		tsk->sched_class->task_move_group(tsk, queued);
+		tsk->sched_class->task_move_group(tsk);
 	else
 #endif
 		set_task_rq(tsk, task_cpu(tsk));
@@ -8167,14 +8187,6 @@ static void cpu_cgroup_exit(struct cgroup_subsys_state *css,
 			    struct cgroup_subsys_state *old_css,
 			    struct task_struct *task)
 {
-	/*
-	 * cgroup_exit() is called in the copy_process() failure path.
-	 * Ignore this case since the task hasn't ran yet, this avoids
-	 * trying to poke a half freed task state from generic code.
-	 */
-	if (!(task->flags & PF_EXITING))
-		return;
-
 	sched_move_task(task);
 }
 
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6e2e3483b1ec..9176f7c588a8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -682,7 +682,7 @@ void init_entity_runnable_average(struct sched_entity *se)
 	sa->load_avg = scale_load_down(se->load.weight);
 	sa->load_sum = sa->load_avg * LOAD_AVG_MAX;
 	sa->util_avg = scale_load_down(SCHED_LOAD_SCALE);
-	sa->util_sum = LOAD_AVG_MAX;
+	sa->util_sum = sa->util_avg * LOAD_AVG_MAX;
 	/* when this task enqueue'ed, it will contribute to its cfs_rq's load_avg */
 }
 
@@ -2069,7 +2069,7 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags)
 	int local = !!(flags & TNF_FAULT_LOCAL);
 	int priv;
 
-	if (!numabalancing_enabled)
+	if (!static_branch_likely(&sched_numa_balancing))
 		return;
 
 	/* for example, ksmd faulting in a user's mm */
@@ -2515,6 +2515,12 @@ static u32 __compute_runnable_contrib(u64 n)
 	return contrib + runnable_avg_yN_sum[n];
 }
 
+#if (SCHED_LOAD_SHIFT - SCHED_LOAD_RESOLUTION) != 10 || SCHED_CAPACITY_SHIFT != 10
+#error "load tracking assumes 2^10 as unit"
+#endif
+
+#define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT)
+
 /*
  * We can represent the historical contribution to runnable average as the
  * coefficients of a geometric series.  To do this we sub-divide our runnable
@@ -2547,10 +2553,10 @@ static __always_inline int
 __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
 		  unsigned long weight, int running, struct cfs_rq *cfs_rq)
 {
-	u64 delta, periods;
+	u64 delta, scaled_delta, periods;
 	u32 contrib;
-	int delta_w, decayed = 0;
-	unsigned long scale_freq = arch_scale_freq_capacity(NULL, cpu);
+	unsigned int delta_w, scaled_delta_w, decayed = 0;
+	unsigned long scale_freq, scale_cpu;
 
 	delta = now - sa->last_update_time;
 	/*
@@ -2571,6 +2577,9 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
 		return 0;
 	sa->last_update_time = now;
 
+	scale_freq = arch_scale_freq_capacity(NULL, cpu);
+	scale_cpu = arch_scale_cpu_capacity(NULL, cpu);
+
 	/* delta_w is the amount already accumulated against our next period */
 	delta_w = sa->period_contrib;
 	if (delta + delta_w >= 1024) {
@@ -2585,13 +2594,16 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
 		 * period and accrue it.
 		 */
 		delta_w = 1024 - delta_w;
+		scaled_delta_w = cap_scale(delta_w, scale_freq);
 		if (weight) {
-			sa->load_sum += weight * delta_w;
-			if (cfs_rq)
-				cfs_rq->runnable_load_sum += weight * delta_w;
+			sa->load_sum += weight * scaled_delta_w;
+			if (cfs_rq) {
+				cfs_rq->runnable_load_sum +=
+						weight * scaled_delta_w;
+			}
 		}
 		if (running)
-			sa->util_sum += delta_w * scale_freq >> SCHED_CAPACITY_SHIFT;
+			sa->util_sum += scaled_delta_w * scale_cpu;
 
 		delta -= delta_w;
 
@@ -2608,23 +2620,25 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
 
 		/* Efficiently calculate \sum (1..n_period) 1024*y^i */
 		contrib = __compute_runnable_contrib(periods);
+		contrib = cap_scale(contrib, scale_freq);
 		if (weight) {
 			sa->load_sum += weight * contrib;
 			if (cfs_rq)
 				cfs_rq->runnable_load_sum += weight * contrib;
 		}
 		if (running)
-			sa->util_sum += contrib * scale_freq >> SCHED_CAPACITY_SHIFT;
+			sa->util_sum += contrib * scale_cpu;
 	}
 
 	/* Remainder of delta accrued against u_0` */
+	scaled_delta = cap_scale(delta, scale_freq);
 	if (weight) {
-		sa->load_sum += weight * delta;
+		sa->load_sum += weight * scaled_delta;
 		if (cfs_rq)
-			cfs_rq->runnable_load_sum += weight * delta;
+			cfs_rq->runnable_load_sum += weight * scaled_delta;
 	}
 	if (running)
-		sa->util_sum += delta * scale_freq >> SCHED_CAPACITY_SHIFT;
+		sa->util_sum += scaled_delta * scale_cpu;
 
 	sa->period_contrib += delta;
 
@@ -2634,7 +2648,7 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
 			cfs_rq->runnable_load_avg =
 				div_u64(cfs_rq->runnable_load_sum, LOAD_AVG_MAX);
 		}
-		sa->util_avg = (sa->util_sum << SCHED_LOAD_SHIFT) / LOAD_AVG_MAX;
+		sa->util_avg = sa->util_sum / LOAD_AVG_MAX;
 	}
 
 	return decayed;
@@ -2664,8 +2678,8 @@ static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
 /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
 static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 {
-	int decayed;
 	struct sched_avg *sa = &cfs_rq->avg;
+	int decayed;
 
 	if (atomic_long_read(&cfs_rq->removed_load_avg)) {
 		long r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
@@ -2676,8 +2690,7 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 	if (atomic_long_read(&cfs_rq->removed_util_avg)) {
 		long r = atomic_long_xchg(&cfs_rq->removed_util_avg, 0);
 		sa->util_avg = max_t(long, sa->util_avg - r, 0);
-		sa->util_sum = max_t(s32, sa->util_sum -
-			((r * LOAD_AVG_MAX) >> SCHED_LOAD_SHIFT), 0);
+		sa->util_sum = max_t(s32, sa->util_sum - r * LOAD_AVG_MAX, 0);
 	}
 
 	decayed = __update_load_avg(now, cpu_of(rq_of(cfs_rq)), sa,
@@ -2695,33 +2708,70 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 static inline void update_load_avg(struct sched_entity *se, int update_tg)
 {
 	struct cfs_rq *cfs_rq = cfs_rq_of(se);
-	int cpu = cpu_of(rq_of(cfs_rq));
 	u64 now = cfs_rq_clock_task(cfs_rq);
+	int cpu = cpu_of(rq_of(cfs_rq));
 
 	/*
 	 * Track task load average for carrying it to new CPU after migrated, and
 	 * track group sched_entity load average for task_h_load calc in migration
 	 */
 	__update_load_avg(now, cpu, &se->avg,
-		se->on_rq * scale_load_down(se->load.weight), cfs_rq->curr == se, NULL);
+			  se->on_rq * scale_load_down(se->load.weight),
+			  cfs_rq->curr == se, NULL);
 
 	if (update_cfs_rq_load_avg(now, cfs_rq) && update_tg)
 		update_tg_load_avg(cfs_rq, 0);
 }
 
+static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+	if (!sched_feat(ATTACH_AGE_LOAD))
+		goto skip_aging;
+
+	/*
+	 * If we got migrated (either between CPUs or between cgroups) we'll
+	 * have aged the average right before clearing @last_update_time.
+	 */
+	if (se->avg.last_update_time) {
+		__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)),
+				  &se->avg, 0, 0, NULL);
+
+		/*
+		 * XXX: we could have just aged the entire load away if we've been
+		 * absent from the fair class for too long.
+		 */
+	}
+
+skip_aging:
+	se->avg.last_update_time = cfs_rq->avg.last_update_time;
+	cfs_rq->avg.load_avg += se->avg.load_avg;
+	cfs_rq->avg.load_sum += se->avg.load_sum;
+	cfs_rq->avg.util_avg += se->avg.util_avg;
+	cfs_rq->avg.util_sum += se->avg.util_sum;
+}
+
+static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+	__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)),
+			  &se->avg, se->on_rq * scale_load_down(se->load.weight),
+			  cfs_rq->curr == se, NULL);
+
+	cfs_rq->avg.load_avg = max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
+	cfs_rq->avg.load_sum = max_t(s64,  cfs_rq->avg.load_sum - se->avg.load_sum, 0);
+	cfs_rq->avg.util_avg = max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
+	cfs_rq->avg.util_sum = max_t(s32,  cfs_rq->avg.util_sum - se->avg.util_sum, 0);
+}
+
 /* Add the load generated by se into cfs_rq's load average */
 static inline void
 enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
 	struct sched_avg *sa = &se->avg;
 	u64 now = cfs_rq_clock_task(cfs_rq);
-	int migrated = 0, decayed;
+	int migrated, decayed;
 
-	if (sa->last_update_time == 0) {
-		sa->last_update_time = now;
-		migrated = 1;
-	}
-	else {
+	migrated = !sa->last_update_time;
+	if (!migrated) {
 		__update_load_avg(now, cpu_of(rq_of(cfs_rq)), sa,
 			se->on_rq * scale_load_down(se->load.weight),
 			cfs_rq->curr == se, NULL);
@@ -2732,12 +2782,8 @@ enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 	cfs_rq->runnable_load_avg += sa->load_avg;
 	cfs_rq->runnable_load_sum += sa->load_sum;
 
-	if (migrated) {
-		cfs_rq->avg.load_avg += sa->load_avg;
-		cfs_rq->avg.load_sum += sa->load_sum;
-		cfs_rq->avg.util_avg += sa->util_avg;
-		cfs_rq->avg.util_sum += sa->util_sum;
-	}
+	if (migrated)
+		attach_entity_load_avg(cfs_rq, se);
 
 	if (decayed || migrated)
 		update_tg_load_avg(cfs_rq, 0);
@@ -2752,7 +2798,7 @@ dequeue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 	cfs_rq->runnable_load_avg =
 		max_t(long, cfs_rq->runnable_load_avg - se->avg.load_avg, 0);
 	cfs_rq->runnable_load_sum =
-		max_t(s64, cfs_rq->runnable_load_sum - se->avg.load_sum, 0);
+		max_t(s64,  cfs_rq->runnable_load_sum - se->avg.load_sum, 0);
 }
 
 /*
@@ -2820,6 +2866,11 @@ static inline void
 dequeue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
 static inline void remove_entity_load_avg(struct sched_entity *se) {}
 
+static inline void
+attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
+static inline void
+detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
+
 static inline int idle_balance(struct rq *rq)
 {
 	return 0;
@@ -4816,32 +4867,39 @@ next:
 done:
 	return target;
 }
+
 /*
- * get_cpu_usage returns the amount of capacity of a CPU that is used by CFS
+ * cpu_util returns the amount of capacity of a CPU that is used by CFS
  * tasks. The unit of the return value must be the one of capacity so we can
- * compare the usage with the capacity of the CPU that is available for CFS
- * task (ie cpu_capacity).
- * cfs.avg.util_avg is the sum of running time of runnable tasks on a
- * CPU. It represents the amount of utilization of a CPU in the range
- * [0..SCHED_LOAD_SCALE].  The usage of a CPU can't be higher than the full
- * capacity of the CPU because it's about the running time on this CPU.
- * Nevertheless, cfs.avg.util_avg can be higher than SCHED_LOAD_SCALE
- * because of unfortunate rounding in util_avg or just
- * after migrating tasks until the average stabilizes with the new running
- * time. So we need to check that the usage stays into the range
- * [0..cpu_capacity_orig] and cap if necessary.
- * Without capping the usage, a group could be seen as overloaded (CPU0 usage
- * at 121% + CPU1 usage at 80%) whereas CPU1 has 20% of available capacity
+ * compare the utilization with the capacity of the CPU that is available for
+ * CFS task (ie cpu_capacity).
+ *
+ * cfs_rq.avg.util_avg is the sum of running time of runnable tasks plus the
+ * recent utilization of currently non-runnable tasks on a CPU. It represents
+ * the amount of utilization of a CPU in the range [0..capacity_orig] where
+ * capacity_orig is the cpu_capacity available at the highest frequency
+ * (arch_scale_freq_capacity()).
+ * The utilization of a CPU converges towards a sum equal to or less than the
+ * current capacity (capacity_curr <= capacity_orig) of the CPU because it is
+ * the running time on this CPU scaled by capacity_curr.
+ *
+ * Nevertheless, cfs_rq.avg.util_avg can be higher than capacity_curr or even
+ * higher than capacity_orig because of unfortunate rounding in
+ * cfs.avg.util_avg or just after migrating tasks and new task wakeups until
+ * the average stabilizes with the new running time. We need to check that the
+ * utilization stays within the range of [0..capacity_orig] and cap it if
+ * necessary. Without utilization capping, a group could be seen as overloaded
+ * (CPU0 utilization at 121% + CPU1 utilization at 80%) whereas CPU1 has 20% of
+ * available capacity. We allow utilization to overshoot capacity_curr (but not
+ * capacity_orig) as it useful for predicting the capacity required after task
+ * migrations (scheduler-driven DVFS).
  */
-static int get_cpu_usage(int cpu)
+static int cpu_util(int cpu)
 {
-	unsigned long usage = cpu_rq(cpu)->cfs.avg.util_avg;
+	unsigned long util = cpu_rq(cpu)->cfs.avg.util_avg;
 	unsigned long capacity = capacity_orig_of(cpu);
 
-	if (usage >= SCHED_LOAD_SCALE)
-		return capacity;
-
-	return (usage * capacity) >> SCHED_LOAD_SHIFT;
+	return (util >= capacity) ? capacity : util;
 }
 
 /*
@@ -5524,10 +5582,10 @@ static int migrate_degrades_locality(struct task_struct *p, struct lb_env *env)
 	unsigned long src_faults, dst_faults;
 	int src_nid, dst_nid;
 
-	if (!p->numa_faults || !(env->sd->flags & SD_NUMA))
+	if (!static_branch_likely(&sched_numa_balancing))
 		return -1;
 
-	if (!sched_feat(NUMA))
+	if (!p->numa_faults || !(env->sd->flags & SD_NUMA))
 		return -1;
 
 	src_nid = cpu_to_node(env->src_cpu);
@@ -5933,7 +5991,7 @@ struct sg_lb_stats {
 	unsigned long sum_weighted_load; /* Weighted load of group's tasks */
 	unsigned long load_per_task;
 	unsigned long group_capacity;
-	unsigned long group_usage; /* Total usage of the group */
+	unsigned long group_util; /* Total utilization of the group */
 	unsigned int sum_nr_running; /* Nr tasks running in the group */
 	unsigned int idle_cpus;
 	unsigned int group_weight;
@@ -6009,19 +6067,6 @@ static inline int get_sd_load_idx(struct sched_domain *sd,
 	return load_idx;
 }
 
-static unsigned long default_scale_cpu_capacity(struct sched_domain *sd, int cpu)
-{
-	if ((sd->flags & SD_SHARE_CPUCAPACITY) && (sd->span_weight > 1))
-		return sd->smt_gain / sd->span_weight;
-
-	return SCHED_CAPACITY_SCALE;
-}
-
-unsigned long __weak arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
-{
-	return default_scale_cpu_capacity(sd, cpu);
-}
-
 static unsigned long scale_rt_capacity(int cpu)
 {
 	struct rq *rq = cpu_rq(cpu);
@@ -6051,16 +6096,9 @@ static unsigned long scale_rt_capacity(int cpu)
 
 static void update_cpu_capacity(struct sched_domain *sd, int cpu)
 {
-	unsigned long capacity = SCHED_CAPACITY_SCALE;
+	unsigned long capacity = arch_scale_cpu_capacity(sd, cpu);
 	struct sched_group *sdg = sd->groups;
 
-	if (sched_feat(ARCH_CAPACITY))
-		capacity *= arch_scale_cpu_capacity(sd, cpu);
-	else
-		capacity *= default_scale_cpu_capacity(sd, cpu);
-
-	capacity >>= SCHED_CAPACITY_SHIFT;
-
 	cpu_rq(cpu)->cpu_capacity_orig = capacity;
 
 	capacity *= scale_rt_capacity(cpu);
@@ -6186,8 +6224,8 @@ static inline int sg_imbalanced(struct sched_group *group)
  * group_has_capacity returns true if the group has spare capacity that could
  * be used by some tasks.
  * We consider that a group has spare capacity if the  * number of task is
- * smaller than the number of CPUs or if the usage is lower than the available
- * capacity for CFS tasks.
+ * smaller than the number of CPUs or if the utilization is lower than the
+ * available capacity for CFS tasks.
  * For the latter, we use a threshold to stabilize the state, to take into
  * account the variance of the tasks' load and to return true if the available
  * capacity in meaningful for the load balancer.
@@ -6201,7 +6239,7 @@ group_has_capacity(struct lb_env *env, struct sg_lb_stats *sgs)
 		return true;
 
 	if ((sgs->group_capacity * 100) >
-			(sgs->group_usage * env->sd->imbalance_pct))
+			(sgs->group_util * env->sd->imbalance_pct))
 		return true;
 
 	return false;
@@ -6222,7 +6260,7 @@ group_is_overloaded(struct lb_env *env, struct sg_lb_stats *sgs)
 		return false;
 
 	if ((sgs->group_capacity * 100) <
-			(sgs->group_usage * env->sd->imbalance_pct))
+			(sgs->group_util * env->sd->imbalance_pct))
 		return true;
 
 	return false;
@@ -6270,7 +6308,7 @@ static inline void update_sg_lb_stats(struct lb_env *env,
 			load = source_load(i, load_idx);
 
 		sgs->group_load += load;
-		sgs->group_usage += get_cpu_usage(i);
+		sgs->group_util += cpu_util(i);
 		sgs->sum_nr_running += rq->cfs.h_nr_running;
 
 		if (rq->nr_running > 1)
@@ -7609,8 +7647,22 @@ out:
 	 * When the cpu is attached to null domain for ex, it will not be
 	 * updated.
 	 */
-	if (likely(update_next_balance))
+	if (likely(update_next_balance)) {
 		rq->next_balance = next_balance;
+
+#ifdef CONFIG_NO_HZ_COMMON
+		/*
+		 * If this CPU has been elected to perform the nohz idle
+		 * balance. Other idle CPUs have already rebalanced with
+		 * nohz_idle_balance() and nohz.next_balance has been
+		 * updated accordingly. This CPU is now running the idle load
+		 * balance for itself and we need to update the
+		 * nohz.next_balance accordingly.
+		 */
+		if ((idle == CPU_IDLE) && time_after(nohz.next_balance, rq->next_balance))
+			nohz.next_balance = rq->next_balance;
+#endif
+	}
 }
 
 #ifdef CONFIG_NO_HZ_COMMON
@@ -7623,6 +7675,9 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
 	int this_cpu = this_rq->cpu;
 	struct rq *rq;
 	int balance_cpu;
+	/* Earliest time when we have to do rebalance again */
+	unsigned long next_balance = jiffies + 60*HZ;
+	int update_next_balance = 0;
 
 	if (idle != CPU_IDLE ||
 	    !test_bit(NOHZ_BALANCE_KICK, nohz_flags(this_cpu)))
@@ -7654,10 +7709,19 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle)
 			rebalance_domains(rq, CPU_IDLE);
 		}
 
-		if (time_after(this_rq->next_balance, rq->next_balance))
-			this_rq->next_balance = rq->next_balance;
+		if (time_after(next_balance, rq->next_balance)) {
+			next_balance = rq->next_balance;
+			update_next_balance = 1;
+		}
 	}
-	nohz.next_balance = this_rq->next_balance;
+
+	/*
+	 * next_balance will be updated only when there is a need.
+	 * When the CPU is attached to null domain for ex, it will not be
+	 * updated.
+	 */
+	if (likely(update_next_balance))
+		nohz.next_balance = next_balance;
 end:
 	clear_bit(NOHZ_BALANCE_KICK, nohz_flags(this_cpu));
 }
@@ -7810,7 +7874,7 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
 		entity_tick(cfs_rq, se, queued);
 	}
 
-	if (numabalancing_enabled)
+	if (!static_branch_unlikely(&sched_numa_balancing))
 		task_tick_numa(rq, curr);
 }
 
@@ -7886,21 +7950,39 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio)
 		check_preempt_curr(rq, p, 0);
 }
 
-static void switched_from_fair(struct rq *rq, struct task_struct *p)
+static inline bool vruntime_normalized(struct task_struct *p)
 {
 	struct sched_entity *se = &p->se;
-	struct cfs_rq *cfs_rq = cfs_rq_of(se);
 
 	/*
-	 * Ensure the task's vruntime is normalized, so that when it's
-	 * switched back to the fair class the enqueue_entity(.flags=0) will
-	 * do the right thing.
+	 * In both the TASK_ON_RQ_QUEUED and TASK_ON_RQ_MIGRATING cases,
+	 * the dequeue_entity(.flags=0) will already have normalized the
+	 * vruntime.
+	 */
+	if (p->on_rq)
+		return true;
+
+	/*
+	 * When !on_rq, vruntime of the task has usually NOT been normalized.
+	 * But there are some cases where it has already been normalized:
 	 *
-	 * If it's queued, then the dequeue_entity(.flags=0) will already
-	 * have normalized the vruntime, if it's !queued, then only when
-	 * the task is sleeping will it still have non-normalized vruntime.
+	 * - A forked child which is waiting for being woken up by
+	 *   wake_up_new_task().
+	 * - A task which has been woken up by try_to_wake_up() and
+	 *   waiting for actually being woken up by sched_ttwu_pending().
 	 */
-	if (!task_on_rq_queued(p) && p->state != TASK_RUNNING) {
+	if (!se->sum_exec_runtime || p->state == TASK_WAKING)
+		return true;
+
+	return false;
+}
+
+static void detach_task_cfs_rq(struct task_struct *p)
+{
+	struct sched_entity *se = &p->se;
+	struct cfs_rq *cfs_rq = cfs_rq_of(se);
+
+	if (!vruntime_normalized(p)) {
 		/*
 		 * Fix up our vruntime so that the current sleep doesn't
 		 * cause 'unlimited' sleep bonus.
@@ -7909,28 +7991,14 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p)
 		se->vruntime -= cfs_rq->min_vruntime;
 	}
 
-#ifdef CONFIG_SMP
 	/* Catch up with the cfs_rq and remove our load when we leave */
-	__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq), &se->avg,
-		se->on_rq * scale_load_down(se->load.weight), cfs_rq->curr == se, NULL);
-
-	cfs_rq->avg.load_avg =
-		max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
-	cfs_rq->avg.load_sum =
-		max_t(s64, cfs_rq->avg.load_sum - se->avg.load_sum, 0);
-	cfs_rq->avg.util_avg =
-		max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
-	cfs_rq->avg.util_sum =
-		max_t(s32, cfs_rq->avg.util_sum - se->avg.util_sum, 0);
-#endif
+	detach_entity_load_avg(cfs_rq, se);
 }
 
-/*
- * We switched to the sched_fair class.
- */
-static void switched_to_fair(struct rq *rq, struct task_struct *p)
+static void attach_task_cfs_rq(struct task_struct *p)
 {
 	struct sched_entity *se = &p->se;
+	struct cfs_rq *cfs_rq = cfs_rq_of(se);
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	/*
@@ -7940,31 +8008,33 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p)
 	se->depth = se->parent ? se->parent->depth + 1 : 0;
 #endif
 
-	if (!task_on_rq_queued(p)) {
+	/* Synchronize task with its cfs_rq */
+	attach_entity_load_avg(cfs_rq, se);
+
+	if (!vruntime_normalized(p))
+		se->vruntime += cfs_rq->min_vruntime;
+}
+
+static void switched_from_fair(struct rq *rq, struct task_struct *p)
+{
+	detach_task_cfs_rq(p);
+}
+
+static void switched_to_fair(struct rq *rq, struct task_struct *p)
+{
+	attach_task_cfs_rq(p);
 
+	if (task_on_rq_queued(p)) {
 		/*
-		 * Ensure the task has a non-normalized vruntime when it is switched
-		 * back to the fair class with !queued, so that enqueue_entity() at
-		 * wake-up time will do the right thing.
-		 *
-		 * If it's queued, then the enqueue_entity(.flags=0) makes the task
-		 * has non-normalized vruntime, if it's !queued, then it still has
-		 * normalized vruntime.
+		 * We were most likely switched from sched_rt, so
+		 * kick off the schedule if running, otherwise just see
+		 * if we can still preempt the current task.
 		 */
-		if (p->state != TASK_RUNNING)
-			se->vruntime += cfs_rq_of(se)->min_vruntime;
-		return;
+		if (rq->curr == p)
+			resched_curr(rq);
+		else
+			check_preempt_curr(rq, p, 0);
 	}
-
-	/*
-	 * We were most likely switched from sched_rt, so
-	 * kick off the schedule if running, otherwise just see
-	 * if we can still preempt the current task.
-	 */
-	if (rq->curr == p)
-		resched_curr(rq);
-	else
-		check_preempt_curr(rq, p, 0);
 }
 
 /* Account for a task changing its policy or group.
@@ -7999,56 +8069,16 @@ void init_cfs_rq(struct cfs_rq *cfs_rq)
 }
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-static void task_move_group_fair(struct task_struct *p, int queued)
+static void task_move_group_fair(struct task_struct *p)
 {
-	struct sched_entity *se = &p->se;
-	struct cfs_rq *cfs_rq;
-
-	/*
-	 * If the task was not on the rq at the time of this cgroup movement
-	 * it must have been asleep, sleeping tasks keep their ->vruntime
-	 * absolute on their old rq until wakeup (needed for the fair sleeper
-	 * bonus in place_entity()).
-	 *
-	 * If it was on the rq, we've just 'preempted' it, which does convert
-	 * ->vruntime to a relative base.
-	 *
-	 * Make sure both cases convert their relative position when migrating
-	 * to another cgroup's rq. This does somewhat interfere with the
-	 * fair sleeper stuff for the first placement, but who cares.
-	 */
-	/*
-	 * When !queued, vruntime of the task has usually NOT been normalized.
-	 * But there are some cases where it has already been normalized:
-	 *
-	 * - Moving a forked child which is waiting for being woken up by
-	 *   wake_up_new_task().
-	 * - Moving a task which has been woken up by try_to_wake_up() and
-	 *   waiting for actually being woken up by sched_ttwu_pending().
-	 *
-	 * To prevent boost or penalty in the new cfs_rq caused by delta
-	 * min_vruntime between the two cfs_rqs, we skip vruntime adjustment.
-	 */
-	if (!queued && (!se->sum_exec_runtime || p->state == TASK_WAKING))
-		queued = 1;
-
-	if (!queued)
-		se->vruntime -= cfs_rq_of(se)->min_vruntime;
+	detach_task_cfs_rq(p);
 	set_task_rq(p, task_cpu(p));
-	se->depth = se->parent ? se->parent->depth + 1 : 0;
-	if (!queued) {
-		cfs_rq = cfs_rq_of(se);
-		se->vruntime += cfs_rq->min_vruntime;
 
 #ifdef CONFIG_SMP
-		/* Virtually synchronize task with its new cfs_rq */
-		p->se.avg.last_update_time = cfs_rq->avg.last_update_time;
-		cfs_rq->avg.load_avg += p->se.avg.load_avg;
-		cfs_rq->avg.load_sum += p->se.avg.load_sum;
-		cfs_rq->avg.util_avg += p->se.avg.util_avg;
-		cfs_rq->avg.util_sum += p->se.avg.util_sum;
+	/* Tell se's cfs_rq has been changed -- migrated */
+	p->se.avg.last_update_time = 0;
 #endif
-	}
+	attach_task_cfs_rq(p);
 }
 
 void free_fair_sched_group(struct task_group *tg)
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index 83a50e7ca533..69631fa46c2f 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -36,11 +36,6 @@ SCHED_FEAT(CACHE_HOT_BUDDY, true)
  */
 SCHED_FEAT(WAKEUP_PREEMPTION, true)
 
-/*
- * Use arch dependent cpu capacity functions
- */
-SCHED_FEAT(ARCH_CAPACITY, true)
-
 SCHED_FEAT(HRTICK, false)
 SCHED_FEAT(DOUBLE_TICK, false)
 SCHED_FEAT(LB_BIAS, true)
@@ -72,19 +67,5 @@ SCHED_FEAT(RT_PUSH_IPI, true)
 SCHED_FEAT(FORCE_SD_OVERLAP, false)
 SCHED_FEAT(RT_RUNTIME_SHARE, true)
 SCHED_FEAT(LB_MIN, false)
+SCHED_FEAT(ATTACH_AGE_LOAD, true)
 
-/*
- * Apply the automatic NUMA scheduling policy. Enabled automatically
- * at runtime if running on a NUMA machine. Can be controlled via
- * numa_balancing=
- */
-#ifdef CONFIG_NUMA_BALANCING
-
-/*
- * NUMA will favor moving tasks towards nodes where a higher number of
- * hinting faults are recorded during active load balancing. It will
- * resist moving tasks towards nodes where a lower number of hinting
- * faults have been recorded.
- */
-SCHED_FEAT(NUMA,	true)
-#endif
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 68cda117574c..167ab4844ee6 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1003,17 +1003,7 @@ extern struct static_key sched_feat_keys[__SCHED_FEAT_NR];
 #define sched_feat(x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x))
 #endif /* SCHED_DEBUG && HAVE_JUMP_LABEL */
 
-#ifdef CONFIG_NUMA_BALANCING
-#define sched_feat_numa(x) sched_feat(x)
-#ifdef CONFIG_SCHED_DEBUG
-#define numabalancing_enabled sched_feat_numa(NUMA)
-#else
-extern bool numabalancing_enabled;
-#endif /* CONFIG_SCHED_DEBUG */
-#else
-#define sched_feat_numa(x) (0)
-#define numabalancing_enabled (0)
-#endif /* CONFIG_NUMA_BALANCING */
+extern struct static_key_false sched_numa_balancing;
 
 static inline u64 global_rt_period(void)
 {
@@ -1226,7 +1216,7 @@ struct sched_class {
 	void (*update_curr) (struct rq *rq);
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-	void (*task_move_group) (struct task_struct *p, int on_rq);
+	void (*task_move_group) (struct task_struct *p);
 #endif
 };
 
@@ -1404,6 +1394,17 @@ unsigned long arch_scale_freq_capacity(struct sched_domain *sd, int cpu)
 }
 #endif
 
+#ifndef arch_scale_cpu_capacity
+static __always_inline
+unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
+{
+	if (sd && (sd->flags & SD_SHARE_CPUCAPACITY) && (sd->span_weight > 1))
+		return sd->smt_gain / sd->span_weight;
+
+	return SCHED_CAPACITY_SCALE;
+}
+#endif
+
 static inline void sched_rt_avg_update(struct rq *rq, u64 rt_delta)
 {
 	rq->rt_avg += rt_delta * arch_scale_freq_capacity(NULL, cpu_of(rq));
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 841b72f720e8..174c594ff8ef 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -479,7 +479,7 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
  * return half the number of nanoseconds the hardware counter can technically
  * cover. This is done so that we can potentially detect problems caused by
  * delayed timers or bad hardware, which might result in time intervals that
- * are larger then what the math used can handle without overflows.
+ * are larger than what the math used can handle without overflows.
  */
 u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
 {
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 457a373e2181..435b8850dd80 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -59,7 +59,7 @@
 /*
  * The timer bases:
  *
- * There are more clockids then hrtimer bases. Thus, we index
+ * There are more clockids than hrtimer bases. Thus, we index
  * into the timer bases by the hrtimer_base_type enum. When trying
  * to reach a base using a clockid, hrtimer_clockid_to_base()
  * is used to convert from clockid to the proper hrtimer_base_type.
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 3319e16f31e5..7c7ec4515983 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -290,16 +290,17 @@ static int __init tick_nohz_full_setup(char *str)
 __setup("nohz_full=", tick_nohz_full_setup);
 
 static int tick_nohz_cpu_down_callback(struct notifier_block *nfb,
-						 unsigned long action,
-						 void *hcpu)
+				       unsigned long action,
+				       void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 
 	switch (action & ~CPU_TASKS_FROZEN) {
 	case CPU_DOWN_PREPARE:
 		/*
-		 * If we handle the timekeeping duty for full dynticks CPUs,
-		 * we can't safely shutdown that CPU.
+		 * The boot CPU handles housekeeping duty (unbound timers,
+		 * workqueues, timekeeping, ...) on behalf of full dynticks
+		 * CPUs. It must remain online when nohz full is enabled.
 		 */
 		if (tick_nohz_full_running && tick_do_timer_cpu == cpu)
 			return NOTIFY_BAD;
@@ -370,6 +371,12 @@ void __init tick_nohz_init(void)
 	cpu_notifier(tick_nohz_cpu_down_callback, 0);
 	pr_info("NO_HZ: Full dynticks CPUs: %*pbl.\n",
 		cpumask_pr_args(tick_nohz_full_mask));
+
+	/*
+	 * We need at least one CPU to handle housekeeping work such
+	 * as timekeeping, unbound timers, workqueues, ...
+	 */
+	WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
 }
 #endif
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index f6ee2e6b6f5d..125f16a29cf6 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1614,7 +1614,7 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
 	negative = (tick_error < 0);
 
 	/* Sort out the magnitude of the correction */
-	tick_error = abs(tick_error);
+	tick_error = abs64(tick_error);
 	for (adj = 0; tick_error > interval; adj++)
 		tick_error >>= 1;
 
@@ -1674,7 +1674,7 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 /**
  * accumulate_nsecs_to_secs - Accumulates nsecs into secs
  *
- * Helper function that accumulates a the nsecs greater then a second
+ * Helper function that accumulates the nsecs greater than a second
  * from the xtime_nsec field to the xtime_secs field.
  * It also calls into the NTP code to handle leapsecond processing.
  *
@@ -1726,7 +1726,7 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
 	cycle_t interval = tk->cycle_interval << shift;
 	u64 raw_nsecs;
 
-	/* If the offset is smaller then a shifted interval, do nothing */
+	/* If the offset is smaller than a shifted interval, do nothing */
 	if (offset < interval)
 		return offset;
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ab76b99adc85..4d1fb075ebb6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -215,7 +215,7 @@ config STRIP_ASM_SYMS
 
 config READABLE_ASM
         bool "Generate readable assembler code"
-        depends on DEBUG_KERNEL
+        depends on DEBUG_KERNEL && !LTO
         help
           Disable some compiler optimizations that tend to generate human unreadable
           assembler output. This may make the kernel slightly slower, but it helps
diff --git a/localversion-next b/localversion-next
new file mode 100644
index 000000000000..7e33ac918478
--- /dev/null
+++ b/localversion-next
@@ -0,0 +1 @@
+-next-20150914
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 1e0071fdcf72..78c8a495b571 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -366,7 +366,18 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
 			return err;
 	}
 
-	hdr.payload_len = htons(skb->len);
+	switch (lowpan_priv(dev)->lltype) {
+	case LOWPAN_LLTYPE_IEEE802154:
+		if (lowpan_802154_cb(skb)->d_size)
+			hdr.payload_len = htons(lowpan_802154_cb(skb)->d_size -
+						sizeof(struct ipv6hdr));
+		else
+			hdr.payload_len = htons(skb->len);
+		break;
+	default:
+		hdr.payload_len = htons(skb->len);
+		break;
+	}
 
 	pr_debug("skb headroom size = %d, data length = %d\n",
 		 skb_headroom(skb), skb->len);
diff --git a/net/6lowpan/nhc_udp.c b/net/6lowpan/nhc_udp.c
index c6bcaeb428ae..72d0b57eb6e5 100644
--- a/net/6lowpan/nhc_udp.c
+++ b/net/6lowpan/nhc_udp.c
@@ -71,7 +71,18 @@ static int udp_uncompress(struct sk_buff *skb, size_t needed)
 	 * here, we obtain the hint from the remaining size of the
 	 * frame
 	 */
-	uh.len = htons(skb->len + sizeof(struct udphdr));
+	switch (lowpan_priv(skb->dev)->lltype) {
+	case LOWPAN_LLTYPE_IEEE802154:
+		if (lowpan_802154_cb(skb)->d_size)
+			uh.len = htons(lowpan_802154_cb(skb)->d_size -
+				       sizeof(struct ipv6hdr));
+		else
+			uh.len = htons(skb->len + sizeof(struct udphdr));
+		break;
+	default:
+		uh.len = htons(skb->len + sizeof(struct udphdr));
+		break;
+	}
 	pr_debug("uncompressed UDP length: src = %d", ntohs(uh.len));
 
 	/* replace the compressed UDP head by the uncompressed UDP
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index bced8c074c12..7bc2208b6cc4 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -108,9 +108,7 @@ struct p9_poll_wait {
  * @unsent_req_list: accounting for requests that haven't been sent
  * @req: current request being processed (if any)
  * @tmp_buf: temporary buffer to read in header
- * @rsize: amount to read for current frame
- * @rpos: read position in current frame
- * @rbuf: current read buffer
+ * @rc: temporary fcall for reading current frame
  * @wpos: write position for current frame
  * @wsize: amount of data to write for current frame
  * @wbuf: current write buffer
@@ -131,9 +129,7 @@ struct p9_conn {
 	struct list_head unsent_req_list;
 	struct p9_req_t *req;
 	char tmp_buf[7];
-	int rsize;
-	int rpos;
-	char *rbuf;
+	struct p9_fcall rc;
 	int wpos;
 	int wsize;
 	char *wbuf;
@@ -305,69 +301,77 @@ static void p9_read_work(struct work_struct *work)
 	if (m->err < 0)
 		return;
 
-	p9_debug(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos);
+	p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
 
-	if (!m->rbuf) {
-		m->rbuf = m->tmp_buf;
-		m->rpos = 0;
-		m->rsize = 7; /* start by reading header */
+	if (!m->rc.sdata) {
+		m->rc.sdata = m->tmp_buf;
+		m->rc.offset = 0;
+		m->rc.capacity = 7; /* start by reading header */
 	}
 
 	clear_bit(Rpending, &m->wsched);
-	p9_debug(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n",
-		 m, m->rpos, m->rsize, m->rsize-m->rpos);
-	err = p9_fd_read(m->client, m->rbuf + m->rpos,
-						m->rsize - m->rpos);
+	p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
+		 m, m->rc.offset, m->rc.capacity,
+		 m->rc.capacity - m->rc.offset);
+	err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
+			 m->rc.capacity - m->rc.offset);
 	p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
-	if (err == -EAGAIN) {
+	if (err == -EAGAIN)
 		goto end_clear;
-	}
 
 	if (err <= 0)
 		goto error;
 
-	m->rpos += err;
+	m->rc.offset += err;
 
-	if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
-		u16 tag;
+	/* header read in */
+	if ((!m->req) && (m->rc.offset == m->rc.capacity)) {
 		p9_debug(P9_DEBUG_TRANS, "got new header\n");
 
-		n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
-		if (n >= m->client->msize) {
+		err = p9_parse_header(&m->rc, NULL, NULL, NULL, 0);
+		if (err) {
+			p9_debug(P9_DEBUG_ERROR,
+				 "error parsing header: %d\n", err);
+			goto error;
+		}
+
+		if (m->rc.size >= m->client->msize) {
 			p9_debug(P9_DEBUG_ERROR,
-				 "requested packet size too big: %d\n", n);
+				 "requested packet size too big: %d\n",
+				 m->rc.size);
 			err = -EIO;
 			goto error;
 		}
 
-		tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
 		p9_debug(P9_DEBUG_TRANS,
-			 "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
+			 "mux %p pkt: size: %d bytes tag: %d\n",
+			 m, m->rc.size, m->rc.tag);
 
-		m->req = p9_tag_lookup(m->client, tag);
+		m->req = p9_tag_lookup(m->client, m->rc.tag);
 		if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
 			p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
-				 tag);
+				 m->rc.tag);
 			err = -EIO;
 			goto error;
 		}
 
 		if (m->req->rc == NULL) {
-			m->req->rc = kmalloc(sizeof(struct p9_fcall) +
-						m->client->msize, GFP_NOFS);
-			if (!m->req->rc) {
-				m->req = NULL;
-				err = -ENOMEM;
-				goto error;
-			}
+			p9_debug(P9_DEBUG_ERROR,
+				 "No recv fcall for tag %d (req %p), disconnecting!\n",
+				 m->rc.tag, m->req);
+			m->req = NULL;
+			err = -EIO;
+			goto error;
 		}
-		m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
-		memcpy(m->rbuf, m->tmp_buf, m->rsize);
-		m->rsize = n;
+		m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall);
+		memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
+		m->rc.capacity = m->rc.size;
 	}
 
-	/* not an else because some packets (like clunk) have no payload */
-	if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
+	/* packet is read in
+	 * not an else because some packets (like clunk) have no payload
+	 */
+	if ((m->req) && (m->rc.offset == m->rc.capacity)) {
 		p9_debug(P9_DEBUG_TRANS, "got new packet\n");
 		spin_lock(&m->client->lock);
 		if (m->req->status != REQ_STATUS_ERROR)
@@ -375,9 +379,9 @@ static void p9_read_work(struct work_struct *work)
 		list_del(&m->req->req_list);
 		spin_unlock(&m->client->lock);
 		p9_client_cb(m->client, m->req, status);
-		m->rbuf = NULL;
-		m->rpos = 0;
-		m->rsize = 0;
+		m->rc.sdata = NULL;
+		m->rc.offset = 0;
+		m->rc.capacity = 0;
 		m->req = NULL;
 	}
 
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 6e70ddb158b4..3827760c8eef 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -662,7 +662,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 	mutex_unlock(&virtio_9p_lock);
 
 	if (!found) {
-		pr_err("no channels available\n");
+		pr_err("no channels available for device %s\n", devname);
 		return ret;
 	}
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index adcbc74c2432..a7cdd99ec3f1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -693,7 +693,8 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
 
 	hci_setup_event_mask(req);
 
-	if (hdev->commands[6] & 0x20) {
+	if (hdev->commands[6] & 0x20 &&
+	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
 		struct hci_cp_read_stored_link_key cp;
 
 		bacpy(&cp.bdaddr, BDADDR_ANY);
@@ -1548,7 +1549,7 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
 	BT_DBG("All LE pending actions cleared");
 }
 
-static int hci_dev_do_close(struct hci_dev *hdev)
+int hci_dev_do_close(struct hci_dev *hdev)
 {
 	BT_DBG("%s %p", hdev->name, hdev);
 
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f2d30d1156c9..150556345263 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -503,7 +503,16 @@ static int hci_sock_release(struct socket *sock)
 
 	if (hdev) {
 		if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
-			hci_dev_close(hdev->id);
+			/* When releasing an user channel exclusive access,
+			 * call hci_dev_do_close directly instead of calling
+			 * hci_dev_close to ensure the exclusive access will
+			 * be released and the controller brought back down.
+			 *
+			 * The checking of HCI_AUTO_OFF is not needed in this
+			 * case since it will have been cleared already when
+			 * opening the user channel.
+			 */
+			hci_dev_do_close(hdev);
 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
 			mgmt_index_added(hdev);
 		}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index ad82324f710f..25644e1bc479 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -495,7 +495,7 @@ static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16],
 	}
 
 	/* The output of the random address function ah is:
-	 *	ah(h, r) = e(k, r') mod 2^24
+	 *	ah(k, r) = e(k, r') mod 2^24
 	 * The output of the security function e is then truncated to 24 bits
 	 * by taking the least significant 24 bits of the output of e as the
 	 * result of ah.
@@ -2311,12 +2311,6 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 	if (!conn)
 		return 1;
 
-	chan = conn->smp;
-	if (!chan) {
-		BT_ERR("SMP security requested but not available");
-		return 1;
-	}
-
 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
 		return 1;
 
@@ -2330,6 +2324,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
 			return 0;
 
+	chan = conn->smp;
+	if (!chan) {
+		BT_ERR("SMP security requested but not available");
+		return 1;
+	}
+
 	l2cap_chan_lock(chan);
 
 	/* If SMP is already in progress ignore this request */
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 66efdc21f548..480b3de1a0e3 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1006,7 +1006,7 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
 
 	ih = igmpv3_report_hdr(skb);
 	num = ntohs(ih->ngrec);
-	len = sizeof(*ih);
+	len = skb_transport_offset(skb) + sizeof(*ih);
 
 	for (i = 0; i < num; i++) {
 		len += sizeof(*grec);
@@ -1067,7 +1067,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
 
 	icmp6h = icmp6_hdr(skb);
 	num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
-	len = sizeof(*icmp6h);
+	len = skb_transport_offset(skb) + sizeof(*icmp6h);
 
 	for (i = 0; i < num; i++) {
 		__be16 *nsrcs, _nsrcs;
diff --git a/net/core/filter.c b/net/core/filter.c
index 13079f03902e..05a04ea87172 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -478,9 +478,9 @@ do_pass:
 				bpf_src = BPF_X;
 			} else {
 				insn->dst_reg = BPF_REG_A;
-				insn->src_reg = BPF_REG_X;
 				insn->imm = fp->k;
 				bpf_src = BPF_SRC(fp->code);
+				insn->src_reg = bpf_src == BPF_X ? BPF_REG_X : 0;
 			}
 
 			/* Common case where 'jump_false' is next insn. */
diff --git a/net/ieee802154/6lowpan/6lowpan_i.h b/net/ieee802154/6lowpan/6lowpan_i.h
index ea339fa94c27..b4e17a7c0df0 100644
--- a/net/ieee802154/6lowpan/6lowpan_i.h
+++ b/net/ieee802154/6lowpan/6lowpan_i.h
@@ -7,6 +7,15 @@
 #include <net/inet_frag.h>
 #include <net/6lowpan.h>
 
+typedef unsigned __bitwise__ lowpan_rx_result;
+#define RX_CONTINUE		((__force lowpan_rx_result) 0u)
+#define RX_DROP_UNUSABLE	((__force lowpan_rx_result) 1u)
+#define RX_DROP			((__force lowpan_rx_result) 2u)
+#define RX_QUEUED		((__force lowpan_rx_result) 3u)
+
+#define LOWPAN_DISPATCH_FRAG1           0xc0
+#define LOWPAN_DISPATCH_FRAGN           0xe0
+
 struct lowpan_create_arg {
 	u16 tag;
 	u16 d_size;
@@ -40,7 +49,7 @@ static inline u32 ieee802154_addr_hash(const struct ieee802154_addr *a)
 
 /* private device info */
 struct lowpan_dev_info {
-	struct net_device	*real_dev; /* real WPAN device ptr */
+	struct net_device	*wdev; /* wpan device ptr */
 	u16			fragment_tag;
 };
 
@@ -62,4 +71,7 @@ int lowpan_header_create(struct sk_buff *skb, struct net_device *dev,
 			 const void *_saddr, unsigned int len);
 netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev);
 
+int lowpan_iphc_decompress(struct sk_buff *skb);
+lowpan_rx_result lowpan_rx_h_ipv6(struct sk_buff *skb);
+
 #endif /* __IEEE802154_6LOWPAN_I_H__ */
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index 953b1c49f5d1..9f0cfa598e3a 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -61,7 +61,7 @@ static struct header_ops lowpan_header_ops = {
 static struct lock_class_key lowpan_tx_busylock;
 static struct lock_class_key lowpan_netdev_xmit_lock_key;
 
-static void lowpan_set_lockdep_class_one(struct net_device *dev,
+static void lowpan_set_lockdep_class_one(struct net_device *ldev,
 					 struct netdev_queue *txq,
 					 void *_unused)
 {
@@ -69,35 +69,52 @@ static void lowpan_set_lockdep_class_one(struct net_device *dev,
 			  &lowpan_netdev_xmit_lock_key);
 }
 
-static int lowpan_dev_init(struct net_device *dev)
+static int lowpan_dev_init(struct net_device *ldev)
 {
-	netdev_for_each_tx_queue(dev, lowpan_set_lockdep_class_one, NULL);
-	dev->qdisc_tx_busylock = &lowpan_tx_busylock;
+	netdev_for_each_tx_queue(ldev, lowpan_set_lockdep_class_one, NULL);
+	ldev->qdisc_tx_busylock = &lowpan_tx_busylock;
+	return 0;
+}
+
+static int lowpan_open(struct net_device *dev)
+{
+	if (!open_count)
+		lowpan_rx_init();
+	open_count++;
+	return 0;
+}
+
+static int lowpan_stop(struct net_device *dev)
+{
+	open_count--;
+	if (!open_count)
+		lowpan_rx_exit();
 	return 0;
 }
 
 static const struct net_device_ops lowpan_netdev_ops = {
 	.ndo_init		= lowpan_dev_init,
 	.ndo_start_xmit		= lowpan_xmit,
+	.ndo_open		= lowpan_open,
+	.ndo_stop		= lowpan_stop,
 };
 
-static void lowpan_setup(struct net_device *dev)
+static void lowpan_setup(struct net_device *ldev)
 {
-	dev->addr_len		= IEEE802154_ADDR_LEN;
-	memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
-	dev->type		= ARPHRD_6LOWPAN;
+	ldev->addr_len		= IEEE802154_ADDR_LEN;
+	memset(ldev->broadcast, 0xff, IEEE802154_ADDR_LEN);
+	ldev->type		= ARPHRD_6LOWPAN;
 	/* Frame Control + Sequence Number + Address fields + Security Header */
-	dev->hard_header_len	= 2 + 1 + 20 + 14;
-	dev->needed_tailroom	= 2; /* FCS */
-	dev->mtu		= IPV6_MIN_MTU;
-	dev->priv_flags		|= IFF_NO_QUEUE;
-	dev->flags		= IFF_BROADCAST | IFF_MULTICAST;
-	dev->watchdog_timeo	= 0;
-
-	dev->netdev_ops		= &lowpan_netdev_ops;
-	dev->header_ops		= &lowpan_header_ops;
-	dev->destructor		= free_netdev;
-	dev->features		|= NETIF_F_NETNS_LOCAL;
+	ldev->hard_header_len	= 2 + 1 + 20 + 14;
+	ldev->needed_tailroom	= 2; /* FCS */
+	ldev->mtu		= IPV6_MIN_MTU;
+	ldev->priv_flags	|= IFF_NO_QUEUE;
+	ldev->flags		= IFF_BROADCAST | IFF_MULTICAST;
+
+	ldev->netdev_ops	= &lowpan_netdev_ops;
+	ldev->header_ops	= &lowpan_header_ops;
+	ldev->destructor	= free_netdev;
+	ldev->features		|= NETIF_F_NETNS_LOCAL;
 }
 
 static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -109,10 +126,10 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
 	return 0;
 }
 
-static int lowpan_newlink(struct net *src_net, struct net_device *dev,
+static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
 			  struct nlattr *tb[], struct nlattr *data[])
 {
-	struct net_device *real_dev;
+	struct net_device *wdev;
 	int ret;
 
 	ASSERT_RTNL();
@@ -120,58 +137,47 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
 	pr_debug("adding new link\n");
 
 	if (!tb[IFLA_LINK] ||
-	    !net_eq(dev_net(dev), &init_net))
+	    !net_eq(dev_net(ldev), &init_net))
 		return -EINVAL;
-	/* find and hold real wpan device */
-	real_dev = dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK]));
-	if (!real_dev)
+	/* find and hold wpan device */
+	wdev = dev_get_by_index(dev_net(ldev), nla_get_u32(tb[IFLA_LINK]));
+	if (!wdev)
 		return -ENODEV;
-	if (real_dev->type != ARPHRD_IEEE802154) {
-		dev_put(real_dev);
+	if (wdev->type != ARPHRD_IEEE802154) {
+		dev_put(wdev);
 		return -EINVAL;
 	}
 
-	if (real_dev->ieee802154_ptr->lowpan_dev) {
-		dev_put(real_dev);
+	if (wdev->ieee802154_ptr->lowpan_dev) {
+		dev_put(wdev);
 		return -EBUSY;
 	}
 
-	lowpan_dev_info(dev)->real_dev = real_dev;
+	lowpan_dev_info(ldev)->wdev = wdev;
 	/* Set the lowpan hardware address to the wpan hardware address. */
-	memcpy(dev->dev_addr, real_dev->dev_addr, IEEE802154_ADDR_LEN);
+	memcpy(ldev->dev_addr, wdev->dev_addr, IEEE802154_ADDR_LEN);
 
-	lowpan_netdev_setup(dev, LOWPAN_LLTYPE_IEEE802154);
+	lowpan_netdev_setup(ldev, LOWPAN_LLTYPE_IEEE802154);
 
-	ret = register_netdevice(dev);
+	ret = register_netdevice(ldev);
 	if (ret < 0) {
-		dev_put(real_dev);
+		dev_put(wdev);
 		return ret;
 	}
 
-	real_dev->ieee802154_ptr->lowpan_dev = dev;
-	if (!open_count)
-		lowpan_rx_init();
-
-	open_count++;
-
+	wdev->ieee802154_ptr->lowpan_dev = ldev;
 	return 0;
 }
 
-static void lowpan_dellink(struct net_device *dev, struct list_head *head)
+static void lowpan_dellink(struct net_device *ldev, struct list_head *head)
 {
-	struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev);
-	struct net_device *real_dev = lowpan_dev->real_dev;
+	struct net_device *wdev = lowpan_dev_info(ldev)->wdev;
 
 	ASSERT_RTNL();
 
-	open_count--;
-
-	if (!open_count)
-		lowpan_rx_exit();
-
-	real_dev->ieee802154_ptr->lowpan_dev = NULL;
-	unregister_netdevice(dev);
-	dev_put(real_dev);
+	wdev->ieee802154_ptr->lowpan_dev = NULL;
+	unregister_netdevice(ldev);
+	dev_put(wdev);
 }
 
 static struct rtnl_link_ops lowpan_link_ops __read_mostly = {
@@ -196,9 +202,9 @@ static inline void lowpan_netlink_fini(void)
 static int lowpan_device_event(struct notifier_block *unused,
 			       unsigned long event, void *ptr)
 {
-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct net_device *wdev = netdev_notifier_info_to_dev(ptr);
 
-	if (dev->type != ARPHRD_IEEE802154)
+	if (wdev->type != ARPHRD_IEEE802154)
 		goto out;
 
 	switch (event) {
@@ -207,8 +213,8 @@ static int lowpan_device_event(struct notifier_block *unused,
 		 * also delete possible lowpan interfaces which belongs
 		 * to the wpan interface.
 		 */
-		if (dev->ieee802154_ptr && dev->ieee802154_ptr->lowpan_dev)
-			lowpan_dellink(dev->ieee802154_ptr->lowpan_dev, NULL);
+		if (wdev->ieee802154_ptr->lowpan_dev)
+			lowpan_dellink(wdev->ieee802154_ptr->lowpan_dev, NULL);
 		break;
 	default:
 		break;
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index 214d44aef35b..12e8cf4bda9f 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -32,21 +32,10 @@
 
 static const char lowpan_frags_cache_name[] = "lowpan-frags";
 
-struct lowpan_frag_info {
-	u16 d_tag;
-	u16 d_size;
-	u8 d_offset;
-};
-
-static struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
-{
-	return (struct lowpan_frag_info *)skb->cb;
-}
-
 static struct inet_frags lowpan_frags;
 
 static int lowpan_frag_reasm(struct lowpan_frag_queue *fq,
-			     struct sk_buff *prev, struct net_device *dev);
+			     struct sk_buff *prev, struct net_device *ldev);
 
 static unsigned int lowpan_hash_frag(u16 tag, u16 d_size,
 				     const struct ieee802154_addr *saddr,
@@ -111,7 +100,7 @@ out:
 }
 
 static inline struct lowpan_frag_queue *
-fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
+fq_find(struct net *net, const struct lowpan_802154_cb *cb,
 	const struct ieee802154_addr *src,
 	const struct ieee802154_addr *dst)
 {
@@ -121,12 +110,12 @@ fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
 	struct netns_ieee802154_lowpan *ieee802154_lowpan =
 		net_ieee802154_lowpan(net);
 
-	arg.tag = frag_info->d_tag;
-	arg.d_size = frag_info->d_size;
+	arg.tag = cb->d_tag;
+	arg.d_size = cb->d_size;
 	arg.src = src;
 	arg.dst = dst;
 
-	hash = lowpan_hash_frag(frag_info->d_tag, frag_info->d_size, src, dst);
+	hash = lowpan_hash_frag(cb->d_tag, cb->d_size, src, dst);
 
 	q = inet_frag_find(&ieee802154_lowpan->frags,
 			   &lowpan_frags, &arg, hash);
@@ -138,17 +127,17 @@ fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
 }
 
 static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
-			     struct sk_buff *skb, const u8 frag_type)
+			     struct sk_buff *skb, u8 frag_type)
 {
 	struct sk_buff *prev, *next;
-	struct net_device *dev;
+	struct net_device *ldev;
 	int end, offset;
 
 	if (fq->q.flags & INET_FRAG_COMPLETE)
 		goto err;
 
-	offset = lowpan_cb(skb)->d_offset << 3;
-	end = lowpan_cb(skb)->d_size;
+	offset = lowpan_802154_cb(skb)->d_offset << 3;
+	end = lowpan_802154_cb(skb)->d_size;
 
 	/* Is this the final fragment? */
 	if (offset + skb->len == end) {
@@ -174,13 +163,16 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
 	 * this fragment, right?
 	 */
 	prev = fq->q.fragments_tail;
-	if (!prev || lowpan_cb(prev)->d_offset < lowpan_cb(skb)->d_offset) {
+	if (!prev ||
+	    lowpan_802154_cb(prev)->d_offset <
+	    lowpan_802154_cb(skb)->d_offset) {
 		next = NULL;
 		goto found;
 	}
 	prev = NULL;
 	for (next = fq->q.fragments; next != NULL; next = next->next) {
-		if (lowpan_cb(next)->d_offset >= lowpan_cb(skb)->d_offset)
+		if (lowpan_802154_cb(next)->d_offset >=
+		    lowpan_802154_cb(skb)->d_offset)
 			break;	/* bingo! */
 		prev = next;
 	}
@@ -195,18 +187,15 @@ found:
 	else
 		fq->q.fragments = skb;
 
-	dev = skb->dev;
-	if (dev)
+	ldev = skb->dev;
+	if (ldev)
 		skb->dev = NULL;
 
 	fq->q.stamp = skb->tstamp;
-	if (frag_type == LOWPAN_DISPATCH_FRAG1) {
-		/* Calculate uncomp. 6lowpan header to estimate full size */
-		fq->q.meat += lowpan_uncompress_size(skb, NULL);
+	if (frag_type == LOWPAN_DISPATCH_FRAG1)
 		fq->q.flags |= INET_FRAG_FIRST_IN;
-	} else {
-		fq->q.meat += skb->len;
-	}
+
+	fq->q.meat += skb->len;
 	add_frag_mem_limit(fq->q.net, skb->truesize);
 
 	if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
@@ -215,7 +204,7 @@ found:
 		unsigned long orefdst = skb->_skb_refdst;
 
 		skb->_skb_refdst = 0UL;
-		res = lowpan_frag_reasm(fq, prev, dev);
+		res = lowpan_frag_reasm(fq, prev, ldev);
 		skb->_skb_refdst = orefdst;
 		return res;
 	}
@@ -235,7 +224,7 @@ err:
  *	the last and the first frames arrived and all the bits are here.
  */
 static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev,
-			     struct net_device *dev)
+			     struct net_device *ldev)
 {
 	struct sk_buff *fp, *head = fq->q.fragments;
 	int sum_truesize;
@@ -313,7 +302,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev,
 	sub_frag_mem_limit(fq->q.net, sum_truesize);
 
 	head->next = NULL;
-	head->dev = dev;
+	head->dev = ldev;
 	head->tstamp = fq->q.stamp;
 
 	fq->q.fragments = NULL;
@@ -325,24 +314,87 @@ out_oom:
 	return -1;
 }
 
-static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type,
-				struct lowpan_frag_info *frag_info)
+static int lowpan_frag_rx_handlers_result(struct sk_buff *skb,
+					  lowpan_rx_result res)
+{
+	switch (res) {
+	case RX_QUEUED:
+		return NET_RX_SUCCESS;
+	case RX_CONTINUE:
+		/* nobody cared about this packet */
+		net_warn_ratelimited("%s: received unknown dispatch\n",
+				     __func__);
+
+		/* fall-through */
+	default:
+		/* all others failure */
+		return NET_RX_DROP;
+	}
+}
+
+static lowpan_rx_result lowpan_frag_rx_h_iphc(struct sk_buff *skb)
+{
+	int ret;
+
+	if (!lowpan_is_iphc(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	ret = lowpan_iphc_decompress(skb);
+	if (ret < 0)
+		return RX_DROP;
+
+	return RX_QUEUED;
+}
+
+static int lowpan_invoke_frag_rx_handlers(struct sk_buff *skb)
+{
+	lowpan_rx_result res;
+
+#define CALL_RXH(rxh)			\
+	do {				\
+		res = rxh(skb);	\
+		if (res != RX_CONTINUE)	\
+			goto rxh_next;	\
+	} while (0)
+
+	/* likely at first */
+	CALL_RXH(lowpan_frag_rx_h_iphc);
+	CALL_RXH(lowpan_rx_h_ipv6);
+
+rxh_next:
+	return lowpan_frag_rx_handlers_result(skb, res);
+#undef CALL_RXH
+}
+
+#define LOWPAN_FRAG_DGRAM_SIZE_HIGH_MASK	0x07
+#define LOWPAN_FRAG_DGRAM_SIZE_HIGH_SHIFT	8
+
+static int lowpan_get_cb(struct sk_buff *skb, u8 frag_type,
+			 struct lowpan_802154_cb *cb)
 {
 	bool fail;
-	u8 pattern = 0, low = 0;
+	u8 high = 0, low = 0;
 	__be16 d_tag = 0;
 
-	fail = lowpan_fetch_skb(skb, &pattern, 1);
+	fail = lowpan_fetch_skb(skb, &high, 1);
 	fail |= lowpan_fetch_skb(skb, &low, 1);
-	frag_info->d_size = (pattern & 7) << 8 | low;
+	/* remove the dispatch value and use first three bits as high value
+	 * for the datagram size
+	 */
+	cb->d_size = (high & LOWPAN_FRAG_DGRAM_SIZE_HIGH_MASK) <<
+		LOWPAN_FRAG_DGRAM_SIZE_HIGH_SHIFT | low;
 	fail |= lowpan_fetch_skb(skb, &d_tag, 2);
-	frag_info->d_tag = ntohs(d_tag);
+	cb->d_tag = ntohs(d_tag);
 
 	if (frag_type == LOWPAN_DISPATCH_FRAGN) {
-		fail |= lowpan_fetch_skb(skb, &frag_info->d_offset, 1);
+		fail |= lowpan_fetch_skb(skb, &cb->d_offset, 1);
 	} else {
 		skb_reset_network_header(skb);
-		frag_info->d_offset = 0;
+		cb->d_offset = 0;
+		/* check if datagram_size has ipv6hdr on FRAG1 */
+		fail |= cb->d_size < sizeof(struct ipv6hdr);
+		/* check if we can dereference the dispatch value */
+		fail |= !skb->len;
 	}
 
 	if (unlikely(fail))
@@ -351,27 +403,33 @@ static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type,
 	return 0;
 }
 
-int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
+int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type)
 {
 	struct lowpan_frag_queue *fq;
 	struct net *net = dev_net(skb->dev);
-	struct lowpan_frag_info *frag_info = lowpan_cb(skb);
-	struct ieee802154_addr source, dest;
+	struct lowpan_802154_cb *cb = lowpan_802154_cb(skb);
+	struct ieee802154_hdr hdr;
 	int err;
 
-	source = mac_cb(skb)->source;
-	dest = mac_cb(skb)->dest;
+	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
+		goto err;
 
-	err = lowpan_get_frag_info(skb, frag_type, frag_info);
+	err = lowpan_get_cb(skb, frag_type, cb);
 	if (err < 0)
 		goto err;
 
-	if (frag_info->d_size > IPV6_MIN_MTU) {
+	if (frag_type == LOWPAN_DISPATCH_FRAG1) {
+		err = lowpan_invoke_frag_rx_handlers(skb);
+		if (err == NET_RX_DROP)
+			goto err;
+	}
+
+	if (cb->d_size > IPV6_MIN_MTU) {
 		net_warn_ratelimited("lowpan_frag_rcv: datagram size exceeds MTU\n");
 		goto err;
 	}
 
-	fq = fq_find(net, frag_info, &source, &dest);
+	fq = fq_find(net, cb, &hdr.source, &hdr.dest);
 	if (fq != NULL) {
 		int ret;
 
@@ -387,7 +445,6 @@ err:
 	kfree_skb(skb);
 	return -1;
 }
-EXPORT_SYMBOL(lowpan_frag_rcv);
 
 #ifdef CONFIG_SYSCTL
 static int zero;
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index 12e10201d263..b1fd47d2802b 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -11,40 +11,99 @@
 #include <linux/if_arp.h>
 
 #include <net/6lowpan.h>
+#include <net/mac802154.h>
 #include <net/ieee802154_netdev.h>
 
 #include "6lowpan_i.h"
 
-static int lowpan_give_skb_to_device(struct sk_buff *skb,
-				     struct net_device *dev)
+#define LOWPAN_DISPATCH_FIRST		0xc0
+#define LOWPAN_DISPATCH_FRAG_MASK	0xf8
+
+#define LOWPAN_DISPATCH_NALP		0x00
+#define LOWPAN_DISPATCH_ESC		0x40
+#define LOWPAN_DISPATCH_HC1		0x42
+#define LOWPAN_DISPATCH_DFF		0x43
+#define LOWPAN_DISPATCH_BC0		0x50
+#define LOWPAN_DISPATCH_MESH		0x80
+
+static int lowpan_give_skb_to_device(struct sk_buff *skb)
 {
-	skb->dev = dev->ieee802154_ptr->lowpan_dev;
 	skb->protocol = htons(ETH_P_IPV6);
-	skb->pkt_type = PACKET_HOST;
 
 	return netif_rx(skb);
 }
 
-static int
-iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
+static int lowpan_rx_handlers_result(struct sk_buff *skb, lowpan_rx_result res)
+{
+	switch (res) {
+	case RX_CONTINUE:
+		/* nobody cared about this packet */
+		net_warn_ratelimited("%s: received unknown dispatch\n",
+				     __func__);
+
+		/* fall-through */
+	case RX_DROP_UNUSABLE:
+		kfree_skb(skb);
+
+		/* fall-through */
+	case RX_DROP:
+		return NET_RX_DROP;
+	case RX_QUEUED:
+		return lowpan_give_skb_to_device(skb);
+	default:
+		break;
+	}
+
+	return NET_RX_DROP;
+}
+
+static inline bool lowpan_is_frag1(u8 dispatch)
+{
+	return (dispatch & LOWPAN_DISPATCH_FRAG_MASK) == LOWPAN_DISPATCH_FRAG1;
+}
+
+static inline bool lowpan_is_fragn(u8 dispatch)
+{
+	return (dispatch & LOWPAN_DISPATCH_FRAG_MASK) == LOWPAN_DISPATCH_FRAGN;
+}
+
+static lowpan_rx_result lowpan_rx_h_frag(struct sk_buff *skb)
+{
+	int ret;
+
+	if (!(lowpan_is_frag1(*skb_network_header(skb)) ||
+	      lowpan_is_fragn(*skb_network_header(skb))))
+		return RX_CONTINUE;
+
+	ret = lowpan_frag_rcv(skb, *skb_network_header(skb) &
+			      LOWPAN_DISPATCH_FRAG_MASK);
+	if (ret == 1)
+		return RX_QUEUED;
+
+	/* Packet is freed by lowpan_frag_rcv on error or put into the frag
+	 * bucket.
+	 */
+	return RX_DROP;
+}
+
+int lowpan_iphc_decompress(struct sk_buff *skb)
 {
-	u8 iphc0, iphc1;
 	struct ieee802154_addr_sa sa, da;
+	struct ieee802154_hdr hdr;
+	u8 iphc0, iphc1;
 	void *sap, *dap;
 
-	raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len);
-	/* at least two bytes will be used for the encoding */
-	if (skb->len < 2)
+	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
 		return -EINVAL;
 
-	if (lowpan_fetch_skb_u8(skb, &iphc0))
-		return -EINVAL;
+	raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len);
 
-	if (lowpan_fetch_skb_u8(skb, &iphc1))
+	if (lowpan_fetch_skb_u8(skb, &iphc0) ||
+	    lowpan_fetch_skb_u8(skb, &iphc1))
 		return -EINVAL;
 
-	ieee802154_addr_to_sa(&sa, &hdr->source);
-	ieee802154_addr_to_sa(&da, &hdr->dest);
+	ieee802154_addr_to_sa(&sa, &hdr.source);
+	ieee802154_addr_to_sa(&da, &hdr.dest);
 
 	if (sa.addr_type == IEEE802154_ADDR_SHORT)
 		sap = &sa.short_addr;
@@ -61,77 +120,216 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
 					IEEE802154_ADDR_LEN, iphc0, iphc1);
 }
 
-static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
-		      struct packet_type *pt, struct net_device *orig_dev)
+static lowpan_rx_result lowpan_rx_h_iphc(struct sk_buff *skb)
 {
-	struct ieee802154_hdr hdr;
 	int ret;
 
-	if (dev->type != ARPHRD_IEEE802154 ||
-	    !dev->ieee802154_ptr->lowpan_dev)
-		goto drop;
+	if (!lowpan_is_iphc(*skb_network_header(skb)))
+		return RX_CONTINUE;
 
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (!skb)
-		goto drop;
+	/* Setting datagram_offset to zero indicates non frag handling
+	 * while doing lowpan_header_decompress.
+	 */
+	lowpan_802154_cb(skb)->d_size = 0;
 
-	if (!netif_running(dev))
-		goto drop_skb;
+	ret = lowpan_iphc_decompress(skb);
+	if (ret < 0)
+		return RX_DROP_UNUSABLE;
 
-	if (skb->pkt_type == PACKET_OTHERHOST)
-		goto drop_skb;
+	return RX_QUEUED;
+}
 
-	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
-		goto drop_skb;
-
-	/* check that it's our buffer */
-	if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
-		/* Pull off the 1-byte of 6lowpan header. */
-		skb_pull(skb, 1);
-		return lowpan_give_skb_to_device(skb, dev);
-	} else {
-		switch (skb->data[0] & 0xe0) {
-		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
-			ret = iphc_decompress(skb, &hdr);
-			if (ret < 0)
-				goto drop_skb;
-
-			return lowpan_give_skb_to_device(skb, dev);
-		case LOWPAN_DISPATCH_FRAG1:	/* first fragment header */
-			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
-			if (ret == 1) {
-				ret = iphc_decompress(skb, &hdr);
-				if (ret < 0)
-					goto drop_skb;
-
-				return lowpan_give_skb_to_device(skb, dev);
-			} else if (ret == -1) {
-				return NET_RX_DROP;
-			} else {
-				return NET_RX_SUCCESS;
-			}
-		case LOWPAN_DISPATCH_FRAGN:	/* next fragments headers */
-			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
-			if (ret == 1) {
-				ret = iphc_decompress(skb, &hdr);
-				if (ret < 0)
-					goto drop_skb;
-
-				return lowpan_give_skb_to_device(skb, dev);
-			} else if (ret == -1) {
-				return NET_RX_DROP;
-			} else {
-				return NET_RX_SUCCESS;
-			}
-		default:
-			break;
-		}
+lowpan_rx_result lowpan_rx_h_ipv6(struct sk_buff *skb)
+{
+	if (!lowpan_is_ipv6(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	/* Pull off the 1-byte of 6lowpan header. */
+	skb_pull(skb, 1);
+	return RX_QUEUED;
+}
+
+static inline bool lowpan_is_esc(u8 dispatch)
+{
+	return dispatch == LOWPAN_DISPATCH_ESC;
+}
+
+static lowpan_rx_result lowpan_rx_h_esc(struct sk_buff *skb)
+{
+	if (!lowpan_is_esc(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	net_warn_ratelimited("%s: %s\n", skb->dev->name,
+			     "6LoWPAN ESC not supported\n");
+
+	return RX_DROP_UNUSABLE;
+}
+
+static inline bool lowpan_is_hc1(u8 dispatch)
+{
+	return dispatch == LOWPAN_DISPATCH_HC1;
+}
+
+static lowpan_rx_result lowpan_rx_h_hc1(struct sk_buff *skb)
+{
+	if (!lowpan_is_hc1(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	net_warn_ratelimited("%s: %s\n", skb->dev->name,
+			     "6LoWPAN HC1 not supported\n");
+
+	return RX_DROP_UNUSABLE;
+}
+
+static inline bool lowpan_is_dff(u8 dispatch)
+{
+	return dispatch == LOWPAN_DISPATCH_DFF;
+}
+
+static lowpan_rx_result lowpan_rx_h_dff(struct sk_buff *skb)
+{
+	if (!lowpan_is_dff(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	net_warn_ratelimited("%s: %s\n", skb->dev->name,
+			     "6LoWPAN DFF not supported\n");
+
+	return RX_DROP_UNUSABLE;
+}
+
+static inline bool lowpan_is_bc0(u8 dispatch)
+{
+	return dispatch == LOWPAN_DISPATCH_BC0;
+}
+
+static lowpan_rx_result lowpan_rx_h_bc0(struct sk_buff *skb)
+{
+	if (!lowpan_is_bc0(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	net_warn_ratelimited("%s: %s\n", skb->dev->name,
+			     "6LoWPAN BC0 not supported\n");
+
+	return RX_DROP_UNUSABLE;
+}
+
+static inline bool lowpan_is_mesh(u8 dispatch)
+{
+	return (dispatch & LOWPAN_DISPATCH_FIRST) == LOWPAN_DISPATCH_MESH;
+}
+
+static lowpan_rx_result lowpan_rx_h_mesh(struct sk_buff *skb)
+{
+	if (!lowpan_is_mesh(*skb_network_header(skb)))
+		return RX_CONTINUE;
+
+	net_warn_ratelimited("%s: %s\n", skb->dev->name,
+			     "6LoWPAN MESH not supported\n");
+
+	return RX_DROP_UNUSABLE;
+}
+
+static int lowpan_invoke_rx_handlers(struct sk_buff *skb)
+{
+	lowpan_rx_result res;
+
+#define CALL_RXH(rxh)			\
+	do {				\
+		res = rxh(skb);	\
+		if (res != RX_CONTINUE)	\
+			goto rxh_next;	\
+	} while (0)
+
+	/* likely at first */
+	CALL_RXH(lowpan_rx_h_iphc);
+	CALL_RXH(lowpan_rx_h_frag);
+	CALL_RXH(lowpan_rx_h_ipv6);
+	CALL_RXH(lowpan_rx_h_esc);
+	CALL_RXH(lowpan_rx_h_hc1);
+	CALL_RXH(lowpan_rx_h_dff);
+	CALL_RXH(lowpan_rx_h_bc0);
+	CALL_RXH(lowpan_rx_h_mesh);
+
+rxh_next:
+	return lowpan_rx_handlers_result(skb, res);
+#undef CALL_RXH
+}
+
+static inline bool lowpan_is_nalp(u8 dispatch)
+{
+	return (dispatch & LOWPAN_DISPATCH_FIRST) == LOWPAN_DISPATCH_NALP;
+}
+
+/* Lookup for reserved dispatch values at:
+ * https://www.iana.org/assignments/_6lowpan-parameters/_6lowpan-parameters.xhtml#_6lowpan-parameters-1
+ *
+ * Last Updated: 2015-01-22
+ */
+static inline bool lowpan_is_reserved(u8 dispatch)
+{
+	return ((dispatch >= 0x44 && dispatch <= 0x4F) ||
+		(dispatch >= 0x51 && dispatch <= 0x5F) ||
+		(dispatch >= 0xc8 && dispatch <= 0xdf) ||
+		(dispatch >= 0xe8 && dispatch <= 0xff));
+}
+
+/* lowpan_rx_h_check checks on generic 6LoWPAN requirements
+ * in MAC and 6LoWPAN header.
+ *
+ * Don't manipulate the skb here, it could be shared buffer.
+ */
+static inline bool lowpan_rx_h_check(struct sk_buff *skb)
+{
+	__le16 fc = ieee802154_get_fc_from_skb(skb);
+
+	/* check on ieee802154 conform 6LoWPAN header */
+	if (!ieee802154_is_data(fc) ||
+	    !ieee802154_is_intra_pan(fc))
+		return false;
+
+	/* check if we can dereference the dispatch */
+	if (unlikely(!skb->len))
+		return false;
+
+	if (lowpan_is_nalp(*skb_network_header(skb)) ||
+	    lowpan_is_reserved(*skb_network_header(skb)))
+		return false;
+
+	return true;
+}
+
+static int lowpan_rcv(struct sk_buff *skb, struct net_device *wdev,
+		      struct packet_type *pt, struct net_device *orig_wdev)
+{
+	struct net_device *ldev;
+
+	if (wdev->type != ARPHRD_IEEE802154 ||
+	    skb->pkt_type == PACKET_OTHERHOST ||
+	    !lowpan_rx_h_check(skb))
+		return NET_RX_DROP;
+
+	ldev = wdev->ieee802154_ptr->lowpan_dev;
+	if (!ldev || !netif_running(ldev))
+		return NET_RX_DROP;
+
+	/* Replacing skb->dev and followed rx handlers will manipulate skb. */
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		return NET_RX_DROP;
+	skb->dev = ldev;
+
+	/* When receive frag1 it's likely that we manipulate the buffer.
+	 * When recevie iphc we manipulate the data buffer. So we need
+	 * to unshare the buffer.
+	 */
+	if (lowpan_is_frag1(*skb_network_header(skb)) ||
+	    lowpan_is_iphc(*skb_network_header(skb))) {
+		skb = skb_unshare(skb, GFP_ATOMIC);
+		if (!skb)
+			return NET_RX_DROP;
 	}
 
-drop_skb:
-	kfree_skb(skb);
-drop:
-	return NET_RX_DROP;
+	return lowpan_invoke_rx_handlers(skb);
 }
 
 static struct packet_type lowpan_packet_type = {
diff --git a/net/ieee802154/6lowpan/tx.c b/net/ieee802154/6lowpan/tx.c
index f6263fc12340..54939d031ea5 100644
--- a/net/ieee802154/6lowpan/tx.c
+++ b/net/ieee802154/6lowpan/tx.c
@@ -36,7 +36,7 @@ lowpan_addr_info *lowpan_skb_priv(const struct sk_buff *skb)
 			sizeof(struct lowpan_addr_info));
 }
 
-int lowpan_header_create(struct sk_buff *skb, struct net_device *dev,
+int lowpan_header_create(struct sk_buff *skb, struct net_device *ldev,
 			 unsigned short type, const void *_daddr,
 			 const void *_saddr, unsigned int len)
 {
@@ -51,7 +51,7 @@ int lowpan_header_create(struct sk_buff *skb, struct net_device *dev,
 		return 0;
 
 	if (!saddr)
-		saddr = dev->dev_addr;
+		saddr = ldev->dev_addr;
 
 	raw_dump_inline(__func__, "saddr", (unsigned char *)saddr, 8);
 	raw_dump_inline(__func__, "daddr", (unsigned char *)daddr, 8);
@@ -73,22 +73,21 @@ static struct sk_buff*
 lowpan_alloc_frag(struct sk_buff *skb, int size,
 		  const struct ieee802154_hdr *master_hdr)
 {
-	struct net_device *real_dev = lowpan_dev_info(skb->dev)->real_dev;
+	struct net_device *wdev = lowpan_dev_info(skb->dev)->wdev;
 	struct sk_buff *frag;
 	int rc;
 
-	frag = alloc_skb(real_dev->hard_header_len +
-			 real_dev->needed_tailroom + size,
+	frag = alloc_skb(wdev->hard_header_len + wdev->needed_tailroom + size,
 			 GFP_ATOMIC);
 
 	if (likely(frag)) {
-		frag->dev = real_dev;
+		frag->dev = wdev;
 		frag->priority = skb->priority;
-		skb_reserve(frag, real_dev->hard_header_len);
+		skb_reserve(frag, wdev->hard_header_len);
 		skb_reset_network_header(frag);
 		*mac_cb(frag) = *mac_cb(skb);
 
-		rc = dev_hard_header(frag, real_dev, 0, &master_hdr->dest,
+		rc = dev_hard_header(frag, wdev, 0, &master_hdr->dest,
 				     &master_hdr->source, size);
 		if (rc < 0) {
 			kfree_skb(frag);
@@ -123,19 +122,17 @@ lowpan_xmit_fragment(struct sk_buff *skb, const struct ieee802154_hdr *wpan_hdr,
 }
 
 static int
-lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev,
-		       const struct ieee802154_hdr *wpan_hdr)
+lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *ldev,
+		       const struct ieee802154_hdr *wpan_hdr, u16 dgram_size,
+		       u16 dgram_offset)
 {
-	u16 dgram_size, dgram_offset;
 	__be16 frag_tag;
 	u8 frag_hdr[5];
 	int frag_cap, frag_len, payload_cap, rc;
 	int skb_unprocessed, skb_offset;
 
-	dgram_size = lowpan_uncompress_size(skb, &dgram_offset) -
-		     skb->mac_len;
-	frag_tag = htons(lowpan_dev_info(dev)->fragment_tag);
-	lowpan_dev_info(dev)->fragment_tag++;
+	frag_tag = htons(lowpan_dev_info(ldev)->fragment_tag);
+	lowpan_dev_info(ldev)->fragment_tag++;
 
 	frag_hdr[0] = LOWPAN_DISPATCH_FRAG1 | ((dgram_size >> 8) & 0x07);
 	frag_hdr[1] = dgram_size & 0xff;
@@ -188,9 +185,10 @@ err:
 	return rc;
 }
 
-static int lowpan_header(struct sk_buff *skb, struct net_device *dev)
+static int lowpan_header(struct sk_buff *skb, struct net_device *ldev,
+			 u16 *dgram_size, u16 *dgram_offset)
 {
-	struct wpan_dev *wpan_dev = lowpan_dev_info(dev)->real_dev->ieee802154_ptr;
+	struct wpan_dev *wpan_dev = lowpan_dev_info(ldev)->wdev->ieee802154_ptr;
 	struct ieee802154_addr sa, da;
 	struct ieee802154_mac_cb *cb = mac_cb_init(skb);
 	struct lowpan_addr_info info;
@@ -202,7 +200,10 @@ static int lowpan_header(struct sk_buff *skb, struct net_device *dev)
 	daddr = &info.daddr.u.extended_addr;
 	saddr = &info.saddr.u.extended_addr;
 
-	lowpan_header_compress(skb, dev, ETH_P_IPV6, daddr, saddr, skb->len);
+	*dgram_size = skb->len;
+	lowpan_header_compress(skb, ldev, ETH_P_IPV6, daddr, saddr, skb->len);
+	/* dgram_offset = (saved bytes after compression) + lowpan header len */
+	*dgram_offset = (*dgram_size - skb->len) + skb_network_header_len(skb);
 
 	cb->type = IEEE802154_FC_TYPE_DATA;
 
@@ -227,14 +228,15 @@ static int lowpan_header(struct sk_buff *skb, struct net_device *dev)
 		cb->ackreq = wpan_dev->ackreq;
 	}
 
-	return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev,
-			ETH_P_IPV6, (void *)&da, (void *)&sa, 0);
+	return dev_hard_header(skb, lowpan_dev_info(ldev)->wdev, ETH_P_IPV6,
+			       (void *)&da, (void *)&sa, 0);
 }
 
-netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *ldev)
 {
 	struct ieee802154_hdr wpan_hdr;
 	int max_single, ret;
+	u16 dgram_size, dgram_offset;
 
 	pr_debug("package xmit\n");
 
@@ -245,7 +247,7 @@ netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!skb)
 		return NET_XMIT_DROP;
 
-	ret = lowpan_header(skb, dev);
+	ret = lowpan_header(skb, ldev, &dgram_size, &dgram_offset);
 	if (ret < 0) {
 		kfree_skb(skb);
 		return NET_XMIT_DROP;
@@ -259,13 +261,14 @@ netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
 	max_single = ieee802154_max_payload(&wpan_hdr);
 
 	if (skb_tail_pointer(skb) - skb_network_header(skb) <= max_single) {
-		skb->dev = lowpan_dev_info(dev)->real_dev;
+		skb->dev = lowpan_dev_info(ldev)->wdev;
 		return dev_queue_xmit(skb);
 	} else {
 		netdev_tx_t rc;
 
 		pr_debug("frame is too big, fragmentation is needed\n");
-		rc = lowpan_xmit_fragmented(skb, dev, &wpan_hdr);
+		rc = lowpan_xmit_fragmented(skb, ldev, &wpan_hdr, dgram_size,
+					    dgram_offset);
 
 		return rc < 0 ? NET_XMIT_DROP : rc;
 	}
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 09c76a7b474d..be033f22a3f3 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -136,6 +136,7 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
 	struct dst_entry *dst = skb_dst(skb);
 	struct xfrm_state *x = dst->xfrm;
 	int mtu;
+	bool toobig;
 
 #ifdef CONFIG_NETFILTER
 	if (!x) {
@@ -144,25 +145,29 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
 	}
 #endif
 
+	if (x->props.mode != XFRM_MODE_TUNNEL)
+		goto skip_frag;
+
 	if (skb->protocol == htons(ETH_P_IPV6))
 		mtu = ip6_skb_dst_mtu(skb);
 	else
 		mtu = dst_mtu(skb_dst(skb));
 
-	if (skb->len > mtu && xfrm6_local_dontfrag(skb)) {
+	toobig = skb->len > mtu && !skb_is_gso(skb);
+
+	if (toobig && xfrm6_local_dontfrag(skb)) {
 		xfrm6_local_rxpmtu(skb, mtu);
 		return -EMSGSIZE;
-	} else if (!skb->ignore_df && skb->len > mtu && skb->sk) {
+	} else if (!skb->ignore_df && toobig && skb->sk) {
 		xfrm_local_error(skb, mtu);
 		return -EMSGSIZE;
 	}
 
-	if (x->props.mode == XFRM_MODE_TUNNEL &&
-	    ((skb->len > mtu && !skb_is_gso(skb)) ||
-		dst_allfrag(skb_dst(skb)))) {
+	if (toobig || dst_allfrag(skb_dst(skb)))
 		return ip6_fragment(sk, skb,
 				    x->outer_mode->afinfo->output_finish);
-	}
+
+skip_frag:
 	return x->outer_mode->afinfo->output_finish(sk, skb);
 }
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 7f86d3b55060..4cad99d6c68b 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -125,6 +125,24 @@ static inline u32 netlink_group_mask(u32 group)
 	return group ? 1 << (group - 1) : 0;
 }
 
+static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
+					   gfp_t gfp_mask)
+{
+	unsigned int len = skb_end_offset(skb);
+	struct sk_buff *new;
+
+	new = alloc_skb(len, gfp_mask);
+	if (new == NULL)
+		return NULL;
+
+	NETLINK_CB(new).portid = NETLINK_CB(skb).portid;
+	NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group;
+	NETLINK_CB(new).creds = NETLINK_CB(skb).creds;
+
+	memcpy(skb_put(new, len), skb->data, len);
+	return new;
+}
+
 int netlink_add_tap(struct netlink_tap *nt)
 {
 	if (unlikely(nt->dev->type != ARPHRD_NETLINK))
@@ -206,7 +224,11 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb,
 	int ret = -ENOMEM;
 
 	dev_hold(dev);
-	nskb = skb_clone(skb, GFP_ATOMIC);
+
+	if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head))
+		nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
+	else
+		nskb = skb_clone(skb, GFP_ATOMIC);
 	if (nskb) {
 		nskb->dev = dev;
 		nskb->protocol = htons((u16) sk->sk_protocol);
@@ -279,11 +301,6 @@ static void netlink_rcv_wake(struct sock *sk)
 }
 
 #ifdef CONFIG_NETLINK_MMAP
-static bool netlink_skb_is_mmaped(const struct sk_buff *skb)
-{
-	return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
-}
-
 static bool netlink_rx_is_mmaped(struct sock *sk)
 {
 	return nlk_sk(sk)->rx_ring.pg_vec != NULL;
@@ -846,7 +863,6 @@ static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb)
 }
 
 #else /* CONFIG_NETLINK_MMAP */
-#define netlink_skb_is_mmaped(skb)	false
 #define netlink_rx_is_mmaped(sk)	false
 #define netlink_tx_is_mmaped(sk)	false
 #define netlink_mmap			sock_no_mmap
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index 89008405d6b4..df9a06090db6 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -59,6 +59,15 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk)
 	return container_of(sk, struct netlink_sock, sk);
 }
 
+static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NETLINK_MMAP
+	return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
+#else
+	return false;
+#endif /* CONFIG_NETLINK_MMAP */
+}
+
 struct netlink_table {
 	struct rhashtable	hash;
 	struct hlist_head	mc_list;
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index 2a071f470d57..d143aa9f6654 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -5,7 +5,8 @@
 config OPENVSWITCH
 	tristate "Open vSwitch"
 	depends on INET
-	depends on (!NF_CONNTRACK || NF_CONNTRACK)
+	depends on !NF_CONNTRACK || \
+		   (NF_CONNTRACK && (!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6))
 	select LIBCRC32C
 	select MPLS
 	select NET_MPLS_GSO
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b7143337e4fa..3d9ea9a48289 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1186,7 +1186,7 @@ static void sctp_v4_del_protocol(void)
 	unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
 }
 
-static int __net_init sctp_net_init(struct net *net)
+static int __net_init sctp_defaults_init(struct net *net)
 {
 	int status;
 
@@ -1279,12 +1279,6 @@ static int __net_init sctp_net_init(struct net *net)
 
 	sctp_dbg_objcnt_init(net);
 
-	/* Initialize the control inode/socket for handling OOTB packets.  */
-	if ((status = sctp_ctl_sock_init(net))) {
-		pr_err("Failed to initialize the SCTP control sock\n");
-		goto err_ctl_sock_init;
-	}
-
 	/* Initialize the local address list. */
 	INIT_LIST_HEAD(&net->sctp.local_addr_list);
 	spin_lock_init(&net->sctp.local_addr_lock);
@@ -1300,9 +1294,6 @@ static int __net_init sctp_net_init(struct net *net)
 
 	return 0;
 
-err_ctl_sock_init:
-	sctp_dbg_objcnt_exit(net);
-	sctp_proc_exit(net);
 err_init_proc:
 	cleanup_sctp_mibs(net);
 err_init_mibs:
@@ -1311,15 +1302,12 @@ err_sysctl_register:
 	return status;
 }
 
-static void __net_exit sctp_net_exit(struct net *net)
+static void __net_exit sctp_defaults_exit(struct net *net)
 {
 	/* Free the local address list */
 	sctp_free_addr_wq(net);
 	sctp_free_local_addr_list(net);
 
-	/* Free the control endpoint.  */
-	inet_ctl_sock_destroy(net->sctp.ctl_sock);
-
 	sctp_dbg_objcnt_exit(net);
 
 	sctp_proc_exit(net);
@@ -1327,9 +1315,32 @@ static void __net_exit sctp_net_exit(struct net *net)
 	sctp_sysctl_net_unregister(net);
 }
 
-static struct pernet_operations sctp_net_ops = {
-	.init = sctp_net_init,
-	.exit = sctp_net_exit,
+static struct pernet_operations sctp_defaults_ops = {
+	.init = sctp_defaults_init,
+	.exit = sctp_defaults_exit,
+};
+
+static int __net_init sctp_ctrlsock_init(struct net *net)
+{
+	int status;
+
+	/* Initialize the control inode/socket for handling OOTB packets.  */
+	status = sctp_ctl_sock_init(net);
+	if (status)
+		pr_err("Failed to initialize the SCTP control sock\n");
+
+	return status;
+}
+
+static void __net_init sctp_ctrlsock_exit(struct net *net)
+{
+	/* Free the control endpoint.  */
+	inet_ctl_sock_destroy(net->sctp.ctl_sock);
+}
+
+static struct pernet_operations sctp_ctrlsock_ops = {
+	.init = sctp_ctrlsock_init,
+	.exit = sctp_ctrlsock_exit,
 };
 
 /* Initialize the universe into something sensible.  */
@@ -1462,8 +1473,11 @@ static __init int sctp_init(void)
 	sctp_v4_pf_init();
 	sctp_v6_pf_init();
 
-	status = sctp_v4_protosw_init();
+	status = register_pernet_subsys(&sctp_defaults_ops);
+	if (status)
+		goto err_register_defaults;
 
+	status = sctp_v4_protosw_init();
 	if (status)
 		goto err_protosw_init;
 
@@ -1471,9 +1485,9 @@ static __init int sctp_init(void)
 	if (status)
 		goto err_v6_protosw_init;
 
-	status = register_pernet_subsys(&sctp_net_ops);
+	status = register_pernet_subsys(&sctp_ctrlsock_ops);
 	if (status)
-		goto err_register_pernet_subsys;
+		goto err_register_ctrlsock;
 
 	status = sctp_v4_add_protocol();
 	if (status)
@@ -1489,12 +1503,14 @@ out:
 err_v6_add_protocol:
 	sctp_v4_del_protocol();
 err_add_protocol:
-	unregister_pernet_subsys(&sctp_net_ops);
-err_register_pernet_subsys:
+	unregister_pernet_subsys(&sctp_ctrlsock_ops);
+err_register_ctrlsock:
 	sctp_v6_protosw_exit();
 err_v6_protosw_init:
 	sctp_v4_protosw_exit();
 err_protosw_init:
+	unregister_pernet_subsys(&sctp_defaults_ops);
+err_register_defaults:
 	sctp_v4_pf_exit();
 	sctp_v6_pf_exit();
 	sctp_sysctl_unregister();
@@ -1527,12 +1543,14 @@ static __exit void sctp_exit(void)
 	sctp_v6_del_protocol();
 	sctp_v4_del_protocol();
 
-	unregister_pernet_subsys(&sctp_net_ops);
+	unregister_pernet_subsys(&sctp_ctrlsock_ops);
 
 	/* Free protosw registrations */
 	sctp_v6_protosw_exit();
 	sctp_v4_protosw_exit();
 
+	unregister_pernet_subsys(&sctp_defaults_ops);
+
 	/* Unregister with socket layer. */
 	sctp_v6_pf_exit();
 	sctp_v4_pf_exit();
diff --git a/samples/Kconfig b/samples/Kconfig
index 224ebb46bed5..a4c6b2f8fa85 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -55,6 +55,13 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_KDBUS
+	bool "Build kdbus API example"
+	depends on KDBUS
+	help
+	  Build an example of how the kdbus API can be used from
+	  userspace.
+
 config SAMPLE_RPMSG_CLIENT
 	tristate "Build rpmsg client sample -- loadable modules only"
 	depends on RPMSG && m
diff --git a/samples/Makefile b/samples/Makefile
index f00257bcc5a7..f0ad51e5b342 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,5 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ trace_events/ livepatch/ \
-			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
+			   hw_breakpoint/ kfifo/ kdb/ kdbus/ hidraw/ rpmsg/ \
+			   seccomp/
diff --git a/samples/kdbus/.gitignore b/samples/kdbus/.gitignore
new file mode 100644
index 000000000000..ee07d9857086
--- /dev/null
+++ b/samples/kdbus/.gitignore
@@ -0,0 +1 @@
+kdbus-workers
diff --git a/samples/kdbus/Makefile b/samples/kdbus/Makefile
new file mode 100644
index 000000000000..137f84272099
--- /dev/null
+++ b/samples/kdbus/Makefile
@@ -0,0 +1,9 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+hostprogs-$(CONFIG_SAMPLE_KDBUS) += kdbus-workers
+
+always := $(hostprogs-y)
+
+HOSTCFLAGS_kdbus-workers.o += -I$(objtree)/usr/include
+HOSTLOADLIBES_kdbus-workers := -lrt
diff --git a/samples/kdbus/kdbus-api.h b/samples/kdbus/kdbus-api.h
new file mode 100644
index 000000000000..7f3abae18396
--- /dev/null
+++ b/samples/kdbus/kdbus-api.h
@@ -0,0 +1,114 @@
+#ifndef KDBUS_API_H
+#define KDBUS_API_H
+
+#include <sys/ioctl.h>
+#include <linux/kdbus.h>
+
+#define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
+#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
+#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
+#define KDBUS_ITEM_NEXT(item) \
+	(typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
+#define KDBUS_FOREACH(iter, first, _size)				\
+	for ((iter) = (first);						\
+	     ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) &&	\
+	       ((uint8_t *)(iter) >= (uint8_t *)(first));		\
+	     (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
+
+static inline int kdbus_cmd_bus_make(int control_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(control_fd, KDBUS_CMD_BUS_MAKE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_endpoint_make(int bus_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(bus_fd, KDBUS_CMD_ENDPOINT_MAKE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_endpoint_update(int ep_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(ep_fd, KDBUS_CMD_ENDPOINT_UPDATE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd)
+{
+	int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_update(int fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(fd, KDBUS_CMD_UPDATE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_byebye(int conn_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_BYEBYE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_conn_info(int conn_fd, struct kdbus_cmd_info *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_CONN_INFO, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_bus_creator_info(int conn_fd, struct kdbus_cmd_info *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_BUS_CREATOR_INFO, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_list(int fd, struct kdbus_cmd_list *cmd)
+{
+	int ret = ioctl(fd, KDBUS_CMD_LIST, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_send(int conn_fd, struct kdbus_cmd_send *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_SEND, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_recv(int conn_fd, struct kdbus_cmd_recv *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_RECV, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_name_release(int conn_fd, struct kdbus_cmd *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_NAME_RELEASE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_match_add(int conn_fd, struct kdbus_cmd_match *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_MATCH_ADD, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kdbus_cmd_match_remove(int conn_fd, struct kdbus_cmd_match *cmd)
+{
+	int ret = ioctl(conn_fd, KDBUS_CMD_MATCH_REMOVE, cmd);
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KDBUS_API_H */
diff --git a/samples/kdbus/kdbus-workers.c b/samples/kdbus/kdbus-workers.c
new file mode 100644
index 000000000000..5a6dfdce3bfd
--- /dev/null
+++ b/samples/kdbus/kdbus-workers.c
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * Example: Workers
+ * This program computes prime-numbers based on the sieve of Eratosthenes. The
+ * master sets up a shared memory region and spawns workers which clear out the
+ * non-primes. The master reacts to keyboard input and to client-requests to
+ * control what each worker does. Note that this is in no way meant as efficient
+ * way to compute primes. It should only serve as example how a master/worker
+ * concept can be implemented with kdbus used as control messages.
+ *
+ * The main process is called the 'master'. It creates a new, private bus which
+ * will be used between the master and its workers to communicate. The master
+ * then spawns a fixed number of workers. Whenever a worker dies (detected via
+ * SIGCHLD), the master spawns a new worker. When done, the master waits for all
+ * workers to exit, prints a status report and exits itself.
+ *
+ * The master process does *not* keep track of its workers. Instead, this
+ * example implements a PULL model. That is, the master acquires a well-known
+ * name on the bus which each worker uses to request tasks from the master. If
+ * there are no more tasks, the master will return an empty task-list, which
+ * casues a worker to exit immediately.
+ *
+ * As tasks can be computationally expensive, we support cancellation. Whenever
+ * the master process is interrupted, it will drop its well-known name on the
+ * bus. This causes kdbus to broadcast a name-change notification. The workers
+ * check for broadcast messages regularly and will exit if they receive one.
+ *
+ * This example exists of 4 objects:
+ *  * master: The master object contains the context of the master process. This
+ *            process manages the prime-context, spawns workers and assigns
+ *            prime-ranges to each worker to compute.
+ *            The master itself does not do any prime-computations itself.
+ *  * child:  The child object contains the context of a worker. It inherits the
+ *            prime context from its parent (the master) and then creates a new
+ *            bus context to request prime-ranges to compute.
+ *  * prime:  The "prime" object is used to abstract how we compute primes. When
+ *            allocated, it prepares a memory region to hold 1 bit for each
+ *            natural number up to a fixed maximum ('MAX_PRIMES').
+ *            The memory region is backed by a memfd which we share between
+ *            processes. Each worker now gets assigned a range of natural
+ *            numbers which it clears multiples of off the memory region. The
+ *            master process is responsible of distributing all natural numbers
+ *            up to the fixed maximum to its workers.
+ *  * bus:    The bus object is an abstraction of the kdbus API. It is pretty
+ *            straightfoward and only manages the connection-fd plus the
+ *            memory-mapped pool in a single object.
+ *
+ * This example is in reversed order, which should make it easier to read
+ * top-down, but requires some forward-declarations. Just ignore those.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+
+/* glibc < 2.7 does not ship sys/signalfd.h */
+/* we require kernels with __NR_memfd_create */
+#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 7 && defined(__NR_memfd_create)
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/memfd.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/signalfd.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+#include "kdbus-api.h"
+
+/* FORWARD DECLARATIONS */
+
+#define POOL_SIZE (16 * 1024 * 1024)
+#define MAX_PRIMES (2UL << 24)
+#define WORKER_COUNT (16)
+#define PRIME_STEPS (65536 * 4)
+
+static const char *arg_busname = "example-workers";
+static const char *arg_modname = "kdbus";
+static const char *arg_master = "org.freedesktop.master";
+
+static int err_assert(int r_errno, const char *msg, const char *func, int line,
+		      const char *file)
+{
+	r_errno = (r_errno != 0) ? -abs(r_errno) : -EFAULT;
+	if (r_errno < 0) {
+		errno = -r_errno;
+		fprintf(stderr, "ERR: %s: %m (%s:%d in %s)\n",
+			msg, func, line, file);
+	}
+	return r_errno;
+}
+
+#define err_r(_r, _msg) err_assert((_r), (_msg), __func__, __LINE__, __FILE__)
+#define err(_msg) err_r(errno, (_msg))
+
+struct prime;
+struct bus;
+struct master;
+struct child;
+
+struct prime {
+	int fd;
+	uint8_t *area;
+	size_t max;
+	size_t done;
+	size_t status;
+};
+
+static int prime_new(struct prime **out);
+static void prime_free(struct prime *p);
+static bool prime_done(struct prime *p);
+static void prime_consume(struct prime *p, size_t amount);
+static int prime_run(struct prime *p, struct bus *cancel, size_t number);
+static void prime_print(struct prime *p);
+
+struct bus {
+	int fd;
+	uint8_t *pool;
+};
+
+static int bus_open_connection(struct bus **out, uid_t uid, const char *name,
+			       uint64_t recv_flags);
+static void bus_close_connection(struct bus *b);
+static void bus_poool_free_slice(struct bus *b, uint64_t offset);
+static int bus_acquire_name(struct bus *b, const char *name);
+static int bus_install_name_loss_match(struct bus *b, const char *name);
+static int bus_poll(struct bus *b);
+static int bus_make(uid_t uid, const char *name);
+
+struct master {
+	size_t n_workers;
+	size_t max_workers;
+
+	int signal_fd;
+	int control_fd;
+
+	struct prime *prime;
+	struct bus *bus;
+};
+
+static int master_new(struct master **out);
+static void master_free(struct master *m);
+static int master_run(struct master *m);
+static int master_poll(struct master *m);
+static int master_handle_stdin(struct master *m);
+static int master_handle_signal(struct master *m);
+static int master_handle_bus(struct master *m);
+static int master_reply(struct master *m, const struct kdbus_msg *msg);
+static int master_waitpid(struct master *m);
+static int master_spawn(struct master *m);
+
+struct child {
+	struct bus *bus;
+	struct prime *prime;
+};
+
+static int child_new(struct child **out, struct prime *p);
+static void child_free(struct child *c);
+static int child_run(struct child *c);
+
+/* END OF FORWARD DECLARATIONS */
+
+/*
+ * This is the main entrypoint of this example. It is pretty straightforward. We
+ * create a master object, run the computation, print a status report and then
+ * exit. Nothing particularly interesting here, so lets look into the master
+ * object...
+ */
+int main(int argc, char **argv)
+{
+	struct master *m = NULL;
+	int r;
+
+	r = master_new(&m);
+	if (r < 0)
+		goto out;
+
+	r = master_run(m);
+	if (r < 0)
+		goto out;
+
+	if (0)
+		prime_print(m->prime);
+
+out:
+	master_free(m);
+	if (r < 0 && r != -EINTR)
+		fprintf(stderr, "failed\n");
+	else
+		fprintf(stderr, "done\n");
+	return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+/*
+ * ...this will allocate a new master context. It keeps track of the current
+ * number of children/workers that are running, manages a signalfd to track
+ * SIGCHLD, and creates a private kdbus bus. Afterwards, it opens its connection
+ * to the bus and acquires a well known-name (arg_master).
+ */
+static int master_new(struct master **out)
+{
+	struct master *m;
+	sigset_t smask;
+	int r;
+
+	m = calloc(1, sizeof(*m));
+	if (!m)
+		return err("cannot allocate master");
+
+	m->max_workers = WORKER_COUNT;
+	m->signal_fd = -1;
+	m->control_fd = -1;
+
+	/* Block SIGINT and SIGCHLD signals */
+	sigemptyset(&smask);
+	sigaddset(&smask, SIGINT);
+	sigaddset(&smask, SIGCHLD);
+	sigprocmask(SIG_BLOCK, &smask, NULL);
+
+	m->signal_fd = signalfd(-1, &smask, SFD_CLOEXEC);
+	if (m->signal_fd < 0) {
+		r = err("cannot create signalfd");
+		goto error;
+	}
+
+	r = prime_new(&m->prime);
+	if (r < 0)
+		goto error;
+
+	m->control_fd = bus_make(getuid(), arg_busname);
+	if (m->control_fd < 0) {
+		r = m->control_fd;
+		goto error;
+	}
+
+	/*
+	 * Open a bus connection for the master, and require each received
+	 * message to have a metadata item of type KDBUS_ITEM_PIDS attached.
+	 * The current UID is needed to compute the name of the bus node to
+	 * connect to.
+	 */
+	r = bus_open_connection(&m->bus, getuid(),
+				arg_busname, KDBUS_ATTACH_PIDS);
+	if (r < 0)
+		goto error;
+
+	/*
+	 * Acquire a well-known name on the bus, so children can address
+	 * messages to the master using KDBUS_DST_ID_NAME as destination-ID
+	 * of messages.
+	 */
+	r = bus_acquire_name(m->bus, arg_master);
+	if (r < 0)
+		goto error;
+
+	*out = m;
+	return 0;
+
+error:
+	master_free(m);
+	return r;
+}
+
+/* pretty straightforward destructor of a master object */
+static void master_free(struct master *m)
+{
+	if (!m)
+		return;
+
+	bus_close_connection(m->bus);
+	if (m->control_fd >= 0)
+		close(m->control_fd);
+	prime_free(m->prime);
+	if (m->signal_fd >= 0)
+		close(m->signal_fd);
+	free(m);
+}
+
+static int master_run(struct master *m)
+{
+	int res, r = 0;
+
+	while (!prime_done(m->prime)) {
+		while (m->n_workers < m->max_workers) {
+			r = master_spawn(m);
+			if (r < 0)
+				break;
+		}
+
+		r = master_poll(m);
+		if (r < 0)
+			break;
+	}
+
+	if (r < 0) {
+		bus_close_connection(m->bus);
+		m->bus = NULL;
+	}
+
+	while (m->n_workers > 0) {
+		res = master_poll(m);
+		if (res < 0) {
+			if (m->bus) {
+				bus_close_connection(m->bus);
+				m->bus = NULL;
+			}
+			r = res;
+		}
+	}
+
+	return r == -EINTR ? 0 : r;
+}
+
+static int master_poll(struct master *m)
+{
+	struct pollfd fds[3] = {};
+	int r = 0, n = 0;
+
+	/*
+	 * Add stdin, the eventfd and the connection owner file descriptor to
+	 * the pollfd table, and handle incoming traffic on the latter in
+	 * master_handle_bus().
+	 */
+	fds[n].fd = STDIN_FILENO;
+	fds[n++].events = POLLIN;
+	fds[n].fd = m->signal_fd;
+	fds[n++].events = POLLIN;
+	if (m->bus) {
+		fds[n].fd = m->bus->fd;
+		fds[n++].events = POLLIN;
+	}
+
+	r = poll(fds, n, -1);
+	if (r < 0)
+		return err("poll() failed");
+
+	if (fds[0].revents & POLLIN)
+		r = master_handle_stdin(m);
+	else if (fds[0].revents)
+		r = err("ERR/HUP on stdin");
+	if (r < 0)
+		return r;
+
+	if (fds[1].revents & POLLIN)
+		r = master_handle_signal(m);
+	else if (fds[1].revents)
+		r = err("ERR/HUP on signalfd");
+	if (r < 0)
+		return r;
+
+	if (fds[2].revents & POLLIN)
+		r = master_handle_bus(m);
+	else if (fds[2].revents)
+		r = err("ERR/HUP on bus");
+
+	return r;
+}
+
+static int master_handle_stdin(struct master *m)
+{
+	char buf[128];
+	ssize_t l;
+	int r = 0;
+
+	l = read(STDIN_FILENO, buf, sizeof(buf));
+	if (l < 0)
+		return err("cannot read stdin");
+	if (l == 0)
+		return err_r(-EINVAL, "EOF on stdin");
+
+	while (l-- > 0) {
+		switch (buf[l]) {
+		case 'q':
+			/* quit */
+			r = -EINTR;
+			break;
+		case '\n':
+		case ' ':
+			/* ignore */
+			break;
+		default:
+			if (isgraph(buf[l]))
+				fprintf(stderr, "invalid input '%c'\n", buf[l]);
+			else
+				fprintf(stderr, "invalid input 0x%x\n", buf[l]);
+			break;
+		}
+	}
+
+	return r;
+}
+
+static int master_handle_signal(struct master *m)
+{
+	struct signalfd_siginfo val;
+	ssize_t l;
+
+	l = read(m->signal_fd, &val, sizeof(val));
+	if (l < 0)
+		return err("cannot read signalfd");
+	if (l != sizeof(val))
+		return err_r(-EINVAL, "invalid data from signalfd");
+
+	switch (val.ssi_signo) {
+	case SIGCHLD:
+		return master_waitpid(m);
+	case SIGINT:
+		return err_r(-EINTR, "interrupted");
+	default:
+		return err_r(-EINVAL, "caught invalid signal");
+	}
+}
+
+static int master_handle_bus(struct master *m)
+{
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+	const struct kdbus_msg *msg = NULL;
+	const struct kdbus_item *item;
+	const struct kdbus_vec *vec = NULL;
+	int r = 0;
+
+	/*
+	 * To receive a message, the KDBUS_CMD_RECV ioctl is used.
+	 * It takes an argument of type 'struct kdbus_cmd_recv', which
+	 * will contain information on the received message when the call
+	 * returns. See kdbus.message(7).
+	 */
+	r = kdbus_cmd_recv(m->bus->fd, &recv);
+	/*
+	 * EAGAIN is returned when there is no message waiting on this
+	 * connection. This is not an error - simply bail out.
+	 */
+	if (r == -EAGAIN)
+		return 0;
+	if (r < 0)
+		return err_r(r, "cannot receive message");
+
+	/*
+	 * Messages received by a connection are stored inside the connection's
+	 * pool, at an offset that has been returned in the 'recv' command
+	 * struct above. The value describes the relative offset from the
+	 * start address of the pool. A message is described with
+	 * 'struct kdbus_msg'. See kdbus.message(7).
+	 */
+	msg = (void *)(m->bus->pool + recv.msg.offset);
+
+	/*
+	 * A messages describes its actual payload in an array of items.
+	 * KDBUS_FOREACH() is a simple iterator that walks such an array.
+	 * struct kdbus_msg has a field to denote its total size, which is
+	 * needed to determine the number of items in the array.
+	 */
+	KDBUS_FOREACH(item, msg->items,
+		      msg->size - offsetof(struct kdbus_msg, items)) {
+		/*
+		 * An item of type PAYLOAD_OFF describes in-line memory
+		 * stored in the pool at a described offset. That offset is
+		 * relative to the start address of the message header.
+		 * This example program only expects one single item of that
+		 * type, remembers the struct kdbus_vec member of the item
+		 * when it sees it, and bails out if there is more than one
+		 * of them.
+		 */
+		if (item->type == KDBUS_ITEM_PAYLOAD_OFF) {
+			if (vec) {
+				r = err_r(-EEXIST,
+					  "message with multiple vecs");
+				break;
+			}
+			vec = &item->vec;
+			if (vec->size != 1) {
+				r = err_r(-EINVAL, "invalid message size");
+				break;
+			}
+
+		/*
+		 * MEMFDs are transported as items of type PAYLOAD_MEMFD.
+		 * If such an item is attached, a new file descriptor was
+		 * installed into the task when KDBUS_CMD_RECV was called, and
+		 * its number is stored in item->memfd.fd.
+		 * Implementers *must* handle this item type and close the
+		 * file descriptor when no longer needed in order to prevent
+		 * file descriptor exhaustion. This example program just bails
+		 * out with an error in this case, as memfds are not expected
+		 * in this context.
+		 */
+		} else if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD) {
+			r = err_r(-EINVAL, "message with memfd");
+			break;
+		}
+	}
+	if (r < 0)
+		goto exit;
+	if (!vec) {
+		r = err_r(-EINVAL, "empty message");
+		goto exit;
+	}
+
+	switch (*((const uint8_t *)msg + vec->offset)) {
+	case 'r': {
+		r = master_reply(m, msg);
+		break;
+	}
+	default:
+		r = err_r(-EINVAL, "invalid message type");
+		break;
+	}
+
+exit:
+	/*
+	 * We are done with the memory slice that was given to us through
+	 * recv.msg.offset. Tell the kernel it can use it for other content
+	 * in the future. See kdbus.pool(7).
+	 */
+	bus_poool_free_slice(m->bus, recv.msg.offset);
+	return r;
+}
+
+static int master_reply(struct master *m, const struct kdbus_msg *msg)
+{
+	struct kdbus_cmd_send cmd;
+	struct kdbus_item *item;
+	struct kdbus_msg *reply;
+	size_t size, status, p[2];
+	int r;
+
+	/*
+	 * This functions sends a message over kdbus. To do this, it uses the
+	 * KDBUS_CMD_SEND ioctl, which takes a command struct argument of type
+	 * 'struct kdbus_cmd_send'. This struct stores a pointer to the actual
+	 * message to send. See kdbus.message(7).
+	 */
+	p[0] = m->prime->done;
+	p[1] = prime_done(m->prime) ? 0 : PRIME_STEPS;
+
+	size = sizeof(*reply);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	/* Prepare the message to send */
+	reply = alloca(size);
+	memset(reply, 0, size);
+	reply->size = size;
+
+	/* Each message has a cookie that can be used to send replies */
+	reply->cookie = 1;
+
+	/* The payload_type is arbitrary, but it must be non-zero */
+	reply->payload_type = 0xdeadbeef;
+
+	/*
+	 * We are sending a reply. Let the kernel know the cookie of the
+	 * message we are replying to.
+	 */
+	reply->cookie_reply = msg->cookie;
+
+	/*
+	 * Messages can either be directed to a well-known name (stored as
+	 * string) or to a unique name (stored as number). This example does
+	 * the latter. If the message would be directed to a well-known name
+	 * instead, the message's dst_id field would be set to
+	 * KDBUS_DST_ID_NAME, and the name would be attaches in an item of type
+	 * KDBUS_ITEM_DST_NAME. See below for an example, and also refer to
+	 * kdbus.message(7).
+	 */
+	reply->dst_id = msg->src_id;
+
+	/* Our message has exactly one item to store its payload */
+	item = reply->items;
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)p;
+	item->vec.size = sizeof(p);
+
+	/*
+	 * Now prepare the command struct, and reference the message we want
+	 * to send.
+	 */
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)reply;
+
+	/*
+	 * Finally, employ the command on the connection owner
+	 * file descriptor.
+	 */
+	r = kdbus_cmd_send(m->bus->fd, &cmd);
+	if (r < 0)
+		return err_r(r, "cannot send reply");
+
+	if (p[1]) {
+		prime_consume(m->prime, p[1]);
+		status = m->prime->done * 10000 / m->prime->max;
+		if (status != m->prime->status) {
+			m->prime->status = status;
+			fprintf(stderr, "status: %7.3lf%%\n",
+				(double)status / 100);
+		}
+	}
+
+	return 0;
+}
+
+static int master_waitpid(struct master *m)
+{
+	pid_t pid;
+	int r;
+
+	while ((pid = waitpid(-1, &r, WNOHANG)) > 0) {
+		if (m->n_workers > 0)
+			--m->n_workers;
+		if (!WIFEXITED(r))
+			r = err_r(-EINVAL, "child died unexpectedly");
+		else if (WEXITSTATUS(r) != 0)
+			r = err_r(-WEXITSTATUS(r), "child failed");
+	}
+
+	return r;
+}
+
+static int master_spawn(struct master *m)
+{
+	struct child *c = NULL;
+	struct prime *p = NULL;
+	pid_t pid;
+	int r;
+
+	/* Spawn off one child and call child_run() inside it */
+
+	pid = fork();
+	if (pid < 0)
+		return err("cannot fork");
+	if (pid > 0) {
+		/* parent */
+		++m->n_workers;
+		return 0;
+	}
+
+	/* child */
+
+	p = m->prime;
+	m->prime = NULL;
+	master_free(m);
+
+	r = child_new(&c, p);
+	if (r < 0)
+		goto exit;
+
+	r = child_run(c);
+
+exit:
+	child_free(c);
+	exit(abs(r));
+}
+
+static int child_new(struct child **out, struct prime *p)
+{
+	struct child *c;
+	int r;
+
+	c = calloc(1, sizeof(*c));
+	if (!c)
+		return err("cannot allocate child");
+
+	c->prime = p;
+
+	/*
+	 * Open a connection to the bus and require each received message to
+	 * carry a list of the well-known names the sendind connection currently
+	 * owns. The current UID is needed in order to determine the name of the
+	 * bus node to connect to.
+	 */
+	r = bus_open_connection(&c->bus, getuid(),
+				arg_busname, KDBUS_ATTACH_NAMES);
+	if (r < 0)
+		goto error;
+
+	/*
+	 * Install a kdbus match so the child's connection gets notified when
+	 * the master loses its well-known name.
+	 */
+	r = bus_install_name_loss_match(c->bus, arg_master);
+	if (r < 0)
+		goto error;
+
+	*out = c;
+	return 0;
+
+error:
+	child_free(c);
+	return r;
+}
+
+static void child_free(struct child *c)
+{
+	if (!c)
+		return;
+
+	bus_close_connection(c->bus);
+	prime_free(c->prime);
+	free(c);
+}
+
+static int child_run(struct child *c)
+{
+	struct kdbus_cmd_send cmd;
+	struct kdbus_item *item;
+	struct kdbus_vec *vec = NULL;
+	struct kdbus_msg *msg;
+	struct timespec spec;
+	size_t n, steps, size;
+	int r = 0;
+
+	/*
+	 * Let's send a message to the master and ask for work. To do this,
+	 * we use the KDBUS_CMD_SEND ioctl, which takes an argument of type
+	 * 'struct kdbus_cmd_send'. This struct stores a pointer to the actual
+	 * message to send. See kdbus.message(7).
+	 */
+	size = sizeof(*msg);
+	size += KDBUS_ITEM_SIZE(strlen(arg_master) + 1);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	msg = alloca(size);
+	memset(msg, 0, size);
+	msg->size = size;
+
+	/*
+	 * Tell the kernel that we expect a reply to this message. This means
+	 * that
+	 *
+	 * a) The remote peer will gain temporary permission to talk to us
+	 *    even if it would not be allowed to normally.
+	 *
+	 * b) A timeout value is required.
+	 *
+	 *    For asynchronous send commands, if no reply is received, we will
+	 *    get a kernel notification with an item of type
+	 *    KDBUS_ITEM_REPLY_TIMEOUT attached.
+	 *
+	 *    For synchronous send commands (which this example does), the
+	 *    ioctl will block until a reply is received or the timeout is
+	 *    exceeded.
+	 */
+	msg->flags = KDBUS_MSG_EXPECT_REPLY;
+
+	/* Set our cookie. Replies must use this cookie to send their reply. */
+	msg->cookie = 1;
+
+	/* The payload_type is arbitrary, but it must be non-zero */
+	msg->payload_type = 0xdeadbeef;
+
+	/*
+	 * We are sending our message to the current owner of a well-known
+	 * name. This makes an item of type KDBUS_ITEM_DST_NAME mandatory.
+	 */
+	msg->dst_id = KDBUS_DST_ID_NAME;
+
+	/*
+	 * Set the reply timeout to 5 seconds. Timeouts are always set in
+	 * absolute timestamps, based con CLOCK_MONOTONIC. See kdbus.message(7).
+	 */
+	clock_gettime(CLOCK_MONOTONIC_COARSE, &spec);
+	msg->timeout_ns += (5 + spec.tv_sec) * 1000ULL * 1000ULL * 1000ULL;
+	msg->timeout_ns += spec.tv_nsec;
+
+	/*
+	 * Fill the appended items. First, set the well-known name of the
+	 * destination we want to talk to.
+	 */
+	item = msg->items;
+	item->type = KDBUS_ITEM_DST_NAME;
+	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(arg_master) + 1;
+	strcpy(item->str, arg_master);
+
+	/*
+	 * The 2nd item contains a vector to memory we want to send. It
+	 * can be content of any type. In our case, we're sending a one-byte
+	 * string only. The memory referenced by this item will be copied into
+	 * the pool of the receiver connection, and does not need to be valid
+	 * after the command is employed.
+	 */
+	item = KDBUS_ITEM_NEXT(item);
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)"r";
+	item->vec.size = 1;
+
+	/* Set up the command struct and reference the message we prepared */
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	/*
+	 * The send commands knows a mode in which it will block until a
+	 * reply to a message is received. This example uses that mode.
+	 * The pool offset to the received reply will be stored in the command
+	 * struct after the send command returned. See below.
+	 */
+	cmd.flags = KDBUS_SEND_SYNC_REPLY;
+
+	/*
+	 * Finally, employ the command on the connection owner
+	 * file descriptor.
+	 */
+	r = kdbus_cmd_send(c->bus->fd, &cmd);
+	if (r == -ESRCH || r == -EPIPE || r == -ECONNRESET)
+		return 0;
+	if (r < 0)
+		return err_r(r, "cannot send request to master");
+
+	/*
+	 * The command was sent with the KDBUS_SEND_SYNC_REPLY flag set,
+	 * and returned successfully, which means that cmd.reply.offset now
+	 * points to a message inside our connection's pool where the reply
+	 * is found. This is equivalent to receiving the reply with
+	 * KDBUS_CMD_RECV, but it doesn't require waiting for the reply with
+	 * poll() and also saves the ioctl to receive the message.
+	 */
+	msg = (void *)(c->bus->pool + cmd.reply.offset);
+
+	/*
+	 * A messages describes its actual payload in an array of items.
+	 * KDBUS_FOREACH() is a simple iterator that walks such an array.
+	 * struct kdbus_msg has a field to denote its total size, which is
+	 * needed to determine the number of items in the array.
+	 */
+	KDBUS_FOREACH(item, msg->items,
+		      msg->size - offsetof(struct kdbus_msg, items)) {
+		/*
+		 * An item of type PAYLOAD_OFF describes in-line memory
+		 * stored in the pool at a described offset. That offset is
+		 * relative to the start address of the message header.
+		 * This example program only expects one single item of that
+		 * type, remembers the struct kdbus_vec member of the item
+		 * when it sees it, and bails out if there is more than one
+		 * of them.
+		 */
+		if (item->type == KDBUS_ITEM_PAYLOAD_OFF) {
+			if (vec) {
+				r = err_r(-EEXIST,
+					  "message with multiple vecs");
+				break;
+			}
+			vec = &item->vec;
+			if (vec->size != 2 * sizeof(size_t)) {
+				r = err_r(-EINVAL, "invalid message size");
+				break;
+			}
+		/*
+		 * MEMFDs are transported as items of type PAYLOAD_MEMFD.
+		 * If such an item is attached, a new file descriptor was
+		 * installed into the task when KDBUS_CMD_RECV was called, and
+		 * its number is stored in item->memfd.fd.
+		 * Implementers *must* handle this item type close the
+		 * file descriptor when no longer needed in order to prevent
+		 * file descriptor exhaustion. This example program just bails
+		 * out with an error in this case, as memfds are not expected
+		 * in this context.
+		 */
+		} else if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD) {
+			r = err_r(-EINVAL, "message with memfd");
+			break;
+		}
+	}
+	if (r < 0)
+		goto exit;
+	if (!vec) {
+		r = err_r(-EINVAL, "empty message");
+		goto exit;
+	}
+
+	n = ((size_t *)((const uint8_t *)msg + vec->offset))[0];
+	steps = ((size_t *)((const uint8_t *)msg + vec->offset))[1];
+
+	while (steps-- > 0) {
+		++n;
+		r = prime_run(c->prime, c->bus, n);
+		if (r < 0)
+			break;
+		r = bus_poll(c->bus);
+		if (r != 0) {
+			r = r < 0 ? r : -EINTR;
+			break;
+		}
+	}
+
+exit:
+	/*
+	 * We are done with the memory slice that was given to us through
+	 * cmd.reply.offset. Tell the kernel it can use it for other content
+	 * in the future. See kdbus.pool(7).
+	 */
+	bus_poool_free_slice(c->bus, cmd.reply.offset);
+	return r;
+}
+
+/*
+ * Prime Computation
+ *
+ */
+
+static int prime_new(struct prime **out)
+{
+	struct prime *p;
+	int r;
+
+	p = calloc(1, sizeof(*p));
+	if (!p)
+		return err("cannot allocate prime memory");
+
+	p->fd = -1;
+	p->area = MAP_FAILED;
+	p->max = MAX_PRIMES;
+
+	/*
+	 * Prepare and map a memfd to store the bit-fields for the number
+	 * ranges we want to perform the prime detection on.
+	 */
+	p->fd = syscall(__NR_memfd_create, "prime-area", MFD_CLOEXEC);
+	if (p->fd < 0) {
+		r = err("cannot create memfd");
+		goto error;
+	}
+
+	r = ftruncate(p->fd, p->max / 8 + 1);
+	if (r < 0) {
+		r = err("cannot ftruncate area");
+		goto error;
+	}
+
+	p->area = mmap(NULL, p->max / 8 + 1, PROT_READ | PROT_WRITE,
+		       MAP_SHARED, p->fd, 0);
+	if (p->area == MAP_FAILED) {
+		r = err("cannot mmap memfd");
+		goto error;
+	}
+
+	*out = p;
+	return 0;
+
+error:
+	prime_free(p);
+	return r;
+}
+
+static void prime_free(struct prime *p)
+{
+	if (!p)
+		return;
+
+	if (p->area != MAP_FAILED)
+		munmap(p->area, p->max / 8 + 1);
+	if (p->fd >= 0)
+		close(p->fd);
+	free(p);
+}
+
+static bool prime_done(struct prime *p)
+{
+	return p->done >= p->max;
+}
+
+static void prime_consume(struct prime *p, size_t amount)
+{
+	p->done += amount;
+}
+
+static int prime_run(struct prime *p, struct bus *cancel, size_t number)
+{
+	size_t i, n = 0;
+	int r;
+
+	if (number < 2 || number > 65535)
+		return 0;
+
+	for (i = number * number;
+	     i < p->max && i > number;
+	     i += number) {
+		p->area[i / 8] |= 1 << (i % 8);
+
+		if (!(++n % (1 << 20))) {
+			r = bus_poll(cancel);
+			if (r != 0)
+				return r < 0 ? r : -EINTR;
+		}
+	}
+
+	return 0;
+}
+
+static void prime_print(struct prime *p)
+{
+	size_t i, l = 0;
+
+	fprintf(stderr, "PRIMES:");
+	for (i = 0; i < p->max; ++i) {
+		if (!(p->area[i / 8] & (1 << (i % 8))))
+			fprintf(stderr, "%c%7zu", !(l++ % 16) ? '\n' : ' ', i);
+	}
+	fprintf(stderr, "\nEND\n");
+}
+
+static int bus_open_connection(struct bus **out, uid_t uid, const char *name,
+			       uint64_t recv_flags)
+{
+	struct kdbus_cmd_hello hello;
+	char path[128];
+	struct bus *b;
+	int r;
+
+	/*
+	 * The 'bus' object is our representation of a kdbus connection which
+	 * stores two details: the connection owner file descriptor, and the
+	 * mmap()ed memory of its associated pool. See kdbus.connection(7) and
+	 * kdbus.pool(7).
+	 */
+	b = calloc(1, sizeof(*b));
+	if (!b)
+		return err("cannot allocate bus memory");
+
+	b->fd = -1;
+	b->pool = MAP_FAILED;
+
+	/* Compute the name of the bus node to connect to. */
+	snprintf(path, sizeof(path), "/sys/fs/%s/%lu-%s/bus",
+		 arg_modname, (unsigned long)uid, name);
+	b->fd = open(path, O_RDWR | O_CLOEXEC);
+	if (b->fd < 0) {
+		r = err("cannot open bus");
+		goto error;
+	}
+
+	/*
+	 * To make a connection to the bus, the KDBUS_CMD_HELLO ioctl is used.
+	 * It takes an argument of type 'struct kdbus_cmd_hello'.
+	 */
+	memset(&hello, 0, sizeof(hello));
+	hello.size = sizeof(hello);
+
+	/*
+	 * Specify a mask of metadata attach flags, describing metadata items
+	 * that this new connection allows to be sent.
+	 */
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+
+	/*
+	 * Specify a mask of metadata attach flags, describing metadata items
+	 * that this new connection wants to be receive along with each message.
+	 */
+	hello.attach_flags_recv = recv_flags;
+
+	/*
+	 * A connection may choose the size of its pool, but the number has to
+	 * comply with two rules: a) it must be greater than 0, and b) it must
+	 * be a mulitple of PAGE_SIZE. See kdbus.pool(7).
+	 */
+	hello.pool_size = POOL_SIZE;
+
+	/*
+	 * Now employ the command on the file descriptor opened above.
+	 * This command will turn the file descriptor into a connection-owner
+	 * file descriptor that controls the life-time of the connection; once
+	 * it's closed, the connection is shut down.
+	 */
+	r = kdbus_cmd_hello(b->fd, &hello);
+	if (r < 0) {
+		err_r(r, "HELLO failed");
+		goto error;
+	}
+
+	bus_poool_free_slice(b, hello.offset);
+
+	/*
+	 * Map the pool of the connection. Its size has been set in the
+	 * command struct above. See kdbus.pool(7).
+	 */
+	b->pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, b->fd, 0);
+	if (b->pool == MAP_FAILED) {
+		r = err("cannot mmap pool");
+		goto error;
+	}
+
+	*out = b;
+	return 0;
+
+error:
+	bus_close_connection(b);
+	return r;
+}
+
+static void bus_close_connection(struct bus *b)
+{
+	if (!b)
+		return;
+
+	/*
+	 * A bus connection is closed by simply calling close() on the
+	 * connection owner file descriptor. The unique name and all owned
+	 * well-known names of the conneciton will disappear.
+	 * See kdbus.connection(7).
+	 */
+	if (b->pool != MAP_FAILED)
+		munmap(b->pool, POOL_SIZE);
+	if (b->fd >= 0)
+		close(b->fd);
+	free(b);
+}
+
+static void bus_poool_free_slice(struct bus *b, uint64_t offset)
+{
+	struct kdbus_cmd_free cmd = {
+		.size = sizeof(cmd),
+		.offset = offset,
+	};
+	int r;
+
+	/*
+	 * Once we're done with a piece of pool memory that was returned
+	 * by a command, we have to call the KDBUS_CMD_FREE ioctl on it so it
+	 * can be reused. The command takes an argument of type
+	 * 'struct kdbus_cmd_free', in which the pool offset of the slice to
+	 * free is stored. The ioctl is employed on the connection owner
+	 * file descriptor. See kdbus.pool(7),
+	 */
+	r = kdbus_cmd_free(b->fd, &cmd);
+	if (r < 0)
+		err_r(r, "cannot free pool slice");
+}
+
+static int bus_acquire_name(struct bus *b, const char *name)
+{
+	struct kdbus_item *item;
+	struct kdbus_cmd *cmd;
+	size_t size;
+	int r;
+
+	/*
+	 * This function acquires a well-known name on the bus through the
+	 * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type
+	 * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7).
+	 */
+	size = sizeof(*cmd);
+	size += KDBUS_ITEM_SIZE(strlen(name) + 1);
+
+	cmd = alloca(size);
+	memset(cmd, 0, size);
+	cmd->size = size;
+
+	/*
+	 * The command requires an item of type KDBUS_ITEM_NAME, and its
+	 * content must be a valid bus name.
+	 */
+	item = cmd->items;
+	item->type = KDBUS_ITEM_NAME;
+	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+	strcpy(item->str, name);
+
+	/*
+	 * Employ the command on the connection owner file descriptor.
+	 */
+	r = kdbus_cmd_name_acquire(b->fd, cmd);
+	if (r < 0)
+		return err_r(r, "cannot acquire name");
+
+	return 0;
+}
+
+static int bus_install_name_loss_match(struct bus *b, const char *name)
+{
+	struct kdbus_cmd_match *match;
+	struct kdbus_item *item;
+	size_t size;
+	int r;
+
+	/*
+	 * In order to install a match for signal messages, we have to
+	 * assemble a 'struct kdbus_cmd_match' and use it along with the
+	 * KDBUS_CMD_MATCH_ADD ioctl. See kdbus.match(7).
+	 */
+	size = sizeof(*match);
+	size += KDBUS_ITEM_SIZE(sizeof(item->name_change) + strlen(name) + 1);
+
+	match = alloca(size);
+	memset(match, 0, size);
+	match->size = size;
+
+	/*
+	 * A match is comprised of many 'rules', each of which describes a
+	 * mandatory detail of the message. All rules of a match must be
+	 * satified in order to make a message pass.
+	 */
+	item = match->items;
+
+	/*
+	 * In this case, we're interested in notifications that inform us
+	 * about a well-known name being removed from the bus.
+	 */
+	item->type = KDBUS_ITEM_NAME_REMOVE;
+	item->size = KDBUS_ITEM_HEADER_SIZE +
+			sizeof(item->name_change) + strlen(name) + 1;
+
+	/*
+	 * We could limit the match further and require a specific unique-ID
+	 * to be the new or the old owner of the name. In this case, however,
+	 * we don't, and allow 'any' id.
+	 */
+	item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
+	item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
+
+	/* Copy in the well-known name we're interested in */
+	strcpy(item->name_change.name, name);
+
+	/*
+	 * Add the match through the KDBUS_CMD_MATCH_ADD ioctl, employed on
+	 * the connection owner fd.
+	 */
+	r = kdbus_cmd_match_add(b->fd, match);
+	if (r < 0)
+		return err_r(r, "cannot add match");
+
+	return 0;
+}
+
+static int bus_poll(struct bus *b)
+{
+	struct pollfd fds[1] = {};
+	int r;
+
+	/*
+	 * A connection endpoint supports poll() and will wake-up the
+	 * task with POLLIN set once a message has arrived.
+	 */
+	fds[0].fd = b->fd;
+	fds[0].events = POLLIN;
+	r = poll(fds, sizeof(fds) / sizeof(*fds), 0);
+	if (r < 0)
+		return err("cannot poll bus");
+	return !!(fds[0].revents & POLLIN);
+}
+
+static int bus_make(uid_t uid, const char *name)
+{
+	struct kdbus_item *item;
+	struct kdbus_cmd *make;
+	char path[128], busname[128];
+	size_t size;
+	int r, fd;
+
+	/*
+	 * Compute the full path to the 'control' node. 'arg_modname' may be
+	 * set to a different value than 'kdbus' for development purposes.
+	 * The 'control' node is the primary entry point to kdbus that must be
+	 * used in order to create a bus. See kdbus(7) and kdbus.bus(7).
+	 */
+	snprintf(path, sizeof(path), "/sys/fs/%s/control", arg_modname);
+
+	/*
+	 * Compute the bus name. A valid bus name must always be prefixed with
+	 * the EUID of the currently running process in order to avoid name
+	 * conflicts. See kdbus.bus(7).
+	 */
+	snprintf(busname, sizeof(busname), "%lu-%s", (unsigned long)uid, name);
+
+	fd = open(path, O_RDWR | O_CLOEXEC);
+	if (fd < 0)
+		return err("cannot open control file");
+
+	/*
+	 * The KDBUS_CMD_BUS_MAKE ioctl takes an argument of type
+	 * 'struct kdbus_cmd', and expects at least two items attached to
+	 * it: one to decribe the bloom parameters to be propagated to
+	 * connections of the bus, and the name of the bus that was computed
+	 * above. Assemble this struct now, and fill it with values.
+	 */
+	size = sizeof(*make);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_parameter));
+	size += KDBUS_ITEM_SIZE(strlen(busname) + 1);
+
+	make = alloca(size);
+	memset(make, 0, size);
+	make->size = size;
+
+	/*
+	 * Each item has a 'type' and 'size' field, and must be stored at an
+	 * 8-byte aligned address. The KDBUS_ITEM_NEXT macro is used to advance
+	 * the pointer. See kdbus.item(7) for more details.
+	 */
+	item = make->items;
+	item->type = KDBUS_ITEM_BLOOM_PARAMETER;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->bloom_parameter);
+	item->bloom_parameter.size = 8;
+	item->bloom_parameter.n_hash = 1;
+
+	/* The name of the new bus is stored in the next item. */
+	item = KDBUS_ITEM_NEXT(item);
+	item->type = KDBUS_ITEM_MAKE_NAME;
+	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(busname) + 1;
+	strcpy(item->str, busname);
+
+	/*
+	 * Now create the bus via the KDBUS_CMD_BUS_MAKE ioctl and return the
+	 * fd that was used back to the caller of this function. This fd is now
+	 * called a 'bus owner file descriptor', and it controls the life-time
+	 * of the newly created bus; once the file descriptor is closed, the
+	 * bus goes away, and all connections are shut down. See kdbus.bus(7).
+	 */
+	r = kdbus_cmd_bus_make(fd, make);
+	if (r < 0) {
+		err_r(r, "cannot make bus");
+		close(fd);
+		return r;
+	}
+
+	return fd;
+}
+
+#else
+
+#warning "Skipping compilation due to unsupported libc version"
+
+int main(int argc, char **argv)
+{
+	fprintf(stderr,
+		"Compilation of %s was skipped due to unsupported libc.\n",
+		argv[0]);
+
+	return EXIT_FAILURE;
+}
+
+#endif /* libc sanity check */
diff --git a/scripts/Makefile.lto b/scripts/Makefile.lto
new file mode 100644
index 000000000000..b8e9e4836f4b
--- /dev/null
+++ b/scripts/Makefile.lto
@@ -0,0 +1,84 @@
+#
+# Support for gcc link time optimization
+#
+
+DISABLE_LTO :=
+LTO_CFLAGS :=
+
+export DISABLE_LTO
+export LTO_CFLAGS
+
+ifdef CONFIG_LTO
+# 4.7 works mostly, but it sometimes loses symbols on large builds
+# This can be worked around by marking those symbols visible,
+# but that is fairly ugly and the problem is gone with 4.8
+# So only allow it with 4.8 for now.
+ifeq ($(call cc-ifversion, -ge, 0408,y),y)
+ifneq ($(call cc-option,${LTO_CFLAGS},n),n)
+# We need HJ Lu's Linux binutils because mainline binutils does not
+# support mixing assembler and LTO code in the same ld -r object.
+# XXX check if the gcc plugin ld is the expected one too
+# XXX some Fedora binutils should also support it. How to check for that?
+ifeq ($(call ld-ifversion,-ge,22710001,y),y)
+        LTO_CFLAGS := -flto -fno-toplevel-reorder
+	LTO_FINAL_CFLAGS := -fuse-linker-plugin
+
+# the -fno-toplevel-reorder is to preserve the order of initcalls
+# everything else should tolerate reordering
+        LTO_FINAL_CFLAGS +=-fno-toplevel-reorder
+
+# enable LTO and set the jobs used by the LTO phase
+# this should be -flto=jobserver to coordinate with the
+# parent make, but work around
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50639
+# use as many jobs as processors are online for now
+# this actually seems to be a kernel bug with the pipe code
+	LTO_FINAL_CFLAGS := -flto=$(shell getconf _NPROCESSORS_ONLN)
+	#LTO_FINAL_CFLAGS := -flto=jobserver
+
+	# requires plugin ar passed and very recent HJ binutils
+        LTO_CFLAGS += -fno-fat-lto-objects
+
+# Used to disable LTO for specific files (e.g. vdso)
+	DISABLE_LTO := -fno-lto
+
+	LTO_FINAL_CFLAGS += ${LTO_CFLAGS} -fwhole-program
+
+ifdef CONFIG_LTO_DEBUG
+	LTO_FINAL_CFLAGS += -dH -fdump-ipa-cgraph -fdump-ipa-inline-details
+	# -Wl,-plugin-save-temps -save-temps
+	LTO_CFLAGS +=
+endif
+ifdef CONFIG_LTO_CP_CLONE
+	LTO_FINAL_CFLAGS += -fipa-cp-clone
+	LTO_CFLAGS += -fipa-cp-clone
+endif
+
+	# In principle gcc should pass through options in the object files,
+	# but it doesn't always work. So do it here manually
+	# Note that special options for individual files does not
+	# work currently (except for some special cases that only
+	# affect the compiler frontend)
+	# The main offenders are FTRACE and GCOV -- we exclude
+	# those in the config.
+	LTO_FINAL_CFLAGS += $(filter -g%,${KBUILD_CFLAGS})
+	LTO_FINAL_CFLAGS += $(filter -O%,${KBUILD_CFLAGS})
+	LTO_FINAL_CFLAGS += $(filter -f%,${KBUILD_CFLAGS})
+	LTO_FINAL_CFLAGS += $(filter -m%,${KBUILD_CFLAGS})
+	LTO_FINAL_CFLAGS += $(filter -W%,${KBUILD_CFLAGS})
+
+	KBUILD_CFLAGS += ${LTO_CFLAGS}
+
+	LDFINAL := ${CONFIG_SHELL} ${srctree}/scripts/gcc-ld \
+                  ${LTO_FINAL_CFLAGS}
+
+else
+        $(warning "WARNING: Too old linker version $(call ld-version) for kernel LTO. You need Linux binutils. CONFIG_LTO disabled.")
+endif
+else
+        $(warning "WARNING: Compiler/Linker does not support LTO/WHOPR with linker plugin. CONFIG_LTO disabled.")
+endif
+else
+        $(warning "WARNING: GCC $(call cc-version) too old for LTO/WHOPR. CONFIG_LTO disabled")
+endif
+endif
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 69f0a1417e9a..9c40daea846c 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -77,7 +77,8 @@ modpost = scripts/mod/modpost                    \
  $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
  $(if $(KBUILD_EXTMOD),-o $(modulesymfile))      \
  $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
+ $(if $(CONFIG_LTO),-w)
 
 MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))
 
@@ -115,8 +116,8 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
 targets += $(modules:.ko=.mod.o)
 
 # Step 6), final link of the modules
-quiet_cmd_ld_ko_o = LD [M]  $@
-      cmd_ld_ko_o = $(LD) -r $(LDFLAGS)                                 \
+quiet_cmd_ld_ko_o = LDFINAL [M]  $@
+      cmd_ld_ko_o = $(LDFINAL) -r $(LDFLAGS)                            \
                              $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
                              -o $@ $(filter-out FORCE,$^)
 
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 9a08fb5c1af6..25029bcaf583 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -206,59 +206,73 @@ my $type_env = '(\$\w+)';
 #  One for each output format
 
 # these work fairly well
-my %highlights_html = ( $type_constant, "<i>\$1</i>",
-			$type_func, "<b>\$1</b>",
-			$type_struct_xml, "<i>\$1</i>",
-			$type_env, "<b><i>\$1</i></b>",
-			$type_param, "<tt><b>\$1</b></tt>" );
+my @highlights_html = (
+                       [$type_constant, "<i>\$1</i>"],
+                       [$type_func, "<b>\$1</b>"],
+                       [$type_struct_xml, "<i>\$1</i>"],
+                       [$type_env, "<b><i>\$1</i></b>"],
+                       [$type_param, "<tt><b>\$1</b></tt>"]
+                      );
 my $local_lt = "\\\\\\\\lt:";
 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 @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>",
-			$type_func, "<function>\$1</function>",
-			$type_struct_xml, "<structname>\$1</structname>",
-			$type_env, "<envar>\$1</envar>",
-			$type_param, "<parameter>\$1</parameter>" );
+my @highlights_xml = (
+                      ["([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>"],
+                      [$type_constant, "<constant>\$1</constant>"],
+                      [$type_struct_xml, "<structname>\$1</structname>"],
+                      [$type_param, "<parameter>\$1</parameter>"],
+                      [$type_func, "<function>\$1</function>"],
+                      [$type_env, "<envar>\$1</envar>"]
+		     );
 my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
 
 # gnome, docbook format
-my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
-			 $type_func, "<function>\$1</function>",
-			 $type_struct, "<structname>\$1</structname>",
-			 $type_env, "<envar>\$1</envar>",
-			 $type_param, "<parameter>\$1</parameter>" );
+my @highlights_gnome = (
+                        [$type_constant, "<replaceable class=\"option\">\$1</replaceable>"],
+                        [$type_func, "<function>\$1</function>"],
+                        [$type_struct, "<structname>\$1</structname>"],
+                        [$type_env, "<envar>\$1</envar>"],
+                        [$type_param, "<parameter>\$1</parameter>" ]
+		       );
 my $blankline_gnome = "</para><para>\n";
 
 # these are pretty rough
-my %highlights_man = ( $type_constant, "\$1",
-		       $type_func, "\\\\fB\$1\\\\fP",
-		       $type_struct, "\\\\fI\$1\\\\fP",
-		       $type_param, "\\\\fI\$1\\\\fP" );
+my @highlights_man = (
+                      [$type_constant, "\$1"],
+                      [$type_func, "\\\\fB\$1\\\\fP"],
+                      [$type_struct, "\\\\fI\$1\\\\fP"],
+                      [$type_param, "\\\\fI\$1\\\\fP"]
+		     );
 my $blankline_man = "";
 
 # text-mode
-my %highlights_text = ( $type_constant, "\$1",
-			$type_func, "\$1",
-			$type_struct, "\$1",
-			$type_param, "\$1" );
+my @highlights_text = (
+                       [$type_constant, "\$1"],
+                       [$type_func, "\$1"],
+                       [$type_struct, "\$1"],
+                       [$type_param, "\$1"]
+		      );
 my $blankline_text = "";
 
 # list mode
-my %highlights_list = ( $type_constant, "\$1",
-			$type_func, "\$1",
-			$type_struct, "\$1",
-			$type_param, "\$1" );
+my @highlights_list = (
+                       [$type_constant, "\$1"],
+                       [$type_func, "\$1"],
+                       [$type_struct, "\$1"],
+                       [$type_param, "\$1"]
+		      );
 my $blankline_list = "";
 
 # read arguments
@@ -273,7 +287,7 @@ my $verbose = 0;
 my $output_mode = "man";
 my $output_preformatted = 0;
 my $no_doc_sections = 0;
-my %highlights = %highlights_man;
+my @highlights = @highlights_man;
 my $blankline = $blankline_man;
 my $modulename = "Kernel API";
 my $function_only = 0;
@@ -374,31 +388,31 @@ while ($ARGV[0] =~ m/^-(.*)/) {
     my $cmd = shift @ARGV;
     if ($cmd eq "-html") {
 	$output_mode = "html";
-	%highlights = %highlights_html;
+	@highlights = @highlights_html;
 	$blankline = $blankline_html;
     } elsif ($cmd eq "-html5") {
 	$output_mode = "html5";
-	%highlights = %highlights_html5;
+	@highlights = @highlights_html5;
 	$blankline = $blankline_html5;
     } elsif ($cmd eq "-man") {
 	$output_mode = "man";
-	%highlights = %highlights_man;
+	@highlights = @highlights_man;
 	$blankline = $blankline_man;
     } elsif ($cmd eq "-text") {
 	$output_mode = "text";
-	%highlights = %highlights_text;
+	@highlights = @highlights_text;
 	$blankline = $blankline_text;
     } elsif ($cmd eq "-docbook") {
 	$output_mode = "xml";
-	%highlights = %highlights_xml;
+	@highlights = @highlights_xml;
 	$blankline = $blankline_xml;
     } elsif ($cmd eq "-list") {
 	$output_mode = "list";
-	%highlights = %highlights_list;
+	@highlights = @highlights_list;
 	$blankline = $blankline_list;
     } elsif ($cmd eq "-gnome") {
 	$output_mode = "gnome";
-	%highlights = %highlights_gnome;
+	@highlights = @highlights_gnome;
 	$blankline = $blankline_gnome;
     } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
 	$modulename = shift @ARGV;
@@ -1746,7 +1760,7 @@ sub output_declaration {
     my $func = "output_${functype}_$output_mode";
     if (($function_only==0) ||
 	( $function_only == 1 && defined($function_table{$name})) ||
-	( $function_only == 2 && !defined($function_table{$name})))
+	( $function_only == 2 && !($functype eq "function" && defined($function_table{$name}))))
     {
 	&$func(@_);
 	$section_counter++;
@@ -2391,12 +2405,13 @@ sub process_file($) {
     my $descr;
     my $in_purpose = 0;
     my $initial_section_counter = $section_counter;
+    my ($orig_file) = @_;
 
     if (defined($ENV{'SRCTREE'})) {
-	$file = "$ENV{'SRCTREE'}" . "/" . "@_";
+	$file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
     }
     else {
-	$file = "@_";
+	$file = $orig_file;
     }
     if (defined($source_map{$file})) {
 	$file = $source_map{$file};
@@ -2640,7 +2655,7 @@ sub process_file($) {
 	    print "<refentry>\n";
 	    print " <refnamediv>\n";
 	    print "  <refname>\n";
-	    print "   ${file}\n";
+	    print "   ${orig_file}\n";
 	    print "  </refname>\n";
 	    print "  <refpurpose>\n";
 	    print "   Document generation inconsistency\n";
@@ -2654,7 +2669,7 @@ sub process_file($) {
 	    print "   <para>\n";
 	    print "    The template for this document tried to insert\n";
 	    print "    the structured comment from the file\n";
-	    print "    <filename>${file}</filename> at this point,\n";
+	    print "    <filename>${orig_file}</filename> at this point,\n";
 	    print "    but none was found.\n";
 	    print "    This dummy section is inserted to allow\n";
 	    print "    generation to continue.\n";
@@ -2671,9 +2686,11 @@ $kernelversion = get_kernel_version();
 
 # generate a sequence of code that will splice in highlighting information
 # using the s// operator.
-foreach my $pattern (sort keys %highlights) {
-#   print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
-    $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
+foreach my $k (keys @highlights) {
+    my $pattern = $highlights[$k][0];
+    my $result = $highlights[$k][1];
+#   print STDERR "scanning pattern:$pattern, highlight:($result)\n";
+    $dohighlight .=  "\$contents =~ s:$pattern:$result:gs;\n";
 }
 
 # Read the file that maps relative names to absolute names for
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 1a10d8ac8162..13efe9857a42 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -53,7 +53,7 @@ vmlinux_link()
 	local lds="${objtree}/${KBUILD_LDS}"
 
 	if [ "${SRCARCH}" != "um" ]; then
-		${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}                  \
+		${LDFINAL} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}                  \
 			-T ${lds} ${KBUILD_VMLINUX_INIT}                     \
 			--start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
 	else
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 12d3db3bd46b..d583c98fde31 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2133,6 +2133,11 @@ static void add_staging_flag(struct buffer *b, const char *name)
 		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
 }
 
+/* In kernel, this size is defined in linux/module.h;
+ * here we use Elf_Addr instead of long for covering cross-compile
+ */
+#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
+
 /**
  * Record CRCs for unresolved symbols
  **/
@@ -2177,6 +2182,12 @@ static int add_versions(struct buffer *b, struct module *mod)
 				s->name, mod->name);
 			continue;
 		}
+		if (strlen(s->name) >= MODULE_NAME_LEN) {
+			merror("too long symbol \"%s\" [%s.ko]\n",
+			       s->name, mod->name);
+			err = 1;
+			break;
+		}
 		buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n",
 			   s->crc, s->name);
 	}
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 73455089feef..03c1652c9a1f 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -401,7 +401,7 @@ static bool verify_new_ex(struct dev_cgroup *dev_cgroup,
 	bool match = false;
 
 	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&
-			 lockdep_is_held(&devcgroup_mutex),
+			 !lockdep_is_held(&devcgroup_mutex),
 			 "device_cgroup:verify_new_ex called without proper synchronization");
 
 	if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 02bd96954dc4..308c9ecf73db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1014,9 +1014,6 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 	snd_free_pages((void*)runtime->control,
 		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 	kfree(runtime->hw_constraints.rules);
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
-	kfree(runtime->hwptr_log);
-#endif
 	kfree(runtime);
 	substream->runtime = NULL;
 	put_pid(substream->pid);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 9bba275b4c9b..2875b4f6d8c9 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5112,6 +5112,7 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
 		dev_err(hdsp->card->dev,
 			"too short firmware size %d (expected %d)\n",
 			   (int)fw->size, HDSP_FIRMWARE_SIZE);
+		release_firmware(fw);
 		return -EINVAL;
 	}
 
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 4972bf3efa91..8e51242db5ee 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3205,6 +3205,13 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
 		},
 	},
+	{
+		.ident = "Google Ultima",
+		.callback = strago_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
+		},
+	},
 	{ }
 };
 
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index f2c6ad4b8fde..8434d45d6b59 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -672,8 +672,10 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 		}
 
 		img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA);
-		if (!img_swap)
+		if (!img_swap) {
+			kfree(out);
 			goto abort;
+		}
 
 		/* We need to re-order for 0010 */
 		byte_swap_64((u64 *)&pll_rec, img_swap, len);
@@ -690,6 +692,8 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 		ret = spi_sync(spi, &m);
 		if (ret != 0) {
 			dev_err(codec->dev, "First PLL write failed: %d\n", ret);
+			kfree(img_swap);
+			kfree(out);
 			goto abort;
 		}
 
@@ -697,6 +701,8 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 		ret = spi_sync(spi, &m);
 		if (ret != 0) {
 			dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
+			kfree(img_swap);
+			kfree(out);
 			goto abort;
 		}
 
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e3b7d0c57411..69753900f3cd 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -211,28 +211,38 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
 	return wm8960_set_deemph(codec);
 }
 
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);
+static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
+static const unsigned int micboost_tlv[] = {
+	TLV_DB_RANGE_HEAD(2),
+	0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0),
+	2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0),
+};
 
 static const struct snd_kcontrol_new wm8960_snd_controls[] = {
 SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
-		 0, 63, 0, adc_tlv),
+		 0, 63, 0, inpga_tlv),
 SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
 	6, 1, 0),
 SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
 	7, 1, 0),
 
 SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume",
-	       WM8960_INBMIX1, 4, 7, 0, boost_tlv),
+	       WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv),
 SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume",
-	       WM8960_INBMIX1, 1, 7, 0, boost_tlv),
+	       WM8960_INBMIX1, 1, 7, 0, lineinboost_tlv),
 SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume",
-	       WM8960_INBMIX2, 4, 7, 0, boost_tlv),
+	       WM8960_INBMIX2, 4, 7, 0, lineinboost_tlv),
 SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume",
-	       WM8960_INBMIX2, 1, 7, 0, boost_tlv),
+	       WM8960_INBMIX2, 1, 7, 0, lineinboost_tlv),
+SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT1 Volume",
+		WM8960_RINPATH, 4, 4, 0, micboost_tlv),
+SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT1 Volume",
+		WM8960_LINPATH, 4, 4, 0, micboost_tlv),
 
 SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
 		 0, 255, 0, dac_tlv),
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5aeb6ed4827e..96f55ae75c71 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -488,7 +488,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 		priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
 	} else {
 		dev_err(&pdev->dev, "unknown Device Tree compatible\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto asrc_fail;
 	}
 
 	/* Common settings for corresponding Freescale CPU DAI driver */
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index f6efa9d4acad..b27f25f70730 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -302,6 +302,10 @@ struct sst_hsw {
 	struct sst_hsw_ipc_dx_reply dx;
 	void *dx_context;
 	dma_addr_t dx_context_paddr;
+	enum sst_hsw_device_id dx_dev;
+	enum sst_hsw_device_mclk dx_mclk;
+	enum sst_hsw_device_mode dx_mode;
+	u32 dx_clock_divider;
 
 	/* boot */
 	wait_queue_head_t boot_wait;
@@ -1400,10 +1404,10 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
 
 	trace_ipc_request("set device config", dev);
 
-	config.ssp_interface = dev;
-	config.clock_frequency = mclk;
-	config.mode = mode;
-	config.clock_divider = clock_divider;
+	hsw->dx_dev = config.ssp_interface = dev;
+	hsw->dx_mclk = config.clock_frequency = mclk;
+	hsw->dx_mode = config.mode = mode;
+	hsw->dx_clock_divider = config.clock_divider = clock_divider;
 	if (mode == SST_HSW_DEVICE_TDM_CLOCK_MASTER)
 		config.channels = 4;
 	else
@@ -1704,10 +1708,10 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
 		return -EIO;
 	}
 
-	/* Set ADSP SSP port settings */
-	ret = sst_hsw_device_set_config(hsw, SST_HSW_DEVICE_SSP_0,
-					SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
-					SST_HSW_DEVICE_CLOCK_MASTER, 9);
+	/* Set ADSP SSP port settings - sadly the FW does not store SSP port
+	   settings as part of the PM context. */
+	ret = sst_hsw_device_set_config(hsw, hsw->dx_dev, hsw->dx_mclk,
+					hsw->dx_mode, hsw->dx_clock_divider);
 	if (ret < 0)
 		dev_err(dev, "error: SSP re-initialization failed\n");
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f4bf21a5539b..ff8bda471b25 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3501,7 +3501,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
 
 	default:
 		WARN(1, "Unknown event %d\n", event);
-		return -EINVAL;
+		ret = -EINVAL;
 	}
 
 out:
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 362c69ac1d6c..53dd085d3ee2 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -101,6 +101,15 @@ static struct snd_soc_codec_driver dummy_codec;
 			SNDRV_PCM_FMTBIT_S32_LE | \
 			SNDRV_PCM_FMTBIT_U32_LE | \
 			SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
+/*
+ * The dummy CODEC is only meant to be used in situations where there is no
+ * actual hardware.
+ *
+ * If there is actual hardware even if it does not have a control bus
+ * the hardware will still have constraints like supported samplerates, etc.
+ * which should be modelled. And the data flow graph also should be modelled
+ * using DAPM.
+ */
 static struct snd_soc_dai_driver dummy_dai = {
 	.name = "snd-soc-dummy-dai",
 	.playback = {
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index f6eefe1b8f8f..843f037a317d 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -989,8 +989,8 @@ static int uni_player_parse_dt(struct platform_device *pdev,
 	if (!info)
 		return -ENOMEM;
 
-	of_property_read_u32(pnode, "version", &player->ver);
-	if (player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
+	if (of_property_read_u32(pnode, "version", &player->ver) ||
+	    player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
 		dev_err(dev, "Unknown uniperipheral version ");
 		return -EINVAL;
 	}
@@ -998,10 +998,16 @@ static int uni_player_parse_dt(struct platform_device *pdev,
 	if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
 		info->underflow_enabled = 1;
 
-	of_property_read_u32(pnode, "uniperiph-id", &info->id);
+	if (of_property_read_u32(pnode, "uniperiph-id", &info->id)) {
+		dev_err(dev, "uniperipheral id not defined");
+		return -EINVAL;
+	}
 
 	/* Read the device mode property */
-	of_property_read_string(pnode, "mode", &mode);
+	if (of_property_read_string(pnode, "mode", &mode)) {
+		dev_err(dev, "uniperipheral mode not defined");
+		return -EINVAL;
+	}
 
 	if (strcasecmp(mode, "hdmi") == 0)
 		info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_HDMI;
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c
index c502626f339b..f791239a3087 100644
--- a/sound/soc/sti/uniperif_reader.c
+++ b/sound/soc/sti/uniperif_reader.c
@@ -316,7 +316,11 @@ static int uni_reader_parse_dt(struct platform_device *pdev,
 	if (!info)
 		return -ENOMEM;
 
-	of_property_read_u32(node, "version", &reader->ver);
+	if (of_property_read_u32(node, "version", &reader->ver) ||
+	    reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
+		dev_err(&pdev->dev, "Unknown uniperipheral version ");
+		return -EINVAL;
+	}
 
 	/* Save the info structure */
 	reader->info = info;
diff --git a/tools/include/linux/filter.h b/tools/include/linux/filter.h
new file mode 100644
index 000000000000..3276625595b2
--- /dev/null
+++ b/tools/include/linux/filter.h
@@ -0,0 +1,231 @@
+/*
+ * Linux Socket Filter Data Structures
+ */
+#ifndef __TOOLS_LINUX_FILTER_H
+#define __TOOLS_LINUX_FILTER_H
+
+#include <linux/bpf.h>
+
+/* ArgX, context and stack frame pointer register positions. Note,
+ * Arg1, Arg2, Arg3, etc are used as argument mappings of function
+ * calls in BPF_CALL instruction.
+ */
+#define BPF_REG_ARG1	BPF_REG_1
+#define BPF_REG_ARG2	BPF_REG_2
+#define BPF_REG_ARG3	BPF_REG_3
+#define BPF_REG_ARG4	BPF_REG_4
+#define BPF_REG_ARG5	BPF_REG_5
+#define BPF_REG_CTX	BPF_REG_6
+#define BPF_REG_FP	BPF_REG_10
+
+/* Additional register mappings for converted user programs. */
+#define BPF_REG_A	BPF_REG_0
+#define BPF_REG_X	BPF_REG_7
+#define BPF_REG_TMP	BPF_REG_8
+
+/* BPF program can access up to 512 bytes of stack space. */
+#define MAX_BPF_STACK	512
+
+/* Helper macros for filter block array initializers. */
+
+/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
+
+#define BPF_ALU64_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define BPF_ALU32_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
+
+#define BPF_ALU64_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+#define BPF_ALU32_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
+
+#define BPF_ENDIAN(TYPE, DST, LEN)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_END | BPF_SRC(TYPE),	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = LEN })
+
+/* Short form of mov, dst_reg = src_reg */
+
+#define BPF_MOV64_REG(DST, SRC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define BPF_MOV32_REG(DST, SRC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_MOV | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* Short form of mov, dst_reg = imm32 */
+
+#define BPF_MOV64_IMM(DST, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+#define BPF_MOV32_IMM(DST, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_MOV | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Short form of mov based on type,  BPF_X: dst_reg = src_reg, BPF_K: dst_reg = imm32 */
+
+#define BPF_MOV64_RAW(TYPE, DST, SRC, IMM)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE),	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+#define BPF_MOV32_RAW(TYPE, DST, SRC, IMM)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_MOV | BPF_SRC(TYPE),	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
+
+#define BPF_LD_ABS(SIZE, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Indirect packet access, R0 = *(uint *) (skb->data + src_reg + imm32) */
+
+#define BPF_LD_IND(SIZE, SRC, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_IND,	\
+		.dst_reg = 0,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
+
+#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
+
+#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
+
+#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
+
+#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
+
+#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Function call */
+
+#define BPF_EMIT_CALL(FUNC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_CALL,			\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = ((FUNC) - BPF_FUNC_unspec) })
+
+/* Raw code statement block */
+
+#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
+	((struct bpf_insn) {					\
+		.code  = CODE,					\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Program exit */
+
+#define BPF_EXIT_INSN()						\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_EXIT,			\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#endif /* __TOOLS_LINUX_FILTER_H */
diff --git a/tools/lib/api/fs/Build b/tools/lib/api/fs/Build
index 6de5a4f0b501..fa726f679b29 100644
--- a/tools/lib/api/fs/Build
+++ b/tools/lib/api/fs/Build
@@ -1,4 +1,5 @@
 libapi-y += fs.o
+libapi-y += tracing_path.o
 libapi-y += debugfs.o
 libapi-y += findfs.o
 libapi-y += tracefs.o
diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c
index eb7cf4d18f8a..c707cfb32782 100644
--- a/tools/lib/api/fs/debugfs.c
+++ b/tools/lib/api/fs/debugfs.c
@@ -75,55 +75,3 @@ char *debugfs_mount(const char *mountpoint)
 out:
 	return debugfs_mountpoint;
 }
-
-int debugfs__strerror_open(int err, char *buf, size_t size, const char *filename)
-{
-	char sbuf[128];
-
-	switch (err) {
-	case ENOENT:
-		if (debugfs_found) {
-			snprintf(buf, size,
-				 "Error:\tFile %s/%s not found.\n"
-				 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n",
-				 debugfs_mountpoint, filename);
-			break;
-		}
-		snprintf(buf, size, "%s",
-			 "Error:\tUnable to find debugfs\n"
-			 "Hint:\tWas your kernel compiled with debugfs support?\n"
-			 "Hint:\tIs the debugfs filesystem mounted?\n"
-			 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
-		break;
-	case EACCES: {
-		const char *mountpoint = debugfs_mountpoint;
-
-		if (!access(debugfs_mountpoint, R_OK) && strncmp(filename, "tracing/", 8) == 0) {
-			const char *tracefs_mntpoint = tracefs_find_mountpoint();
-
-			if (tracefs_mntpoint)
-				mountpoint = tracefs_mntpoint;
-		}
-
-		snprintf(buf, size,
-			 "Error:\tNo permissions to read %s/%s\n"
-			 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
-			 debugfs_mountpoint, filename, mountpoint);
-	}
-		break;
-	default:
-		snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
-		break;
-	}
-
-	return 0;
-}
-
-int debugfs__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name)
-{
-	char path[PATH_MAX];
-
-	snprintf(path, PATH_MAX, "tracing/events/%s/%s", sys, name ?: "*");
-
-	return debugfs__strerror_open(err, buf, size, path);
-}
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 128ef6332a6b..8afe08a99bc6 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -1,5 +1,3 @@
-/* TODO merge/factor in debugfs.c here */
-
 #include <ctype.h>
 #include <errno.h>
 #include <stdbool.h>
@@ -11,10 +9,30 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <sys/mount.h>
 
 #include "debugfs.h"
 #include "fs.h"
 
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+#ifndef SYSFS_MAGIC
+#define SYSFS_MAGIC            0x62656572
+#endif
+
+#ifndef PROC_SUPER_MAGIC
+#define PROC_SUPER_MAGIC       0x9fa0
+#endif
+
+#ifndef DEBUGFS_MAGIC
+#define DEBUGFS_MAGIC          0x64626720
+#endif
+
+#ifndef TRACEFS_MAGIC
+#define TRACEFS_MAGIC          0x74726163
+#endif
+
 static const char * const sysfs__fs_known_mountpoints[] = {
 	"/sys",
 	0,
@@ -25,6 +43,29 @@ static const char * const procfs__known_mountpoints[] = {
 	0,
 };
 
+#ifndef DEBUGFS_DEFAULT_PATH
+#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
+#endif
+
+static const char * const debugfs__known_mountpoints[] = {
+	DEBUGFS_DEFAULT_PATH,
+	"/debug",
+	0,
+};
+
+
+#ifndef TRACEFS_DEFAULT_PATH
+#define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing"
+#endif
+
+static const char * const tracefs__known_mountpoints[] = {
+	TRACEFS_DEFAULT_PATH,
+	"/sys/kernel/debug/tracing",
+	"/tracing",
+	"/trace",
+	0,
+};
+
 struct fs {
 	const char		*name;
 	const char * const	*mounts;
@@ -34,10 +75,16 @@ struct fs {
 };
 
 enum {
-	FS__SYSFS  = 0,
-	FS__PROCFS = 1,
+	FS__SYSFS   = 0,
+	FS__PROCFS  = 1,
+	FS__DEBUGFS = 2,
+	FS__TRACEFS = 3,
 };
 
+#ifndef TRACEFS_MAGIC
+#define TRACEFS_MAGIC 0x74726163
+#endif
+
 static struct fs fs__entries[] = {
 	[FS__SYSFS] = {
 		.name	= "sysfs",
@@ -49,6 +96,16 @@ static struct fs fs__entries[] = {
 		.mounts	= procfs__known_mountpoints,
 		.magic	= PROC_SUPER_MAGIC,
 	},
+	[FS__DEBUGFS] = {
+		.name	= "debugfs",
+		.mounts	= debugfs__known_mountpoints,
+		.magic	= DEBUGFS_MAGIC,
+	},
+	[FS__TRACEFS] = {
+		.name	= "tracefs",
+		.mounts	= tracefs__known_mountpoints,
+		.magic	= TRACEFS_MAGIC,
+	},
 };
 
 static bool fs__read_mounts(struct fs *fs)
@@ -159,14 +216,54 @@ static const char *fs__mountpoint(int idx)
 	return fs__get_mountpoint(fs);
 }
 
-#define FS__MOUNTPOINT(name, idx)	\
-const char *name##__mountpoint(void)	\
-{					\
-	return fs__mountpoint(idx);	\
+static const char *mount_overload(struct fs *fs)
+{
+	size_t name_len = strlen(fs->name);
+	/* "PERF_" + name + "_ENVIRONMENT" + '\0' */
+	char upper_name[5 + name_len + 12 + 1];
+
+	snprintf(upper_name, name_len, "PERF_%s_ENVIRONMENT", fs->name);
+	mem_toupper(upper_name, name_len);
+
+	return getenv(upper_name) ?: *fs->mounts;
+}
+
+static const char *fs__mount(int idx)
+{
+	struct fs *fs = &fs__entries[idx];
+	const char *mountpoint;
+
+	if (fs__mountpoint(idx))
+		return (const char *)fs->path;
+
+	mountpoint = mount_overload(fs);
+
+	if (mount(NULL, mountpoint, fs->name, 0, NULL) < 0)
+		return NULL;
+
+	return fs__check_mounts(fs) ? fs->path : NULL;
+}
+
+#define FS(name, idx)				\
+const char *name##__mountpoint(void)		\
+{						\
+	return fs__mountpoint(idx);		\
+}						\
+						\
+const char *name##__mount(void)			\
+{						\
+	return fs__mount(idx);			\
+}						\
+						\
+bool name##__configured(void)			\
+{						\
+	return name##__mountpoint() != NULL;	\
 }
 
-FS__MOUNTPOINT(sysfs,  FS__SYSFS);
-FS__MOUNTPOINT(procfs, FS__PROCFS);
+FS(sysfs,   FS__SYSFS);
+FS(procfs,  FS__PROCFS);
+FS(debugfs, FS__DEBUGFS);
+FS(tracefs, FS__TRACEFS);
 
 int filename__read_int(const char *filename, int *value)
 {
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index 6caa2bbc6cec..f654bcb99d1e 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -1,16 +1,28 @@
 #ifndef __API_FS__
 #define __API_FS__
 
-#ifndef SYSFS_MAGIC
-#define SYSFS_MAGIC            0x62656572
-#endif
+#include <stdbool.h>
 
-#ifndef PROC_SUPER_MAGIC
-#define PROC_SUPER_MAGIC       0x9fa0
+/*
+ * On most systems <limits.h> would have given us this, but  not on some systems
+ * (e.g. GNU/Hurd).
+ */
+#ifndef PATH_MAX
+#define PATH_MAX 4096
 #endif
 
-const char *sysfs__mountpoint(void);
-const char *procfs__mountpoint(void);
+#define FS(name)				\
+	const char *name##__mountpoint(void);	\
+	const char *name##__mount(void);	\
+	bool name##__configured(void);		\
+
+FS(sysfs)
+FS(procfs)
+FS(debugfs)
+FS(tracefs)
+
+#undef FS
+
 
 int filename__read_int(const char *filename, int *value);
 int sysctl__read_int(const char *sysctl, int *value);
diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c
new file mode 100644
index 000000000000..3b3e4f5fc50b
--- /dev/null
+++ b/tools/lib/api/fs/tracing_path.c
@@ -0,0 +1,137 @@
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include "debugfs.h"
+#include "tracefs.h"
+
+#include "tracing_path.h"
+
+
+char tracing_path[PATH_MAX + 1]        = "/sys/kernel/debug/tracing";
+char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
+
+
+static void __tracing_path_set(const char *tracing, const char *mountpoint)
+{
+	snprintf(tracing_path, sizeof(tracing_path), "%s/%s",
+		 mountpoint, tracing);
+	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
+		 mountpoint, tracing, "events");
+}
+
+static const char *tracing_path_tracefs_mount(void)
+{
+	const char *mnt;
+
+	mnt = tracefs_mount(NULL);
+	if (!mnt)
+		return NULL;
+
+	__tracing_path_set("", mnt);
+
+	return mnt;
+}
+
+static const char *tracing_path_debugfs_mount(void)
+{
+	const char *mnt;
+
+	mnt = debugfs_mount(NULL);
+	if (!mnt)
+		return NULL;
+
+	__tracing_path_set("tracing/", mnt);
+
+	return mnt;
+}
+
+const char *tracing_path_mount(void)
+{
+	const char *mnt;
+
+	mnt = tracing_path_tracefs_mount();
+	if (mnt)
+		return mnt;
+
+	mnt = tracing_path_debugfs_mount();
+
+	return mnt;
+}
+
+void tracing_path_set(const char *mntpt)
+{
+	__tracing_path_set("tracing/", mntpt);
+}
+
+char *get_tracing_file(const char *name)
+{
+	char *file;
+
+	if (asprintf(&file, "%s/%s", tracing_path, name) < 0)
+		return NULL;
+
+	return file;
+}
+
+void put_tracing_file(char *file)
+{
+	free(file);
+}
+
+static int strerror_open(int err, char *buf, size_t size, const char *filename)
+{
+	char sbuf[128];
+
+	switch (err) {
+	case ENOENT:
+		if (debugfs_configured()) {
+			snprintf(buf, size,
+				 "Error:\tFile %s/%s not found.\n"
+				 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n",
+				 debugfs_mountpoint, filename);
+			break;
+		}
+		snprintf(buf, size, "%s",
+			 "Error:\tUnable to find debugfs\n"
+			 "Hint:\tWas your kernel compiled with debugfs support?\n"
+			 "Hint:\tIs the debugfs filesystem mounted?\n"
+			 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
+		break;
+	case EACCES: {
+		const char *mountpoint = debugfs_mountpoint;
+
+		if (!access(debugfs_mountpoint, R_OK) && strncmp(filename, "tracing/", 8) == 0) {
+			const char *tracefs_mntpoint = tracefs_find_mountpoint();
+
+			if (tracefs_mntpoint)
+				mountpoint = tracefs_mntpoint;
+		}
+
+		snprintf(buf, size,
+			 "Error:\tNo permissions to read %s/%s\n"
+			 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
+			 debugfs_mountpoint, filename, mountpoint);
+	}
+		break;
+	default:
+		snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
+		break;
+	}
+
+	return 0;
+}
+
+int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "tracing/events/%s/%s", sys, name ?: "*");
+
+	return strerror_open(err, buf, size, path);
+}
diff --git a/tools/lib/api/fs/tracing_path.h b/tools/lib/api/fs/tracing_path.h
new file mode 100644
index 000000000000..3f233ac70b6f
--- /dev/null
+++ b/tools/lib/api/fs/tracing_path.h
@@ -0,0 +1,16 @@
+#ifndef __API_FS_TRACING_PATH_H
+#define __API_FS_TRACING_PATH_H
+
+#include <linux/types.h>
+
+extern char tracing_path[];
+extern char tracing_events_path[];
+
+void tracing_path_set(const char *mountpoint);
+const char *tracing_path_mount(void);
+
+char *get_tracing_file(const char *name);
+void put_tracing_file(char *file);
+
+int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name);
+#endif /* __API_FS_TRACING_PATH_H */
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 4d885934b919..12447978a921 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -848,6 +848,7 @@ static void free_arg(struct print_arg *arg)
 		free(arg->bitmask.bitmask);
 		break;
 	case PRINT_DYNAMIC_ARRAY:
+	case PRINT_DYNAMIC_ARRAY_LEN:
 		free(arg->dynarray.index);
 		break;
 	case PRINT_OP:
@@ -2729,6 +2730,42 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
 }
 
 static enum event_type
+process_dynamic_array_len(struct event_format *event, struct print_arg *arg,
+			  char **tok)
+{
+	struct format_field *field;
+	enum event_type type;
+	char *token;
+
+	if (read_expect_type(EVENT_ITEM, &token) < 0)
+		goto out_free;
+
+	arg->type = PRINT_DYNAMIC_ARRAY_LEN;
+
+	/* Find the field */
+	field = pevent_find_field(event, token);
+	if (!field)
+		goto out_free;
+
+	arg->dynarray.field = field;
+	arg->dynarray.index = 0;
+
+	if (read_expected(EVENT_DELIM, ")") < 0)
+		goto out_err;
+
+	type = read_token(&token);
+	*tok = token;
+
+	return type;
+
+ out_free:
+	free_token(token);
+ out_err:
+	*tok = NULL;
+	return EVENT_ERROR;
+}
+
+static enum event_type
 process_paren(struct event_format *event, struct print_arg *arg, char **tok)
 {
 	struct print_arg *item_arg;
@@ -2975,6 +3012,10 @@ process_function(struct event_format *event, struct print_arg *arg,
 		free_token(token);
 		return process_dynamic_array(event, arg, tok);
 	}
+	if (strcmp(token, "__get_dynamic_array_len") == 0) {
+		free_token(token);
+		return process_dynamic_array_len(event, arg, tok);
+	}
 
 	func = find_func_handler(event->pevent, token);
 	if (func) {
@@ -3655,14 +3696,25 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
 			goto out_warning_op;
 		}
 		break;
+	case PRINT_DYNAMIC_ARRAY_LEN:
+		offset = pevent_read_number(pevent,
+					    data + arg->dynarray.field->offset,
+					    arg->dynarray.field->size);
+		/*
+		 * The total allocated length of the dynamic array is
+		 * stored in the top half of the field, and the offset
+		 * is in the bottom half of the 32 bit field.
+		 */
+		val = (unsigned long long)(offset >> 16);
+		break;
 	case PRINT_DYNAMIC_ARRAY:
 		/* Without [], we pass the address to the dynamic data */
 		offset = pevent_read_number(pevent,
 					    data + arg->dynarray.field->offset,
 					    arg->dynarray.field->size);
 		/*
-		 * The actual length of the dynamic array is stored
-		 * in the top half of the field, and the offset
+		 * The total allocated length of the dynamic array is
+		 * stored in the top half of the field, and the offset
 		 * is in the bottom half of the 32 bit field.
 		 */
 		offset &= 0xffff;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 204befb05a17..6fc83c7edbe9 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -294,6 +294,7 @@ enum print_arg_type {
 	PRINT_OP,
 	PRINT_FUNC,
 	PRINT_BITMASK,
+	PRINT_DYNAMIC_ARRAY_LEN,
 };
 
 struct print_arg {
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index af009bd6e6b7..2a958a80c763 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -41,6 +41,7 @@ tools/include/asm-generic/bitops.h
 tools/include/linux/atomic.h
 tools/include/linux/bitops.h
 tools/include/linux/compiler.h
+tools/include/linux/filter.h
 tools/include/linux/hash.h
 tools/include/linux/kernel.h
 tools/include/linux/list.h
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index 2ca10d796c0b..b02af064f0f9 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -624,13 +624,49 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	 * threads.
 	 */
 	if (have_timing_info && !cpu_map__empty(cpus)) {
-		err = intel_pt_track_switches(evlist);
-		if (err == -EPERM)
-			pr_debug2("Unable to select sched:sched_switch\n");
-		else if (err)
-			return err;
-		else
-			ptr->have_sched_switch = 1;
+		if (perf_can_record_switch_events()) {
+			bool cpu_wide = !target__none(&opts->target) &&
+					!target__has_task(&opts->target);
+
+			if (!cpu_wide && perf_can_record_cpu_wide()) {
+				struct perf_evsel *switch_evsel;
+
+				err = parse_events(evlist, "dummy:u", NULL);
+				if (err)
+					return err;
+
+				switch_evsel = perf_evlist__last(evlist);
+
+				switch_evsel->attr.freq = 0;
+				switch_evsel->attr.sample_period = 1;
+				switch_evsel->attr.context_switch = 1;
+
+				switch_evsel->system_wide = true;
+				switch_evsel->no_aux_samples = true;
+				switch_evsel->immediate = true;
+
+				perf_evsel__set_sample_bit(switch_evsel, TID);
+				perf_evsel__set_sample_bit(switch_evsel, TIME);
+				perf_evsel__set_sample_bit(switch_evsel, CPU);
+
+				opts->record_switch_events = false;
+				ptr->have_sched_switch = 3;
+			} else {
+				opts->record_switch_events = true;
+				if (cpu_wide)
+					ptr->have_sched_switch = 3;
+				else
+					ptr->have_sched_switch = 2;
+			}
+		} else {
+			err = intel_pt_track_switches(evlist);
+			if (err == -EPERM)
+				pr_debug2("Unable to select sched:sched_switch\n");
+			else if (err)
+				return err;
+			else
+				ptr->have_sched_switch = 1;
+		}
 	}
 
 	if (intel_pt_evsel) {
@@ -663,8 +699,11 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 		tracking_evsel->attr.sample_period = 1;
 
 		/* In per-cpu case, always need the time of mmap events etc */
-		if (!cpu_map__empty(cpus))
+		if (!cpu_map__empty(cpus)) {
 			perf_evsel__set_sample_bit(tracking_evsel, TIME);
+			/* And the CPU for switch events */
+			perf_evsel__set_sample_bit(tracking_evsel, CPU);
+		}
 	}
 
 	/*
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index b81cec33b4b2..ee2c46d8353e 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -41,6 +41,7 @@
 #include "util/parse-options.h"
 #include "util/probe-finder.h"
 #include "util/probe-event.h"
+#include "util/probe-file.h"
 
 #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
 #define DEFAULT_FUNC_FILTER "!_*"
@@ -311,6 +312,111 @@ static void pr_err_with_code(const char *msg, int err)
 	pr_err("\n");
 }
 
+static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
+{
+	int ret;
+	int i, k;
+	const char *event = NULL, *group = NULL;
+
+	ret = convert_perf_probe_events(pevs, npevs);
+	if (ret < 0)
+		goto out_cleanup;
+
+	ret = apply_perf_probe_events(pevs, npevs);
+	if (ret < 0)
+		goto out_cleanup;
+
+	for (i = k = 0; i < npevs; i++)
+		k += pevs[i].ntevs;
+
+	pr_info("Added new event%s\n", (k > 1) ? "s:" : ":");
+	for (i = 0; i < npevs; i++) {
+		struct perf_probe_event *pev = &pevs[i];
+
+		for (k = 0; k < pev->ntevs; k++) {
+			struct probe_trace_event *tev = &pev->tevs[k];
+
+			/* We use tev's name for showing new events */
+			show_perf_probe_event(tev->group, tev->event, pev,
+					      tev->point.module, false);
+
+			/* Save the last valid name */
+			event = tev->event;
+			group = tev->group;
+		}
+	}
+
+	/* Note that it is possible to skip all events because of blacklist */
+	if (event) {
+		/* Show how to use the event. */
+		pr_info("\nYou can now use it in all perf tools, such as:\n\n");
+		pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
+	}
+
+out_cleanup:
+	cleanup_perf_probe_events(pevs, npevs);
+	return ret;
+}
+
+static int perf_del_probe_events(struct strfilter *filter)
+{
+	int ret, ret2, ufd = -1, kfd = -1;
+	char *str = strfilter__string(filter);
+	struct strlist *klist = NULL, *ulist = NULL;
+	struct str_node *ent;
+
+	if (!str)
+		return -EINVAL;
+
+	pr_debug("Delete filter: \'%s\'\n", str);
+
+	/* Get current event names */
+	ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
+	if (ret < 0)
+		goto out;
+
+	klist = strlist__new(NULL, NULL);
+	if (!klist)
+		return -ENOMEM;
+
+	ret = probe_file__get_events(kfd, filter, klist);
+	if (ret == 0) {
+		strlist__for_each(ent, klist)
+			pr_info("Removed event: %s\n", ent->s);
+
+		ret = probe_file__del_strlist(kfd, klist);
+		if (ret < 0)
+			goto error;
+	}
+
+	ret2 = probe_file__get_events(ufd, filter, ulist);
+	if (ret2 == 0) {
+		strlist__for_each(ent, ulist)
+			pr_info("Removed event: %s\n", ent->s);
+
+		ret2 = probe_file__del_strlist(ufd, ulist);
+		if (ret2 < 0)
+			goto error;
+	}
+
+	if (ret == -ENOENT && ret2 == -ENOENT)
+		pr_debug("\"%s\" does not hit any event.\n", str);
+		/* Note that this is silently ignored */
+	ret = 0;
+
+error:
+	if (kfd >= 0)
+		close(kfd);
+	if (ufd >= 0)
+		close(ufd);
+out:
+	strlist__delete(klist);
+	strlist__delete(ulist);
+	free(str);
+
+	return ret;
+}
+
 static int
 __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 {
@@ -483,7 +589,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		return ret;
 #endif
 	case 'd':
-		ret = del_perf_probe_events(params.filter);
+		ret = perf_del_probe_events(params.filter);
 		if (ret < 0) {
 			pr_err_with_code("  Error: Failed to delete events.", ret);
 			return ret;
@@ -496,7 +602,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 			usage_with_options(probe_usage, options);
 		}
 
-		ret = add_perf_probe_events(params.events, params.nevents);
+		ret = perf_add_probe_events(params.events, params.nevents);
 		if (ret < 0) {
 			pr_err_with_code("  Error: Failed to add events.", ret);
 			return ret;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index eb51325e8ad9..284a76e04628 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -768,8 +768,8 @@ static int process_exit_event(struct perf_tool *tool,
 	if (!evsel->attr.sample_id_all) {
 		sample->cpu = 0;
 		sample->time = 0;
-		sample->tid = event->comm.tid;
-		sample->pid = event->comm.pid;
+		sample->tid = event->fork.tid;
+		sample->pid = event->fork.pid;
 	}
 	print_sample_start(sample, thread, evsel);
 	perf_event__fprintf(event, stdout);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d46dbb1bc65d..a96fb5c3bedb 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -215,7 +215,7 @@ static void read_counters(bool close_counters)
 
 	evlist__for_each(evsel_list, counter) {
 		if (read_counter(counter))
-			pr_warning("failed to read counter %s\n", counter->name);
+			pr_debug("failed to read counter %s\n", counter->name);
 
 		if (perf_stat_process_counter(&stat_config, counter))
 			pr_warning("failed to process counter %s\n", counter->name);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 4e3abba03062..215653274102 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -17,6 +17,7 @@
  */
 
 #include <traceevent/event-parse.h>
+#include <api/fs/tracing_path.h>
 #include "builtin.h"
 #include "util/color.h"
 #include "util/debug.h"
@@ -2686,11 +2687,11 @@ out_delete_evlist:
 	char errbuf[BUFSIZ];
 
 out_error_sched_stat_runtime:
-	debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime");
+	tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime");
 	goto out_error;
 
 out_error_raw_syscalls:
-	debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)");
+	tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)");
 	goto out_error;
 
 out_error_mmap:
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 07dbff5c0e60..f2fc019b3671 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -15,7 +15,7 @@
 #include "util/parse-events.h"
 #include "util/parse-options.h"
 #include "util/debug.h"
-#include <api/fs/debugfs.h>
+#include <api/fs/tracing_path.h>
 #include <pthread.h>
 
 const char perf_usage_string[] =
@@ -214,7 +214,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 				fprintf(stderr, "No directory given for --debugfs-dir.\n");
 				usage(perf_usage_string);
 			}
-			perf_debugfs_set_path((*argv)[1]);
+			tracing_path_set((*argv)[1]);
 			if (envchanged)
 				*envchanged = 1;
 			(*argv)++;
@@ -230,7 +230,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 			(*argv)++;
 			(*argc)--;
 		} else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) {
-			perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR));
+			tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR));
 			fprintf(stderr, "dir: %s\n", tracing_path);
 			if (envchanged)
 				*envchanged = 1;
@@ -517,8 +517,10 @@ int main(int argc, const char **argv)
 	cmd = perf_extract_argv0_path(argv[0]);
 	if (!cmd)
 		cmd = "perf-help";
-	/* get debugfs mount point from /proc/mounts */
-	perf_debugfs_mount(NULL);
+
+	/* get debugfs/tracefs mount point from /proc/mounts */
+	tracing_path_mount();
+
 	/*
 	 * "perf-xxxx" is the same as "perf xxxx", but we obviously:
 	 *
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index c1518bdd0f1b..51fb737f82fc 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -35,6 +35,9 @@ perf-y += thread-map.o
 perf-y += llvm.o
 
 perf-$(CONFIG_X86) += perf-time-to-tsc.o
+ifdef CONFIG_AUXTRACE
+perf-$(CONFIG_X86) += insn-x86.o
+endif
 
 ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 136cd934be66..69a77f71d594 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -178,6 +178,14 @@ static struct test {
 		.desc = "Test LLVM searching and compiling",
 		.func = test__llvm,
 	},
+#ifdef HAVE_AUXTRACE_SUPPORT
+#if defined(__x86_64__) || defined(__i386__)
+	{
+		.desc = "Test x86 instruction decoder - new instructions",
+		.func = test__insn_x86,
+	},
+#endif
+#endif
 	{
 		.func = NULL,
 	},
diff --git a/tools/perf/tests/gen-insn-x86-dat.awk b/tools/perf/tests/gen-insn-x86-dat.awk
new file mode 100644
index 000000000000..a21454835cd4
--- /dev/null
+++ b/tools/perf/tests/gen-insn-x86-dat.awk
@@ -0,0 +1,75 @@
+#!/bin/awk -f
+# gen-insn-x86-dat.awk: script to convert data for the insn-x86 test
+# Copyright (c) 2015, Intel Corporation.
+#
+# 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.
+
+BEGIN {
+	print "/*"
+	print " * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk"
+	print " * from insn-x86-dat-src.c for inclusion by insn-x86.c"
+	print " * Do not change this code."
+	print "*/\n"
+	op = ""
+	branch = ""
+	rel = 0
+	going = 0
+}
+
+/ Start here / {
+	going = 1
+}
+
+/ Stop here / {
+	going = 0
+}
+
+/^\s*[0-9a-fA-F]+\:/ {
+	if (going) {
+		colon_pos = index($0, ":")
+		useful_line = substr($0, colon_pos + 1)
+		first_pos = match(useful_line, "[0-9a-fA-F]")
+		useful_line = substr(useful_line, first_pos)
+		gsub("\t", "\\t", useful_line)
+		printf "{{"
+		len = 0
+		for (i = 2; i <= NF; i++) {
+			if (match($i, "^[0-9a-fA-F][0-9a-fA-F]$")) {
+				printf "0x%s, ", $i
+				len += 1
+			} else {
+				break
+			}
+		}
+		printf "}, %d, %s, \"%s\", \"%s\",", len, rel, op, branch
+		printf "\n\"%s\",},\n", useful_line
+		op = ""
+		branch = ""
+		rel = 0
+	}
+}
+
+/ Expecting: / {
+	expecting_str = " Expecting: "
+	expecting_len = length(expecting_str)
+	expecting_pos = index($0, expecting_str)
+	useful_line = substr($0, expecting_pos + expecting_len)
+	for (i = 1; i <= NF; i++) {
+		if ($i == "Expecting:") {
+			i++
+			op = $i
+			i++
+			branch = $i
+			i++
+			rel = $i
+			break
+		}
+	}
+}
diff --git a/tools/perf/tests/gen-insn-x86-dat.sh b/tools/perf/tests/gen-insn-x86-dat.sh
new file mode 100755
index 000000000000..2d4ef94cff98
--- /dev/null
+++ b/tools/perf/tests/gen-insn-x86-dat.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+# gen-insn-x86-dat: generate data for the insn-x86 test
+# Copyright (c) 2015, Intel Corporation.
+#
+# 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.
+
+set -e
+
+if [ "$(uname -m)" != "x86_64" ]; then
+	echo "ERROR: This script only works on x86_64"
+	exit 1
+fi
+
+cd $(dirname $0)
+
+trap 'echo "Might need a more recent version of binutils"' EXIT
+
+echo "Compiling insn-x86-dat-src.c to 64-bit object"
+
+gcc -g -c insn-x86-dat-src.c
+
+objdump -dSw insn-x86-dat-src.o | awk -f gen-insn-x86-dat.awk > insn-x86-dat-64.c
+
+rm -f insn-x86-dat-src.o
+
+echo "Compiling insn-x86-dat-src.c to 32-bit object"
+
+gcc -g -c -m32 insn-x86-dat-src.c
+
+objdump -dSw insn-x86-dat-src.o | awk -f gen-insn-x86-dat.awk > insn-x86-dat-32.c
+
+rm -f insn-x86-dat-src.o
+
+trap - EXIT
+
+echo "Done (use git diff to see the changes)"
diff --git a/tools/perf/tests/insn-x86-dat-32.c b/tools/perf/tests/insn-x86-dat-32.c
new file mode 100644
index 000000000000..3b491cfe204e
--- /dev/null
+++ b/tools/perf/tests/insn-x86-dat-32.c
@@ -0,0 +1,658 @@
+/*
+ * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk
+ * from insn-x86-dat-src.c for inclusion by insn-x86.c
+ * Do not change this code.
+*/
+
+{{0x0f, 0x31, }, 2, 0, "", "",
+"0f 31                \trdtsc  ",},
+{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"f3 0f 1b 00          \tbndmk  (%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1b 05 78 56 34 12 \tbndmk  0x12345678,%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"f3 0f 1b 18          \tbndmk  (%eax),%bnd3",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"f3 0f 1b 04 01       \tbndmk  (%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 04 05 78 56 34 12 \tbndmk  0x12345678(,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"f3 0f 1b 04 08       \tbndmk  (%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"f3 0f 1b 04 c8       \tbndmk  (%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"f3 0f 1b 40 12       \tbndmk  0x12(%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"f3 0f 1b 45 12       \tbndmk  0x12(%ebp),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 01 12    \tbndmk  0x12(%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 05 12    \tbndmk  0x12(%ebp,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 08 12    \tbndmk  0x12(%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 c8 12    \tbndmk  0x12(%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1b 80 78 56 34 12 \tbndmk  0x12345678(%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1b 85 78 56 34 12 \tbndmk  0x12345678(%ebp),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 01 78 56 34 12 \tbndmk  0x12345678(%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 05 78 56 34 12 \tbndmk  0x12345678(%ebp,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 08 78 56 34 12 \tbndmk  0x12345678(%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 c8 78 56 34 12 \tbndmk  0x12345678(%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"f3 0f 1a 00          \tbndcl  (%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1a 05 78 56 34 12 \tbndcl  0x12345678,%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"f3 0f 1a 18          \tbndcl  (%eax),%bnd3",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"f3 0f 1a 04 01       \tbndcl  (%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 04 05 78 56 34 12 \tbndcl  0x12345678(,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"f3 0f 1a 04 08       \tbndcl  (%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"f3 0f 1a 04 c8       \tbndcl  (%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"f3 0f 1a 40 12       \tbndcl  0x12(%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"f3 0f 1a 45 12       \tbndcl  0x12(%ebp),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 01 12    \tbndcl  0x12(%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 05 12    \tbndcl  0x12(%ebp,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 08 12    \tbndcl  0x12(%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 c8 12    \tbndcl  0x12(%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1a 80 78 56 34 12 \tbndcl  0x12345678(%eax),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1a 85 78 56 34 12 \tbndcl  0x12345678(%ebp),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 01 78 56 34 12 \tbndcl  0x12345678(%ecx,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 05 78 56 34 12 \tbndcl  0x12345678(%ebp,%eax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 08 78 56 34 12 \tbndcl  0x12345678(%eax,%ecx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 c8 78 56 34 12 \tbndcl  0x12345678(%eax,%ecx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
+"f3 0f 1a c0          \tbndcl  %eax,%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"f2 0f 1a 00          \tbndcu  (%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1a 05 78 56 34 12 \tbndcu  0x12345678,%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"f2 0f 1a 18          \tbndcu  (%eax),%bnd3",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"f2 0f 1a 04 01       \tbndcu  (%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 04 05 78 56 34 12 \tbndcu  0x12345678(,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"f2 0f 1a 04 08       \tbndcu  (%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"f2 0f 1a 04 c8       \tbndcu  (%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"f2 0f 1a 40 12       \tbndcu  0x12(%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"f2 0f 1a 45 12       \tbndcu  0x12(%ebp),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 01 12    \tbndcu  0x12(%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 05 12    \tbndcu  0x12(%ebp,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 08 12    \tbndcu  0x12(%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 c8 12    \tbndcu  0x12(%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1a 80 78 56 34 12 \tbndcu  0x12345678(%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1a 85 78 56 34 12 \tbndcu  0x12345678(%ebp),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 01 78 56 34 12 \tbndcu  0x12345678(%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 05 78 56 34 12 \tbndcu  0x12345678(%ebp,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 08 78 56 34 12 \tbndcu  0x12345678(%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 c8 78 56 34 12 \tbndcu  0x12345678(%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
+"f2 0f 1a c0          \tbndcu  %eax,%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"f2 0f 1b 00          \tbndcn  (%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1b 05 78 56 34 12 \tbndcn  0x12345678,%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"f2 0f 1b 18          \tbndcn  (%eax),%bnd3",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"f2 0f 1b 04 01       \tbndcn  (%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 04 05 78 56 34 12 \tbndcn  0x12345678(,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"f2 0f 1b 04 08       \tbndcn  (%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"f2 0f 1b 04 c8       \tbndcn  (%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"f2 0f 1b 40 12       \tbndcn  0x12(%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"f2 0f 1b 45 12       \tbndcn  0x12(%ebp),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 01 12    \tbndcn  0x12(%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 05 12    \tbndcn  0x12(%ebp,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 08 12    \tbndcn  0x12(%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 c8 12    \tbndcn  0x12(%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1b 80 78 56 34 12 \tbndcn  0x12345678(%eax),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1b 85 78 56 34 12 \tbndcn  0x12345678(%ebp),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 01 78 56 34 12 \tbndcn  0x12345678(%ecx,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 05 78 56 34 12 \tbndcn  0x12345678(%ebp,%eax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 08 78 56 34 12 \tbndcn  0x12345678(%eax,%ecx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 c8 78 56 34 12 \tbndcn  0x12345678(%eax,%ecx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0xc0, }, 4, 0, "", "",
+"f2 0f 1b c0          \tbndcn  %eax,%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"66 0f 1a 00          \tbndmov (%eax),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1a 05 78 56 34 12 \tbndmov 0x12345678,%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"66 0f 1a 18          \tbndmov (%eax),%bnd3",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"66 0f 1a 04 01       \tbndmov (%ecx,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 04 05 78 56 34 12 \tbndmov 0x12345678(,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"66 0f 1a 04 08       \tbndmov (%eax,%ecx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"66 0f 1a 04 c8       \tbndmov (%eax,%ecx,8),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"66 0f 1a 40 12       \tbndmov 0x12(%eax),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"66 0f 1a 45 12       \tbndmov 0x12(%ebp),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 01 12    \tbndmov 0x12(%ecx,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 05 12    \tbndmov 0x12(%ebp,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 08 12    \tbndmov 0x12(%eax,%ecx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 c8 12    \tbndmov 0x12(%eax,%ecx,8),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1a 80 78 56 34 12 \tbndmov 0x12345678(%eax),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1a 85 78 56 34 12 \tbndmov 0x12345678(%ebp),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 01 78 56 34 12 \tbndmov 0x12345678(%ecx,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 05 78 56 34 12 \tbndmov 0x12345678(%ebp,%eax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 08 78 56 34 12 \tbndmov 0x12345678(%eax,%ecx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 c8 78 56 34 12 \tbndmov 0x12345678(%eax,%ecx,8),%bnd0",},
+{{0x66, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"66 0f 1b 00          \tbndmov %bnd0,(%eax)",},
+{{0x66, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1b 05 78 56 34 12 \tbndmov %bnd0,0x12345678",},
+{{0x66, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"66 0f 1b 18          \tbndmov %bnd3,(%eax)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"66 0f 1b 04 01       \tbndmov %bnd0,(%ecx,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 04 05 78 56 34 12 \tbndmov %bnd0,0x12345678(,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"66 0f 1b 04 08       \tbndmov %bnd0,(%eax,%ecx,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"66 0f 1b 04 c8       \tbndmov %bnd0,(%eax,%ecx,8)",},
+{{0x66, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"66 0f 1b 40 12       \tbndmov %bnd0,0x12(%eax)",},
+{{0x66, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"66 0f 1b 45 12       \tbndmov %bnd0,0x12(%ebp)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 01 12    \tbndmov %bnd0,0x12(%ecx,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 05 12    \tbndmov %bnd0,0x12(%ebp,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 08 12    \tbndmov %bnd0,0x12(%eax,%ecx,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 c8 12    \tbndmov %bnd0,0x12(%eax,%ecx,8)",},
+{{0x66, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1b 80 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax)",},
+{{0x66, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1b 85 78 56 34 12 \tbndmov %bnd0,0x12345678(%ebp)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 01 78 56 34 12 \tbndmov %bnd0,0x12345678(%ecx,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 05 78 56 34 12 \tbndmov %bnd0,0x12345678(%ebp,%eax,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 08 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax,%ecx,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 c8 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax,%ecx,8)",},
+{{0x66, 0x0f, 0x1a, 0xc8, }, 4, 0, "", "",
+"66 0f 1a c8          \tbndmov %bnd0,%bnd1",},
+{{0x66, 0x0f, 0x1a, 0xc1, }, 4, 0, "", "",
+"66 0f 1a c1          \tbndmov %bnd1,%bnd0",},
+{{0x0f, 0x1a, 0x00, }, 3, 0, "", "",
+"0f 1a 00             \tbndldx (%eax),%bnd0",},
+{{0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1a 05 78 56 34 12 \tbndldx 0x12345678,%bnd0",},
+{{0x0f, 0x1a, 0x18, }, 3, 0, "", "",
+"0f 1a 18             \tbndldx (%eax),%bnd3",},
+{{0x0f, 0x1a, 0x04, 0x01, }, 4, 0, "", "",
+"0f 1a 04 01          \tbndldx (%ecx,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 04 05 78 56 34 12 \tbndldx 0x12345678(,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x04, 0x08, }, 4, 0, "", "",
+"0f 1a 04 08          \tbndldx (%eax,%ecx,1),%bnd0",},
+{{0x0f, 0x1a, 0x40, 0x12, }, 4, 0, "", "",
+"0f 1a 40 12          \tbndldx 0x12(%eax),%bnd0",},
+{{0x0f, 0x1a, 0x45, 0x12, }, 4, 0, "", "",
+"0f 1a 45 12          \tbndldx 0x12(%ebp),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x01, 0x12, }, 5, 0, "", "",
+"0f 1a 44 01 12       \tbndldx 0x12(%ecx,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x05, 0x12, }, 5, 0, "", "",
+"0f 1a 44 05 12       \tbndldx 0x12(%ebp,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x08, 0x12, }, 5, 0, "", "",
+"0f 1a 44 08 12       \tbndldx 0x12(%eax,%ecx,1),%bnd0",},
+{{0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1a 80 78 56 34 12 \tbndldx 0x12345678(%eax),%bnd0",},
+{{0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1a 85 78 56 34 12 \tbndldx 0x12345678(%ebp),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 01 78 56 34 12 \tbndldx 0x12345678(%ecx,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 05 78 56 34 12 \tbndldx 0x12345678(%ebp,%eax,1),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 08 78 56 34 12 \tbndldx 0x12345678(%eax,%ecx,1),%bnd0",},
+{{0x0f, 0x1b, 0x00, }, 3, 0, "", "",
+"0f 1b 00             \tbndstx %bnd0,(%eax)",},
+{{0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1b 05 78 56 34 12 \tbndstx %bnd0,0x12345678",},
+{{0x0f, 0x1b, 0x18, }, 3, 0, "", "",
+"0f 1b 18             \tbndstx %bnd3,(%eax)",},
+{{0x0f, 0x1b, 0x04, 0x01, }, 4, 0, "", "",
+"0f 1b 04 01          \tbndstx %bnd0,(%ecx,%eax,1)",},
+{{0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 04 05 78 56 34 12 \tbndstx %bnd0,0x12345678(,%eax,1)",},
+{{0x0f, 0x1b, 0x04, 0x08, }, 4, 0, "", "",
+"0f 1b 04 08          \tbndstx %bnd0,(%eax,%ecx,1)",},
+{{0x0f, 0x1b, 0x40, 0x12, }, 4, 0, "", "",
+"0f 1b 40 12          \tbndstx %bnd0,0x12(%eax)",},
+{{0x0f, 0x1b, 0x45, 0x12, }, 4, 0, "", "",
+"0f 1b 45 12          \tbndstx %bnd0,0x12(%ebp)",},
+{{0x0f, 0x1b, 0x44, 0x01, 0x12, }, 5, 0, "", "",
+"0f 1b 44 01 12       \tbndstx %bnd0,0x12(%ecx,%eax,1)",},
+{{0x0f, 0x1b, 0x44, 0x05, 0x12, }, 5, 0, "", "",
+"0f 1b 44 05 12       \tbndstx %bnd0,0x12(%ebp,%eax,1)",},
+{{0x0f, 0x1b, 0x44, 0x08, 0x12, }, 5, 0, "", "",
+"0f 1b 44 08 12       \tbndstx %bnd0,0x12(%eax,%ecx,1)",},
+{{0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1b 80 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax)",},
+{{0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1b 85 78 56 34 12 \tbndstx %bnd0,0x12345678(%ebp)",},
+{{0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 01 78 56 34 12 \tbndstx %bnd0,0x12345678(%ecx,%eax,1)",},
+{{0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 05 78 56 34 12 \tbndstx %bnd0,0x12345678(%ebp,%eax,1)",},
+{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax,%ecx,1)",},
+{{0xf2, 0xe8, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "call", "unconditional",
+"f2 e8 fc ff ff ff    \tbnd call 3c3 <main+0x3c3>",},
+{{0xf2, 0xff, 0x10, }, 3, 0, "call", "indirect",
+"f2 ff 10             \tbnd call *(%eax)",},
+{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
+"f2 c3                \tbnd ret ",},
+{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
+"f2 e9 fc ff ff ff    \tbnd jmp 3ce <main+0x3ce>",},
+{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
+"f2 e9 fc ff ff ff    \tbnd jmp 3d4 <main+0x3d4>",},
+{{0xf2, 0xff, 0x21, }, 3, 0, "jmp", "indirect",
+"f2 ff 21             \tbnd jmp *(%ecx)",},
+{{0xf2, 0x0f, 0x85, 0xfc, 0xff, 0xff, 0xff, }, 7, 0xfffffffc, "jcc", "conditional",
+"f2 0f 85 fc ff ff ff \tbnd jne 3de <main+0x3de>",},
+{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
+"0f 3a cc c1 00       \tsha1rnds4 $0x0,%xmm1,%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
+"0f 3a cc d7 91       \tsha1rnds4 $0x91,%xmm7,%xmm2",},
+{{0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 5, 0, "", "",
+"0f 3a cc 00 91       \tsha1rnds4 $0x91,(%eax),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
+"0f 3a cc 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678,%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x18, 0x91, }, 5, 0, "", "",
+"0f 3a cc 18 91       \tsha1rnds4 $0x91,(%eax),%xmm3",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x01, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 01 91    \tsha1rnds4 $0x91,(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 04 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x08, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 08 91    \tsha1rnds4 $0x91,(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0xc8, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 c8 91    \tsha1rnds4 $0x91,(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x40, 0x12, 0x91, }, 6, 0, "", "",
+"0f 3a cc 40 12 91    \tsha1rnds4 $0x91,0x12(%eax),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x45, 0x12, 0x91, }, 6, 0, "", "",
+"0f 3a cc 45 12 91    \tsha1rnds4 $0x91,0x12(%ebp),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x01, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 01 12 91 \tsha1rnds4 $0x91,0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x05, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 05 12 91 \tsha1rnds4 $0x91,0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x08, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 08 12 91 \tsha1rnds4 $0x91,0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0xc8, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 c8 12 91 \tsha1rnds4 $0x91,0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
+"0f 3a cc 80 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
+"0f 3a cc 85 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 01 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 08 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0xc1, }, 4, 0, "", "",
+"0f 38 c8 c1          \tsha1nexte %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xc8, 0xd7, }, 4, 0, "", "",
+"0f 38 c8 d7          \tsha1nexte %xmm7,%xmm2",},
+{{0x0f, 0x38, 0xc8, 0x00, }, 4, 0, "", "",
+"0f 38 c8 00          \tsha1nexte (%eax),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c8 05 78 56 34 12 \tsha1nexte 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x18, }, 4, 0, "", "",
+"0f 38 c8 18          \tsha1nexte (%eax),%xmm3",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 c8 04 01       \tsha1nexte (%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 04 05 78 56 34 12 \tsha1nexte 0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 c8 04 08       \tsha1nexte (%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 c8 04 c8       \tsha1nexte (%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 c8 40 12       \tsha1nexte 0x12(%eax),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 c8 45 12       \tsha1nexte 0x12(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 01 12    \tsha1nexte 0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 05 12    \tsha1nexte 0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 08 12    \tsha1nexte 0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 c8 12    \tsha1nexte 0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c8 80 78 56 34 12 \tsha1nexte 0x12345678(%eax),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c8 85 78 56 34 12 \tsha1nexte 0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 01 78 56 34 12 \tsha1nexte 0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 05 78 56 34 12 \tsha1nexte 0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 08 78 56 34 12 \tsha1nexte 0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 c8 78 56 34 12 \tsha1nexte 0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0xc1, }, 4, 0, "", "",
+"0f 38 c9 c1          \tsha1msg1 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xc9, 0xd7, }, 4, 0, "", "",
+"0f 38 c9 d7          \tsha1msg1 %xmm7,%xmm2",},
+{{0x0f, 0x38, 0xc9, 0x00, }, 4, 0, "", "",
+"0f 38 c9 00          \tsha1msg1 (%eax),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c9 05 78 56 34 12 \tsha1msg1 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x18, }, 4, 0, "", "",
+"0f 38 c9 18          \tsha1msg1 (%eax),%xmm3",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 c9 04 01       \tsha1msg1 (%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 04 05 78 56 34 12 \tsha1msg1 0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 c9 04 08       \tsha1msg1 (%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 c9 04 c8       \tsha1msg1 (%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 c9 40 12       \tsha1msg1 0x12(%eax),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 c9 45 12       \tsha1msg1 0x12(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 01 12    \tsha1msg1 0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 05 12    \tsha1msg1 0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 08 12    \tsha1msg1 0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 c8 12    \tsha1msg1 0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c9 80 78 56 34 12 \tsha1msg1 0x12345678(%eax),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c9 85 78 56 34 12 \tsha1msg1 0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 01 78 56 34 12 \tsha1msg1 0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 05 78 56 34 12 \tsha1msg1 0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 08 78 56 34 12 \tsha1msg1 0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 c8 78 56 34 12 \tsha1msg1 0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0xc1, }, 4, 0, "", "",
+"0f 38 ca c1          \tsha1msg2 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xca, 0xd7, }, 4, 0, "", "",
+"0f 38 ca d7          \tsha1msg2 %xmm7,%xmm2",},
+{{0x0f, 0x38, 0xca, 0x00, }, 4, 0, "", "",
+"0f 38 ca 00          \tsha1msg2 (%eax),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 ca 05 78 56 34 12 \tsha1msg2 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xca, 0x18, }, 4, 0, "", "",
+"0f 38 ca 18          \tsha1msg2 (%eax),%xmm3",},
+{{0x0f, 0x38, 0xca, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 ca 04 01       \tsha1msg2 (%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 04 05 78 56 34 12 \tsha1msg2 0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 ca 04 08       \tsha1msg2 (%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 ca 04 c8       \tsha1msg2 (%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 ca 40 12       \tsha1msg2 0x12(%eax),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 ca 45 12       \tsha1msg2 0x12(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 01 12    \tsha1msg2 0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 05 12    \tsha1msg2 0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 08 12    \tsha1msg2 0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 c8 12    \tsha1msg2 0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 ca 80 78 56 34 12 \tsha1msg2 0x12345678(%eax),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 ca 85 78 56 34 12 \tsha1msg2 0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 01 78 56 34 12 \tsha1msg2 0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 05 78 56 34 12 \tsha1msg2 0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 08 78 56 34 12 \tsha1msg2 0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 c8 78 56 34 12 \tsha1msg2 0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcb, 0xcc, }, 4, 0, "", "",
+"0f 38 cb cc          \tsha256rnds2 %xmm0,%xmm4,%xmm1",},
+{{0x0f, 0x38, 0xcb, 0xd7, }, 4, 0, "", "",
+"0f 38 cb d7          \tsha256rnds2 %xmm0,%xmm7,%xmm2",},
+{{0x0f, 0x38, 0xcb, 0x08, }, 4, 0, "", "",
+"0f 38 cb 08          \tsha256rnds2 %xmm0,(%eax),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cb 0d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678,%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x18, }, 4, 0, "", "",
+"0f 38 cb 18          \tsha256rnds2 %xmm0,(%eax),%xmm3",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x01, }, 5, 0, "", "",
+"0f 38 cb 0c 01       \tsha256rnds2 %xmm0,(%ecx,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 0c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x08, }, 5, 0, "", "",
+"0f 38 cb 0c 08       \tsha256rnds2 %xmm0,(%eax,%ecx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0xc8, }, 5, 0, "", "",
+"0f 38 cb 0c c8       \tsha256rnds2 %xmm0,(%eax,%ecx,8),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x48, 0x12, }, 5, 0, "", "",
+"0f 38 cb 48 12       \tsha256rnds2 %xmm0,0x12(%eax),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4d, 0x12, }, 5, 0, "", "",
+"0f 38 cb 4d 12       \tsha256rnds2 %xmm0,0x12(%ebp),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 01 12    \tsha256rnds2 %xmm0,0x12(%ecx,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 05 12    \tsha256rnds2 %xmm0,0x12(%ebp,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 08 12    \tsha256rnds2 %xmm0,0x12(%eax,%ecx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c c8 12    \tsha256rnds2 %xmm0,0x12(%eax,%ecx,8),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cb 88 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cb 8d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ebp),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 01 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ecx,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ebp,%eax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 08 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax,%ecx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x0f, 0x38, 0xcc, 0xc1, }, 4, 0, "", "",
+"0f 38 cc c1          \tsha256msg1 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xcc, 0xd7, }, 4, 0, "", "",
+"0f 38 cc d7          \tsha256msg1 %xmm7,%xmm2",},
+{{0x0f, 0x38, 0xcc, 0x00, }, 4, 0, "", "",
+"0f 38 cc 00          \tsha256msg1 (%eax),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cc 05 78 56 34 12 \tsha256msg1 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x18, }, 4, 0, "", "",
+"0f 38 cc 18          \tsha256msg1 (%eax),%xmm3",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 cc 04 01       \tsha256msg1 (%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 04 05 78 56 34 12 \tsha256msg1 0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 cc 04 08       \tsha256msg1 (%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 cc 04 c8       \tsha256msg1 (%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 cc 40 12       \tsha256msg1 0x12(%eax),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 cc 45 12       \tsha256msg1 0x12(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 01 12    \tsha256msg1 0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 05 12    \tsha256msg1 0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 08 12    \tsha256msg1 0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 c8 12    \tsha256msg1 0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cc 80 78 56 34 12 \tsha256msg1 0x12345678(%eax),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cc 85 78 56 34 12 \tsha256msg1 0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 01 78 56 34 12 \tsha256msg1 0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 05 78 56 34 12 \tsha256msg1 0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 08 78 56 34 12 \tsha256msg1 0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 c8 78 56 34 12 \tsha256msg1 0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0xc1, }, 4, 0, "", "",
+"0f 38 cd c1          \tsha256msg2 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xcd, 0xd7, }, 4, 0, "", "",
+"0f 38 cd d7          \tsha256msg2 %xmm7,%xmm2",},
+{{0x0f, 0x38, 0xcd, 0x00, }, 4, 0, "", "",
+"0f 38 cd 00          \tsha256msg2 (%eax),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cd 05 78 56 34 12 \tsha256msg2 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x18, }, 4, 0, "", "",
+"0f 38 cd 18          \tsha256msg2 (%eax),%xmm3",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 cd 04 01       \tsha256msg2 (%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 04 05 78 56 34 12 \tsha256msg2 0x12345678(,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 cd 04 08       \tsha256msg2 (%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 cd 04 c8       \tsha256msg2 (%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 cd 40 12       \tsha256msg2 0x12(%eax),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 cd 45 12       \tsha256msg2 0x12(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 01 12    \tsha256msg2 0x12(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 05 12    \tsha256msg2 0x12(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 08 12    \tsha256msg2 0x12(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 c8 12    \tsha256msg2 0x12(%eax,%ecx,8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cd 80 78 56 34 12 \tsha256msg2 0x12345678(%eax),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cd 85 78 56 34 12 \tsha256msg2 0x12345678(%ebp),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 01 78 56 34 12 \tsha256msg2 0x12345678(%ecx,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 05 78 56 34 12 \tsha256msg2 0x12345678(%ebp,%eax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 08 78 56 34 12 \tsha256msg2 0x12345678(%eax,%ecx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 c8 78 56 34 12 \tsha256msg2 0x12345678(%eax,%ecx,8),%xmm0",},
+{{0x66, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
+"66 0f ae 38          \tclflushopt (%eax)",},
+{{0x66, 0x0f, 0xae, 0x3d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f ae 3d 78 56 34 12 \tclflushopt 0x12345678",},
+{{0x66, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%eax,%ecx,8)",},
+{{0x0f, 0xae, 0x38, }, 3, 0, "", "",
+"0f ae 38             \tclflush (%eax)",},
+{{0x0f, 0xae, 0xf8, }, 3, 0, "", "",
+"0f ae f8             \tsfence ",},
+{{0x66, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
+"66 0f ae 30          \tclwb   (%eax)",},
+{{0x66, 0x0f, 0xae, 0x35, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f ae 35 78 56 34 12 \tclwb   0x12345678",},
+{{0x66, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae b4 c8 78 56 34 12 \tclwb   0x12345678(%eax,%ecx,8)",},
+{{0x0f, 0xae, 0x30, }, 3, 0, "", "",
+"0f ae 30             \txsaveopt (%eax)",},
+{{0x0f, 0xae, 0xf0, }, 3, 0, "", "",
+"0f ae f0             \tmfence ",},
+{{0x0f, 0xc7, 0x20, }, 3, 0, "", "",
+"0f c7 20             \txsavec (%eax)",},
+{{0x0f, 0xc7, 0x25, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f c7 25 78 56 34 12 \txsavec 0x12345678",},
+{{0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%eax,%ecx,8)",},
+{{0x0f, 0xc7, 0x28, }, 3, 0, "", "",
+"0f c7 28             \txsaves (%eax)",},
+{{0x0f, 0xc7, 0x2d, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f c7 2d 78 56 34 12 \txsaves 0x12345678",},
+{{0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%eax,%ecx,8)",},
+{{0x0f, 0xc7, 0x18, }, 3, 0, "", "",
+"0f c7 18             \txrstors (%eax)",},
+{{0x0f, 0xc7, 0x1d, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f c7 1d 78 56 34 12 \txrstors 0x12345678",},
+{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",},
+{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
+"66 0f ae f8          \tpcommit ",},
diff --git a/tools/perf/tests/insn-x86-dat-64.c b/tools/perf/tests/insn-x86-dat-64.c
new file mode 100644
index 000000000000..4fe7cce179c4
--- /dev/null
+++ b/tools/perf/tests/insn-x86-dat-64.c
@@ -0,0 +1,768 @@
+/*
+ * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk
+ * from insn-x86-dat-src.c for inclusion by insn-x86.c
+ * Do not change this code.
+*/
+
+{{0x0f, 0x31, }, 2, 0, "", "",
+"0f 31                \trdtsc  ",},
+{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"f3 0f 1b 00          \tbndmk  (%rax),%bnd0",},
+{{0xf3, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
+"f3 41 0f 1b 00       \tbndmk  (%r8),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 04 25 78 56 34 12 \tbndmk  0x12345678,%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"f3 0f 1b 18          \tbndmk  (%rax),%bnd3",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"f3 0f 1b 04 01       \tbndmk  (%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 04 05 78 56 34 12 \tbndmk  0x12345678(,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"f3 0f 1b 04 08       \tbndmk  (%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"f3 0f 1b 04 c8       \tbndmk  (%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"f3 0f 1b 40 12       \tbndmk  0x12(%rax),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"f3 0f 1b 45 12       \tbndmk  0x12(%rbp),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 01 12    \tbndmk  0x12(%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 05 12    \tbndmk  0x12(%rbp,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 08 12    \tbndmk  0x12(%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f3 0f 1b 44 c8 12    \tbndmk  0x12(%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1b 80 78 56 34 12 \tbndmk  0x12345678(%rax),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1b 85 78 56 34 12 \tbndmk  0x12345678(%rbp),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 01 78 56 34 12 \tbndmk  0x12345678(%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 05 78 56 34 12 \tbndmk  0x12345678(%rbp,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 08 78 56 34 12 \tbndmk  0x12345678(%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1b 84 c8 78 56 34 12 \tbndmk  0x12345678(%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"f3 0f 1a 00          \tbndcl  (%rax),%bnd0",},
+{{0xf3, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
+"f3 41 0f 1a 00       \tbndcl  (%r8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 04 25 78 56 34 12 \tbndcl  0x12345678,%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"f3 0f 1a 18          \tbndcl  (%rax),%bnd3",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"f3 0f 1a 04 01       \tbndcl  (%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 04 05 78 56 34 12 \tbndcl  0x12345678(,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"f3 0f 1a 04 08       \tbndcl  (%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"f3 0f 1a 04 c8       \tbndcl  (%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"f3 0f 1a 40 12       \tbndcl  0x12(%rax),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"f3 0f 1a 45 12       \tbndcl  0x12(%rbp),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 01 12    \tbndcl  0x12(%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 05 12    \tbndcl  0x12(%rbp,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 08 12    \tbndcl  0x12(%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f3 0f 1a 44 c8 12    \tbndcl  0x12(%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1a 80 78 56 34 12 \tbndcl  0x12345678(%rax),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f3 0f 1a 85 78 56 34 12 \tbndcl  0x12345678(%rbp),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 01 78 56 34 12 \tbndcl  0x12345678(%rcx,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 05 78 56 34 12 \tbndcl  0x12345678(%rbp,%rax,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 08 78 56 34 12 \tbndcl  0x12345678(%rax,%rcx,1),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f3 0f 1a 84 c8 78 56 34 12 \tbndcl  0x12345678(%rax,%rcx,8),%bnd0",},
+{{0xf3, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
+"f3 0f 1a c0          \tbndcl  %rax,%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"f2 0f 1a 00          \tbndcu  (%rax),%bnd0",},
+{{0xf2, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
+"f2 41 0f 1a 00       \tbndcu  (%r8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 04 25 78 56 34 12 \tbndcu  0x12345678,%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"f2 0f 1a 18          \tbndcu  (%rax),%bnd3",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"f2 0f 1a 04 01       \tbndcu  (%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 04 05 78 56 34 12 \tbndcu  0x12345678(,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"f2 0f 1a 04 08       \tbndcu  (%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"f2 0f 1a 04 c8       \tbndcu  (%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"f2 0f 1a 40 12       \tbndcu  0x12(%rax),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"f2 0f 1a 45 12       \tbndcu  0x12(%rbp),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 01 12    \tbndcu  0x12(%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 05 12    \tbndcu  0x12(%rbp,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 08 12    \tbndcu  0x12(%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f2 0f 1a 44 c8 12    \tbndcu  0x12(%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1a 80 78 56 34 12 \tbndcu  0x12345678(%rax),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1a 85 78 56 34 12 \tbndcu  0x12345678(%rbp),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 01 78 56 34 12 \tbndcu  0x12345678(%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 05 78 56 34 12 \tbndcu  0x12345678(%rbp,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 08 78 56 34 12 \tbndcu  0x12345678(%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1a 84 c8 78 56 34 12 \tbndcu  0x12345678(%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
+"f2 0f 1a c0          \tbndcu  %rax,%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"f2 0f 1b 00          \tbndcn  (%rax),%bnd0",},
+{{0xf2, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
+"f2 41 0f 1b 00       \tbndcn  (%r8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 04 25 78 56 34 12 \tbndcn  0x12345678,%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"f2 0f 1b 18          \tbndcn  (%rax),%bnd3",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"f2 0f 1b 04 01       \tbndcn  (%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 04 05 78 56 34 12 \tbndcn  0x12345678(,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"f2 0f 1b 04 08       \tbndcn  (%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"f2 0f 1b 04 c8       \tbndcn  (%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"f2 0f 1b 40 12       \tbndcn  0x12(%rax),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"f2 0f 1b 45 12       \tbndcn  0x12(%rbp),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 01 12    \tbndcn  0x12(%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 05 12    \tbndcn  0x12(%rbp,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 08 12    \tbndcn  0x12(%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"f2 0f 1b 44 c8 12    \tbndcn  0x12(%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1b 80 78 56 34 12 \tbndcn  0x12345678(%rax),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"f2 0f 1b 85 78 56 34 12 \tbndcn  0x12345678(%rbp),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 01 78 56 34 12 \tbndcn  0x12345678(%rcx,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 05 78 56 34 12 \tbndcn  0x12345678(%rbp,%rax,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 08 78 56 34 12 \tbndcn  0x12345678(%rax,%rcx,1),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"f2 0f 1b 84 c8 78 56 34 12 \tbndcn  0x12345678(%rax,%rcx,8),%bnd0",},
+{{0xf2, 0x0f, 0x1b, 0xc0, }, 4, 0, "", "",
+"f2 0f 1b c0          \tbndcn  %rax,%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"66 0f 1a 00          \tbndmov (%rax),%bnd0",},
+{{0x66, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
+"66 41 0f 1a 00       \tbndmov (%r8),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 04 25 78 56 34 12 \tbndmov 0x12345678,%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
+"66 0f 1a 18          \tbndmov (%rax),%bnd3",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
+"66 0f 1a 04 01       \tbndmov (%rcx,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 04 05 78 56 34 12 \tbndmov 0x12345678(,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
+"66 0f 1a 04 08       \tbndmov (%rax,%rcx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
+"66 0f 1a 04 c8       \tbndmov (%rax,%rcx,8),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
+"66 0f 1a 40 12       \tbndmov 0x12(%rax),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
+"66 0f 1a 45 12       \tbndmov 0x12(%rbp),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 01 12    \tbndmov 0x12(%rcx,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 05 12    \tbndmov 0x12(%rbp,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 08 12    \tbndmov 0x12(%rax,%rcx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"66 0f 1a 44 c8 12    \tbndmov 0x12(%rax,%rcx,8),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1a 80 78 56 34 12 \tbndmov 0x12345678(%rax),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1a 85 78 56 34 12 \tbndmov 0x12345678(%rbp),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 01 78 56 34 12 \tbndmov 0x12345678(%rcx,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 05 78 56 34 12 \tbndmov 0x12345678(%rbp,%rax,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 08 78 56 34 12 \tbndmov 0x12345678(%rax,%rcx,1),%bnd0",},
+{{0x66, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1a 84 c8 78 56 34 12 \tbndmov 0x12345678(%rax,%rcx,8),%bnd0",},
+{{0x66, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"66 0f 1b 00          \tbndmov %bnd0,(%rax)",},
+{{0x66, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
+"66 41 0f 1b 00       \tbndmov %bnd0,(%r8)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 04 25 78 56 34 12 \tbndmov %bnd0,0x12345678",},
+{{0x66, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
+"66 0f 1b 18          \tbndmov %bnd3,(%rax)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
+"66 0f 1b 04 01       \tbndmov %bnd0,(%rcx,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 04 05 78 56 34 12 \tbndmov %bnd0,0x12345678(,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
+"66 0f 1b 04 08       \tbndmov %bnd0,(%rax,%rcx,1)",},
+{{0x66, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
+"66 0f 1b 04 c8       \tbndmov %bnd0,(%rax,%rcx,8)",},
+{{0x66, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
+"66 0f 1b 40 12       \tbndmov %bnd0,0x12(%rax)",},
+{{0x66, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
+"66 0f 1b 45 12       \tbndmov %bnd0,0x12(%rbp)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 01 12    \tbndmov %bnd0,0x12(%rcx,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 05 12    \tbndmov %bnd0,0x12(%rbp,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 08 12    \tbndmov %bnd0,0x12(%rax,%rcx,1)",},
+{{0x66, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"66 0f 1b 44 c8 12    \tbndmov %bnd0,0x12(%rax,%rcx,8)",},
+{{0x66, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1b 80 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax)",},
+{{0x66, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"66 0f 1b 85 78 56 34 12 \tbndmov %bnd0,0x12345678(%rbp)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 01 78 56 34 12 \tbndmov %bnd0,0x12345678(%rcx,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 05 78 56 34 12 \tbndmov %bnd0,0x12345678(%rbp,%rax,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 08 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax,%rcx,1)",},
+{{0x66, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f 1b 84 c8 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax,%rcx,8)",},
+{{0x66, 0x0f, 0x1a, 0xc8, }, 4, 0, "", "",
+"66 0f 1a c8          \tbndmov %bnd0,%bnd1",},
+{{0x66, 0x0f, 0x1a, 0xc1, }, 4, 0, "", "",
+"66 0f 1a c1          \tbndmov %bnd1,%bnd0",},
+{{0x0f, 0x1a, 0x00, }, 3, 0, "", "",
+"0f 1a 00             \tbndldx (%rax),%bnd0",},
+{{0x41, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
+"41 0f 1a 00          \tbndldx (%r8),%bnd0",},
+{{0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 04 25 78 56 34 12 \tbndldx 0x12345678,%bnd0",},
+{{0x0f, 0x1a, 0x18, }, 3, 0, "", "",
+"0f 1a 18             \tbndldx (%rax),%bnd3",},
+{{0x0f, 0x1a, 0x04, 0x01, }, 4, 0, "", "",
+"0f 1a 04 01          \tbndldx (%rcx,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 04 05 78 56 34 12 \tbndldx 0x12345678(,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x04, 0x08, }, 4, 0, "", "",
+"0f 1a 04 08          \tbndldx (%rax,%rcx,1),%bnd0",},
+{{0x0f, 0x1a, 0x40, 0x12, }, 4, 0, "", "",
+"0f 1a 40 12          \tbndldx 0x12(%rax),%bnd0",},
+{{0x0f, 0x1a, 0x45, 0x12, }, 4, 0, "", "",
+"0f 1a 45 12          \tbndldx 0x12(%rbp),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x01, 0x12, }, 5, 0, "", "",
+"0f 1a 44 01 12       \tbndldx 0x12(%rcx,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x05, 0x12, }, 5, 0, "", "",
+"0f 1a 44 05 12       \tbndldx 0x12(%rbp,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x44, 0x08, 0x12, }, 5, 0, "", "",
+"0f 1a 44 08 12       \tbndldx 0x12(%rax,%rcx,1),%bnd0",},
+{{0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1a 80 78 56 34 12 \tbndldx 0x12345678(%rax),%bnd0",},
+{{0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1a 85 78 56 34 12 \tbndldx 0x12345678(%rbp),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 01 78 56 34 12 \tbndldx 0x12345678(%rcx,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 05 78 56 34 12 \tbndldx 0x12345678(%rbp,%rax,1),%bnd0",},
+{{0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1a 84 08 78 56 34 12 \tbndldx 0x12345678(%rax,%rcx,1),%bnd0",},
+{{0x0f, 0x1b, 0x00, }, 3, 0, "", "",
+"0f 1b 00             \tbndstx %bnd0,(%rax)",},
+{{0x41, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
+"41 0f 1b 00          \tbndstx %bnd0,(%r8)",},
+{{0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 04 25 78 56 34 12 \tbndstx %bnd0,0x12345678",},
+{{0x0f, 0x1b, 0x18, }, 3, 0, "", "",
+"0f 1b 18             \tbndstx %bnd3,(%rax)",},
+{{0x0f, 0x1b, 0x04, 0x01, }, 4, 0, "", "",
+"0f 1b 04 01          \tbndstx %bnd0,(%rcx,%rax,1)",},
+{{0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 04 05 78 56 34 12 \tbndstx %bnd0,0x12345678(,%rax,1)",},
+{{0x0f, 0x1b, 0x04, 0x08, }, 4, 0, "", "",
+"0f 1b 04 08          \tbndstx %bnd0,(%rax,%rcx,1)",},
+{{0x0f, 0x1b, 0x40, 0x12, }, 4, 0, "", "",
+"0f 1b 40 12          \tbndstx %bnd0,0x12(%rax)",},
+{{0x0f, 0x1b, 0x45, 0x12, }, 4, 0, "", "",
+"0f 1b 45 12          \tbndstx %bnd0,0x12(%rbp)",},
+{{0x0f, 0x1b, 0x44, 0x01, 0x12, }, 5, 0, "", "",
+"0f 1b 44 01 12       \tbndstx %bnd0,0x12(%rcx,%rax,1)",},
+{{0x0f, 0x1b, 0x44, 0x05, 0x12, }, 5, 0, "", "",
+"0f 1b 44 05 12       \tbndstx %bnd0,0x12(%rbp,%rax,1)",},
+{{0x0f, 0x1b, 0x44, 0x08, 0x12, }, 5, 0, "", "",
+"0f 1b 44 08 12       \tbndstx %bnd0,0x12(%rax,%rcx,1)",},
+{{0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1b 80 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax)",},
+{{0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
+"0f 1b 85 78 56 34 12 \tbndstx %bnd0,0x12345678(%rbp)",},
+{{0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 01 78 56 34 12 \tbndstx %bnd0,0x12345678(%rcx,%rax,1)",},
+{{0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 05 78 56 34 12 \tbndstx %bnd0,0x12345678(%rbp,%rax,1)",},
+{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax,%rcx,1)",},
+{{0xf2, 0xe8, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "call", "unconditional",
+"f2 e8 00 00 00 00    \tbnd callq 3f6 <main+0x3f6>",},
+{{0x67, 0xf2, 0xff, 0x10, }, 4, 0, "call", "indirect",
+"67 f2 ff 10          \tbnd callq *(%eax)",},
+{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
+"f2 c3                \tbnd retq ",},
+{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
+"f2 e9 00 00 00 00    \tbnd jmpq 402 <main+0x402>",},
+{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
+"f2 e9 00 00 00 00    \tbnd jmpq 408 <main+0x408>",},
+{{0x67, 0xf2, 0xff, 0x21, }, 4, 0, "jmp", "indirect",
+"67 f2 ff 21          \tbnd jmpq *(%ecx)",},
+{{0xf2, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, }, 7, 0, "jcc", "conditional",
+"f2 0f 85 00 00 00 00 \tbnd jne 413 <main+0x413>",},
+{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
+"0f 3a cc c1 00       \tsha1rnds4 $0x0,%xmm1,%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
+"0f 3a cc d7 91       \tsha1rnds4 $0x91,%xmm7,%xmm2",},
+{{0x41, 0x0f, 0x3a, 0xcc, 0xc0, 0x91, }, 6, 0, "", "",
+"41 0f 3a cc c0 91    \tsha1rnds4 $0x91,%xmm8,%xmm0",},
+{{0x44, 0x0f, 0x3a, 0xcc, 0xc7, 0x91, }, 6, 0, "", "",
+"44 0f 3a cc c7 91    \tsha1rnds4 $0x91,%xmm7,%xmm8",},
+{{0x45, 0x0f, 0x3a, 0xcc, 0xc7, 0x91, }, 6, 0, "", "",
+"45 0f 3a cc c7 91    \tsha1rnds4 $0x91,%xmm15,%xmm8",},
+{{0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 5, 0, "", "",
+"0f 3a cc 00 91       \tsha1rnds4 $0x91,(%rax),%xmm0",},
+{{0x41, 0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 6, 0, "", "",
+"41 0f 3a cc 00 91    \tsha1rnds4 $0x91,(%r8),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 04 25 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678,%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x18, 0x91, }, 5, 0, "", "",
+"0f 3a cc 18 91       \tsha1rnds4 $0x91,(%rax),%xmm3",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x01, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 01 91    \tsha1rnds4 $0x91,(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 04 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0x08, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 08 91    \tsha1rnds4 $0x91,(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x04, 0xc8, 0x91, }, 6, 0, "", "",
+"0f 3a cc 04 c8 91    \tsha1rnds4 $0x91,(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x40, 0x12, 0x91, }, 6, 0, "", "",
+"0f 3a cc 40 12 91    \tsha1rnds4 $0x91,0x12(%rax),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x45, 0x12, 0x91, }, 6, 0, "", "",
+"0f 3a cc 45 12 91    \tsha1rnds4 $0x91,0x12(%rbp),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x01, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 01 12 91 \tsha1rnds4 $0x91,0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x05, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 05 12 91 \tsha1rnds4 $0x91,0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0x08, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 08 12 91 \tsha1rnds4 $0x91,0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x44, 0xc8, 0x12, 0x91, }, 7, 0, "", "",
+"0f 3a cc 44 c8 12 91 \tsha1rnds4 $0x91,0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
+"0f 3a cc 80 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
+"0f 3a cc 85 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 01 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 08 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x3a, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
+"0f 3a cc 84 c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x3a, 0xcc, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 11, 0, "", "",
+"44 0f 3a cc bc c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xc8, 0xc1, }, 4, 0, "", "",
+"0f 38 c8 c1          \tsha1nexte %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xc8, 0xd7, }, 4, 0, "", "",
+"0f 38 c8 d7          \tsha1nexte %xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xc8, 0xc0, }, 5, 0, "", "",
+"41 0f 38 c8 c0       \tsha1nexte %xmm8,%xmm0",},
+{{0x44, 0x0f, 0x38, 0xc8, 0xc7, }, 5, 0, "", "",
+"44 0f 38 c8 c7       \tsha1nexte %xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xc8, 0xc7, }, 5, 0, "", "",
+"45 0f 38 c8 c7       \tsha1nexte %xmm15,%xmm8",},
+{{0x0f, 0x38, 0xc8, 0x00, }, 4, 0, "", "",
+"0f 38 c8 00          \tsha1nexte (%rax),%xmm0",},
+{{0x41, 0x0f, 0x38, 0xc8, 0x00, }, 5, 0, "", "",
+"41 0f 38 c8 00       \tsha1nexte (%r8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 04 25 78 56 34 12 \tsha1nexte 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x18, }, 4, 0, "", "",
+"0f 38 c8 18          \tsha1nexte (%rax),%xmm3",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 c8 04 01       \tsha1nexte (%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 04 05 78 56 34 12 \tsha1nexte 0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 c8 04 08       \tsha1nexte (%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 c8 04 c8       \tsha1nexte (%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 c8 40 12       \tsha1nexte 0x12(%rax),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 c8 45 12       \tsha1nexte 0x12(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 01 12    \tsha1nexte 0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 05 12    \tsha1nexte 0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 08 12    \tsha1nexte 0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 c8 44 c8 12    \tsha1nexte 0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c8 80 78 56 34 12 \tsha1nexte 0x12345678(%rax),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c8 85 78 56 34 12 \tsha1nexte 0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 01 78 56 34 12 \tsha1nexte 0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 05 78 56 34 12 \tsha1nexte 0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 08 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc8, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c8 84 c8 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x38, 0xc8, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 c8 bc c8 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xc9, 0xc1, }, 4, 0, "", "",
+"0f 38 c9 c1          \tsha1msg1 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xc9, 0xd7, }, 4, 0, "", "",
+"0f 38 c9 d7          \tsha1msg1 %xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xc9, 0xc0, }, 5, 0, "", "",
+"41 0f 38 c9 c0       \tsha1msg1 %xmm8,%xmm0",},
+{{0x44, 0x0f, 0x38, 0xc9, 0xc7, }, 5, 0, "", "",
+"44 0f 38 c9 c7       \tsha1msg1 %xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xc9, 0xc7, }, 5, 0, "", "",
+"45 0f 38 c9 c7       \tsha1msg1 %xmm15,%xmm8",},
+{{0x0f, 0x38, 0xc9, 0x00, }, 4, 0, "", "",
+"0f 38 c9 00          \tsha1msg1 (%rax),%xmm0",},
+{{0x41, 0x0f, 0x38, 0xc9, 0x00, }, 5, 0, "", "",
+"41 0f 38 c9 00       \tsha1msg1 (%r8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 04 25 78 56 34 12 \tsha1msg1 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x18, }, 4, 0, "", "",
+"0f 38 c9 18          \tsha1msg1 (%rax),%xmm3",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 c9 04 01       \tsha1msg1 (%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 04 05 78 56 34 12 \tsha1msg1 0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 c9 04 08       \tsha1msg1 (%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 c9 04 c8       \tsha1msg1 (%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 c9 40 12       \tsha1msg1 0x12(%rax),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 c9 45 12       \tsha1msg1 0x12(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 01 12    \tsha1msg1 0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 05 12    \tsha1msg1 0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 08 12    \tsha1msg1 0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 c9 44 c8 12    \tsha1msg1 0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c9 80 78 56 34 12 \tsha1msg1 0x12345678(%rax),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 c9 85 78 56 34 12 \tsha1msg1 0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 01 78 56 34 12 \tsha1msg1 0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 05 78 56 34 12 \tsha1msg1 0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 08 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xc9, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 c9 84 c8 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x38, 0xc9, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 c9 bc c8 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xca, 0xc1, }, 4, 0, "", "",
+"0f 38 ca c1          \tsha1msg2 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xca, 0xd7, }, 4, 0, "", "",
+"0f 38 ca d7          \tsha1msg2 %xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xca, 0xc0, }, 5, 0, "", "",
+"41 0f 38 ca c0       \tsha1msg2 %xmm8,%xmm0",},
+{{0x44, 0x0f, 0x38, 0xca, 0xc7, }, 5, 0, "", "",
+"44 0f 38 ca c7       \tsha1msg2 %xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xca, 0xc7, }, 5, 0, "", "",
+"45 0f 38 ca c7       \tsha1msg2 %xmm15,%xmm8",},
+{{0x0f, 0x38, 0xca, 0x00, }, 4, 0, "", "",
+"0f 38 ca 00          \tsha1msg2 (%rax),%xmm0",},
+{{0x41, 0x0f, 0x38, 0xca, 0x00, }, 5, 0, "", "",
+"41 0f 38 ca 00       \tsha1msg2 (%r8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 04 25 78 56 34 12 \tsha1msg2 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xca, 0x18, }, 4, 0, "", "",
+"0f 38 ca 18          \tsha1msg2 (%rax),%xmm3",},
+{{0x0f, 0x38, 0xca, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 ca 04 01       \tsha1msg2 (%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 04 05 78 56 34 12 \tsha1msg2 0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 ca 04 08       \tsha1msg2 (%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 ca 04 c8       \tsha1msg2 (%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 ca 40 12       \tsha1msg2 0x12(%rax),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 ca 45 12       \tsha1msg2 0x12(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 01 12    \tsha1msg2 0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 05 12    \tsha1msg2 0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 08 12    \tsha1msg2 0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 ca 44 c8 12    \tsha1msg2 0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 ca 80 78 56 34 12 \tsha1msg2 0x12345678(%rax),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 ca 85 78 56 34 12 \tsha1msg2 0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 01 78 56 34 12 \tsha1msg2 0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 05 78 56 34 12 \tsha1msg2 0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 08 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xca, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 ca 84 c8 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x38, 0xca, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 ca bc c8 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xcb, 0xcc, }, 4, 0, "", "",
+"0f 38 cb cc          \tsha256rnds2 %xmm0,%xmm4,%xmm1",},
+{{0x0f, 0x38, 0xcb, 0xd7, }, 4, 0, "", "",
+"0f 38 cb d7          \tsha256rnds2 %xmm0,%xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xcb, 0xc8, }, 5, 0, "", "",
+"41 0f 38 cb c8       \tsha256rnds2 %xmm0,%xmm8,%xmm1",},
+{{0x44, 0x0f, 0x38, 0xcb, 0xc7, }, 5, 0, "", "",
+"44 0f 38 cb c7       \tsha256rnds2 %xmm0,%xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xcb, 0xc7, }, 5, 0, "", "",
+"45 0f 38 cb c7       \tsha256rnds2 %xmm0,%xmm15,%xmm8",},
+{{0x0f, 0x38, 0xcb, 0x08, }, 4, 0, "", "",
+"0f 38 cb 08          \tsha256rnds2 %xmm0,(%rax),%xmm1",},
+{{0x41, 0x0f, 0x38, 0xcb, 0x08, }, 5, 0, "", "",
+"41 0f 38 cb 08       \tsha256rnds2 %xmm0,(%r8),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 0c 25 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678,%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x18, }, 4, 0, "", "",
+"0f 38 cb 18          \tsha256rnds2 %xmm0,(%rax),%xmm3",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x01, }, 5, 0, "", "",
+"0f 38 cb 0c 01       \tsha256rnds2 %xmm0,(%rcx,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 0c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0x08, }, 5, 0, "", "",
+"0f 38 cb 0c 08       \tsha256rnds2 %xmm0,(%rax,%rcx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x0c, 0xc8, }, 5, 0, "", "",
+"0f 38 cb 0c c8       \tsha256rnds2 %xmm0,(%rax,%rcx,8),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x48, 0x12, }, 5, 0, "", "",
+"0f 38 cb 48 12       \tsha256rnds2 %xmm0,0x12(%rax),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4d, 0x12, }, 5, 0, "", "",
+"0f 38 cb 4d 12       \tsha256rnds2 %xmm0,0x12(%rbp),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 01 12    \tsha256rnds2 %xmm0,0x12(%rcx,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 05 12    \tsha256rnds2 %xmm0,0x12(%rbp,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c 08 12    \tsha256rnds2 %xmm0,0x12(%rax,%rcx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x4c, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cb 4c c8 12    \tsha256rnds2 %xmm0,0x12(%rax,%rcx,8),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cb 88 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cb 8d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rbp),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 01 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rcx,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rbp,%rax,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c 08 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,1),%xmm1",},
+{{0x0f, 0x38, 0xcb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cb 8c c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x44, 0x0f, 0x38, 0xcb, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 cb bc c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xcc, 0xc1, }, 4, 0, "", "",
+"0f 38 cc c1          \tsha256msg1 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xcc, 0xd7, }, 4, 0, "", "",
+"0f 38 cc d7          \tsha256msg1 %xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xcc, 0xc0, }, 5, 0, "", "",
+"41 0f 38 cc c0       \tsha256msg1 %xmm8,%xmm0",},
+{{0x44, 0x0f, 0x38, 0xcc, 0xc7, }, 5, 0, "", "",
+"44 0f 38 cc c7       \tsha256msg1 %xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xcc, 0xc7, }, 5, 0, "", "",
+"45 0f 38 cc c7       \tsha256msg1 %xmm15,%xmm8",},
+{{0x0f, 0x38, 0xcc, 0x00, }, 4, 0, "", "",
+"0f 38 cc 00          \tsha256msg1 (%rax),%xmm0",},
+{{0x41, 0x0f, 0x38, 0xcc, 0x00, }, 5, 0, "", "",
+"41 0f 38 cc 00       \tsha256msg1 (%r8),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 04 25 78 56 34 12 \tsha256msg1 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x18, }, 4, 0, "", "",
+"0f 38 cc 18          \tsha256msg1 (%rax),%xmm3",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 cc 04 01       \tsha256msg1 (%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 04 05 78 56 34 12 \tsha256msg1 0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 cc 04 08       \tsha256msg1 (%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 cc 04 c8       \tsha256msg1 (%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 cc 40 12       \tsha256msg1 0x12(%rax),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 cc 45 12       \tsha256msg1 0x12(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 01 12    \tsha256msg1 0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 05 12    \tsha256msg1 0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 08 12    \tsha256msg1 0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cc 44 c8 12    \tsha256msg1 0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cc 80 78 56 34 12 \tsha256msg1 0x12345678(%rax),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cc 85 78 56 34 12 \tsha256msg1 0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 01 78 56 34 12 \tsha256msg1 0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 05 78 56 34 12 \tsha256msg1 0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 08 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cc 84 c8 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x38, 0xcc, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 cc bc c8 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x0f, 0x38, 0xcd, 0xc1, }, 4, 0, "", "",
+"0f 38 cd c1          \tsha256msg2 %xmm1,%xmm0",},
+{{0x0f, 0x38, 0xcd, 0xd7, }, 4, 0, "", "",
+"0f 38 cd d7          \tsha256msg2 %xmm7,%xmm2",},
+{{0x41, 0x0f, 0x38, 0xcd, 0xc0, }, 5, 0, "", "",
+"41 0f 38 cd c0       \tsha256msg2 %xmm8,%xmm0",},
+{{0x44, 0x0f, 0x38, 0xcd, 0xc7, }, 5, 0, "", "",
+"44 0f 38 cd c7       \tsha256msg2 %xmm7,%xmm8",},
+{{0x45, 0x0f, 0x38, 0xcd, 0xc7, }, 5, 0, "", "",
+"45 0f 38 cd c7       \tsha256msg2 %xmm15,%xmm8",},
+{{0x0f, 0x38, 0xcd, 0x00, }, 4, 0, "", "",
+"0f 38 cd 00          \tsha256msg2 (%rax),%xmm0",},
+{{0x41, 0x0f, 0x38, 0xcd, 0x00, }, 5, 0, "", "",
+"41 0f 38 cd 00       \tsha256msg2 (%r8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 04 25 78 56 34 12 \tsha256msg2 0x12345678,%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x18, }, 4, 0, "", "",
+"0f 38 cd 18          \tsha256msg2 (%rax),%xmm3",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x01, }, 5, 0, "", "",
+"0f 38 cd 04 01       \tsha256msg2 (%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 04 05 78 56 34 12 \tsha256msg2 0x12345678(,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0x08, }, 5, 0, "", "",
+"0f 38 cd 04 08       \tsha256msg2 (%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x04, 0xc8, }, 5, 0, "", "",
+"0f 38 cd 04 c8       \tsha256msg2 (%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x40, 0x12, }, 5, 0, "", "",
+"0f 38 cd 40 12       \tsha256msg2 0x12(%rax),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x45, 0x12, }, 5, 0, "", "",
+"0f 38 cd 45 12       \tsha256msg2 0x12(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x01, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 01 12    \tsha256msg2 0x12(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x05, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 05 12    \tsha256msg2 0x12(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0x08, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 08 12    \tsha256msg2 0x12(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
+"0f 38 cd 44 c8 12    \tsha256msg2 0x12(%rax,%rcx,8),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cd 80 78 56 34 12 \tsha256msg2 0x12345678(%rax),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f 38 cd 85 78 56 34 12 \tsha256msg2 0x12345678(%rbp),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 01 78 56 34 12 \tsha256msg2 0x12345678(%rcx,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 05 78 56 34 12 \tsha256msg2 0x12345678(%rbp,%rax,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 08 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,1),%xmm0",},
+{{0x0f, 0x38, 0xcd, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"0f 38 cd 84 c8 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,8),%xmm0",},
+{{0x44, 0x0f, 0x38, 0xcd, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"44 0f 38 cd bc c8 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,8),%xmm15",},
+{{0x66, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
+"66 0f ae 38          \tclflushopt (%rax)",},
+{{0x66, 0x41, 0x0f, 0xae, 0x38, }, 5, 0, "", "",
+"66 41 0f ae 38       \tclflushopt (%r8)",},
+{{0x66, 0x0f, 0xae, 0x3c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae 3c 25 78 56 34 12 \tclflushopt 0x12345678",},
+{{0x66, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%rax,%rcx,8)",},
+{{0x66, 0x41, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"66 41 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%r8,%rcx,8)",},
+{{0x0f, 0xae, 0x38, }, 3, 0, "", "",
+"0f ae 38             \tclflush (%rax)",},
+{{0x41, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
+"41 0f ae 38          \tclflush (%r8)",},
+{{0x0f, 0xae, 0xf8, }, 3, 0, "", "",
+"0f ae f8             \tsfence ",},
+{{0x66, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
+"66 0f ae 30          \tclwb   (%rax)",},
+{{0x66, 0x41, 0x0f, 0xae, 0x30, }, 5, 0, "", "",
+"66 41 0f ae 30       \tclwb   (%r8)",},
+{{0x66, 0x0f, 0xae, 0x34, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae 34 25 78 56 34 12 \tclwb   0x12345678",},
+{{0x66, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"66 0f ae b4 c8 78 56 34 12 \tclwb   0x12345678(%rax,%rcx,8)",},
+{{0x66, 0x41, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"66 41 0f ae b4 c8 78 56 34 12 \tclwb   0x12345678(%r8,%rcx,8)",},
+{{0x0f, 0xae, 0x30, }, 3, 0, "", "",
+"0f ae 30             \txsaveopt (%rax)",},
+{{0x41, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
+"41 0f ae 30          \txsaveopt (%r8)",},
+{{0x0f, 0xae, 0xf0, }, 3, 0, "", "",
+"0f ae f0             \tmfence ",},
+{{0x0f, 0xc7, 0x20, }, 3, 0, "", "",
+"0f c7 20             \txsavec (%rax)",},
+{{0x41, 0x0f, 0xc7, 0x20, }, 4, 0, "", "",
+"41 0f c7 20          \txsavec (%r8)",},
+{{0x0f, 0xc7, 0x24, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 24 25 78 56 34 12 \txsavec 0x12345678",},
+{{0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%rax,%rcx,8)",},
+{{0x41, 0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"41 0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%r8,%rcx,8)",},
+{{0x0f, 0xc7, 0x28, }, 3, 0, "", "",
+"0f c7 28             \txsaves (%rax)",},
+{{0x41, 0x0f, 0xc7, 0x28, }, 4, 0, "", "",
+"41 0f c7 28          \txsaves (%r8)",},
+{{0x0f, 0xc7, 0x2c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 2c 25 78 56 34 12 \txsaves 0x12345678",},
+{{0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%rax,%rcx,8)",},
+{{0x41, 0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"41 0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%r8,%rcx,8)",},
+{{0x0f, 0xc7, 0x18, }, 3, 0, "", "",
+"0f c7 18             \txrstors (%rax)",},
+{{0x41, 0x0f, 0xc7, 0x18, }, 4, 0, "", "",
+"41 0f c7 18          \txrstors (%r8)",},
+{{0x0f, 0xc7, 0x1c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 1c 25 78 56 34 12 \txrstors 0x12345678",},
+{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
+"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",},
+{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
+"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",},
+{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
+"66 0f ae f8          \tpcommit ",},
diff --git a/tools/perf/tests/insn-x86-dat-src.c b/tools/perf/tests/insn-x86-dat-src.c
new file mode 100644
index 000000000000..41b1b1c62660
--- /dev/null
+++ b/tools/perf/tests/insn-x86-dat-src.c
@@ -0,0 +1,877 @@
+/*
+ * This file contains instructions for testing by the test titled:
+ *
+ *         "Test x86 instruction decoder - new instructions"
+ *
+ * Note that the 'Expecting' comment lines are consumed by the
+ * gen-insn-x86-dat.awk script and have the format:
+ *
+ *         Expecting: <op> <branch> <rel>
+ *
+ * If this file is changed, remember to run the gen-insn-x86-dat.sh
+ * script and commit the result.
+ *
+ * Refer to insn-x86.c for more details.
+ */
+
+int main(void)
+{
+	/* Following line is a marker for the awk script - do not change */
+	asm volatile("rdtsc"); /* Start here */
+
+#ifdef __x86_64__
+
+	/* bndmk m64, bnd */
+
+	asm volatile("bndmk (%rax), %bnd0");
+	asm volatile("bndmk (%r8), %bnd0");
+	asm volatile("bndmk (0x12345678), %bnd0");
+	asm volatile("bndmk (%rax), %bnd3");
+	asm volatile("bndmk (%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndmk (%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk (%rax,%rcx,8), %bnd0");
+	asm volatile("bndmk 0x12(%rax), %bnd0");
+	asm volatile("bndmk 0x12(%rbp), %bnd0");
+	asm volatile("bndmk 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax), %bnd0");
+	asm volatile("bndmk 0x12345678(%rbp), %bnd0");
+	asm volatile("bndmk 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%rax,%rcx,8), %bnd0");
+
+	/* bndcl r/m64, bnd */
+
+	asm volatile("bndcl (%rax), %bnd0");
+	asm volatile("bndcl (%r8), %bnd0");
+	asm volatile("bndcl (0x12345678), %bnd0");
+	asm volatile("bndcl (%rax), %bnd3");
+	asm volatile("bndcl (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcl (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl 0x12(%rax), %bnd0");
+	asm volatile("bndcl 0x12(%rbp), %bnd0");
+	asm volatile("bndcl 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax), %bnd0");
+	asm volatile("bndcl 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcl 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcl %rax, %bnd0");
+
+	/* bndcu r/m64, bnd */
+
+	asm volatile("bndcu (%rax), %bnd0");
+	asm volatile("bndcu (%r8), %bnd0");
+	asm volatile("bndcu (0x12345678), %bnd0");
+	asm volatile("bndcu (%rax), %bnd3");
+	asm volatile("bndcu (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcu (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu 0x12(%rax), %bnd0");
+	asm volatile("bndcu 0x12(%rbp), %bnd0");
+	asm volatile("bndcu 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax), %bnd0");
+	asm volatile("bndcu 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcu 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcu %rax, %bnd0");
+
+	/* bndcn r/m64, bnd */
+
+	asm volatile("bndcn (%rax), %bnd0");
+	asm volatile("bndcn (%r8), %bnd0");
+	asm volatile("bndcn (0x12345678), %bnd0");
+	asm volatile("bndcn (%rax), %bnd3");
+	asm volatile("bndcn (%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndcn (%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn (%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn 0x12(%rax), %bnd0");
+	asm volatile("bndcn 0x12(%rbp), %bnd0");
+	asm volatile("bndcn 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax), %bnd0");
+	asm volatile("bndcn 0x12345678(%rbp), %bnd0");
+	asm volatile("bndcn 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%rax,%rcx,8), %bnd0");
+	asm volatile("bndcn %rax, %bnd0");
+
+	/* bndmov m128, bnd */
+
+	asm volatile("bndmov (%rax), %bnd0");
+	asm volatile("bndmov (%r8), %bnd0");
+	asm volatile("bndmov (0x12345678), %bnd0");
+	asm volatile("bndmov (%rax), %bnd3");
+	asm volatile("bndmov (%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndmov (%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov (%rax,%rcx,8), %bnd0");
+	asm volatile("bndmov 0x12(%rax), %bnd0");
+	asm volatile("bndmov 0x12(%rbp), %bnd0");
+	asm volatile("bndmov 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov 0x12(%rax,%rcx,8), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax), %bnd0");
+	asm volatile("bndmov 0x12345678(%rbp), %bnd0");
+	asm volatile("bndmov 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax,%rcx,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%rax,%rcx,8), %bnd0");
+
+	/* bndmov bnd, m128 */
+
+	asm volatile("bndmov %bnd0, (%rax)");
+	asm volatile("bndmov %bnd0, (%r8)");
+	asm volatile("bndmov %bnd0, (0x12345678)");
+	asm volatile("bndmov %bnd3, (%rax)");
+	asm volatile("bndmov %bnd0, (%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(,%rax,1)");
+	asm volatile("bndmov %bnd0, (%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, (%rax,%rcx,8)");
+	asm volatile("bndmov %bnd0, 0x12(%rax)");
+	asm volatile("bndmov %bnd0, 0x12(%rbp)");
+	asm volatile("bndmov %bnd0, 0x12(%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rbp,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,8)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rbp)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rcx,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rbp,%rax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,8)");
+
+	/* bndmov bnd2, bnd1 */
+
+	asm volatile("bndmov %bnd0, %bnd1");
+	asm volatile("bndmov %bnd1, %bnd0");
+
+	/* bndldx mib, bnd */
+
+	asm volatile("bndldx (%rax), %bnd0");
+	asm volatile("bndldx (%r8), %bnd0");
+	asm volatile("bndldx (0x12345678), %bnd0");
+	asm volatile("bndldx (%rax), %bnd3");
+	asm volatile("bndldx (%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(,%rax,1), %bnd0");
+	asm volatile("bndldx (%rax,%rcx,1), %bnd0");
+	asm volatile("bndldx 0x12(%rax), %bnd0");
+	asm volatile("bndldx 0x12(%rbp), %bnd0");
+	asm volatile("bndldx 0x12(%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12(%rbp,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12(%rax,%rcx,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rax), %bnd0");
+	asm volatile("bndldx 0x12345678(%rbp), %bnd0");
+	asm volatile("bndldx 0x12345678(%rcx,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rbp,%rax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%rax,%rcx,1), %bnd0");
+
+	/* bndstx bnd, mib */
+
+	asm volatile("bndstx %bnd0, (%rax)");
+	asm volatile("bndstx %bnd0, (%r8)");
+	asm volatile("bndstx %bnd0, (0x12345678)");
+	asm volatile("bndstx %bnd3, (%rax)");
+	asm volatile("bndstx %bnd0, (%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(,%rax,1)");
+	asm volatile("bndstx %bnd0, (%rax,%rcx,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rax)");
+	asm volatile("bndstx %bnd0, 0x12(%rbp)");
+	asm volatile("bndstx %bnd0, 0x12(%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rbp,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%rax,%rcx,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rax)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rbp)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rcx,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rbp,%rax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%rax,%rcx,1)");
+
+	/* bnd prefix on call, ret, jmp and all jcc */
+
+	asm volatile("bnd call label1");  /* Expecting: call unconditional 0 */
+	asm volatile("bnd call *(%eax)"); /* Expecting: call indirect      0 */
+	asm volatile("bnd ret");          /* Expecting: ret  indirect      0 */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0 */
+	asm volatile("bnd jmp *(%ecx)");  /* Expecting: jmp  indirect      0 */
+	asm volatile("bnd jne label1");   /* Expecting: jcc  conditional   0 */
+
+	/* sha1rnds4 imm8, xmm2/m128, xmm1 */
+
+	asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
+	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
+	asm volatile("sha1rnds4 $0x91, %xmm8, %xmm0");
+	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm8");
+	asm volatile("sha1rnds4 $0x91, %xmm15, %xmm8");
+	asm volatile("sha1rnds4 $0x91, (%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%r8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax), %xmm3");
+	asm volatile("sha1rnds4 $0x91, (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rbp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1nexte xmm2/m128, xmm1 */
+
+	asm volatile("sha1nexte %xmm1, %xmm0");
+	asm volatile("sha1nexte %xmm7, %xmm2");
+	asm volatile("sha1nexte %xmm8, %xmm0");
+	asm volatile("sha1nexte %xmm7, %xmm8");
+	asm volatile("sha1nexte %xmm15, %xmm8");
+	asm volatile("sha1nexte (%rax), %xmm0");
+	asm volatile("sha1nexte (%r8), %xmm0");
+	asm volatile("sha1nexte (0x12345678), %xmm0");
+	asm volatile("sha1nexte (%rax), %xmm3");
+	asm volatile("sha1nexte (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1nexte (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax), %xmm0");
+	asm volatile("sha1nexte 0x12(%rbp), %xmm0");
+	asm volatile("sha1nexte 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg1 %xmm1, %xmm0");
+	asm volatile("sha1msg1 %xmm7, %xmm2");
+	asm volatile("sha1msg1 %xmm8, %xmm0");
+	asm volatile("sha1msg1 %xmm7, %xmm8");
+	asm volatile("sha1msg1 %xmm15, %xmm8");
+	asm volatile("sha1msg1 (%rax), %xmm0");
+	asm volatile("sha1msg1 (%r8), %xmm0");
+	asm volatile("sha1msg1 (0x12345678), %xmm0");
+	asm volatile("sha1msg1 (%rax), %xmm3");
+	asm volatile("sha1msg1 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1msg1 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax), %xmm0");
+	asm volatile("sha1msg1 0x12(%rbp), %xmm0");
+	asm volatile("sha1msg1 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha1msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg2 %xmm1, %xmm0");
+	asm volatile("sha1msg2 %xmm7, %xmm2");
+	asm volatile("sha1msg2 %xmm8, %xmm0");
+	asm volatile("sha1msg2 %xmm7, %xmm8");
+	asm volatile("sha1msg2 %xmm15, %xmm8");
+	asm volatile("sha1msg2 (%rax), %xmm0");
+	asm volatile("sha1msg2 (%r8), %xmm0");
+	asm volatile("sha1msg2 (0x12345678), %xmm0");
+	asm volatile("sha1msg2 (%rax), %xmm3");
+	asm volatile("sha1msg2 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha1msg2 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax), %xmm0");
+	asm volatile("sha1msg2 0x12(%rbp), %xmm0");
+	asm volatile("sha1msg2 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rbp), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
+	/* Note sha256rnds2 has an implicit operand 'xmm0' */
+
+	asm volatile("sha256rnds2 %xmm4, %xmm1");
+	asm volatile("sha256rnds2 %xmm7, %xmm2");
+	asm volatile("sha256rnds2 %xmm8, %xmm1");
+	asm volatile("sha256rnds2 %xmm7, %xmm8");
+	asm volatile("sha256rnds2 %xmm15, %xmm8");
+	asm volatile("sha256rnds2 (%rax), %xmm1");
+	asm volatile("sha256rnds2 (%r8), %xmm1");
+	asm volatile("sha256rnds2 (0x12345678), %xmm1");
+	asm volatile("sha256rnds2 (%rax), %xmm3");
+	asm volatile("sha256rnds2 (%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 (%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 (%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rbp), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rbp,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rbp), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rcx,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rbp,%rax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg1 %xmm1, %xmm0");
+	asm volatile("sha256msg1 %xmm7, %xmm2");
+	asm volatile("sha256msg1 %xmm8, %xmm0");
+	asm volatile("sha256msg1 %xmm7, %xmm8");
+	asm volatile("sha256msg1 %xmm15, %xmm8");
+	asm volatile("sha256msg1 (%rax), %xmm0");
+	asm volatile("sha256msg1 (%r8), %xmm0");
+	asm volatile("sha256msg1 (0x12345678), %xmm0");
+	asm volatile("sha256msg1 (%rax), %xmm3");
+	asm volatile("sha256msg1 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha256msg1 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax), %xmm0");
+	asm volatile("sha256msg1 0x12(%rbp), %xmm0");
+	asm volatile("sha256msg1 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rbp), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* sha256msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg2 %xmm1, %xmm0");
+	asm volatile("sha256msg2 %xmm7, %xmm2");
+	asm volatile("sha256msg2 %xmm8, %xmm0");
+	asm volatile("sha256msg2 %xmm7, %xmm8");
+	asm volatile("sha256msg2 %xmm15, %xmm8");
+	asm volatile("sha256msg2 (%rax), %xmm0");
+	asm volatile("sha256msg2 (%r8), %xmm0");
+	asm volatile("sha256msg2 (0x12345678), %xmm0");
+	asm volatile("sha256msg2 (%rax), %xmm3");
+	asm volatile("sha256msg2 (%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(,%rax,1), %xmm0");
+	asm volatile("sha256msg2 (%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 (%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax), %xmm0");
+	asm volatile("sha256msg2 0x12(%rbp), %xmm0");
+	asm volatile("sha256msg2 0x12(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rbp), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rcx,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rbp,%rax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm15");
+
+	/* clflushopt m8 */
+
+	asm volatile("clflushopt (%rax)");
+	asm volatile("clflushopt (%r8)");
+	asm volatile("clflushopt (0x12345678)");
+	asm volatile("clflushopt 0x12345678(%rax,%rcx,8)");
+	asm volatile("clflushopt 0x12345678(%r8,%rcx,8)");
+	/* Also check instructions in the same group encoding as clflushopt */
+	asm volatile("clflush (%rax)");
+	asm volatile("clflush (%r8)");
+	asm volatile("sfence");
+
+	/* clwb m8 */
+
+	asm volatile("clwb (%rax)");
+	asm volatile("clwb (%r8)");
+	asm volatile("clwb (0x12345678)");
+	asm volatile("clwb 0x12345678(%rax,%rcx,8)");
+	asm volatile("clwb 0x12345678(%r8,%rcx,8)");
+	/* Also check instructions in the same group encoding as clwb */
+	asm volatile("xsaveopt (%rax)");
+	asm volatile("xsaveopt (%r8)");
+	asm volatile("mfence");
+
+	/* xsavec mem */
+
+	asm volatile("xsavec (%rax)");
+	asm volatile("xsavec (%r8)");
+	asm volatile("xsavec (0x12345678)");
+	asm volatile("xsavec 0x12345678(%rax,%rcx,8)");
+	asm volatile("xsavec 0x12345678(%r8,%rcx,8)");
+
+	/* xsaves mem */
+
+	asm volatile("xsaves (%rax)");
+	asm volatile("xsaves (%r8)");
+	asm volatile("xsaves (0x12345678)");
+	asm volatile("xsaves 0x12345678(%rax,%rcx,8)");
+	asm volatile("xsaves 0x12345678(%r8,%rcx,8)");
+
+	/* xrstors mem */
+
+	asm volatile("xrstors (%rax)");
+	asm volatile("xrstors (%r8)");
+	asm volatile("xrstors (0x12345678)");
+	asm volatile("xrstors 0x12345678(%rax,%rcx,8)");
+	asm volatile("xrstors 0x12345678(%r8,%rcx,8)");
+
+#else  /* #ifdef __x86_64__ */
+
+	/* bndmk m32, bnd */
+
+	asm volatile("bndmk (%eax), %bnd0");
+	asm volatile("bndmk (0x12345678), %bnd0");
+	asm volatile("bndmk (%eax), %bnd3");
+	asm volatile("bndmk (%ecx,%eax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndmk (%eax,%ecx,1), %bnd0");
+	asm volatile("bndmk (%eax,%ecx,8), %bnd0");
+	asm volatile("bndmk 0x12(%eax), %bnd0");
+	asm volatile("bndmk 0x12(%ebp), %bnd0");
+	asm volatile("bndmk 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndmk 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndmk 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndmk 0x12(%eax,%ecx,8), %bnd0");
+	asm volatile("bndmk 0x12345678(%eax), %bnd0");
+	asm volatile("bndmk 0x12345678(%ebp), %bnd0");
+	asm volatile("bndmk 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%eax,%ecx,1), %bnd0");
+	asm volatile("bndmk 0x12345678(%eax,%ecx,8), %bnd0");
+
+	/* bndcl r/m32, bnd */
+
+	asm volatile("bndcl (%eax), %bnd0");
+	asm volatile("bndcl (0x12345678), %bnd0");
+	asm volatile("bndcl (%eax), %bnd3");
+	asm volatile("bndcl (%ecx,%eax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndcl (%eax,%ecx,1), %bnd0");
+	asm volatile("bndcl (%eax,%ecx,8), %bnd0");
+	asm volatile("bndcl 0x12(%eax), %bnd0");
+	asm volatile("bndcl 0x12(%ebp), %bnd0");
+	asm volatile("bndcl 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcl 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcl 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcl 0x12(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcl 0x12345678(%eax), %bnd0");
+	asm volatile("bndcl 0x12345678(%ebp), %bnd0");
+	asm volatile("bndcl 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcl 0x12345678(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcl %eax, %bnd0");
+
+	/* bndcu r/m32, bnd */
+
+	asm volatile("bndcu (%eax), %bnd0");
+	asm volatile("bndcu (0x12345678), %bnd0");
+	asm volatile("bndcu (%eax), %bnd3");
+	asm volatile("bndcu (%ecx,%eax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndcu (%eax,%ecx,1), %bnd0");
+	asm volatile("bndcu (%eax,%ecx,8), %bnd0");
+	asm volatile("bndcu 0x12(%eax), %bnd0");
+	asm volatile("bndcu 0x12(%ebp), %bnd0");
+	asm volatile("bndcu 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcu 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcu 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcu 0x12(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcu 0x12345678(%eax), %bnd0");
+	asm volatile("bndcu 0x12345678(%ebp), %bnd0");
+	asm volatile("bndcu 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcu 0x12345678(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcu %eax, %bnd0");
+
+	/* bndcn r/m32, bnd */
+
+	asm volatile("bndcn (%eax), %bnd0");
+	asm volatile("bndcn (0x12345678), %bnd0");
+	asm volatile("bndcn (%eax), %bnd3");
+	asm volatile("bndcn (%ecx,%eax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndcn (%eax,%ecx,1), %bnd0");
+	asm volatile("bndcn (%eax,%ecx,8), %bnd0");
+	asm volatile("bndcn 0x12(%eax), %bnd0");
+	asm volatile("bndcn 0x12(%ebp), %bnd0");
+	asm volatile("bndcn 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcn 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcn 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcn 0x12(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcn 0x12345678(%eax), %bnd0");
+	asm volatile("bndcn 0x12345678(%ebp), %bnd0");
+	asm volatile("bndcn 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%eax,%ecx,1), %bnd0");
+	asm volatile("bndcn 0x12345678(%eax,%ecx,8), %bnd0");
+	asm volatile("bndcn %eax, %bnd0");
+
+	/* bndmov m64, bnd */
+
+	asm volatile("bndmov (%eax), %bnd0");
+	asm volatile("bndmov (0x12345678), %bnd0");
+	asm volatile("bndmov (%eax), %bnd3");
+	asm volatile("bndmov (%ecx,%eax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndmov (%eax,%ecx,1), %bnd0");
+	asm volatile("bndmov (%eax,%ecx,8), %bnd0");
+	asm volatile("bndmov 0x12(%eax), %bnd0");
+	asm volatile("bndmov 0x12(%ebp), %bnd0");
+	asm volatile("bndmov 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndmov 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndmov 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndmov 0x12(%eax,%ecx,8), %bnd0");
+	asm volatile("bndmov 0x12345678(%eax), %bnd0");
+	asm volatile("bndmov 0x12345678(%ebp), %bnd0");
+	asm volatile("bndmov 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%eax,%ecx,1), %bnd0");
+	asm volatile("bndmov 0x12345678(%eax,%ecx,8), %bnd0");
+
+	/* bndmov bnd, m64 */
+
+	asm volatile("bndmov %bnd0, (%eax)");
+	asm volatile("bndmov %bnd0, (0x12345678)");
+	asm volatile("bndmov %bnd3, (%eax)");
+	asm volatile("bndmov %bnd0, (%ecx,%eax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(,%eax,1)");
+	asm volatile("bndmov %bnd0, (%eax,%ecx,1)");
+	asm volatile("bndmov %bnd0, (%eax,%ecx,8)");
+	asm volatile("bndmov %bnd0, 0x12(%eax)");
+	asm volatile("bndmov %bnd0, 0x12(%ebp)");
+	asm volatile("bndmov %bnd0, 0x12(%ecx,%eax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%ebp,%eax,1)");
+	asm volatile("bndmov %bnd0, 0x12(%eax,%ecx,1)");
+	asm volatile("bndmov %bnd0, 0x12(%eax,%ecx,8)");
+	asm volatile("bndmov %bnd0, 0x12345678(%eax)");
+	asm volatile("bndmov %bnd0, 0x12345678(%ebp)");
+	asm volatile("bndmov %bnd0, 0x12345678(%ecx,%eax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%ebp,%eax,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%eax,%ecx,1)");
+	asm volatile("bndmov %bnd0, 0x12345678(%eax,%ecx,8)");
+
+	/* bndmov bnd2, bnd1 */
+
+	asm volatile("bndmov %bnd0, %bnd1");
+	asm volatile("bndmov %bnd1, %bnd0");
+
+	/* bndldx mib, bnd */
+
+	asm volatile("bndldx (%eax), %bnd0");
+	asm volatile("bndldx (0x12345678), %bnd0");
+	asm volatile("bndldx (%eax), %bnd3");
+	asm volatile("bndldx (%ecx,%eax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(,%eax,1), %bnd0");
+	asm volatile("bndldx (%eax,%ecx,1), %bnd0");
+	asm volatile("bndldx 0x12(%eax), %bnd0");
+	asm volatile("bndldx 0x12(%ebp), %bnd0");
+	asm volatile("bndldx 0x12(%ecx,%eax,1), %bnd0");
+	asm volatile("bndldx 0x12(%ebp,%eax,1), %bnd0");
+	asm volatile("bndldx 0x12(%eax,%ecx,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%eax), %bnd0");
+	asm volatile("bndldx 0x12345678(%ebp), %bnd0");
+	asm volatile("bndldx 0x12345678(%ecx,%eax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%ebp,%eax,1), %bnd0");
+	asm volatile("bndldx 0x12345678(%eax,%ecx,1), %bnd0");
+
+	/* bndstx bnd, mib */
+
+	asm volatile("bndstx %bnd0, (%eax)");
+	asm volatile("bndstx %bnd0, (0x12345678)");
+	asm volatile("bndstx %bnd3, (%eax)");
+	asm volatile("bndstx %bnd0, (%ecx,%eax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(,%eax,1)");
+	asm volatile("bndstx %bnd0, (%eax,%ecx,1)");
+	asm volatile("bndstx %bnd0, 0x12(%eax)");
+	asm volatile("bndstx %bnd0, 0x12(%ebp)");
+	asm volatile("bndstx %bnd0, 0x12(%ecx,%eax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%ebp,%eax,1)");
+	asm volatile("bndstx %bnd0, 0x12(%eax,%ecx,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%eax)");
+	asm volatile("bndstx %bnd0, 0x12345678(%ebp)");
+	asm volatile("bndstx %bnd0, 0x12345678(%ecx,%eax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%ebp,%eax,1)");
+	asm volatile("bndstx %bnd0, 0x12345678(%eax,%ecx,1)");
+
+	/* bnd prefix on call, ret, jmp and all jcc */
+
+	asm volatile("bnd call label1");  /* Expecting: call unconditional 0xfffffffc */
+	asm volatile("bnd call *(%eax)"); /* Expecting: call indirect      0 */
+	asm volatile("bnd ret");          /* Expecting: ret  indirect      0 */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0xfffffffc */
+	asm volatile("bnd jmp label1");   /* Expecting: jmp  unconditional 0xfffffffc */
+	asm volatile("bnd jmp *(%ecx)");  /* Expecting: jmp  indirect      0 */
+	asm volatile("bnd jne label1");   /* Expecting: jcc  conditional   0xfffffffc */
+
+	/* sha1rnds4 imm8, xmm2/m128, xmm1 */
+
+	asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
+	asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
+	asm volatile("sha1rnds4 $0x91, (%eax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%eax), %xmm3");
+	asm volatile("sha1rnds4 $0x91, (%ecx,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%eax,%ecx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, (%eax,%ecx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%eax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%ebp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%eax), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%ebp), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1rnds4 $0x91, 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* sha1nexte xmm2/m128, xmm1 */
+
+	asm volatile("sha1nexte %xmm1, %xmm0");
+	asm volatile("sha1nexte %xmm7, %xmm2");
+	asm volatile("sha1nexte (%eax), %xmm0");
+	asm volatile("sha1nexte (0x12345678), %xmm0");
+	asm volatile("sha1nexte (%eax), %xmm3");
+	asm volatile("sha1nexte (%ecx,%eax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha1nexte (%eax,%ecx,1), %xmm0");
+	asm volatile("sha1nexte (%eax,%ecx,8), %xmm0");
+	asm volatile("sha1nexte 0x12(%eax), %xmm0");
+	asm volatile("sha1nexte 0x12(%ebp), %xmm0");
+	asm volatile("sha1nexte 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1nexte 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%eax), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%ebp), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1nexte 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* sha1msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg1 %xmm1, %xmm0");
+	asm volatile("sha1msg1 %xmm7, %xmm2");
+	asm volatile("sha1msg1 (%eax), %xmm0");
+	asm volatile("sha1msg1 (0x12345678), %xmm0");
+	asm volatile("sha1msg1 (%eax), %xmm3");
+	asm volatile("sha1msg1 (%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha1msg1 (%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg1 (%eax,%ecx,8), %xmm0");
+	asm volatile("sha1msg1 0x12(%eax), %xmm0");
+	asm volatile("sha1msg1 0x12(%ebp), %xmm0");
+	asm volatile("sha1msg1 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg1 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%eax), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%ebp), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg1 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* sha1msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha1msg2 %xmm1, %xmm0");
+	asm volatile("sha1msg2 %xmm7, %xmm2");
+	asm volatile("sha1msg2 (%eax), %xmm0");
+	asm volatile("sha1msg2 (0x12345678), %xmm0");
+	asm volatile("sha1msg2 (%eax), %xmm3");
+	asm volatile("sha1msg2 (%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha1msg2 (%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg2 (%eax,%ecx,8), %xmm0");
+	asm volatile("sha1msg2 0x12(%eax), %xmm0");
+	asm volatile("sha1msg2 0x12(%ebp), %xmm0");
+	asm volatile("sha1msg2 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg2 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%eax), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%ebp), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha1msg2 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
+	/* Note sha256rnds2 has an implicit operand 'xmm0' */
+
+	asm volatile("sha256rnds2 %xmm4, %xmm1");
+	asm volatile("sha256rnds2 %xmm7, %xmm2");
+	asm volatile("sha256rnds2 (%eax), %xmm1");
+	asm volatile("sha256rnds2 (0x12345678), %xmm1");
+	asm volatile("sha256rnds2 (%eax), %xmm3");
+	asm volatile("sha256rnds2 (%ecx,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 (%eax,%ecx,1), %xmm1");
+	asm volatile("sha256rnds2 (%eax,%ecx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12(%eax), %xmm1");
+	asm volatile("sha256rnds2 0x12(%ebp), %xmm1");
+	asm volatile("sha256rnds2 0x12(%ecx,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%ebp,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%eax,%ecx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12(%eax,%ecx,8), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%eax), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%ebp), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%ecx,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%ebp,%eax,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%eax,%ecx,1), %xmm1");
+	asm volatile("sha256rnds2 0x12345678(%eax,%ecx,8), %xmm1");
+
+	/* sha256msg1 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg1 %xmm1, %xmm0");
+	asm volatile("sha256msg1 %xmm7, %xmm2");
+	asm volatile("sha256msg1 (%eax), %xmm0");
+	asm volatile("sha256msg1 (0x12345678), %xmm0");
+	asm volatile("sha256msg1 (%eax), %xmm3");
+	asm volatile("sha256msg1 (%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha256msg1 (%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg1 (%eax,%ecx,8), %xmm0");
+	asm volatile("sha256msg1 0x12(%eax), %xmm0");
+	asm volatile("sha256msg1 0x12(%ebp), %xmm0");
+	asm volatile("sha256msg1 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg1 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%eax), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%ebp), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg1 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* sha256msg2 xmm2/m128, xmm1 */
+
+	asm volatile("sha256msg2 %xmm1, %xmm0");
+	asm volatile("sha256msg2 %xmm7, %xmm2");
+	asm volatile("sha256msg2 (%eax), %xmm0");
+	asm volatile("sha256msg2 (0x12345678), %xmm0");
+	asm volatile("sha256msg2 (%eax), %xmm3");
+	asm volatile("sha256msg2 (%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(,%eax,1), %xmm0");
+	asm volatile("sha256msg2 (%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg2 (%eax,%ecx,8), %xmm0");
+	asm volatile("sha256msg2 0x12(%eax), %xmm0");
+	asm volatile("sha256msg2 0x12(%ebp), %xmm0");
+	asm volatile("sha256msg2 0x12(%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%ebp,%eax,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg2 0x12(%eax,%ecx,8), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%eax), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%ebp), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%ecx,%eax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%ebp,%eax,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%eax,%ecx,1), %xmm0");
+	asm volatile("sha256msg2 0x12345678(%eax,%ecx,8), %xmm0");
+
+	/* clflushopt m8 */
+
+	asm volatile("clflushopt (%eax)");
+	asm volatile("clflushopt (0x12345678)");
+	asm volatile("clflushopt 0x12345678(%eax,%ecx,8)");
+	/* Also check instructions in the same group encoding as clflushopt */
+	asm volatile("clflush (%eax)");
+	asm volatile("sfence");
+
+	/* clwb m8 */
+
+	asm volatile("clwb (%eax)");
+	asm volatile("clwb (0x12345678)");
+	asm volatile("clwb 0x12345678(%eax,%ecx,8)");
+	/* Also check instructions in the same group encoding as clwb */
+	asm volatile("xsaveopt (%eax)");
+	asm volatile("mfence");
+
+	/* xsavec mem */
+
+	asm volatile("xsavec (%eax)");
+	asm volatile("xsavec (0x12345678)");
+	asm volatile("xsavec 0x12345678(%eax,%ecx,8)");
+
+	/* xsaves mem */
+
+	asm volatile("xsaves (%eax)");
+	asm volatile("xsaves (0x12345678)");
+	asm volatile("xsaves 0x12345678(%eax,%ecx,8)");
+
+	/* xrstors mem */
+
+	asm volatile("xrstors (%eax)");
+	asm volatile("xrstors (0x12345678)");
+	asm volatile("xrstors 0x12345678(%eax,%ecx,8)");
+
+#endif /* #ifndef __x86_64__ */
+
+	/* pcommit */
+
+	asm volatile("pcommit");
+
+	/* Following line is a marker for the awk script - do not change */
+	asm volatile("rdtsc"); /* Stop here */
+
+	return 0;
+}
diff --git a/tools/perf/tests/insn-x86.c b/tools/perf/tests/insn-x86.c
new file mode 100644
index 000000000000..5c49eec81349
--- /dev/null
+++ b/tools/perf/tests/insn-x86.c
@@ -0,0 +1,184 @@
+#include <linux/types.h>
+
+#include "debug.h"
+#include "tests.h"
+
+#include "intel-pt-decoder/insn.h"
+#include "intel-pt-decoder/intel-pt-insn-decoder.h"
+
+struct test_data {
+	u8 data[MAX_INSN_SIZE];
+	int expected_length;
+	int expected_rel;
+	const char *expected_op_str;
+	const char *expected_branch_str;
+	const char *asm_rep;
+};
+
+struct test_data test_data_32[] = {
+#include "insn-x86-dat-32.c"
+	{{0x0f, 0x01, 0xee}, 3, 0, NULL, NULL, "0f 01 ee             \trdpkru"},
+	{{0x0f, 0x01, 0xef}, 3, 0, NULL, NULL, "0f 01 ef             \twrpkru"},
+	{{0}, 0, 0, NULL, NULL, NULL},
+};
+
+struct test_data test_data_64[] = {
+#include "insn-x86-dat-64.c"
+	{{0x0f, 0x01, 0xee}, 3, 0, NULL, NULL, "0f 01 ee             \trdpkru"},
+	{{0x0f, 0x01, 0xef}, 3, 0, NULL, NULL, "0f 01 ef             \twrpkru"},
+	{{0}, 0, 0, NULL, NULL, NULL},
+};
+
+static int get_op(const char *op_str)
+{
+	struct val_data {
+		const char *name;
+		int val;
+	} vals[] = {
+		{"other",   INTEL_PT_OP_OTHER},
+		{"call",    INTEL_PT_OP_CALL},
+		{"ret",     INTEL_PT_OP_RET},
+		{"jcc",     INTEL_PT_OP_JCC},
+		{"jmp",     INTEL_PT_OP_JMP},
+		{"loop",    INTEL_PT_OP_LOOP},
+		{"iret",    INTEL_PT_OP_IRET},
+		{"int",     INTEL_PT_OP_INT},
+		{"syscall", INTEL_PT_OP_SYSCALL},
+		{"sysret",  INTEL_PT_OP_SYSRET},
+		{NULL, 0},
+	};
+	struct val_data *val;
+
+	if (!op_str || !strlen(op_str))
+		return 0;
+
+	for (val = vals; val->name; val++) {
+		if (!strcmp(val->name, op_str))
+			return val->val;
+	}
+
+	pr_debug("Failed to get op\n");
+
+	return -1;
+}
+
+static int get_branch(const char *branch_str)
+{
+	struct val_data {
+		const char *name;
+		int val;
+	} vals[] = {
+		{"no_branch",     INTEL_PT_BR_NO_BRANCH},
+		{"indirect",      INTEL_PT_BR_INDIRECT},
+		{"conditional",   INTEL_PT_BR_CONDITIONAL},
+		{"unconditional", INTEL_PT_BR_UNCONDITIONAL},
+		{NULL, 0},
+	};
+	struct val_data *val;
+
+	if (!branch_str || !strlen(branch_str))
+		return 0;
+
+	for (val = vals; val->name; val++) {
+		if (!strcmp(val->name, branch_str))
+			return val->val;
+	}
+
+	pr_debug("Failed to get branch\n");
+
+	return -1;
+}
+
+static int test_data_item(struct test_data *dat, int x86_64)
+{
+	struct intel_pt_insn intel_pt_insn;
+	struct insn insn;
+	int op, branch;
+
+	insn_init(&insn, dat->data, MAX_INSN_SIZE, x86_64);
+	insn_get_length(&insn);
+
+	if (!insn_complete(&insn)) {
+		pr_debug("Failed to decode: %s\n", dat->asm_rep);
+		return -1;
+	}
+
+	if (insn.length != dat->expected_length) {
+		pr_debug("Failed to decode length (%d vs expected %d): %s\n",
+			 insn.length, dat->expected_length, dat->asm_rep);
+		return -1;
+	}
+
+	op = get_op(dat->expected_op_str);
+	branch = get_branch(dat->expected_branch_str);
+
+	if (intel_pt_get_insn(dat->data, MAX_INSN_SIZE, x86_64, &intel_pt_insn)) {
+		pr_debug("Intel PT failed to decode: %s\n", dat->asm_rep);
+		return -1;
+	}
+
+	if ((int)intel_pt_insn.op != op) {
+		pr_debug("Failed to decode 'op' value (%d vs expected %d): %s\n",
+			 intel_pt_insn.op, op, dat->asm_rep);
+		return -1;
+	}
+
+	if ((int)intel_pt_insn.branch != branch) {
+		pr_debug("Failed to decode 'branch' value (%d vs expected %d): %s\n",
+			 intel_pt_insn.branch, branch, dat->asm_rep);
+		return -1;
+	}
+
+	if (intel_pt_insn.rel != dat->expected_rel) {
+		pr_debug("Failed to decode 'rel' value (%#x vs expected %#x): %s\n",
+			 intel_pt_insn.rel, dat->expected_rel, dat->asm_rep);
+		return -1;
+	}
+
+	pr_debug("Decoded ok: %s\n", dat->asm_rep);
+
+	return 0;
+}
+
+static int test_data_set(struct test_data *dat_set, int x86_64)
+{
+	struct test_data *dat;
+	int ret = 0;
+
+	for (dat = dat_set; dat->expected_length; dat++) {
+		if (test_data_item(dat, x86_64))
+			ret = -1;
+	}
+
+	return ret;
+}
+
+/**
+ * test__insn_x86 - test x86 instruction decoder - new instructions.
+ *
+ * This function implements a test that decodes a selection of instructions and
+ * checks the results.  The Intel PT function that further categorizes
+ * instructions (i.e. intel_pt_get_insn()) is also checked.
+ *
+ * The instructions are originally in insn-x86-dat-src.c which has been
+ * processed by scripts gen-insn-x86-dat.sh and gen-insn-x86-dat.awk to produce
+ * insn-x86-dat-32.c and insn-x86-dat-64.c which are included into this program.
+ * i.e. to add new instructions to the test, edit insn-x86-dat-src.c, run the
+ * gen-insn-x86-dat.sh script, make perf, and then run the test.
+ *
+ * If the test passes %0 is returned, otherwise %-1 is returned.  Use the
+ * verbose (-v) option to see all the instructions and whether or not they
+ * decoded successfuly.
+ */
+int test__insn_x86(void)
+{
+	int ret = 0;
+
+	if (test_data_set(test_data_32, 0))
+		ret = -1;
+
+	if (test_data_set(test_data_64, 1))
+		ret = -1;
+
+	return ret;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index bf113a247987..4e2c5458269a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -63,6 +63,7 @@ int test__fdarray__add(void);
 int test__kmod_path__parse(void);
 int test__thread_map(void);
 int test__llvm(void);
+int test__insn_x86(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/trace/strace/groups/file b/tools/perf/trace/strace/groups/file
index 62378a899d79..722e25d200bf 100644
--- a/tools/perf/trace/strace/groups/file
+++ b/tools/perf/trace/strace/groups/file
@@ -9,6 +9,7 @@ mkdir
 open
 openat
 quotactl
+read
 readlink
 rename
 rmdir
@@ -16,3 +17,4 @@ stat
 statfs
 symlink
 unlink
+write
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 3667e2123e5b..a05d76ab18d8 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -225,17 +225,12 @@ void cpu_map__put(struct cpu_map *map)
 		cpu_map__delete(map);
 }
 
-int cpu_map__get_socket(struct cpu_map *map, int idx)
+int cpu_map__get_socket_id(int cpu)
 {
 	FILE *fp;
 	const char *mnt;
 	char path[PATH_MAX];
-	int cpu, ret;
-
-	if (idx > map->nr)
-		return -1;
-
-	cpu = map->map[idx];
+	int socket_id, ret;
 
 	mnt = sysfs__mountpoint();
 	if (!mnt)
@@ -248,9 +243,22 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)
 	fp = fopen(path, "r");
 	if (!fp)
 		return -1;
-	ret = fscanf(fp, "%d", &cpu);
+	ret = fscanf(fp, "%d", &socket_id);
 	fclose(fp);
-	return ret == 1 ? cpu : -1;
+
+	return ret == 1 ? socket_id : -1;
+}
+
+int cpu_map__get_socket(struct cpu_map *map, int idx)
+{
+	int cpu;
+
+	if (idx > map->nr)
+		return -1;
+
+	cpu = map->map[idx];
+
+	return cpu_map__get_socket_id(cpu);
 }
 
 static int cmp_ids(const void *a, const void *b)
@@ -289,17 +297,12 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
 	return 0;
 }
 
-int cpu_map__get_core(struct cpu_map *map, int idx)
+int cpu_map__get_core_id(int cpu)
 {
 	FILE *fp;
 	const char *mnt;
 	char path[PATH_MAX];
-	int cpu, ret, s;
-
-	if (idx > map->nr)
-		return -1;
-
-	cpu = map->map[idx];
+	int core_id, ret;
 
 	mnt = sysfs__mountpoint();
 	if (!mnt)
@@ -312,11 +315,23 @@ int cpu_map__get_core(struct cpu_map *map, int idx)
 	fp = fopen(path, "r");
 	if (!fp)
 		return -1;
-	ret = fscanf(fp, "%d", &cpu);
+	ret = fscanf(fp, "%d", &core_id);
 	fclose(fp);
-	if (ret != 1)
+
+	return ret == 1 ? core_id : -1;
+}
+
+int cpu_map__get_core(struct cpu_map *map, int idx)
+{
+	int cpu, s;
+
+	if (idx > map->nr)
 		return -1;
 
+	cpu = map->map[idx];
+
+	cpu = cpu_map__get_core_id(cpu);
+
 	s = cpu_map__get_socket(map, idx);
 	if (s == -1)
 		return -1;
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 0af9cecb4c51..8982d538da83 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -18,7 +18,9 @@ struct cpu_map *cpu_map__new(const char *cpu_list);
 struct cpu_map *cpu_map__dummy_new(void);
 struct cpu_map *cpu_map__read(FILE *file);
 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
+int cpu_map__get_socket_id(int cpu);
 int cpu_map__get_socket(struct cpu_map *map, int idx);
+int cpu_map__get_core_id(int cpu);
 int cpu_map__get_core(struct cpu_map *map, int idx);
 int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
 int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 41814547da15..8fd7b7de1acd 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -88,6 +88,9 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned)
 	return err;
 }
 
+#define string_size(str)						\
+	(PERF_ALIGN((strlen(str) + 1), NAME_ALIGN) + sizeof(u32))
+
 static int do_write_string(int fd, const char *str)
 {
 	u32 len, olen;
@@ -441,10 +444,13 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
 	"/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
 
 struct cpu_topo {
+	u32 cpu_nr;
 	u32 core_sib;
 	u32 thread_sib;
 	char **core_siblings;
 	char **thread_siblings;
+	int *core_id;
+	int *phy_pkg_id;
 };
 
 static int build_cpu_topo(struct cpu_topo *tp, int cpu)
@@ -507,6 +513,9 @@ try_threads:
 	}
 	ret = 0;
 done:
+	tp->core_id[cpu] = cpu_map__get_core_id(cpu);
+	tp->phy_pkg_id[cpu] = cpu_map__get_socket_id(cpu);
+
 	if(fp)
 		fclose(fp);
 	free(buf);
@@ -534,7 +543,7 @@ static struct cpu_topo *build_cpu_topology(void)
 	struct cpu_topo *tp;
 	void *addr;
 	u32 nr, i;
-	size_t sz;
+	size_t sz, sz_id;
 	long ncpus;
 	int ret = -1;
 
@@ -545,17 +554,22 @@ static struct cpu_topo *build_cpu_topology(void)
 	nr = (u32)(ncpus & UINT_MAX);
 
 	sz = nr * sizeof(char *);
+	sz_id = nr * sizeof(int);
 
-	addr = calloc(1, sizeof(*tp) + 2 * sz);
+	addr = calloc(1, sizeof(*tp) + 2 * sz + 2 * sz_id);
 	if (!addr)
 		return NULL;
 
 	tp = addr;
-
+	tp->cpu_nr = nr;
 	addr += sizeof(*tp);
 	tp->core_siblings = addr;
 	addr += sz;
 	tp->thread_siblings = addr;
+	addr += sz;
+	tp->core_id = addr;
+	addr += sz_id;
+	tp->phy_pkg_id = addr;
 
 	for (i = 0; i < nr; i++) {
 		ret = build_cpu_topo(tp, i);
@@ -598,6 +612,15 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused,
 		if (ret < 0)
 			break;
 	}
+
+	for (i = 0; i < tp->cpu_nr; i++) {
+		ret = do_write(fd, &tp->core_id[i], sizeof(int));
+		if (ret < 0)
+			return ret;
+		ret = do_write(fd, &tp->phy_pkg_id[i], sizeof(int));
+		if (ret < 0)
+			return ret;
+	}
 done:
 	free_cpu_topo(tp);
 	return ret;
@@ -938,6 +961,7 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
 {
 	int nr, i;
 	char *str;
+	int cpu_nr = ph->env.nr_cpus_online;
 
 	nr = ph->env.nr_sibling_cores;
 	str = ph->env.sibling_cores;
@@ -954,6 +978,13 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
 		fprintf(fp, "# sibling threads : %s\n", str);
 		str += strlen(str) + 1;
 	}
+
+	if (ph->env.cpu != NULL) {
+		for (i = 0; i < cpu_nr; i++)
+			fprintf(fp, "# CPU %d: Core ID %d, Socket ID %d\n", i,
+				ph->env.cpu[i].core_id, ph->env.cpu[i].socket_id);
+	} else
+		fprintf(fp, "# Core ID and Socket ID information is not available\n");
 }
 
 static void free_event_desc(struct perf_evsel *events)
@@ -1582,7 +1613,7 @@ error:
 	return -1;
 }
 
-static int process_cpu_topology(struct perf_file_section *section __maybe_unused,
+static int process_cpu_topology(struct perf_file_section *section,
 				struct perf_header *ph, int fd,
 				void *data __maybe_unused)
 {
@@ -1590,15 +1621,22 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
 	u32 nr, i;
 	char *str;
 	struct strbuf sb;
+	int cpu_nr = ph->env.nr_cpus_online;
+	u64 size = 0;
+
+	ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
+	if (!ph->env.cpu)
+		return -1;
 
 	ret = readn(fd, &nr, sizeof(nr));
 	if (ret != sizeof(nr))
-		return -1;
+		goto free_cpu;
 
 	if (ph->needs_swap)
 		nr = bswap_32(nr);
 
 	ph->env.nr_sibling_cores = nr;
+	size += sizeof(u32);
 	strbuf_init(&sb, 128);
 
 	for (i = 0; i < nr; i++) {
@@ -1608,6 +1646,7 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
 
 		/* include a NULL character at the end */
 		strbuf_add(&sb, str, strlen(str) + 1);
+		size += string_size(str);
 		free(str);
 	}
 	ph->env.sibling_cores = strbuf_detach(&sb, NULL);
@@ -1620,6 +1659,7 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
 		nr = bswap_32(nr);
 
 	ph->env.nr_sibling_threads = nr;
+	size += sizeof(u32);
 
 	for (i = 0; i < nr; i++) {
 		str = do_read_string(fd, ph);
@@ -1628,13 +1668,57 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
 
 		/* include a NULL character at the end */
 		strbuf_add(&sb, str, strlen(str) + 1);
+		size += string_size(str);
 		free(str);
 	}
 	ph->env.sibling_threads = strbuf_detach(&sb, NULL);
+
+	/*
+	 * The header may be from old perf,
+	 * which doesn't include core id and socket id information.
+	 */
+	if (section->size <= size) {
+		zfree(&ph->env.cpu);
+		return 0;
+	}
+
+	for (i = 0; i < (u32)cpu_nr; i++) {
+		ret = readn(fd, &nr, sizeof(nr));
+		if (ret != sizeof(nr))
+			goto free_cpu;
+
+		if (ph->needs_swap)
+			nr = bswap_32(nr);
+
+		if (nr > (u32)cpu_nr) {
+			pr_debug("core_id number is too big."
+				 "You may need to upgrade the perf tool.\n");
+			goto free_cpu;
+		}
+		ph->env.cpu[i].core_id = nr;
+
+		ret = readn(fd, &nr, sizeof(nr));
+		if (ret != sizeof(nr))
+			goto free_cpu;
+
+		if (ph->needs_swap)
+			nr = bswap_32(nr);
+
+		if (nr > (u32)cpu_nr) {
+			pr_debug("socket_id number is too big."
+				 "You may need to upgrade the perf tool.\n");
+			goto free_cpu;
+		}
+
+		ph->env.cpu[i].socket_id = nr;
+	}
+
 	return 0;
 
 error:
 	strbuf_release(&sb);
+free_cpu:
+	zfree(&ph->env.cpu);
 	return -1;
 }
 
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 396e4965f0c9..975d803f46c8 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -66,6 +66,11 @@ struct perf_header;
 int perf_file_header__read(struct perf_file_header *header,
 			   struct perf_header *ph, int fd);
 
+struct cpu_topology_map {
+	int	socket_id;
+	int	core_id;
+};
+
 struct perf_env {
 	char			*hostname;
 	char			*os_release;
@@ -89,6 +94,7 @@ struct perf_env {
 	char			*sibling_threads;
 	char			*numa_nodes;
 	char			*pmu_mappings;
+	struct cpu_topology_map	*cpu;
 };
 
 struct perf_header {
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index ea768625ab5b..eb0e7f8bf515 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -623,7 +623,7 @@ static int intel_bts_process_event(struct perf_session *session,
 	if (err)
 		return err;
 	if (event->header.type == PERF_RECORD_EXIT) {
-		err = intel_bts_process_tid_exit(bts, event->comm.tid);
+		err = intel_bts_process_tid_exit(bts, event->fork.tid);
 		if (err)
 			return err;
 	}
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build
index 2386322ece4f..0611d619a42e 100644
--- a/tools/perf/util/intel-pt-decoder/Build
+++ b/tools/perf/util/intel-pt-decoder/Build
@@ -7,6 +7,17 @@ $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_table
 	$(call rule_mkdir)
 	@$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@
 
-$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c
+$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c
+	@(test -d ../../kernel -a -d ../../tools -a -d ../perf && (( \
+	diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
+	diff -B -I'^#include' util/intel-pt-decoder/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
+	diff -B util/intel-pt-decoder/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
+	diff -B util/intel-pt-decoder/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \
+	diff -B -I'^#include' util/intel-pt-decoder/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
+	diff -B -I'^#include' util/intel-pt-decoder/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
+	diff -B -I'^#include' util/intel-pt-decoder/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
+	|| echo "Warning: Intel PT: x86 instruction decoder differs from kernel" >&2 )) || true
+	$(call rule_mkdir)
+	$(call if_changed_dep,cc_o_c)
 
 CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init
diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
index 816488c0b97e..d388de72eaca 100644
--- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -353,8 +353,12 @@ AVXcode: 1
 17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
 18: Grp16 (1A)
 19:
-1a: BNDCL Ev,Gv | BNDCU Ev,Gv | BNDMOV Gv,Ev | BNDLDX Gv,Ev,Gv
-1b: BNDCN Ev,Gv | BNDMOV Ev,Gv | BNDMK Gv,Ev | BNDSTX Ev,GV,Gv
+# Intel SDM opcode map does not list MPX instructions. For now using Gv for
+# bnd registers and Ev for everything else is OK because the instruction
+# decoder does not use the information except as an indication that there is
+# a ModR/M byte.
+1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
+1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
 1c:
 1d:
 1e:
@@ -732,6 +736,12 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
 be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
 bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
 # 0x0f 0x38 0xc0-0xff
+c8: sha1nexte Vdq,Wdq
+c9: sha1msg1 Vdq,Wdq
+ca: sha1msg2 Vdq,Wdq
+cb: sha256rnds2 Vdq,Wdq
+cc: sha256msg1 Vdq,Wdq
+cd: sha256msg2 Vdq,Wdq
 db: VAESIMC Vdq,Wdq (66),(v1)
 dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
 dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -790,6 +800,7 @@ AVXcode: 3
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
+cc: sha1rnds4 Vdq,Wdq,Ib
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
 f0: RORX Gy,Ey,Ib (F2),(v)
 EndTable
@@ -874,7 +885,7 @@ GrpTable: Grp7
 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
-5:
+5: rdpkru (110),(11B) | wrpkru (111),(11B)
 6: LMSW Ew
 7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
 EndTable
@@ -888,6 +899,9 @@ EndTable
 
 GrpTable: Grp9
 1: CMPXCHG8B/16B Mq/Mdq
+3: xrstors
+4: xsavec
+5: xsaves
 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
 EndTable
@@ -932,8 +946,8 @@ GrpTable: Grp15
 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
 4: XSAVE
 5: XRSTOR | lfence (11B)
-6: XSAVEOPT | mfence (11B)
-7: clflush | sfence (11B)
+6: XSAVEOPT | clwb (66) | mfence (11B)
+7: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B)
 EndTable
 
 GrpTable: Grp16
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index bb41c20e6005..38942e1eac8f 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -1145,11 +1145,13 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
 	return 0;
 }
 
-static u64 intel_pt_switch_ip(struct machine *machine, u64 *ptss_ip)
+static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
 {
+	struct machine *machine = pt->machine;
 	struct map *map;
 	struct symbol *sym, *start;
 	u64 ip, switch_ip = 0;
+	const char *ptss;
 
 	if (ptss_ip)
 		*ptss_ip = 0;
@@ -1177,8 +1179,13 @@ static u64 intel_pt_switch_ip(struct machine *machine, u64 *ptss_ip)
 	if (!switch_ip || !ptss_ip)
 		return 0;
 
+	if (pt->have_sched_switch == 1)
+		ptss = "perf_trace_sched_switch";
+	else
+		ptss = "__perf_event_task_sched_out";
+
 	for (sym = start; sym; sym = dso__next_symbol(sym)) {
-		if (!strcmp(sym->name, "perf_trace_sched_switch")) {
+		if (!strcmp(sym->name, ptss)) {
 			ip = map->unmap_ip(map, sym->start);
 			if (ip >= map->start && ip < map->end) {
 				*ptss_ip = ip;
@@ -1198,11 +1205,11 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
 
 	if (!pt->kernel_start) {
 		pt->kernel_start = machine__kernel_start(pt->machine);
-		if (pt->per_cpu_mmaps && pt->have_sched_switch &&
+		if (pt->per_cpu_mmaps &&
+		    (pt->have_sched_switch == 1 || pt->have_sched_switch == 3) &&
 		    !pt->timeless_decoding && intel_pt_tracing_kernel(pt) &&
 		    !pt->sampling_mode) {
-			pt->switch_ip = intel_pt_switch_ip(pt->machine,
-							   &pt->ptss_ip);
+			pt->switch_ip = intel_pt_switch_ip(pt, &pt->ptss_ip);
 			if (pt->switch_ip) {
 				intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n",
 					     pt->switch_ip, pt->ptss_ip);
@@ -1387,31 +1394,18 @@ static struct intel_pt_queue *intel_pt_cpu_to_ptq(struct intel_pt *pt, int cpu)
 	return NULL;
 }
 
-static int intel_pt_process_switch(struct intel_pt *pt,
-				   struct perf_sample *sample)
+static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid,
+				u64 timestamp)
 {
 	struct intel_pt_queue *ptq;
-	struct perf_evsel *evsel;
-	pid_t tid;
-	int cpu, err;
-
-	evsel = perf_evlist__id2evsel(pt->session->evlist, sample->id);
-	if (evsel != pt->switch_evsel)
-		return 0;
-
-	tid = perf_evsel__intval(evsel, sample, "next_pid");
-	cpu = sample->cpu;
-
-	intel_pt_log("sched_switch: cpu %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
-		     cpu, tid, sample->time, perf_time_to_tsc(sample->time,
-		     &pt->tc));
+	int err;
 
 	if (!pt->sync_switch)
-		goto out;
+		return 1;
 
 	ptq = intel_pt_cpu_to_ptq(pt, cpu);
 	if (!ptq)
-		goto out;
+		return 1;
 
 	switch (ptq->switch_state) {
 	case INTEL_PT_SS_NOT_TRACING:
@@ -1424,7 +1418,7 @@ static int intel_pt_process_switch(struct intel_pt *pt,
 		return 0;
 	case INTEL_PT_SS_EXPECTING_SWITCH_EVENT:
 		if (!ptq->on_heap) {
-			ptq->timestamp = perf_time_to_tsc(sample->time,
+			ptq->timestamp = perf_time_to_tsc(timestamp,
 							  &pt->tc);
 			err = auxtrace_heap__add(&pt->heap, ptq->queue_nr,
 						 ptq->timestamp);
@@ -1441,10 +1435,76 @@ static int intel_pt_process_switch(struct intel_pt *pt,
 	default:
 		break;
 	}
-out:
+
+	return 1;
+}
+
+static int intel_pt_process_switch(struct intel_pt *pt,
+				   struct perf_sample *sample)
+{
+	struct perf_evsel *evsel;
+	pid_t tid;
+	int cpu, ret;
+
+	evsel = perf_evlist__id2evsel(pt->session->evlist, sample->id);
+	if (evsel != pt->switch_evsel)
+		return 0;
+
+	tid = perf_evsel__intval(evsel, sample, "next_pid");
+	cpu = sample->cpu;
+
+	intel_pt_log("sched_switch: cpu %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
+		     cpu, tid, sample->time, perf_time_to_tsc(sample->time,
+		     &pt->tc));
+
+	ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
+	if (ret <= 0)
+		return ret;
+
 	return machine__set_current_tid(pt->machine, cpu, -1, tid);
 }
 
+static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
+				   struct perf_sample *sample)
+{
+	bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
+	pid_t pid, tid;
+	int cpu, ret;
+
+	cpu = sample->cpu;
+
+	if (pt->have_sched_switch == 3) {
+		if (!out)
+			return 0;
+		if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
+			pr_err("Expecting CPU-wide context switch event\n");
+			return -EINVAL;
+		}
+		pid = event->context_switch.next_prev_pid;
+		tid = event->context_switch.next_prev_tid;
+	} else {
+		if (out)
+			return 0;
+		pid = sample->pid;
+		tid = sample->tid;
+	}
+
+	if (tid == -1) {
+		pr_err("context_switch event has no tid\n");
+		return -EINVAL;
+	}
+
+	intel_pt_log("context_switch: cpu %d pid %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
+		     cpu, pid, tid, sample->time, perf_time_to_tsc(sample->time,
+		     &pt->tc));
+
+	ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
+	if (ret <= 0)
+		return ret;
+
+	return machine__set_current_tid(pt->machine, cpu, pid, tid);
+}
+
 static int intel_pt_process_itrace_start(struct intel_pt *pt,
 					 union perf_event *event,
 					 struct perf_sample *sample)
@@ -1494,7 +1554,7 @@ static int intel_pt_process_event(struct perf_session *session,
 	if (pt->timeless_decoding) {
 		if (event->header.type == PERF_RECORD_EXIT) {
 			err = intel_pt_process_timeless_queues(pt,
-							       event->comm.tid,
+							       event->fork.tid,
 							       sample->time);
 		}
 	} else if (timestamp) {
@@ -1515,6 +1575,9 @@ static int intel_pt_process_event(struct perf_session *session,
 		err = intel_pt_process_switch(pt, sample);
 	else if (event->header.type == PERF_RECORD_ITRACE_START)
 		err = intel_pt_process_itrace_start(pt, event, sample);
+	else if (event->header.type == PERF_RECORD_SWITCH ||
+		 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
+		err = intel_pt_context_switch(pt, event, sample);
 
 	intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n",
 		     perf_event__name(event->header.type), event->header.type,
@@ -1777,6 +1840,18 @@ static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist)
 	return NULL;
 }
 
+static bool intel_pt_find_switch(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel) {
+		if (evsel->attr.context_switch)
+			return true;
+	}
+
+	return false;
+}
+
 static const char * const intel_pt_info_fmts[] = {
 	[INTEL_PT_PMU_TYPE]		= "  PMU Type            %"PRId64"\n",
 	[INTEL_PT_TIME_SHIFT]		= "  Time Shift          %"PRIu64"\n",
@@ -1888,6 +1963,10 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
 			pr_err("%s: missing sched_switch event\n", __func__);
 			goto err_delete_thread;
 		}
+	} else if (pt->have_sched_switch == 2 &&
+		   !intel_pt_find_switch(session->evlist)) {
+		pr_err("%s: missing context_switch attribute flag\n", __func__);
+		goto err_delete_thread;
 	}
 
 	if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d826e6f515db..3840176642f8 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -11,7 +11,7 @@
 #include "cache.h"
 #include "header.h"
 #include "debug.h"
-#include <api/fs/debugfs.h>
+#include <api/fs/tracing_path.h>
 #include "parse-events-bison.h"
 #define YY_EXTRA_TYPE int
 #include "parse-events-flex.h"
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 591905a02b92..9cd70819c795 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -255,7 +255,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
 	list_add_tail(&term->list, head);
 
 	ALLOC_LIST(list);
-	ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
+	ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
 	parse_events__free_terms(head);
 	$$ = list;
 }
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index eb5f18b75402..3da9e1c792fa 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2180,9 +2180,9 @@ out:
 }
 
 /* Show an event */
-static int show_perf_probe_event(const char *group, const char *event,
-				 struct perf_probe_event *pev,
-				 const char *module, bool use_stdout)
+int show_perf_probe_event(const char *group, const char *event,
+			  struct perf_probe_event *pev,
+			  const char *module, bool use_stdout)
 {
 	struct strbuf buf = STRBUF_INIT;
 	int ret;
@@ -2399,7 +2399,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 {
 	int i, fd, ret;
 	struct probe_trace_event *tev = NULL;
-	const char *event = NULL, *group = NULL;
 	struct strlist *namelist;
 
 	fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
@@ -2415,7 +2414,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	}
 
 	ret = 0;
-	pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
 		/* Skip if the symbol is out of .text or blacklisted */
@@ -2432,13 +2430,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		if (ret < 0)
 			break;
 
-		/* We use tev's name for showing new events */
-		show_perf_probe_event(tev->group, tev->event, pev,
-				      tev->point.module, false);
-		/* Save the last valid name */
-		event = tev->event;
-		group = tev->group;
-
 		/*
 		 * Probes after the first probe which comes from same
 		 * user input are always allowed to add suffix, because
@@ -2450,13 +2441,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	if (ret == -EINVAL && pev->uprobes)
 		warn_uprobe_event_compat(tev);
 
-	/* Note that it is possible to skip all events because of blacklist */
-	if (ret >= 0 && event) {
-		/* Show how to use the event. */
-		pr_info("\nYou can now use it in all perf tools, such as:\n\n");
-		pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
-	}
-
 	strlist__delete(namelist);
 close_out:
 	close(fd);
@@ -2759,62 +2743,70 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 	return find_probe_trace_events_from_map(pev, tevs);
 }
 
-struct __event_package {
-	struct perf_probe_event		*pev;
-	struct probe_trace_event	*tevs;
-	int				ntevs;
-};
-
-int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
+int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
 {
-	int i, j, ret;
-	struct __event_package *pkgs;
-
-	ret = 0;
-	pkgs = zalloc(sizeof(struct __event_package) * npevs);
-
-	if (pkgs == NULL)
-		return -ENOMEM;
+	int i, ret;
 
 	ret = init_symbol_maps(pevs->uprobes);
-	if (ret < 0) {
-		free(pkgs);
+	if (ret < 0)
 		return ret;
-	}
 
 	/* Loop 1: convert all events */
 	for (i = 0; i < npevs; i++) {
-		pkgs[i].pev = &pevs[i];
 		/* Init kprobe blacklist if needed */
-		if (!pkgs[i].pev->uprobes)
+		if (!pevs[i].uprobes)
 			kprobe_blacklist__init();
 		/* Convert with or without debuginfo */
-		ret  = convert_to_probe_trace_events(pkgs[i].pev,
-						     &pkgs[i].tevs);
+		ret  = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs);
 		if (ret < 0)
-			goto end;
-		pkgs[i].ntevs = ret;
+			return ret;
+		pevs[i].ntevs = ret;
 	}
 	/* This just release blacklist only if allocated */
 	kprobe_blacklist__release();
 
+	return 0;
+}
+
+int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
+{
+	int i, ret = 0;
+
 	/* Loop 2: add all events */
 	for (i = 0; i < npevs; i++) {
-		ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
-					       pkgs[i].ntevs,
+		ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs,
+					       pevs[i].ntevs,
 					       probe_conf.force_add);
 		if (ret < 0)
 			break;
 	}
-end:
+	return ret;
+}
+
+void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs)
+{
+	int i, j;
+
 	/* Loop 3: cleanup and free trace events  */
 	for (i = 0; i < npevs; i++) {
-		for (j = 0; j < pkgs[i].ntevs; j++)
-			clear_probe_trace_event(&pkgs[i].tevs[j]);
-		zfree(&pkgs[i].tevs);
+		for (j = 0; j < pevs[i].ntevs; j++)
+			clear_probe_trace_event(&pevs[i].tevs[j]);
+		zfree(&pevs[i].tevs);
+		pevs[i].ntevs = 0;
 	}
-	free(pkgs);
+
 	exit_symbol_maps();
+}
+
+int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
+{
+	int ret;
+
+	ret = convert_perf_probe_events(pevs, npevs);
+	if (ret == 0)
+		ret = apply_perf_probe_events(pevs, npevs);
+
+	cleanup_perf_probe_events(pevs, npevs);
 
 	return ret;
 }
@@ -2827,8 +2819,6 @@ int del_perf_probe_events(struct strfilter *filter)
 	if (!str)
 		return -EINVAL;
 
-	pr_debug("Delete filter: \'%s\'\n", str);
-
 	/* Get current event names */
 	ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
 	if (ret < 0)
@@ -2843,9 +2833,6 @@ int del_perf_probe_events(struct strfilter *filter)
 		ret = ret2;
 		goto error;
 	}
-	if (ret == -ENOENT && ret2 == -ENOENT)
-		pr_debug("\"%s\" does not hit any event.\n", str);
-		/* Note that this is silently ignored */
 	ret = 0;
 
 error:
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 6e7ec68a4aa8..9bcea36359f2 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -87,6 +87,8 @@ struct perf_probe_event {
 	bool			uprobes;	/* Uprobe event flag */
 	char			*target;	/* Target binary */
 	struct perf_probe_arg	*args;	/* Arguments */
+	struct probe_trace_event *tevs;
+	int			ntevs;
 };
 
 /* Line range */
@@ -138,7 +140,14 @@ extern void line_range__clear(struct line_range *lr);
 extern int line_range__init(struct line_range *lr);
 
 extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
+extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
+extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
+extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 extern int del_perf_probe_events(struct strfilter *filter);
+
+extern int show_perf_probe_event(const char *group, const char *event,
+				 struct perf_probe_event *pev,
+				 const char *module, bool use_stdout);
 extern int show_perf_probe_events(struct strfilter *filter);
 extern int show_line_range(struct line_range *lr, const char *module,
 			   bool user);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index bbb243717ec8..38c0a62039cc 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -267,7 +267,6 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
 		goto error;
 	}
 
-	pr_info("Removed event: %s\n", ent->s);
 	return 0;
 error:
 	pr_warning("Failed to delete event: %s\n",
@@ -275,7 +274,8 @@ error:
 	return ret;
 }
 
-int probe_file__del_events(int fd, struct strfilter *filter)
+int probe_file__get_events(int fd, struct strfilter *filter,
+			   struct strlist *plist)
 {
 	struct strlist *namelist;
 	struct str_node *ent;
@@ -290,12 +290,43 @@ int probe_file__del_events(int fd, struct strfilter *filter)
 		p = strchr(ent->s, ':');
 		if ((p && strfilter__compare(filter, p + 1)) ||
 		    strfilter__compare(filter, ent->s)) {
-			ret = __del_trace_probe_event(fd, ent);
-			if (ret < 0)
-				break;
+			strlist__add(plist, ent->s);
+			ret = 0;
 		}
 	}
 	strlist__delete(namelist);
 
 	return ret;
 }
+
+int probe_file__del_strlist(int fd, struct strlist *namelist)
+{
+	int ret = 0;
+	struct str_node *ent;
+
+	strlist__for_each(ent, namelist) {
+		ret = __del_trace_probe_event(fd, ent);
+		if (ret < 0)
+			break;
+	}
+	return ret;
+}
+
+int probe_file__del_events(int fd, struct strfilter *filter)
+{
+	struct strlist *namelist;
+	int ret;
+
+	namelist = strlist__new(NULL, NULL);
+	if (!namelist)
+		return -ENOMEM;
+
+	ret = probe_file__get_events(fd, filter, namelist);
+	if (ret < 0)
+		return ret;
+
+	ret = probe_file__del_strlist(fd, namelist);
+	strlist__delete(namelist);
+
+	return ret;
+}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index ada94a242a17..18ac9cf51c34 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -14,5 +14,9 @@ struct strlist *probe_file__get_namelist(int fd);
 struct strlist *probe_file__get_rawlist(int fd);
 int probe_file__add_event(int fd, struct probe_trace_event *tev);
 int probe_file__del_events(int fd, struct strfilter *filter);
+int probe_file__get_events(int fd, struct strfilter *filter,
+				  struct strlist *plist);
+int probe_file__del_strlist(int fd, struct strlist *namelist);
+
 
 #endif
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 1bd593bbf7a5..544509c159ce 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -221,6 +221,7 @@ static void define_event_symbols(struct event_format *event,
 		break;
 	case PRINT_BSTRING:
 	case PRINT_DYNAMIC_ARRAY:
+	case PRINT_DYNAMIC_ARRAY_LEN:
 	case PRINT_STRING:
 	case PRINT_BITMASK:
 		break;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index ace2484985cb..aa9e1257c1ee 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -251,6 +251,7 @@ static void define_event_symbols(struct event_format *event,
 		/* gcc warns for these? */
 	case PRINT_BSTRING:
 	case PRINT_DYNAMIC_ARRAY:
+	case PRINT_DYNAMIC_ARRAY_LEN:
 	case PRINT_FUNC:
 	case PRINT_BITMASK:
 		/* we should warn... */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8a4537ee9bc3..23fed17307ff 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -185,6 +185,7 @@ static void perf_session_env__exit(struct perf_env *env)
 	zfree(&env->sibling_threads);
 	zfree(&env->numa_nodes);
 	zfree(&env->pmu_mappings);
+	zfree(&env->cpu);
 }
 
 void perf_session__delete(struct perf_session *session)
@@ -1079,11 +1080,11 @@ static int machines__deliver_event(struct machines *machines,
 
 	switch (event->header.type) {
 	case PERF_RECORD_SAMPLE:
-		dump_sample(evsel, event, sample);
 		if (evsel == NULL) {
 			++evlist->stats.nr_unknown_id;
 			return 0;
 		}
+		dump_sample(evsel, event, sample);
 		if (machine == NULL) {
 			++evlist->stats.nr_unprocessable_samples;
 			return 0;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 7e3871606df3..a97bceeac0e7 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -328,8 +328,8 @@ static char *get_srcfile(struct hist_entry *e)
 	char *sf, *p;
 	struct map *map = e->ms.map;
 
-	sf = get_srcline(map->dso, map__rip_2objdump(map, e->ip),
-			 e->ms.sym, true);
+	sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip),
+			 e->ms.sym, false, true);
 	if (!strcmp(sf, SRCLINE_UNKNOWN))
 		return no_srcfile;
 	p = strchr(sf, ':');
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index fc08248f08ca..b4db3f48e3b0 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -149,8 +149,11 @@ static void addr2line_cleanup(struct a2l_data *a2l)
 	free(a2l);
 }
 
+#define MAX_INLINE_NEST 1024
+
 static int addr2line(const char *dso_name, u64 addr,
-		     char **file, unsigned int *line, struct dso *dso)
+		     char **file, unsigned int *line, struct dso *dso,
+		     bool unwind_inlines)
 {
 	int ret = 0;
 	struct a2l_data *a2l = dso->a2l;
@@ -170,6 +173,15 @@ static int addr2line(const char *dso_name, u64 addr,
 
 	bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
 
+	if (a2l->found && unwind_inlines) {
+		int cnt = 0;
+
+		while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
+					     &a2l->funcname, &a2l->line) &&
+		       cnt++ < MAX_INLINE_NEST)
+			;
+	}
+
 	if (a2l->found && a2l->filename) {
 		*file = strdup(a2l->filename);
 		*line = a2l->line;
@@ -197,7 +209,8 @@ void dso__free_a2l(struct dso *dso)
 
 static int addr2line(const char *dso_name, u64 addr,
 		     char **file, unsigned int *line_nr,
-		     struct dso *dso __maybe_unused)
+		     struct dso *dso __maybe_unused,
+		     bool unwind_inlines __maybe_unused)
 {
 	FILE *fp;
 	char cmd[PATH_MAX];
@@ -254,8 +267,8 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
  */
 #define A2L_FAIL_LIMIT 123
 
-char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
-		  bool show_sym)
+char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
+		  bool show_sym, bool unwind_inlines)
 {
 	char *file = NULL;
 	unsigned line = 0;
@@ -276,7 +289,7 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
 	if (!strncmp(dso_name, "/tmp/perf-", 10))
 		goto out;
 
-	if (!addr2line(dso_name, addr, &file, &line, dso))
+	if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
 		goto out;
 
 	if (asprintf(&srcline, "%s:%u",
@@ -310,3 +323,9 @@ void free_srcline(char *srcline)
 	if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
 		free(srcline);
 }
+
+char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
+		  bool show_sym)
+{
+	return __get_srcline(dso, addr, sym, show_sym, false);
+}
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 22245986e59e..d995743cb673 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -38,7 +38,7 @@
 
 #include "../perf.h"
 #include "trace-event.h"
-#include <api/fs/debugfs.h>
+#include <api/fs/tracing_path.h>
 #include "evsel.h"
 #include "debug.h"
 
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index b90e646c7a91..2f4996ab313d 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <linux/kernel.h>
 #include <traceevent/event-parse.h>
+#include <api/fs/tracing_path.h>
 #include "trace-event.h"
 #include "machine.h"
 #include "util.h"
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 7acafb3c5592..49a5c6ad55f5 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -34,9 +34,6 @@ bool test_attr__enabled;
 bool perf_host  = true;
 bool perf_guest = false;
 
-char tracing_path[PATH_MAX + 1]        = "/sys/kernel/debug/tracing";
-char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
-
 void event_attr_init(struct perf_event_attr *attr)
 {
 	if (!perf_host)
@@ -390,73 +387,6 @@ void set_term_quiet_input(struct termios *old)
 	tcsetattr(0, TCSANOW, &tc);
 }
 
-static void set_tracing_events_path(const char *tracing, const char *mountpoint)
-{
-	snprintf(tracing_path, sizeof(tracing_path), "%s/%s",
-		 mountpoint, tracing);
-	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
-		 mountpoint, tracing, "events");
-}
-
-static const char *__perf_tracefs_mount(const char *mountpoint)
-{
-	const char *mnt;
-
-	mnt = tracefs_mount(mountpoint);
-	if (!mnt)
-		return NULL;
-
-	set_tracing_events_path("", mnt);
-
-	return mnt;
-}
-
-static const char *__perf_debugfs_mount(const char *mountpoint)
-{
-	const char *mnt;
-
-	mnt = debugfs_mount(mountpoint);
-	if (!mnt)
-		return NULL;
-
-	set_tracing_events_path("tracing/", mnt);
-
-	return mnt;
-}
-
-const char *perf_debugfs_mount(const char *mountpoint)
-{
-	const char *mnt;
-
-	mnt = __perf_tracefs_mount(mountpoint);
-	if (mnt)
-		return mnt;
-
-	mnt = __perf_debugfs_mount(mountpoint);
-
-	return mnt;
-}
-
-void perf_debugfs_set_path(const char *mntpt)
-{
-	set_tracing_events_path("tracing/", mntpt);
-}
-
-char *get_tracing_file(const char *name)
-{
-	char *file;
-
-	if (asprintf(&file, "%s/%s", tracing_path, name) < 0)
-		return NULL;
-
-	return file;
-}
-
-void put_tracing_file(char *file)
-{
-	free(file);
-}
-
 int parse_nsec_time(const char *str, u64 *ptime)
 {
 	u64 time_sec, time_nsec;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 291be1d84bc3..495b99ccb588 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -83,12 +83,6 @@
 extern const char *graph_line;
 extern const char *graph_dotted_line;
 extern char buildid_dir[];
-extern char tracing_path[];
-extern char tracing_events_path[];
-extern void perf_debugfs_set_path(const char *mountpoint);
-const char *perf_debugfs_mount(const char *mountpoint);
-char *get_tracing_file(const char *name);
-void put_tracing_file(char *file);
 
 /* On most systems <limits.h> would have given us this, but
  * not on some systems (e.g. GNU/Hurd).
@@ -321,6 +315,8 @@ struct symbol;
 extern bool srcline_full_filename;
 char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
 		  bool show_sym);
+char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
+		  bool show_sym, bool unwind_inlines);
 void free_srcline(char *srcline);
 
 int filename__read_str(const char *filename, char **buf, size_t *sizep);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 89b05e2222c9..ac40ec9c6968 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -6,6 +6,7 @@ TARGETS += firmware
 TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
+TARGETS += kdbus
 TARGETS += membarrier
 TARGETS += memfd
 TARGETS += memory-hotplug
diff --git a/tools/testing/selftests/kdbus/.gitignore b/tools/testing/selftests/kdbus/.gitignore
new file mode 100644
index 000000000000..d3ef42f6ada6
--- /dev/null
+++ b/tools/testing/selftests/kdbus/.gitignore
@@ -0,0 +1 @@
+kdbus-test
diff --git a/tools/testing/selftests/kdbus/Makefile b/tools/testing/selftests/kdbus/Makefile
new file mode 100644
index 000000000000..8f36cb5667cc
--- /dev/null
+++ b/tools/testing/selftests/kdbus/Makefile
@@ -0,0 +1,49 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kdbus/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99
+CFLAGS += -DKBUILD_MODNAME=\"kdbus\" -D_GNU_SOURCE
+LDLIBS = -pthread -lcap -lm
+
+OBJS= \
+	kdbus-enum.o		\
+	kdbus-util.o		\
+	kdbus-test.o		\
+	kdbus-test.o		\
+	test-activator.o	\
+	test-benchmark.o	\
+	test-bus.o		\
+	test-chat.o		\
+	test-connection.o	\
+	test-daemon.o		\
+	test-endpoint.o		\
+	test-fd.o		\
+	test-free.o		\
+	test-match.o		\
+	test-message.o		\
+	test-metadata-ns.o	\
+	test-monitor.o		\
+	test-names.o		\
+	test-policy.o		\
+	test-policy-ns.o	\
+	test-policy-priv.o	\
+	test-sync.o		\
+	test-timeout.o
+
+all: kdbus-test
+
+include ../lib.mk
+
+%.o: %.c kdbus-enum.h kdbus-test.h kdbus-util.h
+	$(CC) $(CFLAGS) -c $< -o $@
+
+kdbus-test: $(OBJS)
+	$(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+TEST_PROGS := kdbus-test
+
+run_tests:
+	./kdbus-test --tap
+
+clean:
+	rm -f *.o kdbus-test
diff --git a/tools/testing/selftests/kdbus/kdbus-enum.c b/tools/testing/selftests/kdbus/kdbus-enum.c
new file mode 100644
index 000000000000..4f1e5797895f
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-enum.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+struct kdbus_enum_table {
+	long long id;
+	const char *name;
+};
+
+#define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
+#define ENUM(_id) { .id = _id, .name = STRINGIFY(_id) }
+#define LOOKUP(what)							\
+	const char *enum_##what(long long id)				\
+	{								\
+		for (size_t i = 0; i < ELEMENTSOF(kdbus_table_##what); i++) \
+			if (id == kdbus_table_##what[i].id)		\
+				return kdbus_table_##what[i].name;	\
+		return "UNKNOWN";					\
+	}
+
+TABLE(CMD) = {
+	ENUM(KDBUS_CMD_BUS_MAKE),
+	ENUM(KDBUS_CMD_ENDPOINT_MAKE),
+	ENUM(KDBUS_CMD_HELLO),
+	ENUM(KDBUS_CMD_SEND),
+	ENUM(KDBUS_CMD_RECV),
+	ENUM(KDBUS_CMD_LIST),
+	ENUM(KDBUS_CMD_NAME_RELEASE),
+	ENUM(KDBUS_CMD_CONN_INFO),
+	ENUM(KDBUS_CMD_MATCH_ADD),
+	ENUM(KDBUS_CMD_MATCH_REMOVE),
+};
+LOOKUP(CMD);
+
+TABLE(MSG) = {
+	ENUM(_KDBUS_ITEM_NULL),
+	ENUM(KDBUS_ITEM_PAYLOAD_VEC),
+	ENUM(KDBUS_ITEM_PAYLOAD_OFF),
+	ENUM(KDBUS_ITEM_PAYLOAD_MEMFD),
+	ENUM(KDBUS_ITEM_FDS),
+	ENUM(KDBUS_ITEM_BLOOM_PARAMETER),
+	ENUM(KDBUS_ITEM_BLOOM_FILTER),
+	ENUM(KDBUS_ITEM_DST_NAME),
+	ENUM(KDBUS_ITEM_MAKE_NAME),
+	ENUM(KDBUS_ITEM_ATTACH_FLAGS_SEND),
+	ENUM(KDBUS_ITEM_ATTACH_FLAGS_RECV),
+	ENUM(KDBUS_ITEM_ID),
+	ENUM(KDBUS_ITEM_NAME),
+	ENUM(KDBUS_ITEM_TIMESTAMP),
+	ENUM(KDBUS_ITEM_CREDS),
+	ENUM(KDBUS_ITEM_PIDS),
+	ENUM(KDBUS_ITEM_AUXGROUPS),
+	ENUM(KDBUS_ITEM_OWNED_NAME),
+	ENUM(KDBUS_ITEM_TID_COMM),
+	ENUM(KDBUS_ITEM_PID_COMM),
+	ENUM(KDBUS_ITEM_EXE),
+	ENUM(KDBUS_ITEM_CMDLINE),
+	ENUM(KDBUS_ITEM_CGROUP),
+	ENUM(KDBUS_ITEM_CAPS),
+	ENUM(KDBUS_ITEM_SECLABEL),
+	ENUM(KDBUS_ITEM_AUDIT),
+	ENUM(KDBUS_ITEM_CONN_DESCRIPTION),
+	ENUM(KDBUS_ITEM_NAME_ADD),
+	ENUM(KDBUS_ITEM_NAME_REMOVE),
+	ENUM(KDBUS_ITEM_NAME_CHANGE),
+	ENUM(KDBUS_ITEM_ID_ADD),
+	ENUM(KDBUS_ITEM_ID_REMOVE),
+	ENUM(KDBUS_ITEM_REPLY_TIMEOUT),
+	ENUM(KDBUS_ITEM_REPLY_DEAD),
+};
+LOOKUP(MSG);
+
+TABLE(PAYLOAD) = {
+	ENUM(KDBUS_PAYLOAD_KERNEL),
+	ENUM(KDBUS_PAYLOAD_DBUS),
+};
+LOOKUP(PAYLOAD);
diff --git a/tools/testing/selftests/kdbus/kdbus-enum.h b/tools/testing/selftests/kdbus/kdbus-enum.h
new file mode 100644
index 000000000000..ed28cca26906
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-enum.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#pragma once
+
+const char *enum_CMD(long long id);
+const char *enum_MSG(long long id);
+const char *enum_MATCH(long long id);
+const char *enum_PAYLOAD(long long id);
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c b/tools/testing/selftests/kdbus/kdbus-test.c
new file mode 100644
index 000000000000..db57381570fa
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -0,0 +1,905 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <assert.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <sys/mount.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+#include <sys/eventfd.h>
+#include <linux/sched.h>
+
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+enum {
+	TEST_CREATE_BUS		= 1 << 0,
+	TEST_CREATE_CONN	= 1 << 1,
+};
+
+struct kdbus_test {
+	const char *name;
+	const char *desc;
+	int (*func)(struct kdbus_test_env *env);
+	unsigned int flags;
+};
+
+struct kdbus_test_args {
+	bool mntns;
+	bool pidns;
+	bool userns;
+	char *uid_map;
+	char *gid_map;
+	int loop;
+	int wait;
+	int fork;
+	int tap_output;
+	char *module;
+	char *root;
+	char *test;
+	char *busname;
+};
+
+static const struct kdbus_test tests[] = {
+	{
+		.name	= "bus-make",
+		.desc	= "bus make functions",
+		.func	= kdbus_test_bus_make,
+		.flags	= 0,
+	},
+	{
+		.name	= "hello",
+		.desc	= "the HELLO command",
+		.func	= kdbus_test_hello,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "byebye",
+		.desc	= "the BYEBYE command",
+		.func	= kdbus_test_byebye,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "chat",
+		.desc	= "a chat pattern",
+		.func	= kdbus_test_chat,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "daemon",
+		.desc	= "a simple daemon",
+		.func	= kdbus_test_daemon,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "fd-passing",
+		.desc	= "file descriptor passing",
+		.func	= kdbus_test_fd_passing,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "endpoint",
+		.desc	= "custom endpoint",
+		.func	= kdbus_test_custom_endpoint,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "monitor",
+		.desc	= "monitor functionality",
+		.func	= kdbus_test_monitor,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "name-basics",
+		.desc	= "basic name registry functions",
+		.func	= kdbus_test_name_basic,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "name-conflict",
+		.desc	= "name registry conflict details",
+		.func	= kdbus_test_name_conflict,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "name-queue",
+		.desc	= "queuing of names",
+		.func	= kdbus_test_name_queue,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "name-takeover",
+		.desc	= "takeover of names",
+		.func	= kdbus_test_name_takeover,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "message-basic",
+		.desc	= "basic message handling",
+		.func	= kdbus_test_message_basic,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "message-prio",
+		.desc	= "handling of messages with priority",
+		.func	= kdbus_test_message_prio,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "message-quota",
+		.desc	= "message quotas are enforced",
+		.func	= kdbus_test_message_quota,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "memory-access",
+		.desc	= "memory access",
+		.func	= kdbus_test_memory_access,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "timeout",
+		.desc	= "timeout",
+		.func	= kdbus_test_timeout,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "sync-byebye",
+		.desc	= "synchronous replies vs. BYEBYE",
+		.func	= kdbus_test_sync_byebye,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "sync-reply",
+		.desc	= "synchronous replies",
+		.func	= kdbus_test_sync_reply,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "message-free",
+		.desc	= "freeing of memory",
+		.func	= kdbus_test_free,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "connection-info",
+		.desc	= "retrieving connection information",
+		.func	= kdbus_test_conn_info,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "connection-update",
+		.desc	= "updating connection information",
+		.func	= kdbus_test_conn_update,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "writable-pool",
+		.desc	= "verifying pools are never writable",
+		.func	= kdbus_test_writable_pool,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "policy",
+		.desc	= "policy",
+		.func	= kdbus_test_policy,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "policy-priv",
+		.desc	= "unprivileged bus access",
+		.func	= kdbus_test_policy_priv,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "policy-ns",
+		.desc	= "policy in user namespaces",
+		.func	= kdbus_test_policy_ns,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "metadata-ns",
+		.desc	= "metadata in different namespaces",
+		.func	= kdbus_test_metadata_ns,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-id-add",
+		.desc	= "adding of matches by id",
+		.func	= kdbus_test_match_id_add,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-id-remove",
+		.desc	= "removing of matches by id",
+		.func	= kdbus_test_match_id_remove,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-replace",
+		.desc	= "replace of matches with the same cookie",
+		.func	= kdbus_test_match_replace,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-name-add",
+		.desc	= "adding of matches by name",
+		.func	= kdbus_test_match_name_add,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-name-remove",
+		.desc	= "removing of matches by name",
+		.func	= kdbus_test_match_name_remove,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-name-change",
+		.desc	= "matching for name changes",
+		.func	= kdbus_test_match_name_change,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "match-bloom",
+		.desc	= "matching with bloom filters",
+		.func	= kdbus_test_match_bloom,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "activator",
+		.desc	= "activator connections",
+		.func	= kdbus_test_activator,
+		.flags	= TEST_CREATE_BUS | TEST_CREATE_CONN,
+	},
+	{
+		.name	= "benchmark",
+		.desc	= "benchmark",
+		.func	= kdbus_test_benchmark,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "benchmark-nomemfds",
+		.desc	= "benchmark without using memfds",
+		.func	= kdbus_test_benchmark_nomemfds,
+		.flags	= TEST_CREATE_BUS,
+	},
+	{
+		.name	= "benchmark-uds",
+		.desc	= "benchmark comparison to UDS",
+		.func	= kdbus_test_benchmark_uds,
+		.flags	= TEST_CREATE_BUS,
+	},
+};
+
+#define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0])))
+
+static int test_prepare_env(const struct kdbus_test *t,
+			    const struct kdbus_test_args *args,
+			    struct kdbus_test_env *env)
+{
+	if (t->flags & TEST_CREATE_BUS) {
+		char *s;
+		char *n = NULL;
+		int ret;
+
+		asprintf(&s, "%s/control", args->root);
+
+		env->control_fd = open(s, O_RDWR);
+		free(s);
+		ASSERT_RETURN(env->control_fd >= 0);
+
+		if (!args->busname) {
+			n = unique_name("test-bus");
+			ASSERT_RETURN(n);
+		}
+
+		ret = kdbus_create_bus(env->control_fd,
+				       args->busname ?: n,
+				       _KDBUS_ATTACH_ALL, &s);
+		free(n);
+		ASSERT_RETURN(ret == 0);
+
+		asprintf(&env->buspath, "%s/%s/bus", args->root, s);
+		free(s);
+	}
+
+	if (t->flags & TEST_CREATE_CONN) {
+		env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_RETURN(env->conn);
+	}
+
+	env->root = args->root;
+	env->module = args->module;
+
+	return 0;
+}
+
+void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env)
+{
+	if (env->conn) {
+		kdbus_conn_free(env->conn);
+		env->conn = NULL;
+	}
+
+	if (env->control_fd >= 0) {
+		close(env->control_fd);
+		env->control_fd = -1;
+	}
+
+	if (env->buspath) {
+		free(env->buspath);
+		env->buspath = NULL;
+	}
+}
+
+static int test_run(const struct kdbus_test *t,
+		    const struct kdbus_test_args *kdbus_args,
+		    int wait)
+{
+	int ret;
+	struct kdbus_test_env env = {};
+
+	ret = test_prepare_env(t, kdbus_args, &env);
+	if (ret != TEST_OK)
+		return ret;
+
+	if (wait > 0) {
+		printf("Sleeping %d seconds before running test ...\n", wait);
+		sleep(wait);
+	}
+
+	ret = t->func(&env);
+	test_unprepare_env(t, &env);
+	return ret;
+}
+
+static int test_run_forked(const struct kdbus_test *t,
+			   const struct kdbus_test_args *kdbus_args,
+			   int wait)
+{
+	int ret;
+	pid_t pid;
+
+	pid = fork();
+	if (pid < 0) {
+		return TEST_ERR;
+	} else if (pid == 0) {
+		ret = test_run(t, kdbus_args, wait);
+		_exit(ret);
+	}
+
+	pid = waitpid(pid, &ret, 0);
+	if (pid <= 0)
+		return TEST_ERR;
+	else if (!WIFEXITED(ret))
+		return TEST_ERR;
+	else
+		return WEXITSTATUS(ret);
+}
+
+static void print_test_result(int ret)
+{
+	switch (ret) {
+	case TEST_OK:
+		printf("OK");
+		break;
+	case TEST_SKIP:
+		printf("SKIPPED");
+		break;
+	case TEST_ERR:
+		printf("ERROR");
+		break;
+	}
+}
+
+static int start_all_tests(struct kdbus_test_args *kdbus_args)
+{
+	int ret;
+	unsigned int fail_cnt = 0;
+	unsigned int skip_cnt = 0;
+	unsigned int ok_cnt = 0;
+	unsigned int i;
+
+	if (kdbus_args->tap_output) {
+		printf("1..%d\n", N_TESTS);
+		fflush(stdout);
+	}
+
+	kdbus_util_verbose = false;
+
+	for (i = 0; i < N_TESTS; i++) {
+		const struct kdbus_test *t = tests + i;
+
+		if (!kdbus_args->tap_output) {
+			unsigned int n;
+
+			printf("Testing %s (%s) ", t->desc, t->name);
+			for (n = 0; n < 60 - strlen(t->desc) - strlen(t->name); n++)
+				printf(".");
+			printf(" ");
+		}
+
+		ret = test_run_forked(t, kdbus_args, 0);
+		switch (ret) {
+		case TEST_OK:
+			ok_cnt++;
+			break;
+		case TEST_SKIP:
+			skip_cnt++;
+			break;
+		case TEST_ERR:
+			fail_cnt++;
+			break;
+		}
+
+		if (kdbus_args->tap_output) {
+			printf("%sok %d - %s%s (%s)\n",
+			       (ret == TEST_ERR) ? "not " : "", i + 1,
+			       (ret == TEST_SKIP) ? "# SKIP " : "",
+			       t->desc, t->name);
+			fflush(stdout);
+		} else {
+			print_test_result(ret);
+			printf("\n");
+		}
+	}
+
+	if (kdbus_args->tap_output)
+		printf("Failed %d/%d tests, %.2f%% okay\n", fail_cnt, N_TESTS,
+		       100.0 - (fail_cnt * 100.0) / ((float) N_TESTS));
+	else
+		printf("\nSUMMARY: %u tests passed, %u skipped, %u failed\n",
+		       ok_cnt, skip_cnt, fail_cnt);
+
+	return fail_cnt > 0 ? TEST_ERR : TEST_OK;
+}
+
+static int start_one_test(struct kdbus_test_args *kdbus_args)
+{
+	int i, ret;
+	bool test_found = false;
+
+	for (i = 0; i < N_TESTS; i++) {
+		const struct kdbus_test *t = tests + i;
+
+		if (strcmp(t->name, kdbus_args->test))
+			continue;
+
+		do {
+			test_found = true;
+			if (kdbus_args->fork)
+				ret = test_run_forked(t, kdbus_args,
+						      kdbus_args->wait);
+			else
+				ret = test_run(t, kdbus_args,
+					       kdbus_args->wait);
+
+			printf("Testing %s: ", t->desc);
+			print_test_result(ret);
+			printf("\n");
+
+			if (ret != TEST_OK)
+				break;
+		} while (kdbus_args->loop);
+
+		return ret;
+	}
+
+	if (!test_found) {
+		printf("Unknown test-id '%s'\n", kdbus_args->test);
+		return TEST_ERR;
+	}
+
+	return TEST_OK;
+}
+
+static void usage(const char *argv0)
+{
+	unsigned int i, j;
+
+	printf("Usage: %s [options]\n"
+	       "Options:\n"
+	       "\t-a, --tap		Output test results in TAP format\n"
+	       "\t-m, --module <module>	Kdbus module name\n"
+	       "\t-x, --loop		Run in a loop\n"
+	       "\t-f, --fork		Fork before running a test\n"
+	       "\t-h, --help		Print this help\n"
+	       "\t-r, --root <root>	Toplevel of the kdbus hierarchy\n"
+	       "\t-t, --test <test-id>	Run one specific test only, in verbose mode\n"
+	       "\t-b, --bus <busname>	Instead of generating a random bus name, take <busname>.\n"
+	       "\t-w, --wait <secs>	Wait <secs> before actually starting test\n"
+	       "\t    --mntns		New mount namespace\n"
+	       "\t    --pidns		New PID namespace\n"
+	       "\t    --userns		New user namespace\n"
+	       "\t    --uidmap uid_map	UID map for user namespace\n"
+	       "\t    --gidmap gid_map	GID map for user namespace\n"
+	       "\n", argv0);
+
+	printf("By default, all test are run once, and a summary is printed.\n"
+	       "Available tests for --test:\n\n");
+
+	for (i = 0; i < N_TESTS; i++) {
+		const struct kdbus_test *t = tests + i;
+
+		printf("\t%s", t->name);
+
+		for (j = 0; j < 24 - strlen(t->name); j++)
+			printf(" ");
+
+		printf("Test %s\n", t->desc);
+	}
+
+	printf("\n");
+	printf("Note that some tests may, if run specifically by --test, "
+	       "behave differently, and not terminate by themselves.\n");
+
+	exit(EXIT_FAILURE);
+}
+
+void print_kdbus_test_args(struct kdbus_test_args *args)
+{
+	if (args->userns || args->pidns || args->mntns)
+		printf("# Starting tests in new %s%s%s namespaces%s\n",
+			args->mntns ? "MOUNT " : "",
+			args->pidns ? "PID " : "",
+			args->userns ? "USER " : "",
+			args->mntns ? ", kdbusfs will be remounted" : "");
+	else
+		printf("# Starting tests in the same namespaces\n");
+}
+
+void print_metadata_support(void)
+{
+	bool no_meta_audit, no_meta_cgroups, no_meta_seclabel;
+
+	/*
+	 * KDBUS_ATTACH_CGROUP, KDBUS_ATTACH_AUDIT and
+	 * KDBUS_ATTACH_SECLABEL
+	 */
+	no_meta_audit = !config_auditsyscall_is_enabled();
+	no_meta_cgroups = !config_cgroups_is_enabled();
+	no_meta_seclabel = !config_security_is_enabled();
+
+	if (no_meta_audit | no_meta_cgroups | no_meta_seclabel)
+		printf("# Starting tests without %s%s%s metadata support\n",
+		       no_meta_audit ? "AUDIT " : "",
+		       no_meta_cgroups ? "CGROUP " : "",
+		       no_meta_seclabel ? "SECLABEL " : "");
+	else
+		printf("# Starting tests with full metadata support\n");
+}
+
+int run_tests(struct kdbus_test_args *kdbus_args)
+{
+	int ret;
+	static char control[4096];
+
+	snprintf(control, sizeof(control), "%s/control", kdbus_args->root);
+
+	if (access(control, W_OK) < 0) {
+		printf("Unable to locate control node at '%s'.\n",
+			control);
+		return TEST_ERR;
+	}
+
+	if (kdbus_args->test) {
+		ret = start_one_test(kdbus_args);
+	} else {
+		do {
+			ret = start_all_tests(kdbus_args);
+			if (ret != TEST_OK)
+				break;
+		} while (kdbus_args->loop);
+	}
+
+	return ret;
+}
+
+static void nop_handler(int sig) {}
+
+static int test_prepare_mounts(struct kdbus_test_args *kdbus_args)
+{
+	int ret;
+	char kdbusfs[64] = {'\0'};
+
+	snprintf(kdbusfs, sizeof(kdbusfs), "%sfs", kdbus_args->module);
+
+	/* make current mount slave */
+	ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
+	if (ret < 0) {
+		ret = -errno;
+		printf("error mount() root: %d (%m)\n", ret);
+		return ret;
+	}
+
+	/* Remount procfs since we need it in our tests */
+	if (kdbus_args->pidns) {
+		ret = mount("proc", "/proc", "proc",
+			    MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+		if (ret < 0) {
+			ret = -errno;
+			printf("error mount() /proc : %d (%m)\n", ret);
+			return ret;
+		}
+	}
+
+	/* Remount kdbusfs */
+	ret = mount(kdbusfs, kdbus_args->root, kdbusfs,
+		    MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+	if (ret < 0) {
+		ret = -errno;
+		printf("error mount() %s :%d (%m)\n", kdbusfs, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args)
+{
+	int ret;
+	int efd = -1;
+	int status;
+	pid_t pid, rpid;
+	struct sigaction oldsa;
+	struct sigaction sa = {
+		.sa_handler = nop_handler,
+		.sa_flags = SA_NOCLDSTOP,
+	};
+
+	efd = eventfd(0, EFD_CLOEXEC);
+	if (efd < 0) {
+		ret = -errno;
+		printf("eventfd() failed: %d (%m)\n", ret);
+		return TEST_ERR;
+	}
+
+	ret = sigaction(SIGCHLD, &sa, &oldsa);
+	if (ret < 0) {
+		ret = -errno;
+		printf("sigaction() failed: %d (%m)\n", ret);
+		return TEST_ERR;
+	}
+
+	/* setup namespaces */
+	pid = syscall(__NR_clone, SIGCHLD|
+		      (kdbus_args->userns ? CLONE_NEWUSER : 0) |
+		      (kdbus_args->mntns ? CLONE_NEWNS : 0) |
+		      (kdbus_args->pidns ? CLONE_NEWPID : 0), NULL);
+	if (pid < 0) {
+		printf("clone() failed: %d (%m)\n", -errno);
+		return TEST_ERR;
+	}
+
+	if (pid == 0) {
+		eventfd_t event_status = 0;
+
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		if (ret < 0) {
+			ret = -errno;
+			printf("error prctl(): %d (%m)\n", ret);
+			_exit(TEST_ERR);
+		}
+
+		/* reset sighandlers of childs */
+		ret = sigaction(SIGCHLD, &oldsa, NULL);
+		if (ret < 0) {
+			ret = -errno;
+			printf("sigaction() failed: %d (%m)\n", ret);
+			_exit(TEST_ERR);
+		}
+
+		ret = eventfd_read(efd, &event_status);
+		if (ret < 0 || event_status != 1) {
+			printf("error eventfd_read()\n");
+			_exit(TEST_ERR);
+		}
+
+		if (kdbus_args->mntns) {
+			ret = test_prepare_mounts(kdbus_args);
+			if (ret < 0) {
+				printf("error preparing mounts\n");
+				_exit(TEST_ERR);
+			}
+		}
+
+		ret = run_tests(kdbus_args);
+		_exit(ret);
+	}
+
+	/* Setup userns mapping */
+	if (kdbus_args->userns) {
+		ret = userns_map_uid_gid(pid, kdbus_args->uid_map,
+					 kdbus_args->gid_map);
+		if (ret < 0) {
+			printf("error mapping uid and gid in userns\n");
+			eventfd_write(efd, 2);
+			return TEST_ERR;
+		}
+	}
+
+	ret = eventfd_write(efd, 1);
+	if (ret < 0) {
+		ret = -errno;
+		printf("error eventfd_write(): %d (%m)\n", ret);
+		return TEST_ERR;
+	}
+
+	rpid = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(rpid == pid, TEST_ERR);
+
+	close(efd);
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		return TEST_ERR;
+
+	return TEST_OK;
+}
+
+int start_tests(struct kdbus_test_args *kdbus_args)
+{
+	int ret;
+	bool namespaces;
+	static char fspath[4096];
+
+	namespaces = (kdbus_args->mntns || kdbus_args->pidns ||
+		      kdbus_args->userns);
+
+	/* for pidns we need mntns set */
+	if (kdbus_args->pidns && !kdbus_args->mntns) {
+		printf("Failed: please set both pid and mnt namesapces\n");
+		return TEST_ERR;
+	}
+
+	if (kdbus_args->userns) {
+		if (!config_user_ns_is_enabled()) {
+			printf("User namespace not supported\n");
+			return TEST_ERR;
+		}
+
+		if (!kdbus_args->uid_map || !kdbus_args->gid_map) {
+			printf("Failed: please specify uid or gid mapping\n");
+			return TEST_ERR;
+		}
+	}
+
+	print_kdbus_test_args(kdbus_args);
+	print_metadata_support();
+
+	/* setup kdbus paths */
+	if (!kdbus_args->module)
+		kdbus_args->module = "kdbus";
+
+	if (!kdbus_args->root) {
+		snprintf(fspath, sizeof(fspath), "/sys/fs/%s",
+			 kdbus_args->module);
+		kdbus_args->root = fspath;
+	}
+
+	/* Start tests */
+	if (namespaces)
+		ret = run_tests_in_namespaces(kdbus_args);
+	else
+		ret = run_tests(kdbus_args);
+
+	return ret;
+}
+
+int main(int argc, char *argv[])
+{
+	int t, ret = 0;
+	struct kdbus_test_args *kdbus_args;
+	enum {
+		ARG_MNTNS = 0x100,
+		ARG_PIDNS,
+		ARG_USERNS,
+		ARG_UIDMAP,
+		ARG_GIDMAP,
+	};
+
+	kdbus_args = malloc(sizeof(*kdbus_args));
+	if (!kdbus_args) {
+		printf("unable to malloc() kdbus_args\n");
+		return EXIT_FAILURE;
+	}
+
+	memset(kdbus_args, 0, sizeof(*kdbus_args));
+
+	static const struct option options[] = {
+		{ "loop",	no_argument,		NULL, 'x' },
+		{ "help",	no_argument,		NULL, 'h' },
+		{ "root",	required_argument,	NULL, 'r' },
+		{ "test",	required_argument,	NULL, 't' },
+		{ "bus",	required_argument,	NULL, 'b' },
+		{ "wait",	required_argument,	NULL, 'w' },
+		{ "fork",	no_argument,		NULL, 'f' },
+		{ "module",	required_argument,	NULL, 'm' },
+		{ "tap",	no_argument,		NULL, 'a' },
+		{ "mntns",	no_argument,		NULL, ARG_MNTNS },
+		{ "pidns",	no_argument,		NULL, ARG_PIDNS },
+		{ "userns",	no_argument,		NULL, ARG_USERNS },
+		{ "uidmap",	required_argument,	NULL, ARG_UIDMAP },
+		{ "gidmap",	required_argument,	NULL, ARG_GIDMAP },
+		{}
+	};
+
+	srand(time(NULL));
+
+	while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) >= 0) {
+		switch (t) {
+		case 'x':
+			kdbus_args->loop = 1;
+			break;
+
+		case 'm':
+			kdbus_args->module = optarg;
+			break;
+
+		case 'r':
+			kdbus_args->root = optarg;
+			break;
+
+		case 't':
+			kdbus_args->test = optarg;
+			break;
+
+		case 'b':
+			kdbus_args->busname = optarg;
+			break;
+
+		case 'w':
+			kdbus_args->wait = strtol(optarg, NULL, 10);
+			break;
+
+		case 'f':
+			kdbus_args->fork = 1;
+			break;
+
+		case 'a':
+			kdbus_args->tap_output = 1;
+			break;
+
+		case ARG_MNTNS:
+			kdbus_args->mntns = true;
+			break;
+
+		case ARG_PIDNS:
+			kdbus_args->pidns = true;
+			break;
+
+		case ARG_USERNS:
+			kdbus_args->userns = true;
+			break;
+
+		case ARG_UIDMAP:
+			kdbus_args->uid_map = optarg;
+			break;
+
+		case ARG_GIDMAP:
+			kdbus_args->gid_map = optarg;
+			break;
+
+		default:
+		case 'h':
+			usage(argv[0]);
+		}
+	}
+
+	ret = start_tests(kdbus_args);
+	if (ret == TEST_ERR)
+		return EXIT_FAILURE;
+
+	free(kdbus_args);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/kdbus/kdbus-test.h b/tools/testing/selftests/kdbus/kdbus-test.h
new file mode 100644
index 000000000000..ee937f9a84dc
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-test.h
@@ -0,0 +1,84 @@
+#ifndef _TEST_KDBUS_H_
+#define _TEST_KDBUS_H_
+
+struct kdbus_test_env {
+	char *buspath;
+	const char *root;
+	const char *module;
+	int control_fd;
+	struct kdbus_conn *conn;
+};
+
+enum {
+	TEST_OK,
+	TEST_SKIP,
+	TEST_ERR,
+};
+
+#define ASSERT_RETURN_VAL(cond, val)		\
+	if (!(cond)) {			\
+		fprintf(stderr,	"Assertion '%s' failed in %s(), %s:%d\n", \
+			#cond, __func__, __FILE__, __LINE__);	\
+		return val;	\
+	}
+
+#define ASSERT_EXIT_VAL(cond, val)		\
+	if (!(cond)) {			\
+		fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \
+			#cond, __func__, __FILE__, __LINE__);	\
+		_exit(val);	\
+	}
+
+#define ASSERT_BREAK(cond)		\
+	if (!(cond)) {			\
+		fprintf(stderr, "Assertion '%s' failed in %s(), %s:%d\n", \
+			#cond, __func__, __FILE__, __LINE__);	\
+		break; \
+	}
+
+#define ASSERT_RETURN(cond)		\
+	ASSERT_RETURN_VAL(cond, TEST_ERR)
+
+#define ASSERT_EXIT(cond)		\
+	ASSERT_EXIT_VAL(cond, EXIT_FAILURE)
+
+int kdbus_test_activator(struct kdbus_test_env *env);
+int kdbus_test_benchmark(struct kdbus_test_env *env);
+int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env);
+int kdbus_test_benchmark_uds(struct kdbus_test_env *env);
+int kdbus_test_bus_make(struct kdbus_test_env *env);
+int kdbus_test_byebye(struct kdbus_test_env *env);
+int kdbus_test_chat(struct kdbus_test_env *env);
+int kdbus_test_conn_info(struct kdbus_test_env *env);
+int kdbus_test_conn_update(struct kdbus_test_env *env);
+int kdbus_test_daemon(struct kdbus_test_env *env);
+int kdbus_test_custom_endpoint(struct kdbus_test_env *env);
+int kdbus_test_fd_passing(struct kdbus_test_env *env);
+int kdbus_test_free(struct kdbus_test_env *env);
+int kdbus_test_hello(struct kdbus_test_env *env);
+int kdbus_test_match_bloom(struct kdbus_test_env *env);
+int kdbus_test_match_id_add(struct kdbus_test_env *env);
+int kdbus_test_match_id_remove(struct kdbus_test_env *env);
+int kdbus_test_match_replace(struct kdbus_test_env *env);
+int kdbus_test_match_name_add(struct kdbus_test_env *env);
+int kdbus_test_match_name_change(struct kdbus_test_env *env);
+int kdbus_test_match_name_remove(struct kdbus_test_env *env);
+int kdbus_test_message_basic(struct kdbus_test_env *env);
+int kdbus_test_message_prio(struct kdbus_test_env *env);
+int kdbus_test_message_quota(struct kdbus_test_env *env);
+int kdbus_test_memory_access(struct kdbus_test_env *env);
+int kdbus_test_metadata_ns(struct kdbus_test_env *env);
+int kdbus_test_monitor(struct kdbus_test_env *env);
+int kdbus_test_name_basic(struct kdbus_test_env *env);
+int kdbus_test_name_conflict(struct kdbus_test_env *env);
+int kdbus_test_name_queue(struct kdbus_test_env *env);
+int kdbus_test_name_takeover(struct kdbus_test_env *env);
+int kdbus_test_policy(struct kdbus_test_env *env);
+int kdbus_test_policy_ns(struct kdbus_test_env *env);
+int kdbus_test_policy_priv(struct kdbus_test_env *env);
+int kdbus_test_sync_byebye(struct kdbus_test_env *env);
+int kdbus_test_sync_reply(struct kdbus_test_env *env);
+int kdbus_test_timeout(struct kdbus_test_env *env);
+int kdbus_test_writable_pool(struct kdbus_test_env *env);
+
+#endif /* _TEST_KDBUS_H_ */
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c b/tools/testing/selftests/kdbus/kdbus-util.c
new file mode 100644
index 000000000000..82fa89b1a881
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -0,0 +1,1612 @@
+/*
+ * Copyright (C) 2013-2015 Daniel Mack
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <grp.h>
+#include <sys/capability.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <linux/unistd.h>
+#include <linux/memfd.h>
+
+#ifndef __NR_memfd_create
+  #ifdef __x86_64__
+    #define __NR_memfd_create 319
+  #elif defined __arm__
+    #define __NR_memfd_create 385
+  #else
+    #define __NR_memfd_create 356
+  #endif
+#endif
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+#ifndef F_ADD_SEALS
+#define F_LINUX_SPECIFIC_BASE	1024
+#define F_ADD_SEALS     (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS     (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
+#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
+#define F_SEAL_GROW     0x0004  /* prevent file from growing */
+#define F_SEAL_WRITE    0x0008  /* prevent writes */
+#endif
+
+int kdbus_util_verbose = true;
+
+int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask)
+{
+	int ret;
+	FILE *file;
+	unsigned long long value;
+
+	file = fopen(path, "r");
+	if (!file) {
+		ret = -errno;
+		kdbus_printf("--- error fopen(): %d (%m)\n", ret);
+		return ret;
+	}
+
+	ret = fscanf(file, "%llu", &value);
+	if (ret != 1) {
+		if (ferror(file))
+			ret = -errno;
+		else
+			ret = -EIO;
+
+		kdbus_printf("--- error fscanf(): %d\n", ret);
+		fclose(file);
+		return ret;
+	}
+
+	*mask = (uint64_t)value;
+
+	fclose(file);
+
+	return 0;
+}
+
+int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask)
+{
+	int ret;
+	FILE *file;
+
+	file = fopen(path, "w");
+	if (!file) {
+		ret = -errno;
+		kdbus_printf("--- error open(): %d (%m)\n", ret);
+		return ret;
+	}
+
+	ret = fprintf(file, "%llu", (unsigned long long)mask);
+	if (ret <= 0) {
+		ret = -EIO;
+		kdbus_printf("--- error fprintf(): %d\n", ret);
+	}
+
+	fclose(file);
+
+	return ret > 0 ? 0 : ret;
+}
+
+int kdbus_create_bus(int control_fd, const char *name,
+		     uint64_t owner_meta, char **path)
+{
+	struct {
+		struct kdbus_cmd cmd;
+
+		/* bloom size item */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_bloom_parameter bloom;
+		} bp;
+
+		/* owner metadata items */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			uint64_t flags;
+		} attach;
+
+		/* name item */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			char str[64];
+		} name;
+	} bus_make;
+	int ret;
+
+	memset(&bus_make, 0, sizeof(bus_make));
+	bus_make.bp.size = sizeof(bus_make.bp);
+	bus_make.bp.type = KDBUS_ITEM_BLOOM_PARAMETER;
+	bus_make.bp.bloom.size = 64;
+	bus_make.bp.bloom.n_hash = 1;
+
+	snprintf(bus_make.name.str, sizeof(bus_make.name.str),
+		 "%u-%s", getuid(), name);
+
+	bus_make.attach.type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
+	bus_make.attach.size = sizeof(bus_make.attach);
+	bus_make.attach.flags = owner_meta;
+
+	bus_make.name.type = KDBUS_ITEM_MAKE_NAME;
+	bus_make.name.size = KDBUS_ITEM_HEADER_SIZE +
+			     strlen(bus_make.name.str) + 1;
+
+	bus_make.cmd.flags = KDBUS_MAKE_ACCESS_WORLD;
+	bus_make.cmd.size = sizeof(bus_make.cmd) +
+			     bus_make.bp.size +
+			     bus_make.attach.size +
+			     bus_make.name.size;
+
+	kdbus_printf("Creating bus with name >%s< on control fd %d ...\n",
+		     name, control_fd);
+
+	ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
+	if (ret < 0) {
+		kdbus_printf("--- error when making bus: %d (%m)\n", ret);
+		return ret;
+	}
+
+	if (ret == 0 && path)
+		*path = strdup(bus_make.name.str);
+
+	return ret;
+}
+
+struct kdbus_conn *
+kdbus_hello(const char *path, uint64_t flags,
+	    const struct kdbus_item *item, size_t item_size)
+{
+	struct kdbus_cmd_free cmd_free = {};
+	int fd, ret;
+	struct {
+		struct kdbus_cmd_hello hello;
+
+		struct {
+			uint64_t size;
+			uint64_t type;
+			char str[16];
+		} conn_name;
+
+		uint8_t extra_items[item_size];
+	} h;
+	struct kdbus_conn *conn;
+
+	memset(&h, 0, sizeof(h));
+
+	if (item_size > 0)
+		memcpy(h.extra_items, item, item_size);
+
+	kdbus_printf("-- opening bus connection %s\n", path);
+	fd = open(path, O_RDWR|O_CLOEXEC);
+	if (fd < 0) {
+		kdbus_printf("--- error %d (%m)\n", fd);
+		return NULL;
+	}
+
+	h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD;
+	h.hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	h.hello.attach_flags_recv = _KDBUS_ATTACH_ALL;
+	h.conn_name.type = KDBUS_ITEM_CONN_DESCRIPTION;
+	strcpy(h.conn_name.str, "this-is-my-name");
+	h.conn_name.size = KDBUS_ITEM_HEADER_SIZE + strlen(h.conn_name.str) + 1;
+
+	h.hello.size = sizeof(h);
+	h.hello.pool_size = POOL_SIZE;
+
+	ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) &h.hello);
+	if (ret < 0) {
+		kdbus_printf("--- error when saying hello: %d (%m)\n", ret);
+		return NULL;
+	}
+	kdbus_printf("-- Our peer ID for %s: %llu -- bus uuid: '%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'\n",
+		     path, (unsigned long long)h.hello.id,
+		     h.hello.id128[0],  h.hello.id128[1],  h.hello.id128[2],
+		     h.hello.id128[3],  h.hello.id128[4],  h.hello.id128[5],
+		     h.hello.id128[6],  h.hello.id128[7],  h.hello.id128[8],
+		     h.hello.id128[9],  h.hello.id128[10], h.hello.id128[11],
+		     h.hello.id128[12], h.hello.id128[13], h.hello.id128[14],
+		     h.hello.id128[15]);
+
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = h.hello.offset;
+	kdbus_cmd_free(fd, &cmd_free);
+
+	conn = malloc(sizeof(*conn));
+	if (!conn) {
+		kdbus_printf("unable to malloc()!?\n");
+		return NULL;
+	}
+
+	conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
+	if (conn->buf == MAP_FAILED) {
+		free(conn);
+		close(fd);
+		kdbus_printf("--- error mmap (%m)\n");
+		return NULL;
+	}
+
+	conn->fd = fd;
+	conn->id = h.hello.id;
+	return conn;
+}
+
+struct kdbus_conn *
+kdbus_hello_registrar(const char *path, const char *name,
+		      const struct kdbus_policy_access *access,
+		      size_t num_access, uint64_t flags)
+{
+	struct kdbus_item *item, *items;
+	size_t i, size;
+
+	size = KDBUS_ITEM_SIZE(strlen(name) + 1) +
+		num_access * KDBUS_ITEM_SIZE(sizeof(*access));
+
+	items = alloca(size);
+
+	item = items;
+	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+	item->type = KDBUS_ITEM_NAME;
+	strcpy(item->str, name);
+	item = KDBUS_ITEM_NEXT(item);
+
+	for (i = 0; i < num_access; i++) {
+		item->size = KDBUS_ITEM_HEADER_SIZE +
+			     sizeof(struct kdbus_policy_access);
+		item->type = KDBUS_ITEM_POLICY_ACCESS;
+
+		item->policy_access.type = access[i].type;
+		item->policy_access.access = access[i].access;
+		item->policy_access.id = access[i].id;
+
+		item = KDBUS_ITEM_NEXT(item);
+	}
+
+	return kdbus_hello(path, flags, items, size);
+}
+
+struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name,
+				   const struct kdbus_policy_access *access,
+				   size_t num_access)
+{
+	return kdbus_hello_registrar(path, name, access, num_access,
+				     KDBUS_HELLO_ACTIVATOR);
+}
+
+bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type)
+{
+	const struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, msg, items)
+		if (item->type == type)
+			return true;
+
+	return false;
+}
+
+int kdbus_bus_creator_info(struct kdbus_conn *conn,
+			   uint64_t flags,
+			   uint64_t *offset)
+{
+	struct kdbus_cmd_info *cmd;
+	size_t size = sizeof(*cmd);
+	int ret;
+
+	cmd = alloca(size);
+	memset(cmd, 0, size);
+	cmd->size = size;
+	cmd->attach_flags = flags;
+
+	ret = kdbus_cmd_bus_creator_info(conn->fd, cmd);
+	if (ret < 0) {
+		kdbus_printf("--- error when requesting info: %d (%m)\n", ret);
+		return ret;
+	}
+
+	if (offset)
+		*offset = cmd->offset;
+	else
+		kdbus_free(conn, cmd->offset);
+
+	return 0;
+}
+
+int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id,
+		    const char *name, uint64_t flags,
+		    uint64_t *offset)
+{
+	struct kdbus_cmd_info *cmd;
+	size_t size = sizeof(*cmd);
+	struct kdbus_info *info;
+	int ret;
+
+	if (name)
+		size += KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+
+	cmd = alloca(size);
+	memset(cmd, 0, size);
+	cmd->size = size;
+	cmd->attach_flags = flags;
+
+	if (name) {
+		cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+		cmd->items[0].type = KDBUS_ITEM_NAME;
+		strcpy(cmd->items[0].str, name);
+	} else {
+		cmd->id = id;
+	}
+
+	ret = kdbus_cmd_conn_info(conn->fd, cmd);
+	if (ret < 0) {
+		kdbus_printf("--- error when requesting info: %d (%m)\n", ret);
+		return ret;
+	}
+
+	info = (struct kdbus_info *) (conn->buf + cmd->offset);
+	if (info->size != cmd->info_size) {
+		kdbus_printf("%s(): size mismatch: %d != %d\n", __func__,
+				(int) info->size, (int) cmd->info_size);
+		return -EIO;
+	}
+
+	if (offset)
+		*offset = cmd->offset;
+	else
+		kdbus_free(conn, cmd->offset);
+
+	return 0;
+}
+
+void kdbus_conn_free(struct kdbus_conn *conn)
+{
+	if (!conn)
+		return;
+
+	if (conn->buf)
+		munmap(conn->buf, POOL_SIZE);
+
+	if (conn->fd >= 0)
+		close(conn->fd);
+
+	free(conn);
+}
+
+int sys_memfd_create(const char *name, __u64 size)
+{
+	int ret, fd;
+
+	fd = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
+	if (fd < 0)
+		return fd;
+
+	ret = ftruncate(fd, size);
+	if (ret < 0) {
+		close(fd);
+		return ret;
+	}
+
+	return fd;
+}
+
+int sys_memfd_seal_set(int fd)
+{
+	return fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK |
+			 F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL);
+}
+
+off_t sys_memfd_get_size(int fd, off_t *size)
+{
+	struct stat stat;
+	int ret;
+
+	ret = fstat(fd, &stat);
+	if (ret < 0) {
+		kdbus_printf("stat() failed: %m\n");
+		return ret;
+	}
+
+	*size = stat.st_size;
+	return 0;
+}
+
+static int __kdbus_msg_send(const struct kdbus_conn *conn,
+			    const char *name,
+			    uint64_t cookie,
+			    uint64_t flags,
+			    uint64_t timeout,
+			    int64_t priority,
+			    uint64_t dst_id,
+			    uint64_t cmd_flags,
+			    int cancel_fd)
+{
+	struct kdbus_cmd_send *cmd = NULL;
+	struct kdbus_msg *msg = NULL;
+	const char ref1[1024 * 128 + 3] = "0123456789_0";
+	const char ref2[] = "0123456789_1";
+	struct kdbus_item *item;
+	struct timespec now;
+	uint64_t size;
+	int memfd = -1;
+	int ret;
+
+	size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST)
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+	else {
+		memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024);
+		if (memfd < 0) {
+			kdbus_printf("failed to create memfd: %m\n");
+			return memfd;
+		}
+
+		if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
+			ret = -errno;
+			kdbus_printf("writing to memfd failed: %m\n");
+			goto out;
+		}
+
+		ret = sys_memfd_seal_set(memfd);
+		if (ret < 0) {
+			ret = -errno;
+			kdbus_printf("memfd sealing failed: %m\n");
+			goto out;
+		}
+
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
+	}
+
+	if (name)
+		size += KDBUS_ITEM_SIZE(strlen(name) + 1);
+
+	msg = malloc(size);
+	if (!msg) {
+		ret = -errno;
+		kdbus_printf("unable to malloc()!?\n");
+		goto out;
+	}
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST)
+		flags |= KDBUS_MSG_SIGNAL;
+
+	memset(msg, 0, size);
+	msg->flags = flags;
+	msg->priority = priority;
+	msg->size = size;
+	msg->src_id = conn->id;
+	msg->dst_id = name ? 0 : dst_id;
+	msg->cookie = cookie;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	if (timeout) {
+		ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+		if (ret < 0)
+			goto out;
+
+		msg->timeout_ns = now.tv_sec * 1000000000ULL +
+				  now.tv_nsec + timeout;
+	}
+
+	item = msg->items;
+
+	if (name) {
+		item->type = KDBUS_ITEM_DST_NAME;
+		item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+		strcpy(item->str, name);
+		item = KDBUS_ITEM_NEXT(item);
+	}
+
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)&ref1;
+	item->vec.size = sizeof(ref1);
+	item = KDBUS_ITEM_NEXT(item);
+
+	/* data padding for ref1 */
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)NULL;
+	item->vec.size =  KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1);
+	item = KDBUS_ITEM_NEXT(item);
+
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)&ref2;
+	item->vec.size = sizeof(ref2);
+	item = KDBUS_ITEM_NEXT(item);
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST) {
+		item->type = KDBUS_ITEM_BLOOM_FILTER;
+		item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+		item->bloom_filter.generation = 0;
+	} else {
+		item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
+		item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
+		item->memfd.size = 16;
+		item->memfd.fd = memfd;
+	}
+	item = KDBUS_ITEM_NEXT(item);
+
+	size = sizeof(*cmd);
+	if (cancel_fd != -1)
+		size += KDBUS_ITEM_SIZE(sizeof(cancel_fd));
+
+	cmd = malloc(size);
+	if (!cmd) {
+		ret = -errno;
+		kdbus_printf("unable to malloc()!?\n");
+		goto out;
+	}
+
+	cmd->size = size;
+	cmd->flags = cmd_flags;
+	cmd->msg_address = (uintptr_t)msg;
+
+	item = cmd->items;
+
+	if (cancel_fd != -1) {
+		item->type = KDBUS_ITEM_CANCEL_FD;
+		item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(cancel_fd);
+		item->fds[0] = cancel_fd;
+		item = KDBUS_ITEM_NEXT(item);
+	}
+
+	ret = kdbus_cmd_send(conn->fd, cmd);
+	if (ret < 0) {
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+		goto out;
+	}
+
+	if (cmd_flags & KDBUS_SEND_SYNC_REPLY) {
+		struct kdbus_msg *reply;
+
+		kdbus_printf("SYNC REPLY @offset %llu:\n", cmd->reply.offset);
+		reply = (struct kdbus_msg *)(conn->buf + cmd->reply.offset);
+		kdbus_msg_dump(conn, reply);
+
+		kdbus_msg_free(reply);
+
+		ret = kdbus_free(conn, cmd->reply.offset);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	free(msg);
+	free(cmd);
+
+	if (memfd >= 0)
+		close(memfd);
+
+	return ret < 0 ? ret : 0;
+}
+
+int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
+		   uint64_t cookie, uint64_t flags, uint64_t timeout,
+		   int64_t priority, uint64_t dst_id)
+{
+	return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority,
+				dst_id, 0, -1);
+}
+
+int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name,
+			uint64_t cookie, uint64_t flags, uint64_t timeout,
+			int64_t priority, uint64_t dst_id, int cancel_fd)
+{
+	return __kdbus_msg_send(conn, name, cookie, flags, timeout, priority,
+				dst_id, KDBUS_SEND_SYNC_REPLY, cancel_fd);
+}
+
+int kdbus_msg_send_reply(const struct kdbus_conn *conn,
+			 uint64_t reply_cookie,
+			 uint64_t dst_id)
+{
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_msg *msg;
+	const char ref1[1024 * 128 + 3] = "0123456789_0";
+	struct kdbus_item *item;
+	uint64_t size;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	msg = malloc(size);
+	if (!msg) {
+		kdbus_printf("unable to malloc()!?\n");
+		return -ENOMEM;
+	}
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = conn->id;
+	msg->dst_id = dst_id;
+	msg->cookie_reply = reply_cookie;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	item = msg->items;
+
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)&ref1;
+	item->vec.size = sizeof(ref1);
+	item = KDBUS_ITEM_NEXT(item);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	if (ret < 0)
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+
+	free(msg);
+
+	return ret;
+}
+
+static char *msg_id(uint64_t id, char *buf)
+{
+	if (id == 0)
+		return "KERNEL";
+	if (id == ~0ULL)
+		return "BROADCAST";
+	sprintf(buf, "%llu", (unsigned long long)id);
+	return buf;
+}
+
+int kdbus_msg_dump(const struct kdbus_conn *conn, const struct kdbus_msg *msg)
+{
+	const struct kdbus_item *item = msg->items;
+	char buf_src[32];
+	char buf_dst[32];
+	uint64_t timeout = 0;
+	uint64_t cookie_reply = 0;
+	int ret = 0;
+
+	if (msg->flags & KDBUS_MSG_EXPECT_REPLY)
+		timeout = msg->timeout_ns;
+	else
+		cookie_reply = msg->cookie_reply;
+
+	kdbus_printf("MESSAGE: %s (%llu bytes) flags=0x%08llx, %s → %s, "
+		     "cookie=%llu, timeout=%llu cookie_reply=%llu priority=%lli\n",
+		enum_PAYLOAD(msg->payload_type), (unsigned long long)msg->size,
+		(unsigned long long)msg->flags,
+		msg_id(msg->src_id, buf_src), msg_id(msg->dst_id, buf_dst),
+		(unsigned long long)msg->cookie, (unsigned long long)timeout,
+		(unsigned long long)cookie_reply, (long long)msg->priority);
+
+	KDBUS_ITEM_FOREACH(item, msg, items) {
+		if (item->size < KDBUS_ITEM_HEADER_SIZE) {
+			kdbus_printf("  +%s (%llu bytes) invalid data record\n",
+				     enum_MSG(item->type), item->size);
+			ret = -EINVAL;
+			break;
+		}
+
+		switch (item->type) {
+		case KDBUS_ITEM_PAYLOAD_OFF: {
+			char *s;
+
+			if (item->vec.offset == ~0ULL)
+				s = "[\\0-bytes]";
+			else
+				s = (char *)msg + item->vec.offset;
+
+			kdbus_printf("  +%s (%llu bytes) off=%llu size=%llu '%s'\n",
+			       enum_MSG(item->type), item->size,
+			       (unsigned long long)item->vec.offset,
+			       (unsigned long long)item->vec.size, s);
+			break;
+		}
+
+		case KDBUS_ITEM_FDS: {
+			int i, n = (item->size - KDBUS_ITEM_HEADER_SIZE) /
+					sizeof(int);
+
+			kdbus_printf("  +%s (%llu bytes, %d fds)\n",
+			       enum_MSG(item->type), item->size, n);
+
+			for (i = 0; i < n; i++)
+				kdbus_printf("    fd[%d] = %d\n",
+					     i, item->fds[i]);
+
+			break;
+		}
+
+		case KDBUS_ITEM_PAYLOAD_MEMFD: {
+			char *buf;
+			off_t size;
+
+			buf = mmap(NULL, item->memfd.size, PROT_READ,
+				   MAP_PRIVATE, item->memfd.fd, 0);
+			if (buf == MAP_FAILED) {
+				kdbus_printf("mmap() fd=%i size=%llu failed: %m\n",
+					     item->memfd.fd, item->memfd.size);
+				break;
+			}
+
+			if (sys_memfd_get_size(item->memfd.fd, &size) < 0) {
+				kdbus_printf("KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n");
+				break;
+			}
+
+			kdbus_printf("  +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n",
+			       enum_MSG(item->type), item->size, item->memfd.fd,
+			       (unsigned long long)item->memfd.size,
+			       (unsigned long long)size, buf);
+			munmap(buf, item->memfd.size);
+			break;
+		}
+
+		case KDBUS_ITEM_CREDS:
+			kdbus_printf("  +%s (%llu bytes) uid=%lld, euid=%lld, suid=%lld, fsuid=%lld, "
+							"gid=%lld, egid=%lld, sgid=%lld, fsgid=%lld\n",
+				enum_MSG(item->type), item->size,
+				item->creds.uid, item->creds.euid,
+				item->creds.suid, item->creds.fsuid,
+				item->creds.gid, item->creds.egid,
+				item->creds.sgid, item->creds.fsgid);
+			break;
+
+		case KDBUS_ITEM_PIDS:
+			kdbus_printf("  +%s (%llu bytes) pid=%lld, tid=%lld, ppid=%lld\n",
+				enum_MSG(item->type), item->size,
+				item->pids.pid, item->pids.tid,
+				item->pids.ppid);
+			break;
+
+		case KDBUS_ITEM_AUXGROUPS: {
+			int i, n;
+
+			kdbus_printf("  +%s (%llu bytes)\n",
+				     enum_MSG(item->type), item->size);
+			n = (item->size - KDBUS_ITEM_HEADER_SIZE) /
+				sizeof(uint64_t);
+
+			for (i = 0; i < n; i++)
+				kdbus_printf("    gid[%d] = %lld\n",
+					     i, item->data64[i]);
+			break;
+		}
+
+		case KDBUS_ITEM_NAME:
+		case KDBUS_ITEM_PID_COMM:
+		case KDBUS_ITEM_TID_COMM:
+		case KDBUS_ITEM_EXE:
+		case KDBUS_ITEM_CGROUP:
+		case KDBUS_ITEM_SECLABEL:
+		case KDBUS_ITEM_DST_NAME:
+		case KDBUS_ITEM_CONN_DESCRIPTION:
+			kdbus_printf("  +%s (%llu bytes) '%s' (%zu)\n",
+				     enum_MSG(item->type), item->size,
+				     item->str, strlen(item->str));
+			break;
+
+		case KDBUS_ITEM_OWNED_NAME: {
+			kdbus_printf("  +%s (%llu bytes) '%s' (%zu) flags=0x%08llx\n",
+				     enum_MSG(item->type), item->size,
+				     item->name.name, strlen(item->name.name),
+				     item->name.flags);
+			break;
+		}
+
+		case KDBUS_ITEM_CMDLINE: {
+			size_t size = item->size - KDBUS_ITEM_HEADER_SIZE;
+			const char *str = item->str;
+			int count = 0;
+
+			kdbus_printf("  +%s (%llu bytes) ",
+				     enum_MSG(item->type), item->size);
+			while (size) {
+				kdbus_printf("'%s' ", str);
+				size -= strlen(str) + 1;
+				str += strlen(str) + 1;
+				count++;
+			}
+
+			kdbus_printf("(%d string%s)\n",
+				     count, (count == 1) ? "" : "s");
+			break;
+		}
+
+		case KDBUS_ITEM_AUDIT:
+			kdbus_printf("  +%s (%llu bytes) loginuid=%u sessionid=%u\n",
+			       enum_MSG(item->type), item->size,
+			       item->audit.loginuid, item->audit.sessionid);
+			break;
+
+		case KDBUS_ITEM_CAPS: {
+			const uint32_t *cap;
+			int n, i;
+
+			kdbus_printf("  +%s (%llu bytes) len=%llu bytes, last_cap %d\n",
+				     enum_MSG(item->type), item->size,
+				     (unsigned long long)item->size -
+					KDBUS_ITEM_HEADER_SIZE,
+				     (int) item->caps.last_cap);
+
+			cap = item->caps.caps;
+			n = (item->size - offsetof(struct kdbus_item, caps.caps))
+				/ 4 / sizeof(uint32_t);
+
+			kdbus_printf("    CapInh=");
+			for (i = 0; i < n; i++)
+				kdbus_printf("%08x", cap[(0 * n) + (n - i - 1)]);
+
+			kdbus_printf(" CapPrm=");
+			for (i = 0; i < n; i++)
+				kdbus_printf("%08x", cap[(1 * n) + (n - i - 1)]);
+
+			kdbus_printf(" CapEff=");
+			for (i = 0; i < n; i++)
+				kdbus_printf("%08x", cap[(2 * n) + (n - i - 1)]);
+
+			kdbus_printf(" CapBnd=");
+			for (i = 0; i < n; i++)
+				kdbus_printf("%08x", cap[(3 * n) + (n - i - 1)]);
+			kdbus_printf("\n");
+			break;
+		}
+
+		case KDBUS_ITEM_TIMESTAMP:
+			kdbus_printf("  +%s (%llu bytes) seq=%llu realtime=%lluns monotonic=%lluns\n",
+			       enum_MSG(item->type), item->size,
+			       (unsigned long long)item->timestamp.seqnum,
+			       (unsigned long long)item->timestamp.realtime_ns,
+			       (unsigned long long)item->timestamp.monotonic_ns);
+			break;
+
+		case KDBUS_ITEM_REPLY_TIMEOUT:
+			kdbus_printf("  +%s (%llu bytes) cookie=%llu\n",
+			       enum_MSG(item->type), item->size,
+			       msg->cookie_reply);
+			break;
+
+		case KDBUS_ITEM_NAME_ADD:
+		case KDBUS_ITEM_NAME_REMOVE:
+		case KDBUS_ITEM_NAME_CHANGE:
+			kdbus_printf("  +%s (%llu bytes) '%s', old id=%lld, now id=%lld, old_flags=0x%llx new_flags=0x%llx\n",
+				enum_MSG(item->type),
+				(unsigned long long) item->size,
+				item->name_change.name,
+				item->name_change.old_id.id,
+				item->name_change.new_id.id,
+				item->name_change.old_id.flags,
+				item->name_change.new_id.flags);
+			break;
+
+		case KDBUS_ITEM_ID_ADD:
+		case KDBUS_ITEM_ID_REMOVE:
+			kdbus_printf("  +%s (%llu bytes) id=%llu flags=%llu\n",
+			       enum_MSG(item->type),
+			       (unsigned long long) item->size,
+			       (unsigned long long) item->id_change.id,
+			       (unsigned long long) item->id_change.flags);
+			break;
+
+		default:
+			kdbus_printf("  +%s (%llu bytes)\n",
+				     enum_MSG(item->type), item->size);
+			break;
+		}
+	}
+
+	if ((char *)item - ((char *)msg + msg->size) >= 8) {
+		kdbus_printf("invalid padding at end of message\n");
+		ret = -EINVAL;
+	}
+
+	kdbus_printf("\n");
+
+	return ret;
+}
+
+void kdbus_msg_free(struct kdbus_msg *msg)
+{
+	const struct kdbus_item *item;
+	int nfds, i;
+
+	if (!msg)
+		return;
+
+	KDBUS_ITEM_FOREACH(item, msg, items) {
+		switch (item->type) {
+		/* close all memfds */
+		case KDBUS_ITEM_PAYLOAD_MEMFD:
+			close(item->memfd.fd);
+			break;
+		case KDBUS_ITEM_FDS:
+			nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) /
+				sizeof(int);
+
+			for (i = 0; i < nfds; i++)
+				close(item->fds[i]);
+
+			break;
+		}
+	}
+}
+
+int kdbus_msg_recv(struct kdbus_conn *conn,
+		   struct kdbus_msg **msg_out,
+		   uint64_t *offset)
+{
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+	struct kdbus_msg *msg;
+	int ret;
+
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	if (ret < 0)
+		return ret;
+
+	msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
+	ret = kdbus_msg_dump(conn, msg);
+	if (ret < 0) {
+		kdbus_msg_free(msg);
+		return ret;
+	}
+
+	if (msg_out) {
+		*msg_out = msg;
+
+		if (offset)
+			*offset = recv.msg.offset;
+	} else {
+		kdbus_msg_free(msg);
+
+		ret = kdbus_free(conn, recv.msg.offset);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Returns: 0 on success, negative errno on failure.
+ *
+ * We must return -ETIMEDOUT, -ECONNREST, -EAGAIN and other errors.
+ * We must return the result of kdbus_msg_recv()
+ */
+int kdbus_msg_recv_poll(struct kdbus_conn *conn,
+			int timeout_ms,
+			struct kdbus_msg **msg_out,
+			uint64_t *offset)
+{
+	int ret;
+
+	do {
+		struct timeval before, after, diff;
+		struct pollfd fd;
+
+		fd.fd = conn->fd;
+		fd.events = POLLIN | POLLPRI | POLLHUP;
+		fd.revents = 0;
+
+		gettimeofday(&before, NULL);
+		ret = poll(&fd, 1, timeout_ms);
+		gettimeofday(&after, NULL);
+
+		if (ret == 0) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		if (ret > 0) {
+			if (fd.revents & POLLIN)
+				ret = kdbus_msg_recv(conn, msg_out, offset);
+
+			if (fd.revents & (POLLHUP | POLLERR))
+				ret = -ECONNRESET;
+		}
+
+		if (ret == 0 || ret != -EAGAIN)
+			break;
+
+		timersub(&after, &before, &diff);
+		timeout_ms -= diff.tv_sec * 1000UL +
+			      diff.tv_usec / 1000UL;
+	} while (timeout_ms > 0);
+
+	return ret;
+}
+
+int kdbus_free(const struct kdbus_conn *conn, uint64_t offset)
+{
+	struct kdbus_cmd_free cmd_free = {};
+	int ret;
+
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = offset;
+	cmd_free.flags = 0;
+
+	ret = kdbus_cmd_free(conn->fd, &cmd_free);
+	if (ret < 0) {
+		kdbus_printf("KDBUS_CMD_FREE failed: %d (%m)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int kdbus_name_acquire(struct kdbus_conn *conn,
+		       const char *name, uint64_t *flags)
+{
+	struct kdbus_cmd *cmd_name;
+	size_t name_len = strlen(name) + 1;
+	uint64_t size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(name_len);
+	struct kdbus_item *item;
+	int ret;
+
+	cmd_name = alloca(size);
+
+	memset(cmd_name, 0, size);
+
+	item = cmd_name->items;
+	item->size = KDBUS_ITEM_HEADER_SIZE + name_len;
+	item->type = KDBUS_ITEM_NAME;
+	strcpy(item->str, name);
+
+	cmd_name->size = size;
+	if (flags)
+		cmd_name->flags = *flags;
+
+	ret = kdbus_cmd_name_acquire(conn->fd, cmd_name);
+	if (ret < 0) {
+		kdbus_printf("error aquiring name: %s\n", strerror(-ret));
+		return ret;
+	}
+
+	kdbus_printf("%s(): flags after call: 0x%llx\n", __func__,
+		     cmd_name->return_flags);
+
+	if (flags)
+		*flags = cmd_name->return_flags;
+
+	return 0;
+}
+
+int kdbus_name_release(struct kdbus_conn *conn, const char *name)
+{
+	struct kdbus_cmd *cmd_name;
+	size_t name_len = strlen(name) + 1;
+	uint64_t size = sizeof(*cmd_name) + KDBUS_ITEM_SIZE(name_len);
+	struct kdbus_item *item;
+	int ret;
+
+	cmd_name = alloca(size);
+
+	memset(cmd_name, 0, size);
+
+	item = cmd_name->items;
+	item->size = KDBUS_ITEM_HEADER_SIZE + name_len;
+	item->type = KDBUS_ITEM_NAME;
+	strcpy(item->str, name);
+
+	cmd_name->size = size;
+
+	kdbus_printf("conn %lld giving up name '%s'\n",
+		     (unsigned long long) conn->id, name);
+
+	ret = kdbus_cmd_name_release(conn->fd, cmd_name);
+	if (ret < 0) {
+		kdbus_printf("error releasing name: %s\n", strerror(-ret));
+		return ret;
+	}
+
+	return 0;
+}
+
+int kdbus_list(struct kdbus_conn *conn, uint64_t flags)
+{
+	struct kdbus_cmd_list cmd_list = {};
+	struct kdbus_info *list, *name;
+	int ret;
+
+	cmd_list.size = sizeof(cmd_list);
+	cmd_list.flags = flags;
+
+	ret = kdbus_cmd_list(conn->fd, &cmd_list);
+	if (ret < 0) {
+		kdbus_printf("error listing names: %d (%m)\n", ret);
+		return ret;
+	}
+
+	kdbus_printf("REGISTRY:\n");
+	list = (struct kdbus_info *)(conn->buf + cmd_list.offset);
+
+	KDBUS_FOREACH(name, list, cmd_list.list_size) {
+		uint64_t flags = 0;
+		struct kdbus_item *item;
+		const char *n = "MISSING-NAME";
+
+		if (name->size == sizeof(struct kdbus_cmd))
+			continue;
+
+		KDBUS_ITEM_FOREACH(item, name, items)
+			if (item->type == KDBUS_ITEM_OWNED_NAME) {
+				n = item->name.name;
+				flags = item->name.flags;
+
+				kdbus_printf("%8llu flags=0x%08llx conn=0x%08llx '%s'\n",
+					     name->id,
+					     (unsigned long long) flags,
+					     name->flags, n);
+			}
+	}
+	kdbus_printf("\n");
+
+	ret = kdbus_free(conn, cmd_list.offset);
+
+	return ret;
+}
+
+int kdbus_conn_update_attach_flags(struct kdbus_conn *conn,
+				   uint64_t attach_flags_send,
+				   uint64_t attach_flags_recv)
+{
+	int ret;
+	size_t size;
+	struct kdbus_cmd *update;
+	struct kdbus_item *item;
+
+	size = sizeof(struct kdbus_cmd);
+	size += KDBUS_ITEM_SIZE(sizeof(uint64_t)) * 2;
+
+	update = malloc(size);
+	if (!update) {
+		kdbus_printf("error malloc: %m\n");
+		return -ENOMEM;
+	}
+
+	memset(update, 0, size);
+	update->size = size;
+
+	item = update->items;
+
+	item->type = KDBUS_ITEM_ATTACH_FLAGS_SEND;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
+	item->data64[0] = attach_flags_send;
+	item = KDBUS_ITEM_NEXT(item);
+
+	item->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
+	item->data64[0] = attach_flags_recv;
+	item = KDBUS_ITEM_NEXT(item);
+
+	ret = kdbus_cmd_update(conn->fd, update);
+	if (ret < 0)
+		kdbus_printf("error conn update: %d (%m)\n", ret);
+
+	free(update);
+
+	return ret;
+}
+
+int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name,
+			     const struct kdbus_policy_access *access,
+			     size_t num_access)
+{
+	struct kdbus_cmd *update;
+	struct kdbus_item *item;
+	size_t i, size;
+	int ret;
+
+	size = sizeof(struct kdbus_cmd);
+	size += KDBUS_ITEM_SIZE(strlen(name) + 1);
+	size += num_access * KDBUS_ITEM_SIZE(sizeof(struct kdbus_policy_access));
+
+	update = malloc(size);
+	if (!update) {
+		kdbus_printf("error malloc: %m\n");
+		return -ENOMEM;
+	}
+
+	memset(update, 0, size);
+	update->size = size;
+
+	item = update->items;
+
+	item->type = KDBUS_ITEM_NAME;
+	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
+	strcpy(item->str, name);
+	item = KDBUS_ITEM_NEXT(item);
+
+	for (i = 0; i < num_access; i++) {
+		item->size = KDBUS_ITEM_HEADER_SIZE +
+			     sizeof(struct kdbus_policy_access);
+		item->type = KDBUS_ITEM_POLICY_ACCESS;
+
+		item->policy_access.type = access[i].type;
+		item->policy_access.access = access[i].access;
+		item->policy_access.id = access[i].id;
+
+		item = KDBUS_ITEM_NEXT(item);
+	}
+
+	ret = kdbus_cmd_update(conn->fd, update);
+	if (ret < 0)
+		kdbus_printf("error conn update: %d (%m)\n", ret);
+
+	free(update);
+
+	return ret;
+}
+
+int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie,
+		       uint64_t type, uint64_t id)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_id_change chg;
+		} item;
+	} buf;
+	int ret;
+
+	memset(&buf, 0, sizeof(buf));
+
+	buf.cmd.size = sizeof(buf);
+	buf.cmd.cookie = cookie;
+	buf.item.size = sizeof(buf.item);
+	buf.item.type = type;
+	buf.item.chg.id = id;
+
+	ret = kdbus_cmd_match_add(conn->fd, &buf.cmd);
+	if (ret < 0)
+		kdbus_printf("--- error adding conn match: %d (%m)\n", ret);
+
+	return ret;
+}
+
+int kdbus_add_match_empty(struct kdbus_conn *conn)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct kdbus_item item;
+	} buf;
+	int ret;
+
+	memset(&buf, 0, sizeof(buf));
+
+	buf.item.size = sizeof(uint64_t) * 3;
+	buf.item.type = KDBUS_ITEM_ID;
+	buf.item.id = KDBUS_MATCH_ID_ANY;
+
+	buf.cmd.size = sizeof(buf.cmd) + buf.item.size;
+
+	ret = kdbus_cmd_match_add(conn->fd, &buf.cmd);
+	if (ret < 0)
+		kdbus_printf("--- error adding conn match: %d (%m)\n", ret);
+
+	return ret;
+}
+
+static int all_ids_are_mapped(const char *path)
+{
+	int ret;
+	FILE *file;
+	uint32_t inside_id, length;
+
+	file = fopen(path, "r");
+	if (!file) {
+		ret = -errno;
+		kdbus_printf("error fopen() %s: %d (%m)\n",
+			     path, ret);
+		return ret;
+	}
+
+	ret = fscanf(file, "%u\t%*u\t%u", &inside_id, &length);
+	if (ret != 2) {
+		if (ferror(file))
+			ret = -errno;
+		else
+			ret = -EIO;
+
+		kdbus_printf("--- error fscanf(): %d\n", ret);
+		fclose(file);
+		return ret;
+	}
+
+	fclose(file);
+
+	/*
+	 * If length is 4294967295 which means the invalid uid
+	 * (uid_t) -1 then we are able to map all uid/gids
+	 */
+	if (inside_id == 0 && length == (uid_t) -1)
+		return 1;
+
+	return 0;
+}
+
+int all_uids_gids_are_mapped(void)
+{
+	int ret;
+
+	ret = all_ids_are_mapped("/proc/self/uid_map");
+	if (ret <= 0) {
+		kdbus_printf("--- error not all uids are mapped\n");
+		return 0;
+	}
+
+	ret = all_ids_are_mapped("/proc/self/gid_map");
+	if (ret <= 0) {
+		kdbus_printf("--- error not all gids are mapped\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+int drop_privileges(uid_t uid, gid_t gid)
+{
+	int ret;
+
+	ret = setgroups(0, NULL);
+	if (ret < 0) {
+		ret = -errno;
+		kdbus_printf("error setgroups: %d (%m)\n", ret);
+		return ret;
+	}
+
+	ret = setresgid(gid, gid, gid);
+	if (ret < 0) {
+		ret = -errno;
+		kdbus_printf("error setresgid: %d (%m)\n", ret);
+		return ret;
+	}
+
+	ret = setresuid(uid, uid, uid);
+	if (ret < 0) {
+		ret = -errno;
+		kdbus_printf("error setresuid: %d (%m)\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+uint64_t now(clockid_t clock)
+{
+	struct timespec spec;
+
+	clock_gettime(clock, &spec);
+	return spec.tv_sec * 1000ULL * 1000ULL * 1000ULL + spec.tv_nsec;
+}
+
+char *unique_name(const char *prefix)
+{
+	unsigned int i;
+	uint64_t u_now;
+	char n[17];
+	char *str;
+	int r;
+
+	/*
+	 * This returns a random string which is guaranteed to be
+	 * globally unique across all calls to unique_name(). We
+	 * compose the string as:
+	 *   <prefix>-<random>-<time>
+	 * With:
+	 *   <prefix>: string provided by the caller
+	 *   <random>: a random alpha string of 16 characters
+	 *   <time>: the current time in micro-seconds since last boot
+	 *
+	 * The <random> part makes the string always look vastly different,
+	 * the <time> part makes sure no two calls return the same string.
+	 */
+
+	u_now = now(CLOCK_MONOTONIC);
+
+	for (i = 0; i < sizeof(n) - 1; ++i)
+		n[i] = 'a' + (rand() % ('z' - 'a'));
+	n[sizeof(n) - 1] = 0;
+
+	r = asprintf(&str, "%s-%s-%" PRIu64, prefix, n, u_now);
+	if (r < 0)
+		return NULL;
+
+	return str;
+}
+
+static int do_userns_map_id(pid_t pid,
+			    const char *map_file,
+			    const char *map_id)
+{
+	int ret;
+	int fd;
+	char *map;
+	unsigned int i;
+
+	map = strndupa(map_id, strlen(map_id));
+	if (!map) {
+		ret = -errno;
+		kdbus_printf("error strndupa %s: %d (%m)\n",
+			map_file, ret);
+		return ret;
+	}
+
+	for (i = 0; i < strlen(map); i++)
+		if (map[i] == ',')
+			map[i] = '\n';
+
+	fd = open(map_file, O_RDWR);
+	if (fd < 0) {
+		ret = -errno;
+		kdbus_printf("error open %s: %d (%m)\n",
+			map_file, ret);
+		return ret;
+	}
+
+	ret = write(fd, map, strlen(map));
+	if (ret < 0) {
+		ret = -errno;
+		kdbus_printf("error write to %s: %d (%m)\n",
+			     map_file, ret);
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	close(fd);
+	return ret;
+}
+
+int userns_map_uid_gid(pid_t pid,
+		       const char *map_uid,
+		       const char *map_gid)
+{
+	int fd, ret;
+	char file_id[128] = {'\0'};
+
+	snprintf(file_id, sizeof(file_id), "/proc/%ld/uid_map",
+		 (long) pid);
+
+	ret = do_userns_map_id(pid, file_id, map_uid);
+	if (ret < 0)
+		return ret;
+
+	snprintf(file_id, sizeof(file_id), "/proc/%ld/setgroups",
+		 (long) pid);
+
+	fd = open(file_id, O_WRONLY);
+	if (fd >= 0) {
+		write(fd, "deny\n", 5);
+		close(fd);
+	}
+
+	snprintf(file_id, sizeof(file_id), "/proc/%ld/gid_map",
+		 (long) pid);
+
+	return do_userns_map_id(pid, file_id, map_gid);
+}
+
+static int do_cap_get_flag(cap_t caps, cap_value_t cap)
+{
+	int ret;
+	cap_flag_value_t flag_set;
+
+	ret = cap_get_flag(caps, cap, CAP_EFFECTIVE, &flag_set);
+	if (ret < 0) {
+		ret = -errno;
+		kdbus_printf("error cap_get_flag(): %d (%m)\n", ret);
+		return ret;
+	}
+
+	return (flag_set == CAP_SET);
+}
+
+/*
+ * Returns:
+ *  1 in case all the requested effective capabilities are set.
+ *  0 in case we do not have the requested capabilities. This value
+ *    will be used to abort tests with TEST_SKIP
+ *  Negative errno on failure.
+ *
+ *  Terminate args with a negative value.
+ */
+int test_is_capable(int cap, ...)
+{
+	int ret;
+	va_list ap;
+	cap_t caps;
+
+	caps = cap_get_proc();
+	if (!caps) {
+		ret = -errno;
+		kdbus_printf("error cap_get_proc(): %d (%m)\n", ret);
+		return ret;
+	}
+
+	ret = do_cap_get_flag(caps, (cap_value_t)cap);
+	if (ret <= 0)
+		goto out;
+
+	va_start(ap, cap);
+	while ((cap = va_arg(ap, int)) > 0) {
+		ret = do_cap_get_flag(caps, (cap_value_t)cap);
+		if (ret <= 0)
+			break;
+	}
+	va_end(ap);
+
+out:
+	cap_free(caps);
+	return ret;
+}
+
+int config_user_ns_is_enabled(void)
+{
+	return (access("/proc/self/uid_map", F_OK) == 0);
+}
+
+int config_auditsyscall_is_enabled(void)
+{
+	return (access("/proc/self/loginuid", F_OK) == 0);
+}
+
+int config_cgroups_is_enabled(void)
+{
+	return (access("/proc/self/cgroup", F_OK) == 0);
+}
+
+int config_security_is_enabled(void)
+{
+	int fd;
+	int ret;
+	char buf[128];
+
+	/* CONFIG_SECURITY is disabled */
+	if (access("/proc/self/attr/current", F_OK) != 0)
+		return 0;
+
+	/*
+	 * Now only if read() fails with -EINVAL then we assume
+	 * that SECLABEL and LSM are disabled
+	 */
+	fd = open("/proc/self/attr/current", O_RDONLY|O_CLOEXEC);
+	if (fd < 0)
+		return 1;
+
+	ret = read(fd, buf, sizeof(buf));
+	if (ret == -1 && errno == EINVAL)
+		ret = 0;
+	else
+		ret = 1;
+
+	close(fd);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/kdbus/kdbus-util.h b/tools/testing/selftests/kdbus/kdbus-util.h
new file mode 100644
index 000000000000..e1e18b92f425
--- /dev/null
+++ b/tools/testing/selftests/kdbus/kdbus-util.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Daniel Mack
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#pragma once
+
+#define BIT(X) (1 << (X))
+
+#include <time.h>
+#include <stdbool.h>
+#include <linux/kdbus.h>
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(x) _STRINGIFY(x)
+#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
+
+#define KDBUS_PTR(addr) ((void *)(uintptr_t)(addr))
+
+#define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
+#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
+#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
+
+#define KDBUS_ITEM_NEXT(item) \
+	(typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
+#define KDBUS_ITEM_FOREACH(item, head, first)				\
+	for ((item) = (head)->first;					\
+	     ((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) &&	\
+	       ((uint8_t *)(item) >= (uint8_t *)(head));		\
+	     (item) = KDBUS_ITEM_NEXT(item))
+#define KDBUS_FOREACH(iter, first, _size)				\
+	for ((iter) = (first);						\
+	     ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) &&	\
+	       ((uint8_t *)(iter) >= (uint8_t *)(first));		\
+	     (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
+
+#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL))
+
+/* Sum of KDBUS_ITEM_* that reflects _KDBUS_ATTACH_ALL */
+#define KDBUS_ATTACH_ITEMS_TYPE_SUM					\
+	((((_KDBUS_ATTACH_BITS_SET_NR - 1) *				\
+	((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2) +			\
+	(_KDBUS_ITEM_ATTACH_BASE * _KDBUS_ATTACH_BITS_SET_NR))
+
+#define POOL_SIZE (16 * 1024LU * 1024LU)
+
+#define UNPRIV_UID 65534
+#define UNPRIV_GID 65534
+
+/* Dump as user of process, useful for user namespace testing */
+#define SUID_DUMP_USER	1
+
+extern int kdbus_util_verbose;
+
+#define kdbus_printf(X...) \
+	if (kdbus_util_verbose) \
+		printf(X)
+
+#define RUN_UNPRIVILEGED(child_uid, child_gid, _child_, _parent_) ({	\
+		pid_t pid, rpid;					\
+		int ret;						\
+									\
+		pid = fork();						\
+		if (pid == 0) {						\
+			ret = drop_privileges(child_uid, child_gid);	\
+			ASSERT_EXIT_VAL(ret == 0, ret);			\
+									\
+			_child_;					\
+			_exit(0);					\
+		} else if (pid > 0) {					\
+			_parent_;					\
+			rpid = waitpid(pid, &ret, 0);			\
+			ASSERT_RETURN(rpid == pid);			\
+			ASSERT_RETURN(WIFEXITED(ret));			\
+			ASSERT_RETURN(WEXITSTATUS(ret) == 0);		\
+			ret = TEST_OK;					\
+		} else {						\
+			ret = pid;					\
+		}							\
+									\
+		ret;							\
+	})
+
+#define RUN_UNPRIVILEGED_CONN(_var_, _bus_, _code_)			\
+	RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({			\
+		struct kdbus_conn *_var_;				\
+		_var_ = kdbus_hello(_bus_, 0, NULL, 0);			\
+		ASSERT_EXIT(_var_);					\
+		_code_;							\
+		kdbus_conn_free(_var_);					\
+	}), ({ 0; }))
+
+#define RUN_CLONE_CHILD(clone_ret, flags, _setup_, _child_body_,	\
+			_parent_setup_, _parent_body_) ({		\
+	pid_t pid, rpid;						\
+	int ret;							\
+	int efd = -1;							\
+									\
+	_setup_;							\
+	efd = eventfd(0, EFD_CLOEXEC);					\
+	ASSERT_RETURN(efd >= 0);					\
+	*(clone_ret) = 0;						\
+	pid = syscall(__NR_clone, flags, NULL);				\
+	if (pid == 0) {							\
+		eventfd_t event_status = 0;				\
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);			\
+		ASSERT_EXIT(ret == 0);					\
+		ret = eventfd_read(efd, &event_status);			\
+		if (ret < 0 || event_status != 1) {			\
+			kdbus_printf("error eventfd_read()\n");		\
+			_exit(EXIT_FAILURE);				\
+		}							\
+		_child_body_;						\
+		_exit(0);						\
+	} else if (pid > 0) {						\
+		_parent_setup_;						\
+		ret = eventfd_write(efd, 1);				\
+		ASSERT_RETURN(ret >= 0);				\
+		_parent_body_;						\
+		rpid = waitpid(pid, &ret, 0);				\
+		ASSERT_RETURN(rpid == pid);				\
+		ASSERT_RETURN(WIFEXITED(ret));				\
+		ASSERT_RETURN(WEXITSTATUS(ret) == 0);			\
+		ret = TEST_OK;						\
+	} else {							\
+		ret = -errno;						\
+		*(clone_ret) = -errno;					\
+	}								\
+	close(efd);							\
+	ret;								\
+})
+
+/* Enums for parent if it should drop privs or not */
+enum kdbus_drop_parent {
+	DO_NOT_DROP,
+	DROP_SAME_UNPRIV,
+	DROP_OTHER_UNPRIV,
+};
+
+struct kdbus_conn {
+	int fd;
+	uint64_t id;
+	unsigned char *buf;
+};
+
+int kdbus_sysfs_get_parameter_mask(const char *path, uint64_t *mask);
+int kdbus_sysfs_set_parameter_mask(const char *path, uint64_t mask);
+
+int sys_memfd_create(const char *name, __u64 size);
+int sys_memfd_seal_set(int fd);
+off_t sys_memfd_get_size(int fd, off_t *size);
+
+int kdbus_list(struct kdbus_conn *conn, uint64_t flags);
+int kdbus_name_release(struct kdbus_conn *conn, const char *name);
+int kdbus_name_acquire(struct kdbus_conn *conn, const char *name,
+		       uint64_t *flags);
+void kdbus_msg_free(struct kdbus_msg *msg);
+int kdbus_msg_recv(struct kdbus_conn *conn,
+		   struct kdbus_msg **msg, uint64_t *offset);
+int kdbus_msg_recv_poll(struct kdbus_conn *conn, int timeout_ms,
+			struct kdbus_msg **msg_out, uint64_t *offset);
+int kdbus_free(const struct kdbus_conn *conn, uint64_t offset);
+int kdbus_msg_dump(const struct kdbus_conn *conn,
+		   const struct kdbus_msg *msg);
+int kdbus_create_bus(int control_fd, const char *name,
+		     uint64_t owner_meta, char **path);
+int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
+		   uint64_t cookie, uint64_t flags, uint64_t timeout,
+		   int64_t priority, uint64_t dst_id);
+int kdbus_msg_send_sync(const struct kdbus_conn *conn, const char *name,
+			uint64_t cookie, uint64_t flags, uint64_t timeout,
+			int64_t priority, uint64_t dst_id, int cancel_fd);
+int kdbus_msg_send_reply(const struct kdbus_conn *conn,
+			 uint64_t reply_cookie,
+			 uint64_t dst_id);
+struct kdbus_conn *kdbus_hello(const char *path, uint64_t hello_flags,
+			       const struct kdbus_item *item,
+			       size_t item_size);
+struct kdbus_conn *kdbus_hello_registrar(const char *path, const char *name,
+					 const struct kdbus_policy_access *access,
+					 size_t num_access, uint64_t flags);
+struct kdbus_conn *kdbus_hello_activator(const char *path, const char *name,
+					 const struct kdbus_policy_access *access,
+					 size_t num_access);
+bool kdbus_item_in_message(struct kdbus_msg *msg, uint64_t type);
+int kdbus_bus_creator_info(struct kdbus_conn *conn,
+			   uint64_t flags,
+			   uint64_t *offset);
+int kdbus_conn_info(struct kdbus_conn *conn, uint64_t id,
+		    const char *name, uint64_t flags, uint64_t *offset);
+void kdbus_conn_free(struct kdbus_conn *conn);
+int kdbus_conn_update_attach_flags(struct kdbus_conn *conn,
+				   uint64_t attach_flags_send,
+				   uint64_t attach_flags_recv);
+int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name,
+			     const struct kdbus_policy_access *access,
+			     size_t num_access);
+
+int kdbus_add_match_id(struct kdbus_conn *conn, uint64_t cookie,
+		       uint64_t type, uint64_t id);
+int kdbus_add_match_empty(struct kdbus_conn *conn);
+
+int all_uids_gids_are_mapped(void);
+int drop_privileges(uid_t uid, gid_t gid);
+uint64_t now(clockid_t clock);
+char *unique_name(const char *prefix);
+
+int userns_map_uid_gid(pid_t pid, const char *map_uid, const char *map_gid);
+int test_is_capable(int cap, ...);
+int config_user_ns_is_enabled(void);
+int config_auditsyscall_is_enabled(void);
+int config_cgroups_is_enabled(void);
+int config_security_is_enabled(void);
diff --git a/tools/testing/selftests/kdbus/test-activator.c b/tools/testing/selftests/kdbus/test-activator.c
new file mode 100644
index 000000000000..3d1b76370ce8
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-activator.c
@@ -0,0 +1,318 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <sys/capability.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+static int kdbus_starter_poll(struct kdbus_conn *conn)
+{
+	int ret;
+	struct pollfd fd;
+
+	fd.fd = conn->fd;
+	fd.events = POLLIN | POLLPRI | POLLHUP;
+	fd.revents = 0;
+
+	ret = poll(&fd, 1, 100);
+	if (ret == 0)
+		return -ETIMEDOUT;
+	else if (ret > 0) {
+		if (fd.revents & POLLIN)
+			return 0;
+
+		if (fd.revents & (POLLHUP | POLLERR))
+			ret = -ECONNRESET;
+	}
+
+	return ret;
+}
+
+/* Ensure that kdbus activator logic is safe */
+static int kdbus_priv_activator(struct kdbus_test_env *env)
+{
+	int ret;
+	struct kdbus_msg *msg = NULL;
+	uint64_t cookie = 0xdeadbeef;
+	uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
+	struct kdbus_conn *activator;
+	struct kdbus_conn *service;
+	struct kdbus_conn *client;
+	struct kdbus_conn *holder;
+	struct kdbus_policy_access *access;
+
+	access = (struct kdbus_policy_access[]){
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = getuid(),
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = getuid(),
+			.access = KDBUS_POLICY_TALK,
+		},
+	};
+
+	activator = kdbus_hello_activator(env->buspath, "foo.priv.activator",
+					  access, 2);
+	ASSERT_RETURN(activator);
+
+	service = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(service);
+
+	client = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(client);
+
+	/*
+	 * Make sure that other users can't TALK to the activator
+	 */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		/* Try to talk using the ID */
+		ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef, 0, 0,
+				     0, activator->id);
+		ASSERT_EXIT(ret == -ENXIO);
+
+		/* Try to talk to the name */
+		ret = kdbus_msg_send(unpriv, "foo.priv.activator",
+				     0xdeadbeef, 0, 0, 0,
+				     KDBUS_DST_ID_NAME);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure that we did not receive anything, so the
+	 * service will not be started automatically
+	 */
+
+	ret = kdbus_starter_poll(activator);
+	ASSERT_RETURN(ret == -ETIMEDOUT);
+
+	/*
+	 * Now try to emulate the starter/service logic and
+	 * acquire the name.
+	 */
+
+	cookie++;
+	ret = kdbus_msg_send(service, "foo.priv.activator", cookie,
+			     0, 0, 0, KDBUS_DST_ID_NAME);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_starter_poll(activator);
+	ASSERT_RETURN(ret == 0);
+
+	/* Policies are still checked, access denied */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "foo.priv.activator",
+					 &flags);
+		ASSERT_RETURN(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_name_acquire(service, "foo.priv.activator",
+				 &flags);
+	ASSERT_RETURN(ret == 0);
+
+	/* We read our previous starter message */
+
+	ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* Try to talk, we still fail */
+
+	cookie++;
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		/* Try to talk to the name */
+		ret = kdbus_msg_send(unpriv, "foo.priv.activator",
+				     cookie, 0, 0, 0,
+				     KDBUS_DST_ID_NAME);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/* Still nothing to read */
+
+	ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
+	ASSERT_RETURN(ret == -ETIMEDOUT);
+
+	/* We receive every thing now */
+
+	cookie++;
+	ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
+			     0, 0, 0, KDBUS_DST_ID_NAME);
+	ASSERT_RETURN(ret == 0);
+	ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	/* Policies default to deny TALK now */
+	kdbus_conn_free(activator);
+
+	cookie++;
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		/* Try to talk to the name */
+		ret = kdbus_msg_send(unpriv, "foo.priv.activator",
+				     cookie, 0, 0, 0,
+				     KDBUS_DST_ID_NAME);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
+	ASSERT_RETURN(ret == -ETIMEDOUT);
+
+	/* Same user is able to TALK */
+	cookie++;
+	ret = kdbus_msg_send(client, "foo.priv.activator", cookie,
+			     0, 0, 0, KDBUS_DST_ID_NAME);
+	ASSERT_RETURN(ret == 0);
+	ret = kdbus_msg_recv_poll(service, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	access = (struct kdbus_policy_access []){
+		{
+			.type = KDBUS_POLICY_ACCESS_WORLD,
+			.id = getuid(),
+			.access = KDBUS_POLICY_TALK,
+		},
+	};
+
+	holder = kdbus_hello_registrar(env->buspath, "foo.priv.activator",
+				       access, 1, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(holder);
+
+	/* Now we are able to TALK to the name */
+
+	cookie++;
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		/* Try to talk to the name */
+		ret = kdbus_msg_send(unpriv, "foo.priv.activator",
+				     cookie, 0, 0, 0,
+				     KDBUS_DST_ID_NAME);
+		ASSERT_EXIT(ret == 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(service, 100, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "foo.priv.activator",
+					 &flags);
+		ASSERT_RETURN(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	kdbus_conn_free(service);
+	kdbus_conn_free(client);
+	kdbus_conn_free(holder);
+
+	return 0;
+}
+
+int kdbus_test_activator(struct kdbus_test_env *env)
+{
+	int ret;
+	struct kdbus_conn *activator;
+	struct pollfd fds[2];
+	bool activator_done = false;
+	struct kdbus_policy_access access[2];
+
+	access[0].type = KDBUS_POLICY_ACCESS_USER;
+	access[0].id = getuid();
+	access[0].access = KDBUS_POLICY_OWN;
+
+	access[1].type = KDBUS_POLICY_ACCESS_WORLD;
+	access[1].access = KDBUS_POLICY_TALK;
+
+	activator = kdbus_hello_activator(env->buspath, "foo.test.activator",
+					  access, 2);
+	ASSERT_RETURN(activator);
+
+	ret = kdbus_add_match_empty(env->conn);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_list(env->conn, KDBUS_LIST_NAMES |
+				    KDBUS_LIST_UNIQUE |
+				    KDBUS_LIST_ACTIVATORS |
+				    KDBUS_LIST_QUEUED);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_send(env->conn, "foo.test.activator", 0xdeafbeef,
+			     0, 0, 0, KDBUS_DST_ID_NAME);
+	ASSERT_RETURN(ret == 0);
+
+	fds[0].fd = activator->fd;
+	fds[1].fd = env->conn->fd;
+
+	kdbus_printf("-- entering poll loop ...\n");
+
+	for (;;) {
+		int i, nfds = sizeof(fds) / sizeof(fds[0]);
+
+		for (i = 0; i < nfds; i++) {
+			fds[i].events = POLLIN | POLLPRI;
+			fds[i].revents = 0;
+		}
+
+		ret = poll(fds, nfds, 3000);
+		ASSERT_RETURN(ret >= 0);
+
+		ret = kdbus_list(env->conn, KDBUS_LIST_NAMES);
+		ASSERT_RETURN(ret == 0);
+
+		if ((fds[0].revents & POLLIN) && !activator_done) {
+			uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
+
+			kdbus_printf("Starter was called back!\n");
+
+			ret = kdbus_name_acquire(env->conn,
+						 "foo.test.activator", &flags);
+			ASSERT_RETURN(ret == 0);
+
+			activator_done = true;
+		}
+
+		if (fds[1].revents & POLLIN) {
+			kdbus_msg_recv(env->conn, NULL, NULL);
+			break;
+		}
+	}
+
+	/* Check if all uids/gids are mapped */
+	if (!all_uids_gids_are_mapped())
+		return TEST_SKIP;
+
+	/* Check now capabilities, so we run the previous tests */
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	if (!ret)
+		return TEST_SKIP;
+
+	ret = kdbus_priv_activator(env);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_conn_free(activator);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-benchmark.c b/tools/testing/selftests/kdbus/test-benchmark.c
new file mode 100644
index 000000000000..8a9744b00508
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-benchmark.c
@@ -0,0 +1,451 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <math.h>
+
+#include "kdbus-api.h"
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+#define SERVICE_NAME "foo.bar.echo"
+
+/*
+ * To have a banchmark comparison with unix socket, set:
+ * user_memfd	= false;
+ * compare_uds	= true;
+ * attach_none	= true;		do not attached metadata
+ */
+
+static bool use_memfd = true;		/* transmit memfd? */
+static bool compare_uds = false;		/* unix-socket comparison? */
+static bool attach_none = false;		/* clear attach-flags? */
+static char stress_payload[8192];
+
+struct stats {
+	uint64_t count;
+	uint64_t latency_acc;
+	uint64_t latency_low;
+	uint64_t latency_high;
+	uint64_t latency_avg;
+	uint64_t latency_ssquares;
+};
+
+static struct stats stats;
+
+static void reset_stats(void)
+{
+	stats.count = 0;
+	stats.latency_acc = 0;
+	stats.latency_low = UINT64_MAX;
+	stats.latency_high = 0;
+	stats.latency_avg = 0;
+	stats.latency_ssquares = 0;
+}
+
+static void dump_stats(bool is_uds)
+{
+	if (stats.count > 0) {
+		kdbus_printf("stats %s: %'llu packets processed, latency (nsecs) min/max/avg/dev %'7llu // %'7llu // %'7llu // %'7.f\n",
+			     is_uds ? " (UNIX)" : "(KDBUS)",
+			     (unsigned long long) stats.count,
+			     (unsigned long long) stats.latency_low,
+			     (unsigned long long) stats.latency_high,
+			     (unsigned long long) stats.latency_avg,
+			     sqrt(stats.latency_ssquares / stats.count));
+	} else {
+		kdbus_printf("*** no packets received. bus stuck?\n");
+	}
+}
+
+static void add_stats(uint64_t prev)
+{
+	uint64_t diff, latency_avg_prev;
+
+	diff = now(CLOCK_THREAD_CPUTIME_ID) - prev;
+
+	stats.count++;
+	stats.latency_acc += diff;
+
+	/* see Welford62 */
+	latency_avg_prev = stats.latency_avg;
+	stats.latency_avg = stats.latency_acc / stats.count;
+	stats.latency_ssquares += (diff - latency_avg_prev) * (diff - stats.latency_avg);
+
+	if (stats.latency_low > diff)
+		stats.latency_low = diff;
+
+	if (stats.latency_high < diff)
+		stats.latency_high = diff;
+}
+
+static int setup_simple_kdbus_msg(struct kdbus_conn *conn,
+				  uint64_t dst_id,
+				  struct kdbus_msg **msg_out)
+{
+	struct kdbus_msg *msg;
+	struct kdbus_item *item;
+	uint64_t size;
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	msg = malloc(size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = conn->id;
+	msg->dst_id = dst_id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	item = msg->items;
+
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t) stress_payload;
+	item->vec.size = sizeof(stress_payload);
+	item = KDBUS_ITEM_NEXT(item);
+
+	*msg_out = msg;
+
+	return 0;
+}
+
+static int setup_memfd_kdbus_msg(struct kdbus_conn *conn,
+				 uint64_t dst_id,
+				 off_t *memfd_item_offset,
+				 struct kdbus_msg **msg_out)
+{
+	struct kdbus_msg *msg;
+	struct kdbus_item *item;
+	uint64_t size;
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
+
+	msg = malloc(size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = conn->id;
+	msg->dst_id = dst_id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	item = msg->items;
+
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t) stress_payload;
+	item->vec.size = sizeof(stress_payload);
+	item = KDBUS_ITEM_NEXT(item);
+
+	item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
+	item->memfd.size = sizeof(uint64_t);
+
+	*memfd_item_offset = (unsigned char *)item - (unsigned char *)msg;
+	*msg_out = msg;
+
+	return 0;
+}
+
+static int
+send_echo_request(struct kdbus_conn *conn, uint64_t dst_id,
+		  void *kdbus_msg, off_t memfd_item_offset)
+{
+	struct kdbus_cmd_send cmd = {};
+	int memfd = -1;
+	int ret;
+
+	if (use_memfd) {
+		uint64_t now_ns = now(CLOCK_THREAD_CPUTIME_ID);
+		struct kdbus_item *item = memfd_item_offset + kdbus_msg;
+		memfd = sys_memfd_create("memfd-name", 0);
+		ASSERT_RETURN_VAL(memfd >= 0, memfd);
+
+		ret = write(memfd, &now_ns, sizeof(now_ns));
+		ASSERT_RETURN_VAL(ret == sizeof(now_ns), -EAGAIN);
+
+		ret = sys_memfd_seal_set(memfd);
+		ASSERT_RETURN_VAL(ret == 0, -errno);
+
+		item->memfd.fd = memfd;
+	}
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)kdbus_msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	close(memfd);
+
+	return 0;
+}
+
+static int
+handle_echo_reply(struct kdbus_conn *conn, uint64_t send_ns)
+{
+	int ret;
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+	struct kdbus_msg *msg;
+	const struct kdbus_item *item;
+	bool has_memfd = false;
+
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	if (ret == -EAGAIN)
+		return ret;
+
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	if (!use_memfd)
+		goto out;
+
+	msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
+
+	KDBUS_ITEM_FOREACH(item, msg, items) {
+		switch (item->type) {
+		case KDBUS_ITEM_PAYLOAD_MEMFD: {
+			char *buf;
+
+			buf = mmap(NULL, item->memfd.size, PROT_READ,
+				   MAP_PRIVATE, item->memfd.fd, 0);
+			ASSERT_RETURN_VAL(buf != MAP_FAILED, -EINVAL);
+			ASSERT_RETURN_VAL(item->memfd.size == sizeof(uint64_t),
+					  -EINVAL);
+
+			add_stats(*(uint64_t*)buf);
+			munmap(buf, item->memfd.size);
+			close(item->memfd.fd);
+			has_memfd = true;
+			break;
+		}
+
+		case KDBUS_ITEM_PAYLOAD_OFF:
+			/* ignore */
+			break;
+		}
+	}
+
+out:
+	if (!has_memfd)
+		add_stats(send_ns);
+
+	ret = kdbus_free(conn, recv.msg.offset);
+	ASSERT_RETURN_VAL(ret == 0, -errno);
+
+	return 0;
+}
+
+static int benchmark(struct kdbus_test_env *env)
+{
+	static char buf[sizeof(stress_payload)];
+	struct kdbus_msg *kdbus_msg = NULL;
+	off_t memfd_cached_offset = 0;
+	int ret;
+	struct kdbus_conn *conn_a, *conn_b;
+	struct pollfd fds[2];
+	uint64_t start, send_ns, now_ns, diff;
+	unsigned int i;
+	int uds[2];
+
+	setlocale(LC_ALL, "");
+
+	for (i = 0; i < sizeof(stress_payload); i++)
+		stress_payload[i] = i;
+
+	/* setup kdbus pair */
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	ret = kdbus_add_match_empty(conn_a);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_empty(conn_b);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(conn_a, SERVICE_NAME, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	if (attach_none) {
+		ret = kdbus_conn_update_attach_flags(conn_a,
+						     _KDBUS_ATTACH_ALL,
+						     0);
+		ASSERT_RETURN(ret == 0);
+	}
+
+	/* setup UDS pair */
+
+	ret = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, uds);
+	ASSERT_RETURN(ret == 0);
+
+	/* setup a kdbus msg now */
+	if (use_memfd) {
+		ret = setup_memfd_kdbus_msg(conn_b, conn_a->id,
+					    &memfd_cached_offset,
+					    &kdbus_msg);
+		ASSERT_RETURN(ret == 0);
+	} else {
+		ret = setup_simple_kdbus_msg(conn_b, conn_a->id, &kdbus_msg);
+		ASSERT_RETURN(ret == 0);
+	}
+
+	/* start benchmark */
+
+	kdbus_printf("-- entering poll loop ...\n");
+
+	do {
+		/* run kdbus benchmark */
+		fds[0].fd = conn_a->fd;
+		fds[1].fd = conn_b->fd;
+
+		/* cancel any pending message */
+		handle_echo_reply(conn_a, 0);
+
+		start = now(CLOCK_THREAD_CPUTIME_ID);
+		reset_stats();
+
+		send_ns = now(CLOCK_THREAD_CPUTIME_ID);
+		ret = send_echo_request(conn_b, conn_a->id,
+					kdbus_msg, memfd_cached_offset);
+		ASSERT_RETURN(ret == 0);
+
+		while (1) {
+			unsigned int nfds = sizeof(fds) / sizeof(fds[0]);
+			unsigned int i;
+
+			for (i = 0; i < nfds; i++) {
+				fds[i].events = POLLIN | POLLPRI | POLLHUP;
+				fds[i].revents = 0;
+			}
+
+			ret = poll(fds, nfds, 10);
+			if (ret < 0)
+				break;
+
+			if (fds[0].revents & POLLIN) {
+				ret = handle_echo_reply(conn_a, send_ns);
+				ASSERT_RETURN(ret == 0);
+
+				send_ns = now(CLOCK_THREAD_CPUTIME_ID);
+				ret = send_echo_request(conn_b, conn_a->id,
+							kdbus_msg,
+							memfd_cached_offset);
+				ASSERT_RETURN(ret == 0);
+			}
+
+			now_ns = now(CLOCK_THREAD_CPUTIME_ID);
+			diff = now_ns - start;
+			if (diff > 1000000000ULL) {
+				start = now_ns;
+
+				dump_stats(false);
+				break;
+			}
+		}
+
+		if (!compare_uds)
+			continue;
+
+		/* run unix-socket benchmark as comparison */
+
+		fds[0].fd = uds[0];
+		fds[1].fd = uds[1];
+
+		/* cancel any pendign message */
+		read(uds[1], buf, sizeof(buf));
+
+		start = now(CLOCK_THREAD_CPUTIME_ID);
+		reset_stats();
+
+		send_ns = now(CLOCK_THREAD_CPUTIME_ID);
+		ret = write(uds[0], stress_payload, sizeof(stress_payload));
+		ASSERT_RETURN(ret == sizeof(stress_payload));
+
+		while (1) {
+			unsigned int nfds = sizeof(fds) / sizeof(fds[0]);
+			unsigned int i;
+
+			for (i = 0; i < nfds; i++) {
+				fds[i].events = POLLIN | POLLPRI | POLLHUP;
+				fds[i].revents = 0;
+			}
+
+			ret = poll(fds, nfds, 10);
+			if (ret < 0)
+				break;
+
+			if (fds[1].revents & POLLIN) {
+				ret = read(uds[1], buf, sizeof(buf));
+				ASSERT_RETURN(ret == sizeof(buf));
+
+				add_stats(send_ns);
+
+				send_ns = now(CLOCK_THREAD_CPUTIME_ID);
+				ret = write(uds[0], buf, sizeof(buf));
+				ASSERT_RETURN(ret == sizeof(buf));
+			}
+
+			now_ns = now(CLOCK_THREAD_CPUTIME_ID);
+			diff = now_ns - start;
+			if (diff > 1000000000ULL) {
+				start = now_ns;
+
+				dump_stats(true);
+				break;
+			}
+		}
+
+	} while (kdbus_util_verbose);
+
+	kdbus_printf("-- closing bus connections\n");
+
+	free(kdbus_msg);
+
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	return (stats.count > 1) ? TEST_OK : TEST_ERR;
+}
+
+int kdbus_test_benchmark(struct kdbus_test_env *env)
+{
+	use_memfd = true;
+	attach_none = false;
+	compare_uds = false;
+	return benchmark(env);
+}
+
+int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env)
+{
+	use_memfd = false;
+	attach_none = false;
+	compare_uds = false;
+	return benchmark(env);
+}
+
+int kdbus_test_benchmark_uds(struct kdbus_test_env *env)
+{
+	use_memfd = false;
+	attach_none = true;
+	compare_uds = true;
+	return benchmark(env);
+}
diff --git a/tools/testing/selftests/kdbus/test-bus.c b/tools/testing/selftests/kdbus/test-bus.c
new file mode 100644
index 000000000000..762fb30397d4
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-bus.c
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+static struct kdbus_item *kdbus_get_item(struct kdbus_info *info,
+					 uint64_t type)
+{
+	struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, info, items)
+		if (item->type == type)
+			return item;
+
+	return NULL;
+}
+
+static int test_bus_creator_info(const char *bus_path)
+{
+	int ret;
+	uint64_t offset;
+	struct kdbus_conn *conn;
+	struct kdbus_info *info;
+	struct kdbus_item *item;
+	char *tmp, *busname;
+
+	/* extract the bus-name from @bus_path */
+	tmp = strdup(bus_path);
+	ASSERT_RETURN(tmp);
+	busname = strrchr(tmp, '/');
+	ASSERT_RETURN(busname);
+	*busname = 0;
+	busname = strrchr(tmp, '/');
+	ASSERT_RETURN(busname);
+	++busname;
+
+	conn = kdbus_hello(bus_path, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	ret = kdbus_bus_creator_info(conn, _KDBUS_ATTACH_ALL, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(conn->buf + offset);
+
+	item = kdbus_get_item(info, KDBUS_ITEM_MAKE_NAME);
+	ASSERT_RETURN(item);
+	ASSERT_RETURN(!strcmp(item->str, busname));
+
+	ret = kdbus_free(conn, offset);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	free(tmp);
+	kdbus_conn_free(conn);
+	return 0;
+}
+
+int kdbus_test_bus_make(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd cmd;
+
+		/* bloom size item */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_bloom_parameter bloom;
+		} bs;
+
+		/* name item */
+		uint64_t n_size;
+		uint64_t n_type;
+		char name[64];
+	} bus_make;
+	char s[PATH_MAX], *name;
+	int ret, control_fd2;
+	uid_t uid;
+
+	name = unique_name("");
+	ASSERT_RETURN(name);
+
+	snprintf(s, sizeof(s), "%s/control", env->root);
+	env->control_fd = open(s, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(env->control_fd >= 0);
+
+	control_fd2 = open(s, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(control_fd2 >= 0);
+
+	memset(&bus_make, 0, sizeof(bus_make));
+
+	bus_make.bs.size = sizeof(bus_make.bs);
+	bus_make.bs.type = KDBUS_ITEM_BLOOM_PARAMETER;
+	bus_make.bs.bloom.size = 64;
+	bus_make.bs.bloom.n_hash = 1;
+
+	bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
+
+	uid = getuid();
+
+	/* missing uid prefix */
+	snprintf(bus_make.name, sizeof(bus_make.name), "foo");
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* non alphanumeric character */
+	snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah@123", uid);
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* '-' at the end */
+	snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah-", uid);
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* create a new bus */
+	snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-1", uid, name);
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
+	ASSERT_RETURN(ret == -EEXIST);
+
+	snprintf(s, sizeof(s), "%s/%u-%s-1/bus", env->root, uid, name);
+	ASSERT_RETURN(access(s, F_OK) == 0);
+
+	ret = test_bus_creator_info(s);
+	ASSERT_RETURN(ret == 0);
+
+	/* can't use the same fd for bus make twice, even though a different
+	 * bus name is used
+	 */
+	snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+	ASSERT_RETURN(ret == -EBADFD);
+
+	/* create a new bus, with different fd and different bus name */
+	snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
+	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+	bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+			    sizeof(bus_make.bs) + bus_make.n_size;
+	ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	close(control_fd2);
+	free(name);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-chat.c b/tools/testing/selftests/kdbus/test-chat.c
new file mode 100644
index 000000000000..41e5b53fe0cc
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-chat.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <stdbool.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int kdbus_test_chat(struct kdbus_test_env *env)
+{
+	int ret, cookie;
+	struct kdbus_conn *conn_a, *conn_b;
+	struct pollfd fds[2];
+	uint64_t flags;
+	int count;
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	flags = KDBUS_NAME_ALLOW_REPLACEMENT;
+	ret = kdbus_name_acquire(conn_a, "foo.bar.test", &flags);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(conn_a, "foo.bar.baz", NULL);
+	ASSERT_RETURN(ret == 0);
+
+	flags = KDBUS_NAME_QUEUE;
+	ret = kdbus_name_acquire(conn_b, "foo.bar.baz", &flags);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(conn_a, "foo.bar.double", NULL);
+	ASSERT_RETURN(ret == 0);
+
+	flags = 0;
+	ret = kdbus_name_acquire(conn_a, "foo.bar.double", &flags);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(!(flags & KDBUS_NAME_ACQUIRED));
+
+	ret = kdbus_name_release(conn_a, "foo.bar.double");
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_release(conn_a, "foo.bar.double");
+	ASSERT_RETURN(ret == -ESRCH);
+
+	ret = kdbus_list(conn_b, KDBUS_LIST_UNIQUE |
+				 KDBUS_LIST_NAMES  |
+				 KDBUS_LIST_QUEUED |
+				 KDBUS_LIST_ACTIVATORS);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_empty(conn_a);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_empty(conn_b);
+	ASSERT_RETURN(ret == 0);
+
+	cookie = 0;
+	ret = kdbus_msg_send(conn_b, NULL, 0xc0000000 | cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	fds[0].fd = conn_a->fd;
+	fds[1].fd = conn_b->fd;
+
+	kdbus_printf("-- entering poll loop ...\n");
+
+	for (count = 0;; count++) {
+		int i, nfds = sizeof(fds) / sizeof(fds[0]);
+
+		for (i = 0; i < nfds; i++) {
+			fds[i].events = POLLIN | POLLPRI | POLLHUP;
+			fds[i].revents = 0;
+		}
+
+		ret = poll(fds, nfds, 3000);
+		ASSERT_RETURN(ret >= 0);
+
+		if (fds[0].revents & POLLIN) {
+			if (count > 2)
+				kdbus_name_release(conn_a, "foo.bar.baz");
+
+			ret = kdbus_msg_recv(conn_a, NULL, NULL);
+			ASSERT_RETURN(ret == 0);
+			ret = kdbus_msg_send(conn_a, NULL,
+					     0xc0000000 | cookie++,
+					     0, 0, 0, conn_b->id);
+			ASSERT_RETURN(ret == 0);
+		}
+
+		if (fds[1].revents & POLLIN) {
+			ret = kdbus_msg_recv(conn_b, NULL, NULL);
+			ASSERT_RETURN(ret == 0);
+			ret = kdbus_msg_send(conn_b, NULL,
+					     0xc0000000 | cookie++,
+					     0, 0, 0, conn_a->id);
+			ASSERT_RETURN(ret == 0);
+		}
+
+		ret = kdbus_list(conn_b, KDBUS_LIST_UNIQUE |
+					 KDBUS_LIST_NAMES  |
+					 KDBUS_LIST_QUEUED |
+					 KDBUS_LIST_ACTIVATORS);
+		ASSERT_RETURN(ret == 0);
+
+		if (count > 10)
+			break;
+	}
+
+	kdbus_printf("-- closing bus connections\n");
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-connection.c b/tools/testing/selftests/kdbus/test-connection.c
new file mode 100644
index 000000000000..4688ce8ec40b
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-connection.c
@@ -0,0 +1,597 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/capability.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+int kdbus_test_hello(struct kdbus_test_env *env)
+{
+	struct kdbus_cmd_free cmd_free = {};
+	struct kdbus_cmd_hello hello;
+	int fd, ret;
+
+	memset(&hello, 0, sizeof(hello));
+
+	fd = open(env->buspath, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(fd >= 0);
+
+	hello.flags = KDBUS_HELLO_ACCEPT_FD;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	hello.attach_flags_recv = _KDBUS_ATTACH_ALL;
+	hello.size = sizeof(struct kdbus_cmd_hello);
+	hello.pool_size = POOL_SIZE;
+
+	/* an unaligned hello must result in -EFAULT */
+	ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) ((char *) &hello + 1));
+	ASSERT_RETURN(ret == -EFAULT);
+
+	/* a size of 0 must return EMSGSIZE */
+	hello.size = 1;
+	hello.flags = KDBUS_HELLO_ACCEPT_FD;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	hello.size = sizeof(struct kdbus_cmd_hello);
+
+	/* check faulty flags */
+	hello.flags = 1ULL << 32;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* check for faulty pool sizes */
+	hello.pool_size = 0;
+	hello.flags = KDBUS_HELLO_ACCEPT_FD;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	hello.pool_size = 4097;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	hello.pool_size = POOL_SIZE;
+
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	hello.offset = (__u64)-1;
+
+	/* success test */
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == 0);
+
+	/* The kernel should have returned some items */
+	ASSERT_RETURN(hello.offset != (__u64)-1);
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = hello.offset;
+	ret = kdbus_cmd_free(fd, &cmd_free);
+	ASSERT_RETURN(ret >= 0);
+
+	close(fd);
+
+	fd = open(env->buspath, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(fd >= 0);
+
+	/* no ACTIVATOR flag without a name */
+	hello.flags = KDBUS_HELLO_ACTIVATOR;
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	close(fd);
+
+	return TEST_OK;
+}
+
+int kdbus_test_byebye(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	struct kdbus_cmd_recv cmd_recv = { .size = sizeof(cmd_recv) };
+	struct kdbus_cmd cmd_byebye = { .size = sizeof(cmd_byebye) };
+	int ret;
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	ret = kdbus_add_match_empty(conn);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_empty(env->conn);
+	ASSERT_RETURN(ret == 0);
+
+	/* send over 1st connection */
+	ret = kdbus_msg_send(env->conn, NULL, 0, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	/* say byebye on the 2nd, which must fail */
+	ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye);
+	ASSERT_RETURN(ret == -EBUSY);
+
+	/* receive the message */
+	ret = kdbus_cmd_recv(conn->fd, &cmd_recv);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_free(conn, cmd_recv.msg.offset);
+	ASSERT_RETURN(ret == 0);
+
+	/* and try again */
+	ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye);
+	ASSERT_RETURN(ret == 0);
+
+	/* a 2nd try should result in -ECONNRESET */
+	ret = kdbus_cmd_byebye(conn->fd, &cmd_byebye);
+	ASSERT_RETURN(ret == -ECONNRESET);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+/* Get only the first item */
+static struct kdbus_item *kdbus_get_item(struct kdbus_info *info,
+					 uint64_t type)
+{
+	struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, info, items)
+		if (item->type == type)
+			return item;
+
+	return NULL;
+}
+
+static unsigned int kdbus_count_item(struct kdbus_info *info,
+				     uint64_t type)
+{
+	unsigned int i = 0;
+	const struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, info, items)
+		if (item->type == type)
+			i++;
+
+	return i;
+}
+
+static int kdbus_fuzz_conn_info(struct kdbus_test_env *env, int capable)
+{
+	int ret;
+	unsigned int cnt = 0;
+	uint64_t offset = 0;
+	struct kdbus_info *info;
+	struct kdbus_conn *conn;
+	struct kdbus_conn *privileged;
+	const struct kdbus_item *item;
+	uint64_t valid_flags = KDBUS_ATTACH_NAMES |
+			       KDBUS_ATTACH_CREDS |
+			       KDBUS_ATTACH_PIDS |
+			       KDBUS_ATTACH_CONN_DESCRIPTION;
+
+	uint64_t invalid_flags = KDBUS_ATTACH_NAMES	|
+				 KDBUS_ATTACH_CREDS	|
+				 KDBUS_ATTACH_PIDS	|
+				 KDBUS_ATTACH_CAPS	|
+				 KDBUS_ATTACH_CGROUP	|
+				 KDBUS_ATTACH_CONN_DESCRIPTION;
+
+	struct kdbus_creds cached_creds;
+	uid_t ruid, euid, suid;
+	gid_t rgid, egid, sgid;
+
+	getresuid(&ruid, &euid, &suid);
+	getresgid(&rgid, &egid, &sgid);
+
+	cached_creds.uid = ruid;
+	cached_creds.euid = euid;
+	cached_creds.suid = suid;
+	cached_creds.fsuid = ruid;
+
+	cached_creds.gid = rgid;
+	cached_creds.egid = egid;
+	cached_creds.sgid = sgid;
+	cached_creds.fsgid = rgid;
+
+	struct kdbus_pids cached_pids = {
+		.pid	= getpid(),
+		.tid	= syscall(SYS_gettid),
+		.ppid	= getppid(),
+	};
+
+	ret = kdbus_conn_info(env->conn, env->conn->id, NULL,
+			      valid_flags, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(env->conn->buf + offset);
+	ASSERT_RETURN(info->id == env->conn->id);
+
+	/* We do not have any well-known name */
+	item = kdbus_get_item(info, KDBUS_ITEM_NAME);
+	ASSERT_RETURN(item == NULL);
+
+	item = kdbus_get_item(info, KDBUS_ITEM_CONN_DESCRIPTION);
+	if (valid_flags & KDBUS_ATTACH_CONN_DESCRIPTION) {
+		ASSERT_RETURN(item);
+	} else {
+		ASSERT_RETURN(item == NULL);
+	}
+
+	kdbus_free(env->conn, offset);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	privileged = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(privileged);
+
+	ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(conn->buf + offset);
+	ASSERT_RETURN(info->id == conn->id);
+
+	/* We do not have any well-known name */
+	item = kdbus_get_item(info, KDBUS_ITEM_NAME);
+	ASSERT_RETURN(item == NULL);
+
+	cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS);
+	if (valid_flags & KDBUS_ATTACH_CREDS) {
+		ASSERT_RETURN(cnt == 1);
+
+		item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
+		ASSERT_RETURN(item);
+
+		/* Compare received items with cached creds */
+		ASSERT_RETURN(memcmp(&item->creds, &cached_creds,
+				      sizeof(struct kdbus_creds)) == 0);
+	} else {
+		ASSERT_RETURN(cnt == 0);
+	}
+
+	item = kdbus_get_item(info, KDBUS_ITEM_PIDS);
+	if (valid_flags & KDBUS_ATTACH_PIDS) {
+		ASSERT_RETURN(item);
+
+		/* Compare item->pids with cached PIDs */
+		ASSERT_RETURN(item->pids.pid == cached_pids.pid &&
+			      item->pids.tid == cached_pids.tid &&
+			      item->pids.ppid == cached_pids.ppid);
+	} else {
+		ASSERT_RETURN(item == NULL);
+	}
+
+	/* We did not request KDBUS_ITEM_CAPS */
+	item = kdbus_get_item(info, KDBUS_ITEM_CAPS);
+	ASSERT_RETURN(item == NULL);
+
+	kdbus_free(conn, offset);
+
+	ret = kdbus_name_acquire(conn, "com.example.a", NULL);
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(conn->buf + offset);
+	ASSERT_RETURN(info->id == conn->id);
+
+	item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME);
+	if (valid_flags & KDBUS_ATTACH_NAMES) {
+		ASSERT_RETURN(item && !strcmp(item->name.name, "com.example.a"));
+	} else {
+		ASSERT_RETURN(item == NULL);
+	}
+
+	kdbus_free(conn, offset);
+
+	ret = kdbus_conn_info(conn, 0, "com.example.a", valid_flags, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(conn->buf + offset);
+	ASSERT_RETURN(info->id == conn->id);
+
+	kdbus_free(conn, offset);
+
+	/* does not have the necessary caps to drop to unprivileged */
+	if (!capable)
+		goto continue_test;
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
+		ret = kdbus_conn_info(conn, conn->id, NULL,
+				      valid_flags, &offset);
+		ASSERT_EXIT(ret == 0);
+
+		info = (struct kdbus_info *)(conn->buf + offset);
+		ASSERT_EXIT(info->id == conn->id);
+
+		if (valid_flags & KDBUS_ATTACH_NAMES) {
+			item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME);
+			ASSERT_EXIT(item &&
+				    strcmp(item->name.name,
+				           "com.example.a") == 0);
+		}
+
+		if (valid_flags & KDBUS_ATTACH_CREDS) {
+			item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
+			ASSERT_EXIT(item);
+
+			/* Compare received items with cached creds */
+			ASSERT_EXIT(memcmp(&item->creds, &cached_creds,
+				    sizeof(struct kdbus_creds)) == 0);
+		}
+
+		if (valid_flags & KDBUS_ATTACH_PIDS) {
+			item = kdbus_get_item(info, KDBUS_ITEM_PIDS);
+			ASSERT_EXIT(item);
+
+			/*
+			 * Compare item->pids with cached pids of
+			 * privileged one.
+			 *
+			 * cmd_info will always return cached pids.
+			 */
+			ASSERT_EXIT(item->pids.pid == cached_pids.pid &&
+				    item->pids.tid == cached_pids.tid);
+		}
+
+		kdbus_free(conn, offset);
+
+		/*
+		 * Use invalid_flags and make sure that userspace
+		 * do not play with us.
+		 */
+		ret = kdbus_conn_info(conn, conn->id, NULL,
+				      invalid_flags, &offset);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * Make sure that we return only one creds item and
+		 * it points to the cached creds.
+		 */
+		cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS);
+		if (invalid_flags & KDBUS_ATTACH_CREDS) {
+			ASSERT_EXIT(cnt == 1);
+
+			item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
+			ASSERT_EXIT(item);
+
+			/* Compare received items with cached creds */
+			ASSERT_EXIT(memcmp(&item->creds, &cached_creds,
+				    sizeof(struct kdbus_creds)) == 0);
+		} else {
+			ASSERT_EXIT(cnt == 0);
+		}
+
+		if (invalid_flags & KDBUS_ATTACH_PIDS) {
+			cnt = kdbus_count_item(info, KDBUS_ITEM_PIDS);
+			ASSERT_EXIT(cnt == 1);
+
+			item = kdbus_get_item(info, KDBUS_ITEM_PIDS);
+			ASSERT_EXIT(item);
+
+			/* Compare item->pids with cached pids */
+			ASSERT_EXIT(item->pids.pid == cached_pids.pid &&
+				    item->pids.tid == cached_pids.tid);
+		}
+
+		cnt = kdbus_count_item(info, KDBUS_ITEM_CGROUP);
+		if (invalid_flags & KDBUS_ATTACH_CGROUP) {
+			ASSERT_EXIT(cnt == 1);
+		} else {
+			ASSERT_EXIT(cnt == 0);
+		}
+
+		cnt = kdbus_count_item(info, KDBUS_ITEM_CAPS);
+		if (invalid_flags & KDBUS_ATTACH_CAPS) {
+			ASSERT_EXIT(cnt == 1);
+		} else {
+			ASSERT_EXIT(cnt == 0);
+		}
+
+		kdbus_free(conn, offset);
+	}),
+	({ 0; }));
+	ASSERT_RETURN(ret == 0);
+
+continue_test:
+
+	/* A second name */
+	ret = kdbus_name_acquire(conn, "com.example.b", NULL);
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_conn_info(conn, conn->id, NULL, valid_flags, &offset);
+	ASSERT_RETURN(ret == 0);
+
+	info = (struct kdbus_info *)(conn->buf + offset);
+	ASSERT_RETURN(info->id == conn->id);
+
+	cnt = kdbus_count_item(info, KDBUS_ITEM_OWNED_NAME);
+	if (valid_flags & KDBUS_ATTACH_NAMES) {
+		ASSERT_RETURN(cnt == 2);
+	} else {
+		ASSERT_RETURN(cnt == 0);
+	}
+
+	kdbus_free(conn, offset);
+
+	ASSERT_RETURN(ret == 0);
+
+	return 0;
+}
+
+int kdbus_test_conn_info(struct kdbus_test_env *env)
+{
+	int ret;
+	int have_caps;
+	struct {
+		struct kdbus_cmd_info cmd_info;
+
+		struct {
+			uint64_t size;
+			uint64_t type;
+			char str[64];
+		} name;
+	} buf;
+
+	buf.cmd_info.size = sizeof(struct kdbus_cmd_info);
+	buf.cmd_info.flags = 0;
+	buf.cmd_info.attach_flags = 0;
+	buf.cmd_info.id = env->conn->id;
+
+	ret = kdbus_conn_info(env->conn, env->conn->id, NULL, 0, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* try to pass a name that is longer than the buffer's size */
+	buf.name.size = KDBUS_ITEM_HEADER_SIZE + 1;
+	buf.name.type = KDBUS_ITEM_NAME;
+	strcpy(buf.name.str, "foo.bar.bla");
+
+	buf.cmd_info.id = 0;
+	buf.cmd_info.size = sizeof(buf.cmd_info) + buf.name.size;
+	ret = kdbus_cmd_conn_info(env->conn->fd, (struct kdbus_cmd_info *) &buf);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* Pass a non existent name */
+	ret = kdbus_conn_info(env->conn, 0, "non.existent.name", 0, NULL);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	if (!all_uids_gids_are_mapped())
+		return TEST_SKIP;
+
+	/* Test for caps here, so we run the previous test */
+	have_caps = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(have_caps >= 0);
+
+	ret = kdbus_fuzz_conn_info(env, have_caps);
+	ASSERT_RETURN(ret == 0);
+
+	/* Now if we have skipped some tests then let the user know */
+	if (!have_caps)
+		return TEST_SKIP;
+
+	return TEST_OK;
+}
+
+int kdbus_test_conn_update(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	int found = 0;
+	int ret;
+
+	/*
+	 * kdbus_hello() sets all attach flags. Receive a message by this
+	 * connection, and make sure a timestamp item (just to pick one) is
+	 * present.
+	 */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	found = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
+	ASSERT_RETURN(found == 1);
+
+	kdbus_msg_free(msg);
+
+	/*
+	 * Now, modify the attach flags and repeat the action. The item must
+	 * now be missing.
+	 */
+	found = 0;
+
+	ret = kdbus_conn_update_attach_flags(conn,
+					     _KDBUS_ATTACH_ALL,
+					     _KDBUS_ATTACH_ALL &
+					     ~KDBUS_ATTACH_TIMESTAMP);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_send(env->conn, NULL, 0x12345678, 0, 0, 0, conn->id);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	found = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
+	ASSERT_RETURN(found == 0);
+
+	/* Provide a bogus attach_flags value */
+	ret = kdbus_conn_update_attach_flags(conn,
+					     _KDBUS_ATTACH_ALL + 1,
+					     _KDBUS_ATTACH_ALL);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	kdbus_msg_free(msg);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+int kdbus_test_writable_pool(struct kdbus_test_env *env)
+{
+	struct kdbus_cmd_free cmd_free = {};
+	struct kdbus_cmd_hello hello;
+	int fd, ret;
+	void *map;
+
+	fd = open(env->buspath, O_RDWR | O_CLOEXEC);
+	ASSERT_RETURN(fd >= 0);
+
+	memset(&hello, 0, sizeof(hello));
+	hello.flags = KDBUS_HELLO_ACCEPT_FD;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+	hello.attach_flags_recv = _KDBUS_ATTACH_ALL;
+	hello.size = sizeof(struct kdbus_cmd_hello);
+	hello.pool_size = POOL_SIZE;
+	hello.offset = (__u64)-1;
+
+	/* success test */
+	ret = kdbus_cmd_hello(fd, &hello);
+	ASSERT_RETURN(ret == 0);
+
+	/* The kernel should have returned some items */
+	ASSERT_RETURN(hello.offset != (__u64)-1);
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = hello.offset;
+	ret = kdbus_cmd_free(fd, &cmd_free);
+	ASSERT_RETURN(ret >= 0);
+
+	/* pools cannot be mapped writable */
+	map = mmap(NULL, POOL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	ASSERT_RETURN(map == MAP_FAILED);
+
+	/* pools can always be mapped readable */
+	map = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
+	ASSERT_RETURN(map != MAP_FAILED);
+
+	/* make sure we cannot change protection masks to writable */
+	ret = mprotect(map, POOL_SIZE, PROT_READ | PROT_WRITE);
+	ASSERT_RETURN(ret < 0);
+
+	munmap(map, POOL_SIZE);
+	close(fd);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-daemon.c b/tools/testing/selftests/kdbus/test-daemon.c
new file mode 100644
index 000000000000..8bc2386190d9
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-daemon.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <stdbool.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int kdbus_test_daemon(struct kdbus_test_env *env)
+{
+	struct pollfd fds[2];
+	int count;
+	int ret;
+
+	/* This test doesn't make any sense in non-interactive mode */
+	if (!kdbus_util_verbose)
+		return TEST_OK;
+
+	printf("Created connection %llu on bus '%s'\n",
+		(unsigned long long) env->conn->id, env->buspath);
+
+	ret = kdbus_name_acquire(env->conn, "com.example.kdbus-test", NULL);
+	ASSERT_RETURN(ret == 0);
+	printf("  Aquired name: com.example.kdbus-test\n");
+
+	fds[0].fd = env->conn->fd;
+	fds[1].fd = STDIN_FILENO;
+
+	printf("Monitoring connections:\n");
+
+	for (count = 0;; count++) {
+		int i, nfds = sizeof(fds) / sizeof(fds[0]);
+
+		for (i = 0; i < nfds; i++) {
+			fds[i].events = POLLIN | POLLPRI | POLLHUP;
+			fds[i].revents = 0;
+		}
+
+		ret = poll(fds, nfds, -1);
+		if (ret <= 0)
+			break;
+
+		if (fds[0].revents & POLLIN) {
+			ret = kdbus_msg_recv(env->conn, NULL, NULL);
+			ASSERT_RETURN(ret == 0);
+		}
+
+		/* stdin */
+		if (fds[1].revents & POLLIN)
+			break;
+	}
+
+	printf("Closing bus connection\n");
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-endpoint.c b/tools/testing/selftests/kdbus/test-endpoint.c
new file mode 100644
index 000000000000..34a7be49c482
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-endpoint.c
@@ -0,0 +1,352 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <libgen.h>
+#include <sys/capability.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+#define KDBUS_SYSNAME_MAX_LEN			63
+
+static int install_name_add_match(struct kdbus_conn *conn, const char *name)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_name_change chg;
+		} item;
+		char name[64];
+	} buf;
+	int ret;
+
+	/* install the match rule */
+	memset(&buf, 0, sizeof(buf));
+	buf.item.type = KDBUS_ITEM_NAME_ADD;
+	buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY;
+	buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY;
+	strncpy(buf.name, name, sizeof(buf.name) - 1);
+	buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1;
+	buf.cmd.size = sizeof(buf.cmd) + buf.item.size;
+
+	ret = kdbus_cmd_match_add(conn->fd, &buf.cmd);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int create_endpoint(const char *buspath, uid_t uid, const char *name,
+			   uint64_t flags)
+{
+	struct {
+		struct kdbus_cmd cmd;
+
+		/* name item */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			/* max should be KDBUS_SYSNAME_MAX_LEN */
+			char str[128];
+		} name;
+	} ep_make;
+	int fd, ret;
+
+	fd = open(buspath, O_RDWR);
+	if (fd < 0)
+		return fd;
+
+	memset(&ep_make, 0, sizeof(ep_make));
+
+	snprintf(ep_make.name.str,
+		 /* Use the KDBUS_SYSNAME_MAX_LEN or sizeof(str) */
+		 KDBUS_SYSNAME_MAX_LEN > strlen(name) ?
+		 KDBUS_SYSNAME_MAX_LEN : sizeof(ep_make.name.str),
+		 "%u-%s", uid, name);
+
+	ep_make.name.type = KDBUS_ITEM_MAKE_NAME;
+	ep_make.name.size = KDBUS_ITEM_HEADER_SIZE +
+			    strlen(ep_make.name.str) + 1;
+
+	ep_make.cmd.flags = flags;
+	ep_make.cmd.size = sizeof(ep_make.cmd) + ep_make.name.size;
+
+	ret = kdbus_cmd_endpoint_make(fd, &ep_make.cmd);
+	if (ret < 0) {
+		kdbus_printf("error creating endpoint: %d (%m)\n", ret);
+		return ret;
+	}
+
+	return fd;
+}
+
+static int unpriv_test_custom_ep(const char *buspath)
+{
+	int ret, ep_fd1, ep_fd2;
+	char *ep1, *ep2, *tmp1, *tmp2;
+
+	tmp1 = strdup(buspath);
+	tmp2 = strdup(buspath);
+	ASSERT_RETURN(tmp1 && tmp2);
+
+	ret = asprintf(&ep1, "%s/%u-%s", dirname(tmp1), getuid(), "apps1");
+	ASSERT_RETURN(ret >= 0);
+
+	ret = asprintf(&ep2, "%s/%u-%s", dirname(tmp2), getuid(), "apps2");
+	ASSERT_RETURN(ret >= 0);
+
+	free(tmp1);
+	free(tmp2);
+
+	/* endpoint only accessible to current uid */
+	ep_fd1 = create_endpoint(buspath, getuid(), "apps1", 0);
+	ASSERT_RETURN(ep_fd1 >= 0);
+
+	/* endpoint world accessible */
+	ep_fd2 = create_endpoint(buspath, getuid(), "apps2",
+				  KDBUS_MAKE_ACCESS_WORLD);
+	ASSERT_RETURN(ep_fd2 >= 0);
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
+		int ep_fd;
+		struct kdbus_conn *ep_conn;
+
+		/*
+		 * Make sure that we are not able to create custom
+		 * endpoints
+		 */
+		ep_fd = create_endpoint(buspath, getuid(),
+					"unpriv_costum_ep", 0);
+		ASSERT_EXIT(ep_fd == -EPERM);
+
+		/*
+		 * Endpoint "apps1" only accessible to same users,
+		 * that own the endpoint. Access denied by VFS
+		 */
+		ep_conn = kdbus_hello(ep1, 0, NULL, 0);
+		ASSERT_EXIT(!ep_conn && errno == EACCES);
+
+		/* Endpoint "apps2" world accessible */
+		ep_conn = kdbus_hello(ep2, 0, NULL, 0);
+		ASSERT_EXIT(ep_conn);
+
+		kdbus_conn_free(ep_conn);
+
+		_exit(EXIT_SUCCESS);
+	}),
+	({ 0; }));
+	ASSERT_RETURN(ret == 0);
+
+	close(ep_fd1);
+	close(ep_fd2);
+	free(ep1);
+	free(ep2);
+
+	return 0;
+}
+
+static int update_endpoint(int fd, const char *name)
+{
+	int len = strlen(name) + 1;
+	struct {
+		struct kdbus_cmd cmd;
+
+		/* name item */
+		struct {
+			uint64_t size;
+			uint64_t type;
+			char str[KDBUS_ALIGN8(len)];
+		} name;
+
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_policy_access access;
+		} access;
+	} ep_update;
+	int ret;
+
+	memset(&ep_update, 0, sizeof(ep_update));
+
+	ep_update.name.size = KDBUS_ITEM_HEADER_SIZE + len;
+	ep_update.name.type = KDBUS_ITEM_NAME;
+	strncpy(ep_update.name.str, name, sizeof(ep_update.name.str) - 1);
+
+	ep_update.access.size = sizeof(ep_update.access);
+	ep_update.access.type = KDBUS_ITEM_POLICY_ACCESS;
+	ep_update.access.access.type = KDBUS_POLICY_ACCESS_WORLD;
+	ep_update.access.access.access = KDBUS_POLICY_SEE;
+
+	ep_update.cmd.size = sizeof(ep_update);
+
+	ret = kdbus_cmd_endpoint_update(fd, &ep_update.cmd);
+	if (ret < 0) {
+		kdbus_printf("error updating endpoint: %d (%m)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
+{
+	char *ep, *tmp;
+	int ret, ep_fd;
+	struct kdbus_msg *msg;
+	struct kdbus_conn *ep_conn;
+	struct kdbus_conn *reader;
+	const char *name = "foo.bar.baz";
+	const char *epname = "foo";
+	char fake_ep[KDBUS_SYSNAME_MAX_LEN + 1] = {'\0'};
+
+	memset(fake_ep, 'X', sizeof(fake_ep) - 1);
+
+	/* Try to create a custom endpoint with a long name */
+	ret = create_endpoint(env->buspath, getuid(), fake_ep, 0);
+	ASSERT_RETURN(ret == -ENAMETOOLONG);
+
+	/* Try to create a custom endpoint with a different uid */
+	ret = create_endpoint(env->buspath, getuid() + 1, "foobar", 0);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* create a custom endpoint, and open a connection on it */
+	ep_fd = create_endpoint(env->buspath, getuid(), "foo", 0);
+	ASSERT_RETURN(ep_fd >= 0);
+
+	tmp = strdup(env->buspath);
+	ASSERT_RETURN(tmp);
+
+	ret = asprintf(&ep, "%s/%u-%s", dirname(tmp), getuid(), epname);
+	free(tmp);
+	ASSERT_RETURN(ret >= 0);
+
+	/* Register a connection that listen to broadcasts */
+	reader = kdbus_hello(ep, 0, NULL, 0);
+	ASSERT_RETURN(reader);
+
+	/* Register to kernel signals */
+	ret = kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	ret = install_name_add_match(reader, name);
+	ASSERT_RETURN(ret == 0);
+
+	/* Monitor connections are not supported on custom endpoints */
+	ep_conn = kdbus_hello(ep, KDBUS_HELLO_MONITOR, NULL, 0);
+	ASSERT_RETURN(!ep_conn && errno == EOPNOTSUPP);
+
+	ep_conn = kdbus_hello(ep, 0, NULL, 0);
+	ASSERT_RETURN(ep_conn);
+
+	/* Check that the reader got the IdAdd notification */
+	ret = kdbus_msg_recv(reader, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD);
+	ASSERT_RETURN(msg->items[0].id_change.id == ep_conn->id);
+	kdbus_msg_free(msg);
+
+	/*
+	 * Add a name add match on the endpoint connection, acquire name from
+	 * the unfiltered connection, and make sure the filtered connection
+	 * did not get the notification on the name owner change. Also, the
+	 * endpoint connection may not be able to call conn_info, neither on
+	 * the name nor on the ID.
+	 */
+	ret = install_name_add_match(ep_conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(ep_conn, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	ret = kdbus_conn_info(ep_conn, 0, name, 0, NULL);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	ret = kdbus_conn_info(ep_conn, 0, "random.crappy.name", 0, NULL);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	ret = kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL);
+	ASSERT_RETURN(ret == -ENXIO);
+
+	ret = kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL);
+	ASSERT_RETURN(ret == -ENXIO);
+
+	/* Check that the reader did not receive the name notification */
+	ret = kdbus_msg_recv(reader, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/*
+	 * Release the name again, update the custom endpoint policy,
+	 * and try again. This time, the connection on the custom endpoint
+	 * should have gotten it.
+	 */
+	ret = kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	/* Check that the reader did not receive the name notification */
+	ret = kdbus_msg_recv(reader, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	ret = update_endpoint(ep_fd, name);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(ep_conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_ADD);
+	ASSERT_RETURN(msg->items[0].name_change.old_id.id == 0);
+	ASSERT_RETURN(msg->items[0].name_change.new_id.id == env->conn->id);
+	ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0);
+	kdbus_msg_free(msg);
+
+	ret = kdbus_msg_recv(reader, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0);
+
+	kdbus_msg_free(msg);
+
+	ret = kdbus_conn_info(ep_conn, 0, name, 0, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_info(ep_conn, env->conn->id, NULL, 0, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* If we have privileges test custom endpoints */
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * All uids/gids are mapped and we have the necessary caps
+	 */
+	if (ret && all_uids_gids_are_mapped()) {
+		ret = unpriv_test_custom_ep(env->buspath);
+		ASSERT_RETURN(ret == 0);
+	}
+
+	kdbus_conn_free(reader);
+	kdbus_conn_free(ep_conn);
+	close(ep_fd);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-fd.c b/tools/testing/selftests/kdbus/test-fd.c
new file mode 100644
index 000000000000..2ae0f5ae8fd0
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-fd.c
@@ -0,0 +1,789 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include "kdbus-api.h"
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+#define KDBUS_MSG_MAX_ITEMS     128
+#define KDBUS_USER_MAX_CONN	256
+
+/* maximum number of inflight fds in a target queue per user */
+#define KDBUS_CONN_MAX_FDS_PER_USER	16
+
+/* maximum number of memfd items per message */
+#define KDBUS_MSG_MAX_MEMFD_ITEMS       16
+
+static int make_msg_payload_dbus(uint64_t src_id, uint64_t dst_id,
+				 uint64_t msg_size,
+				 struct kdbus_msg **msg_dbus)
+{
+	struct kdbus_msg *msg;
+
+	msg = malloc(msg_size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, msg_size);
+	msg->size = msg_size;
+	msg->src_id = src_id;
+	msg->dst_id = dst_id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	*msg_dbus = msg;
+
+	return 0;
+}
+
+static void make_item_memfds(struct kdbus_item *item,
+			     int *memfds, size_t memfd_size)
+{
+	size_t i;
+
+	for (i = 0; i < memfd_size; i++) {
+		item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
+		item->size = KDBUS_ITEM_HEADER_SIZE +
+			     sizeof(struct kdbus_memfd);
+		item->memfd.fd = memfds[i];
+		item->memfd.size = sizeof(uint64_t); /* const size */
+		item = KDBUS_ITEM_NEXT(item);
+	}
+}
+
+static void make_item_fds(struct kdbus_item *item,
+			  int *fd_array, size_t fd_size)
+{
+	size_t i;
+	item->type = KDBUS_ITEM_FDS;
+	item->size = KDBUS_ITEM_HEADER_SIZE + (sizeof(int) * fd_size);
+
+	for (i = 0; i < fd_size; i++)
+		item->fds[i] = fd_array[i];
+}
+
+static int memfd_write(const char *name, void *buf, size_t bufsize)
+{
+	ssize_t ret;
+	int memfd;
+
+	memfd = sys_memfd_create(name, 0);
+	ASSERT_RETURN_VAL(memfd >= 0, memfd);
+
+	ret = write(memfd, buf, bufsize);
+	ASSERT_RETURN_VAL(ret == (ssize_t)bufsize, -EAGAIN);
+
+	ret = sys_memfd_seal_set(memfd);
+	ASSERT_RETURN_VAL(ret == 0, -errno);
+
+	return memfd;
+}
+
+static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id,
+		       int *memfds_array, size_t memfd_count)
+{
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_item *item;
+	struct kdbus_msg *msg;
+	uint64_t size;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	size += memfd_count * KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST)
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+
+	ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	item = msg->items;
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST) {
+		item->type = KDBUS_ITEM_BLOOM_FILTER;
+		item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+		item = KDBUS_ITEM_NEXT(item);
+
+		msg->flags |= KDBUS_MSG_SIGNAL;
+	}
+
+	make_item_memfds(item, memfds_array, memfd_count);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	if (ret < 0) {
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+		return ret;
+	}
+
+	free(msg);
+	return 0;
+}
+
+static int send_fds(struct kdbus_conn *conn, uint64_t dst_id,
+		    int *fd_array, size_t fd_count)
+{
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_item *item;
+	struct kdbus_msg *msg;
+	uint64_t size;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(int) * fd_count);
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST)
+		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+
+	ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	item = msg->items;
+
+	if (dst_id == KDBUS_DST_ID_BROADCAST) {
+		item->type = KDBUS_ITEM_BLOOM_FILTER;
+		item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
+		item = KDBUS_ITEM_NEXT(item);
+
+		msg->flags |= KDBUS_MSG_SIGNAL;
+	}
+
+	make_item_fds(item, fd_array, fd_count);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	if (ret < 0) {
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+		return ret;
+	}
+
+	free(msg);
+	return ret;
+}
+
+static int send_fds_memfds(struct kdbus_conn *conn, uint64_t dst_id,
+			   int *fds_array, size_t fd_count,
+			   int *memfds_array, size_t memfd_count)
+{
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_item *item;
+	struct kdbus_msg *msg;
+	uint64_t size;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	size += memfd_count * KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
+	size += KDBUS_ITEM_SIZE(sizeof(int) * fd_count);
+
+	ret = make_msg_payload_dbus(conn->id, dst_id, size, &msg);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	item = msg->items;
+
+	make_item_fds(item, fds_array, fd_count);
+	item = KDBUS_ITEM_NEXT(item);
+	make_item_memfds(item, memfds_array, memfd_count);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	if (ret < 0) {
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+		return ret;
+	}
+
+	free(msg);
+	return ret;
+}
+
+/* Return the number of received fds */
+static unsigned int kdbus_item_get_nfds(struct kdbus_msg *msg)
+{
+	unsigned int fds = 0;
+	const struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, msg, items) {
+		switch (item->type) {
+		case KDBUS_ITEM_FDS: {
+			fds += (item->size - KDBUS_ITEM_HEADER_SIZE) /
+				sizeof(int);
+			break;
+		}
+
+		case KDBUS_ITEM_PAYLOAD_MEMFD:
+			fds++;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	return fds;
+}
+
+static struct kdbus_msg *
+get_kdbus_msg_with_fd(struct kdbus_conn *conn_src,
+		      uint64_t dst_id, uint64_t cookie, int fd)
+{
+	int ret;
+	uint64_t size;
+	struct kdbus_item *item;
+	struct kdbus_msg *msg;
+
+	size = sizeof(struct kdbus_msg);
+	if (fd >= 0)
+		size += KDBUS_ITEM_SIZE(sizeof(int));
+
+	ret = make_msg_payload_dbus(conn_src->id, dst_id, size, &msg);
+	ASSERT_RETURN_VAL(ret == 0, NULL);
+
+	msg->cookie = cookie;
+
+	if (fd >= 0) {
+		item = msg->items;
+
+		make_item_fds(item, (int *)&fd, 1);
+	}
+
+	return msg;
+}
+
+static int kdbus_test_no_fds(struct kdbus_test_env *env,
+			     int *fds, int *memfd)
+{
+	pid_t pid;
+	int ret, status;
+	uint64_t cookie;
+	int connfd1, connfd2;
+	struct kdbus_msg *msg, *msg_sync_reply;
+	struct kdbus_cmd_hello hello;
+	struct kdbus_conn *conn_src, *conn_dst, *conn_dummy;
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_cmd_free cmd_free = {};
+
+	conn_src = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_src);
+
+	connfd1 = open(env->buspath, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(connfd1 >= 0);
+
+	connfd2 = open(env->buspath, O_RDWR|O_CLOEXEC);
+	ASSERT_RETURN(connfd2 >= 0);
+
+	/*
+	 * Create connections without KDBUS_HELLO_ACCEPT_FD
+	 * to test if send fd operations are blocked
+	 */
+	conn_dst = malloc(sizeof(*conn_dst));
+	ASSERT_RETURN(conn_dst);
+
+	conn_dummy = malloc(sizeof(*conn_dummy));
+	ASSERT_RETURN(conn_dummy);
+
+	memset(&hello, 0, sizeof(hello));
+	hello.size = sizeof(struct kdbus_cmd_hello);
+	hello.pool_size = POOL_SIZE;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+
+	ret = kdbus_cmd_hello(connfd1, &hello);
+	ASSERT_RETURN(ret == 0);
+
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = hello.offset;
+	ret = kdbus_cmd_free(connfd1, &cmd_free);
+	ASSERT_RETURN(ret >= 0);
+
+	conn_dst->fd = connfd1;
+	conn_dst->id = hello.id;
+
+	memset(&hello, 0, sizeof(hello));
+	hello.size = sizeof(struct kdbus_cmd_hello);
+	hello.pool_size = POOL_SIZE;
+	hello.attach_flags_send = _KDBUS_ATTACH_ALL;
+
+	ret = kdbus_cmd_hello(connfd2, &hello);
+	ASSERT_RETURN(ret == 0);
+
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = hello.offset;
+	ret = kdbus_cmd_free(connfd2, &cmd_free);
+	ASSERT_RETURN(ret >= 0);
+
+	conn_dummy->fd = connfd2;
+	conn_dummy->id = hello.id;
+
+	conn_dst->buf = mmap(NULL, POOL_SIZE, PROT_READ,
+			     MAP_SHARED, connfd1, 0);
+	ASSERT_RETURN(conn_dst->buf != MAP_FAILED);
+
+	conn_dummy->buf = mmap(NULL, POOL_SIZE, PROT_READ,
+			       MAP_SHARED, connfd2, 0);
+	ASSERT_RETURN(conn_dummy->buf != MAP_FAILED);
+
+	/*
+	 * Send fds to connection that do not accept fd passing
+	 */
+	ret = send_fds(conn_src, conn_dst->id, fds, 1);
+	ASSERT_RETURN(ret == -ECOMM);
+
+	/*
+	 * memfd are kdbus payload
+	 */
+	ret = send_memfds(conn_src, conn_dst->id, memfd, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv_poll(conn_dst, 100, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	cookie = time(NULL);
+
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		struct timespec now;
+
+		/*
+		 * A sync send/reply to a connection that do not
+		 * accept fds should fail if it contains an fd
+		 */
+		msg_sync_reply = get_kdbus_msg_with_fd(conn_dst,
+						       conn_dummy->id,
+						       cookie, fds[0]);
+		ASSERT_EXIT(msg_sync_reply);
+
+		ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+		ASSERT_EXIT(ret == 0);
+
+		msg_sync_reply->timeout_ns = now.tv_sec * 1000000000ULL +
+					     now.tv_nsec + 100000000ULL;
+		msg_sync_reply->flags = KDBUS_MSG_EXPECT_REPLY;
+
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.size = sizeof(cmd);
+		cmd.msg_address = (uintptr_t)msg_sync_reply;
+		cmd.flags = KDBUS_SEND_SYNC_REPLY;
+
+		ret = kdbus_cmd_send(conn_dst->fd, &cmd);
+		ASSERT_EXIT(ret == -ECOMM);
+
+		/*
+		 * Now send a normal message, but the sync reply
+		 * will fail since it contains an fd that the
+		 * original sender do not want.
+		 *
+		 * The original sender will fail with -ETIMEDOUT
+		 */
+		cookie++;
+		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
+					  KDBUS_MSG_EXPECT_REPLY,
+					  5000000000ULL, 0, conn_src->id, -1);
+		ASSERT_EXIT(ret == -EREMOTEIO);
+
+		cookie++;
+		ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL);
+		ASSERT_EXIT(ret == 0);
+		ASSERT_EXIT(msg->cookie == cookie);
+
+		free(msg_sync_reply);
+		kdbus_msg_free(msg);
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	ret = kdbus_msg_recv_poll(conn_dummy, 100, NULL, NULL);
+	ASSERT_RETURN(ret == -ETIMEDOUT);
+
+	cookie++;
+	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	/*
+	 * Try to reply with a kdbus connection handle, this should
+	 * fail with -EOPNOTSUPP
+	 */
+	msg_sync_reply = get_kdbus_msg_with_fd(conn_src,
+					       conn_dst->id,
+					       cookie, conn_dst->fd);
+	ASSERT_RETURN(msg_sync_reply);
+
+	msg_sync_reply->cookie_reply = cookie;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg_sync_reply;
+
+	ret = kdbus_cmd_send(conn_src->fd, &cmd);
+	ASSERT_RETURN(ret == -EOPNOTSUPP);
+
+	free(msg_sync_reply);
+
+	/*
+	 * Try to reply with a normal fd, this should fail even
+	 * if the response is a sync reply
+	 *
+	 * From the sender view we fail with -ECOMM
+	 */
+	msg_sync_reply = get_kdbus_msg_with_fd(conn_src,
+					       conn_dst->id,
+					       cookie, fds[0]);
+	ASSERT_RETURN(msg_sync_reply);
+
+	msg_sync_reply->cookie_reply = cookie;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg_sync_reply;
+
+	ret = kdbus_cmd_send(conn_src->fd, &cmd);
+	ASSERT_RETURN(ret == -ECOMM);
+
+	free(msg_sync_reply);
+
+	/*
+	 * Resend another normal message and check if the queue
+	 * is clear
+	 */
+	cookie++;
+	ret = kdbus_msg_send(conn_src, NULL, cookie, 0, 0, 0,
+			     conn_dst->id);
+	ASSERT_RETURN(ret == 0);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	kdbus_conn_free(conn_dummy);
+	kdbus_conn_free(conn_dst);
+	kdbus_conn_free(conn_src);
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+static int kdbus_send_multiple_fds(struct kdbus_conn *conn_src,
+				   struct kdbus_conn *conn_dst)
+{
+	int ret, i;
+	unsigned int nfds;
+	int fds[KDBUS_CONN_MAX_FDS_PER_USER + 1];
+	int memfds[KDBUS_MSG_MAX_ITEMS + 1];
+	struct kdbus_msg *msg;
+	uint64_t dummy_value;
+
+	dummy_value = time(NULL);
+
+	for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) {
+		fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC);
+		ASSERT_RETURN_VAL(fds[i] >= 0, -errno);
+	}
+
+	/* Send KDBUS_CONN_MAX_FDS_PER_USER with one more fd */
+	ret = send_fds(conn_src, conn_dst->id, fds,
+		       KDBUS_CONN_MAX_FDS_PER_USER + 1);
+	ASSERT_RETURN(ret == -EMFILE);
+
+	/* Retry with the correct KDBUS_CONN_MAX_FDS_PER_USER */
+	ret = send_fds(conn_src, conn_dst->id, fds,
+		       KDBUS_CONN_MAX_FDS_PER_USER);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* Check we got the right number of fds */
+	nfds = kdbus_item_get_nfds(msg);
+	ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER);
+
+	kdbus_msg_free(msg);
+
+	for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++, dummy_value++) {
+		memfds[i] = memfd_write("memfd-name",
+					&dummy_value,
+					sizeof(dummy_value));
+		ASSERT_RETURN_VAL(memfds[i] >= 0, memfds[i]);
+	}
+
+	/* Send KDBUS_MSG_MAX_ITEMS with one more memfd */
+	ret = send_memfds(conn_src, conn_dst->id,
+			  memfds, KDBUS_MSG_MAX_ITEMS + 1);
+	ASSERT_RETURN(ret == -E2BIG);
+
+	ret = send_memfds(conn_src, conn_dst->id,
+			  memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1);
+	ASSERT_RETURN(ret == -E2BIG);
+
+	/* Retry with the correct KDBUS_MSG_MAX_ITEMS */
+	ret = send_memfds(conn_src, conn_dst->id,
+			  memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* Check we got the right number of fds */
+	nfds = kdbus_item_get_nfds(msg);
+	ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS);
+
+	kdbus_msg_free(msg);
+
+
+	/*
+	 * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER+1 fds and
+	 * 10 memfds
+	 */
+	ret = send_fds_memfds(conn_src, conn_dst->id,
+			      fds, KDBUS_CONN_MAX_FDS_PER_USER + 1,
+			      memfds, 10);
+	ASSERT_RETURN(ret == -EMFILE);
+
+	ret = kdbus_msg_recv(conn_dst, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/*
+	 * Combine multiple KDBUS_CONN_MAX_FDS_PER_USER fds and
+	 * (128 - 1) + 1 memfds, all fds take one item, while each
+	 * memfd takes one item
+	 */
+	ret = send_fds_memfds(conn_src, conn_dst->id,
+			      fds, KDBUS_CONN_MAX_FDS_PER_USER,
+			      memfds, (KDBUS_MSG_MAX_ITEMS - 1) + 1);
+	ASSERT_RETURN(ret == -E2BIG);
+
+	ret = send_fds_memfds(conn_src, conn_dst->id,
+			      fds, KDBUS_CONN_MAX_FDS_PER_USER,
+			      memfds, KDBUS_MSG_MAX_MEMFD_ITEMS + 1);
+	ASSERT_RETURN(ret == -E2BIG);
+
+	ret = kdbus_msg_recv(conn_dst, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/*
+	 * Send KDBUS_CONN_MAX_FDS_PER_USER fds +
+	 * KDBUS_MSG_MAX_MEMFD_ITEMS memfds
+	 */
+	ret = send_fds_memfds(conn_src, conn_dst->id,
+			      fds, KDBUS_CONN_MAX_FDS_PER_USER,
+			      memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* Check we got the right number of fds */
+	nfds = kdbus_item_get_nfds(msg);
+	ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER +
+			      KDBUS_MSG_MAX_MEMFD_ITEMS);
+
+	kdbus_msg_free(msg);
+
+
+	/*
+	 * Re-send fds + memfds, close them, but do not receive them
+	 * and try to queue more
+	 */
+	ret = send_fds_memfds(conn_src, conn_dst->id,
+			      fds, KDBUS_CONN_MAX_FDS_PER_USER,
+			      memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
+	ASSERT_RETURN(ret == 0);
+
+	/* close old references and get a new ones */
+	for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++) {
+		close(fds[i]);
+		fds[i] = open("/dev/null", O_RDWR|O_CLOEXEC);
+		ASSERT_RETURN_VAL(fds[i] >= 0, -errno);
+	}
+
+	/* should fail since we have already fds in the queue */
+	ret = send_fds(conn_src, conn_dst->id, fds,
+		       KDBUS_CONN_MAX_FDS_PER_USER);
+	ASSERT_RETURN(ret == -EMFILE);
+
+	/* This should succeed */
+	ret = send_memfds(conn_src, conn_dst->id,
+			  memfds, KDBUS_MSG_MAX_MEMFD_ITEMS);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	nfds = kdbus_item_get_nfds(msg);
+	ASSERT_RETURN(nfds == KDBUS_CONN_MAX_FDS_PER_USER +
+			      KDBUS_MSG_MAX_MEMFD_ITEMS);
+
+	kdbus_msg_free(msg);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	nfds = kdbus_item_get_nfds(msg);
+	ASSERT_RETURN(nfds == KDBUS_MSG_MAX_MEMFD_ITEMS);
+
+	kdbus_msg_free(msg);
+
+	ret = kdbus_msg_recv(conn_dst, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	for (i = 0; i < KDBUS_CONN_MAX_FDS_PER_USER + 1; i++)
+		close(fds[i]);
+
+	for (i = 0; i < KDBUS_MSG_MAX_ITEMS + 1; i++)
+		close(memfds[i]);
+
+	return 0;
+}
+
+int kdbus_test_fd_passing(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn_src, *conn_dst;
+	const char *str = "stackenblocken";
+	const struct kdbus_item *item;
+	struct kdbus_msg *msg;
+	unsigned int i;
+	uint64_t now;
+	int fds_conn[2];
+	int sock_pair[2];
+	int fds[2];
+	int memfd;
+	int ret;
+
+	now = (uint64_t) time(NULL);
+
+	/* create two connections */
+	conn_src = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_dst = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_src && conn_dst);
+
+	fds_conn[0] = conn_src->fd;
+	fds_conn[1] = conn_dst->fd;
+
+	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock_pair);
+	ASSERT_RETURN(ret == 0);
+
+	/* Setup memfd */
+	memfd = memfd_write("memfd-name", &now, sizeof(now));
+	ASSERT_RETURN(memfd >= 0);
+
+	/* Setup pipes */
+	ret = pipe(fds);
+	ASSERT_RETURN(ret == 0);
+
+	i = write(fds[1], str, strlen(str));
+	ASSERT_RETURN(i == strlen(str));
+
+	/*
+	 * Try to ass the handle of a connection as message payload.
+	 * This must fail.
+	 */
+	ret = send_fds(conn_src, conn_dst->id, fds_conn, 2);
+	ASSERT_RETURN(ret == -ENOTSUP);
+
+	ret = send_fds(conn_dst, conn_src->id, fds_conn, 2);
+	ASSERT_RETURN(ret == -ENOTSUP);
+
+	ret = send_fds(conn_src, conn_dst->id, sock_pair, 2);
+	ASSERT_RETURN(ret == -ENOTSUP);
+
+	/*
+	 * Send fds and memfds to connection that do not accept fds
+	 */
+	ret = kdbus_test_no_fds(env, fds, (int *)&memfd);
+	ASSERT_RETURN(ret == 0);
+
+	/* Try to broadcast file descriptors. This must fail. */
+	ret = send_fds(conn_src, KDBUS_DST_ID_BROADCAST, fds, 1);
+	ASSERT_RETURN(ret == -ENOTUNIQ);
+
+	/* Try to broadcast memfd. This must succeed. */
+	ret = send_memfds(conn_src, KDBUS_DST_ID_BROADCAST, (int *)&memfd, 1);
+	ASSERT_RETURN(ret == 0);
+
+	/* Open code this loop */
+loop_send_fds:
+
+	/*
+	 * Send the read end of the pipe and close it.
+	 */
+	ret = send_fds(conn_src, conn_dst->id, fds, 1);
+	ASSERT_RETURN(ret == 0);
+	close(fds[0]);
+
+	ret = kdbus_msg_recv(conn_dst, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	KDBUS_ITEM_FOREACH(item, msg, items) {
+		if (item->type == KDBUS_ITEM_FDS) {
+			char tmp[14];
+			int nfds = (item->size - KDBUS_ITEM_HEADER_SIZE) /
+					sizeof(int);
+			ASSERT_RETURN(nfds == 1);
+
+			i = read(item->fds[0], tmp, sizeof(tmp));
+			if (i != 0) {
+				ASSERT_RETURN(i == sizeof(tmp));
+				ASSERT_RETURN(memcmp(tmp, str, sizeof(tmp)) == 0);
+
+				/* Write EOF */
+				close(fds[1]);
+
+				/*
+				 * Resend the read end of the pipe,
+				 * the receiver still holds a reference
+				 * to it...
+				 */
+				goto loop_send_fds;
+			}
+
+			/* Got EOF */
+
+			/*
+			 * Close the last reference to the read end
+			 * of the pipe, other references are
+			 * automatically closed just after send.
+			 */
+			close(item->fds[0]);
+		}
+	}
+
+	/*
+	 * Try to resend the read end of the pipe. Must fail with
+	 * -EBADF since both the sender and receiver closed their
+	 * references to it. We assume the above since sender and
+	 * receiver are on the same process.
+	 */
+	ret = send_fds(conn_src, conn_dst->id, fds, 1);
+	ASSERT_RETURN(ret == -EBADF);
+
+	/* Then we clear out received any data... */
+	kdbus_msg_free(msg);
+
+	ret = kdbus_send_multiple_fds(conn_src, conn_dst);
+	ASSERT_RETURN(ret == 0);
+
+	close(sock_pair[0]);
+	close(sock_pair[1]);
+	close(memfd);
+
+	kdbus_conn_free(conn_src);
+	kdbus_conn_free(conn_dst);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-free.c b/tools/testing/selftests/kdbus/test-free.c
new file mode 100644
index 000000000000..f666da3e87cc
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-free.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+static int sample_ioctl_call(struct kdbus_test_env *env)
+{
+	int ret;
+	struct kdbus_cmd_list cmd_list = {
+		.flags = KDBUS_LIST_QUEUED,
+		.size = sizeof(cmd_list),
+	};
+
+	ret = kdbus_cmd_list(env->conn->fd, &cmd_list);
+	ASSERT_RETURN(ret == 0);
+
+	/* DON'T FREE THIS SLICE OF MEMORY! */
+
+	return TEST_OK;
+}
+
+int kdbus_test_free(struct kdbus_test_env *env)
+{
+	int ret;
+	struct kdbus_cmd_free cmd_free = {};
+
+	/* free an unallocated buffer */
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.flags = 0;
+	cmd_free.offset = 0;
+	ret = kdbus_cmd_free(env->conn->fd, &cmd_free);
+	ASSERT_RETURN(ret == -ENXIO);
+
+	/* free a buffer out of the pool's bounds */
+	cmd_free.size = sizeof(cmd_free);
+	cmd_free.offset = POOL_SIZE + 1;
+	ret = kdbus_cmd_free(env->conn->fd, &cmd_free);
+	ASSERT_RETURN(ret == -ENXIO);
+
+	/*
+	 * The user application is responsible for freeing the allocated
+	 * memory with the KDBUS_CMD_FREE ioctl, so let's test what happens
+	 * if we forget about it.
+	 */
+
+	ret = sample_ioctl_call(env);
+	ASSERT_RETURN(ret == 0);
+
+	ret = sample_ioctl_call(env);
+	ASSERT_RETURN(ret == 0);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-match.c b/tools/testing/selftests/kdbus/test-match.c
new file mode 100644
index 000000000000..2360dc1d76a4
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-match.c
@@ -0,0 +1,441 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+int kdbus_test_match_id_add(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_id_change chg;
+		} item;
+	} buf;
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	int ret;
+
+	memset(&buf, 0, sizeof(buf));
+
+	buf.cmd.size = sizeof(buf);
+	buf.cmd.cookie = 0xdeafbeefdeaddead;
+	buf.item.size = sizeof(buf.item);
+	buf.item.type = KDBUS_ITEM_ID_ADD;
+	buf.item.chg.id = KDBUS_MATCH_ID_ANY;
+
+	/* match on id add */
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* create 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* 1st connection should have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD);
+	ASSERT_RETURN(msg->items[0].id_change.id == conn->id);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+int kdbus_test_match_id_remove(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_id_change chg;
+		} item;
+	} buf;
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	size_t id;
+	int ret;
+
+	/* create 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+	id = conn->id;
+
+	memset(&buf, 0, sizeof(buf));
+	buf.cmd.size = sizeof(buf);
+	buf.cmd.cookie = 0xdeafbeefdeaddead;
+	buf.item.size = sizeof(buf.item);
+	buf.item.type = KDBUS_ITEM_ID_REMOVE;
+	buf.item.chg.id = id;
+
+	/* register match on 2nd connection */
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* remove 2nd connection again */
+	kdbus_conn_free(conn);
+
+	/* 1st connection should have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_REMOVE);
+	ASSERT_RETURN(msg->items[0].id_change.id == id);
+
+	return TEST_OK;
+}
+
+int kdbus_test_match_replace(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_id_change chg;
+		} item;
+	} buf;
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	size_t id;
+	int ret;
+
+	/* add a match to id_add */
+	ASSERT_RETURN(kdbus_test_match_id_add(env) == TEST_OK);
+
+	/* do a replace of the match from id_add to id_remove */
+	memset(&buf, 0, sizeof(buf));
+
+	buf.cmd.size = sizeof(buf);
+	buf.cmd.cookie = 0xdeafbeefdeaddead;
+	buf.cmd.flags = KDBUS_MATCH_REPLACE;
+	buf.item.size = sizeof(buf.item);
+	buf.item.type = KDBUS_ITEM_ID_REMOVE;
+	buf.item.chg.id = KDBUS_MATCH_ID_ANY;
+
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+
+	/* create 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+	id = conn->id;
+
+	/* 1st connection should _not_ have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret != 0);
+
+	/* remove 2nd connection */
+	kdbus_conn_free(conn);
+
+	/* 1st connection should _now_ have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_REMOVE);
+	ASSERT_RETURN(msg->items[0].id_change.id == id);
+
+	return TEST_OK;
+}
+
+int kdbus_test_match_name_add(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_name_change chg;
+		} item;
+		char name[64];
+	} buf;
+	struct kdbus_msg *msg;
+	char *name;
+	int ret;
+
+	name = "foo.bla.blaz";
+
+	/* install the match rule */
+	memset(&buf, 0, sizeof(buf));
+	buf.item.type = KDBUS_ITEM_NAME_ADD;
+	buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY;
+	buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY;
+	strncpy(buf.name, name, sizeof(buf.name) - 1);
+	buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1;
+	buf.cmd.size = sizeof(buf.cmd) + buf.item.size;
+
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* acquire the name */
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* we should have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_ADD);
+	ASSERT_RETURN(msg->items[0].name_change.old_id.id == 0);
+	ASSERT_RETURN(msg->items[0].name_change.new_id.id == env->conn->id);
+	ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0);
+
+	return TEST_OK;
+}
+
+int kdbus_test_match_name_remove(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_name_change chg;
+		} item;
+		char name[64];
+	} buf;
+	struct kdbus_msg *msg;
+	char *name;
+	int ret;
+
+	name = "foo.bla.blaz";
+
+	/* acquire the name */
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* install the match rule */
+	memset(&buf, 0, sizeof(buf));
+	buf.item.type = KDBUS_ITEM_NAME_REMOVE;
+	buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY;
+	buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY;
+	strncpy(buf.name, name, sizeof(buf.name) - 1);
+	buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1;
+	buf.cmd.size = sizeof(buf.cmd) + buf.item.size;
+
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* release the name again */
+	kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	/* we should have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_REMOVE);
+	ASSERT_RETURN(msg->items[0].name_change.old_id.id == env->conn->id);
+	ASSERT_RETURN(msg->items[0].name_change.new_id.id == 0);
+	ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0);
+
+	return TEST_OK;
+}
+
+int kdbus_test_match_name_change(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			struct kdbus_notify_name_change chg;
+		} item;
+		char name[64];
+	} buf;
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	uint64_t flags;
+	char *name = "foo.bla.baz";
+	int ret;
+
+	/* acquire the name */
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* install the match rule */
+	memset(&buf, 0, sizeof(buf));
+	buf.item.type = KDBUS_ITEM_NAME_CHANGE;
+	buf.item.chg.old_id.id = KDBUS_MATCH_ID_ANY;
+	buf.item.chg.new_id.id = KDBUS_MATCH_ID_ANY;
+	strncpy(buf.name, name, sizeof(buf.name) - 1);
+	buf.item.size = sizeof(buf.item) + strlen(buf.name) + 1;
+	buf.cmd.size = sizeof(buf.cmd) + buf.item.size;
+
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* allow the new connection to own the same name */
+	/* queue the 2nd connection as waiting owner */
+	flags = KDBUS_NAME_QUEUE;
+	ret = kdbus_name_acquire(conn, name, &flags);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(flags & KDBUS_NAME_IN_QUEUE);
+
+	/* release name from 1st connection */
+	ret = kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	/* we should have received a notification */
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_NAME_CHANGE);
+	ASSERT_RETURN(msg->items[0].name_change.old_id.id == env->conn->id);
+	ASSERT_RETURN(msg->items[0].name_change.new_id.id == conn->id);
+	ASSERT_RETURN(strcmp(msg->items[0].name_change.name, name) == 0);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+static int send_bloom_filter(const struct kdbus_conn *conn,
+			     uint64_t cookie,
+			     const uint8_t *filter,
+			     size_t filter_size,
+			     uint64_t filter_generation)
+{
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_msg *msg;
+	struct kdbus_item *item;
+	uint64_t size;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + filter_size;
+
+	msg = alloca(size);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = conn->id;
+	msg->dst_id = KDBUS_DST_ID_BROADCAST;
+	msg->flags = KDBUS_MSG_SIGNAL;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+	msg->cookie = cookie;
+
+	item = msg->items;
+	item->type = KDBUS_ITEM_BLOOM_FILTER;
+	item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) +
+				filter_size;
+
+	item->bloom_filter.generation = filter_generation;
+	memcpy(item->bloom_filter.data, filter, filter_size);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(conn->fd, &cmd);
+	if (ret < 0) {
+		kdbus_printf("error sending message: %d (%m)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int kdbus_test_match_bloom(struct kdbus_test_env *env)
+{
+	struct {
+		struct kdbus_cmd_match cmd;
+		struct {
+			uint64_t size;
+			uint64_t type;
+			uint8_t data_gen0[64];
+			uint8_t data_gen1[64];
+		} item;
+	} buf;
+	struct kdbus_conn *conn;
+	struct kdbus_msg *msg;
+	uint64_t cookie = 0xf000f00f;
+	uint8_t filter[64];
+	int ret;
+
+	/* install the match rule */
+	memset(&buf, 0, sizeof(buf));
+	buf.cmd.size = sizeof(buf);
+
+	buf.item.size = sizeof(buf.item);
+	buf.item.type = KDBUS_ITEM_BLOOM_MASK;
+	buf.item.data_gen0[0] = 0x55;
+	buf.item.data_gen0[63] = 0x80;
+
+	buf.item.data_gen1[1] = 0xaa;
+	buf.item.data_gen1[9] = 0x02;
+
+	ret = kdbus_cmd_match_add(env->conn->fd, &buf.cmd);
+	ASSERT_RETURN(ret == 0);
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* a message with a 0'ed out filter must not reach the other peer */
+	memset(filter, 0, sizeof(filter));
+	ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/* now set the filter to the connection's mask and expect success */
+	filter[0] = 0x55;
+	filter[63] = 0x80;
+	ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	/* broaden the filter and try again. this should also succeed. */
+	filter[0] = 0xff;
+	filter[8] = 0xff;
+	filter[63] = 0xff;
+	ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 0);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	/* the same filter must not match against bloom generation 1 */
+	ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/* set a different filter and try again */
+	filter[1] = 0xaa;
+	filter[9] = 0x02;
+	ret = send_bloom_filter(conn, ++cookie, filter, sizeof(filter), 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(env->conn, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-message.c b/tools/testing/selftests/kdbus/test-message.c
new file mode 100644
index 000000000000..563dc859077a
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-message.c
@@ -0,0 +1,734 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <stdbool.h>
+#include <sys/eventfd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+/* maximum number of queued messages from the same individual user */
+#define KDBUS_CONN_MAX_MSGS			256
+
+/* maximum number of queued requests waiting for a reply */
+#define KDBUS_CONN_MAX_REQUESTS_PENDING		128
+
+/* maximum message payload size */
+#define KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE		(2 * 1024UL * 1024UL)
+
+int kdbus_test_message_basic(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	struct kdbus_conn *sender;
+	struct kdbus_msg *msg;
+	uint64_t cookie = 0x1234abcd5678eeff;
+	uint64_t offset;
+	int ret;
+
+	sender = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(sender != NULL);
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	ret = kdbus_add_match_empty(conn);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_empty(sender);
+	ASSERT_RETURN(ret == 0);
+
+	/* send over 1st connection */
+	ret = kdbus_msg_send(sender, NULL, cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	/* Make sure that we do get our own broadcasts */
+	ret = kdbus_msg_recv(sender, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	/* ... and receive on the 2nd */
+	ret = kdbus_msg_recv_poll(conn, 100, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	/* Msgs that expect a reply must have timeout and cookie */
+	ret = kdbus_msg_send(sender, NULL, 0, KDBUS_MSG_EXPECT_REPLY,
+			     0, 0, conn->id);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* Faked replies with a valid reply cookie are rejected */
+	ret = kdbus_msg_send_reply(conn, time(NULL) ^ cookie, sender->id);
+	ASSERT_RETURN(ret == -EBADSLT);
+
+	ret = kdbus_free(conn, offset);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_conn_free(sender);
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+static int msg_recv_prio(struct kdbus_conn *conn,
+			 int64_t requested_prio,
+			 int64_t expected_prio)
+{
+	struct kdbus_cmd_recv recv = {
+		.size = sizeof(recv),
+		.flags = KDBUS_RECV_USE_PRIORITY,
+		.priority = requested_prio,
+	};
+	struct kdbus_msg *msg;
+	int ret;
+
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	if (ret < 0) {
+		kdbus_printf("error receiving message: %d (%m)\n", -errno);
+		return ret;
+	}
+
+	msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
+	kdbus_msg_dump(conn, msg);
+
+	if (msg->priority != expected_prio) {
+		kdbus_printf("expected message prio %lld, got %lld\n",
+			     (unsigned long long) expected_prio,
+			     (unsigned long long) msg->priority);
+		return -EINVAL;
+	}
+
+	kdbus_msg_free(msg);
+	ret = kdbus_free(conn, recv.msg.offset);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int kdbus_test_message_prio(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *a, *b;
+	uint64_t cookie = 0;
+
+	a = kdbus_hello(env->buspath, 0, NULL, 0);
+	b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(a && b);
+
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   25, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -600, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   10, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -35, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -100, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   20, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -15, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -150, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,   10, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0, -800, a->id) == 0);
+	ASSERT_RETURN(kdbus_msg_send(b, NULL, ++cookie, 0, 0,  -10, a->id) == 0);
+
+	ASSERT_RETURN(msg_recv_prio(a, -200, -800) == 0);
+	ASSERT_RETURN(msg_recv_prio(a, -100, -800) == 0);
+	ASSERT_RETURN(msg_recv_prio(a, -400, -600) == 0);
+	ASSERT_RETURN(msg_recv_prio(a, -400, -600) == -EAGAIN);
+	ASSERT_RETURN(msg_recv_prio(a, 10, -150) == 0);
+	ASSERT_RETURN(msg_recv_prio(a, 10, -100) == 0);
+
+	kdbus_printf("--- get priority (all)\n");
+	ASSERT_RETURN(kdbus_msg_recv(a, NULL, NULL) == 0);
+
+	kdbus_conn_free(a);
+	kdbus_conn_free(b);
+
+	return TEST_OK;
+}
+
+static int kdbus_test_notify_kernel_quota(struct kdbus_test_env *env)
+{
+	int ret;
+	unsigned int i;
+	struct kdbus_conn *conn;
+	struct kdbus_conn *reader;
+	struct kdbus_msg *msg = NULL;
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+
+	reader = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(reader);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	/* Register for ID signals */
+	ret = kdbus_add_match_id(reader, 0x1, KDBUS_ITEM_ID_ADD,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_id(reader, 0x2, KDBUS_ITEM_ID_REMOVE,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	/* Each iteration two notifications: add and remove ID */
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS / 2; i++) {
+		struct kdbus_conn *notifier;
+
+		notifier = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_RETURN(notifier);
+
+		kdbus_conn_free(notifier);
+	}
+
+	/*
+	 * Now the reader queue is full with kernel notfications,
+	 * but as a user we still have room to push our messages.
+	 */
+	ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0, 0, reader->id);
+	ASSERT_RETURN(ret == 0);
+
+	/* More ID kernel notifications that will be lost */
+	kdbus_conn_free(conn);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	kdbus_conn_free(conn);
+
+	/*
+	 * We lost only 3 packets since only signal msgs are
+	 * accounted. The connection ID add/remove notification
+	 */
+	ret = kdbus_cmd_recv(reader->fd, &recv);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS);
+	ASSERT_RETURN(recv.dropped_msgs == 3);
+
+	msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
+	kdbus_msg_free(msg);
+
+	/* Read our queue */
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS - 1; i++) {
+		memset(&recv, 0, sizeof(recv));
+		recv.size = sizeof(recv);
+
+		ret = kdbus_cmd_recv(reader->fd, &recv);
+		ASSERT_RETURN(ret == 0);
+		ASSERT_RETURN(!(recv.return_flags &
+			        KDBUS_RECV_RETURN_DROPPED_MSGS));
+
+		msg = (struct kdbus_msg *)(reader->buf + recv.msg.offset);
+		kdbus_msg_free(msg);
+	}
+
+	ret = kdbus_msg_recv(reader, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(reader, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	kdbus_conn_free(reader);
+
+	return 0;
+}
+
+/* Return the number of message successfully sent */
+static int kdbus_fill_conn_queue(struct kdbus_conn *conn_src,
+				 uint64_t dst_id,
+				 unsigned int max_msgs)
+{
+	unsigned int i;
+	uint64_t cookie = 0;
+	size_t size;
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_msg *msg;
+	int ret;
+
+	size = sizeof(struct kdbus_msg);
+	msg = malloc(size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = conn_src->id;
+	msg->dst_id = dst_id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	for (i = 0; i < max_msgs; i++) {
+		msg->cookie = cookie++;
+		ret = kdbus_cmd_send(conn_src->fd, &cmd);
+		if (ret < 0)
+			break;
+	}
+
+	free(msg);
+
+	return i;
+}
+
+static int kdbus_test_activator_quota(struct kdbus_test_env *env)
+{
+	int ret;
+	unsigned int i;
+	unsigned int activator_msgs_count = 0;
+	uint64_t cookie = time(NULL);
+	struct kdbus_conn *conn;
+	struct kdbus_conn *sender;
+	struct kdbus_conn *activator;
+	struct kdbus_msg *msg;
+	uint64_t flags = KDBUS_NAME_REPLACE_EXISTING;
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+	struct kdbus_policy_access access = {
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	activator = kdbus_hello_activator(env->buspath, "foo.test.activator",
+					  &access, 1);
+	ASSERT_RETURN(activator);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	sender = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn || sender);
+
+	ret = kdbus_list(sender, KDBUS_LIST_NAMES |
+				 KDBUS_LIST_UNIQUE |
+				 KDBUS_LIST_ACTIVATORS |
+				 KDBUS_LIST_QUEUED);
+	ASSERT_RETURN(ret == 0);
+
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
+		ret = kdbus_msg_send(sender, "foo.test.activator",
+				     cookie++, 0, 0, 0,
+				     KDBUS_DST_ID_NAME);
+		if (ret < 0)
+			break;
+		activator_msgs_count++;
+	}
+
+	/* we must have at least sent one message */
+	ASSERT_RETURN_VAL(i > 0, -errno);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	/* Good, activator queue is full now */
+
+	/* ENXIO on direct send (activators can never be addressed by ID) */
+	ret = kdbus_msg_send(conn, NULL, cookie++, 0, 0, 0, activator->id);
+	ASSERT_RETURN(ret == -ENXIO);
+
+	/* can't queue more */
+	ret = kdbus_msg_send(conn, "foo.test.activator", cookie++,
+			     0, 0, 0, KDBUS_DST_ID_NAME);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	/* no match installed, so the broadcast will not inc dropped_msgs */
+	ret = kdbus_msg_send(sender, NULL, cookie++, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	/* Check activator queue */
+	ret = kdbus_cmd_recv(activator->fd, &recv);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv.dropped_msgs == 0);
+
+	activator_msgs_count--;
+
+	msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
+	kdbus_msg_free(msg);
+
+
+	/* Stage 1) of test check the pool memory quota */
+
+	/* Consume the connection pool memory */
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
+		ret = kdbus_msg_send(sender, NULL,
+				     cookie++, 0, 0, 0, conn->id);
+		if (ret < 0)
+			break;
+	}
+
+	/* consume one message, so later at least one can be moved */
+	memset(&recv, 0, sizeof(recv));
+	recv.size = sizeof(recv);
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv.dropped_msgs == 0);
+	msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
+	kdbus_msg_free(msg);
+
+	/* Try to acquire the name now */
+	ret = kdbus_name_acquire(conn, "foo.test.activator", &flags);
+	ASSERT_RETURN(ret == 0);
+
+	/* try to read messages and see if we have lost some */
+	memset(&recv, 0, sizeof(recv));
+	recv.size = sizeof(recv);
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv.dropped_msgs != 0);
+
+	/* number of dropped msgs < received ones (at least one was moved) */
+	ASSERT_RETURN(recv.dropped_msgs < activator_msgs_count);
+
+	/* Deduct the number of dropped msgs from the activator msgs */
+	activator_msgs_count -= recv.dropped_msgs;
+
+	msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
+	kdbus_msg_free(msg);
+
+	/*
+	 * Release the name and hand it back to activator, now
+	 * we should have 'activator_msgs_count' msgs again in
+	 * the activator queue
+	 */
+	ret = kdbus_name_release(conn, "foo.test.activator");
+	ASSERT_RETURN(ret == 0);
+
+	/* make sure that we got our previous activator msgs */
+	ret = kdbus_msg_recv(activator, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->src_id == sender->id);
+
+	activator_msgs_count--;
+
+	kdbus_msg_free(msg);
+
+
+	/* Stage 2) of test check max message quota */
+
+	/* Empty conn queue */
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS; i++) {
+		ret = kdbus_msg_recv(conn, NULL, NULL);
+		if (ret == -EAGAIN)
+			break;
+	}
+
+	/* fill queue with max msgs quota */
+	ret = kdbus_fill_conn_queue(sender, conn->id, KDBUS_CONN_MAX_MSGS);
+	ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
+
+	/* This one is lost but it is not accounted */
+	ret = kdbus_msg_send(sender, NULL,
+			     cookie++, 0, 0, 0, conn->id);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	/* Acquire the name again */
+	ret = kdbus_name_acquire(conn, "foo.test.activator", &flags);
+	ASSERT_RETURN(ret == 0);
+
+	memset(&recv, 0, sizeof(recv));
+	recv.size = sizeof(recv);
+
+	/*
+	 * Try to read messages and make sure that we have lost all
+	 * the activator messages due to quota checks. Our queue is
+	 * already full.
+	 */
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv.dropped_msgs == activator_msgs_count);
+
+	msg = (struct kdbus_msg *)(activator->buf + recv.msg.offset);
+	kdbus_msg_free(msg);
+
+	kdbus_conn_free(sender);
+	kdbus_conn_free(conn);
+	kdbus_conn_free(activator);
+
+	return 0;
+}
+
+static int kdbus_test_expected_reply_quota(struct kdbus_test_env *env)
+{
+	int ret;
+	unsigned int i, n;
+	unsigned int count;
+	uint64_t cookie = 0x1234abcd5678eeff;
+	struct kdbus_conn *conn;
+	struct kdbus_conn *connections[9];
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	for (i = 0; i < 9; i++) {
+		connections[i] = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_RETURN(connections[i]);
+	}
+
+	count = 0;
+	/* Send 16 messages to 8 different connections */
+	for (i = 0; i < 8; i++) {
+		for (n = 0; n < 16; n++) {
+			ret = kdbus_msg_send(conn, NULL, cookie++,
+					     KDBUS_MSG_EXPECT_REPLY,
+					     100000000ULL, 0,
+					     connections[i]->id);
+			if (ret < 0)
+				break;
+
+			count++;
+		}
+	}
+
+	/*
+	 * We should have queued at least
+	 * KDBUS_CONN_MAX_REQUESTS_PENDING method call
+	 */
+	ASSERT_RETURN(count == KDBUS_CONN_MAX_REQUESTS_PENDING);
+
+	/*
+	 * Now try to send a message to the last connection,
+	 * if we have reached KDBUS_CONN_MAX_REQUESTS_PENDING
+	 * no further requests are allowed
+	 */
+	ret = kdbus_msg_send(conn, NULL, cookie++, KDBUS_MSG_EXPECT_REPLY,
+			     1000000000ULL, 0, connections[8]->id);
+	ASSERT_RETURN(ret == -EMLINK);
+
+	for (i = 0; i < 9; i++)
+		kdbus_conn_free(connections[i]);
+
+	kdbus_conn_free(conn);
+
+	return 0;
+}
+
+int kdbus_test_pool_quota(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *a, *b, *c;
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_item *item;
+	struct kdbus_msg *recv_msg;
+	struct kdbus_msg *msg;
+	uint64_t cookie = time(NULL);
+	uint64_t size;
+	unsigned int i;
+	char *payload;
+	int ret;
+
+	/* just a guard */
+	if (POOL_SIZE <= KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE ||
+	    POOL_SIZE % KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE != 0)
+		return 0;
+
+	payload = calloc(KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE, sizeof(char));
+	ASSERT_RETURN_VAL(payload, -ENOMEM);
+
+	a = kdbus_hello(env->buspath, 0, NULL, 0);
+	b = kdbus_hello(env->buspath, 0, NULL, 0);
+	c = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(a && b && c);
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	msg = malloc(size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = a->id;
+	msg->dst_id = c->id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	item = msg->items;
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = (uintptr_t)payload;
+	item->vec.size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
+	item = KDBUS_ITEM_NEXT(item);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	/*
+	 * Send 2097248 bytes, a user is only allowed to get 33% of half of
+	 * the free space of the pool, the already used space is
+	 * accounted as free space
+	 */
+	size += KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
+	for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
+		msg->cookie = cookie++;
+
+		ret = kdbus_cmd_send(a->fd, &cmd);
+		ASSERT_RETURN_VAL(ret == 0, ret);
+	}
+
+	/* Try to get more than 33% */
+	msg->cookie = cookie++;
+	ret = kdbus_cmd_send(a->fd, &cmd);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	/* We still can pass small messages */
+	ret = kdbus_msg_send(b, NULL, cookie++, 0, 0, 0, c->id);
+	ASSERT_RETURN(ret == 0);
+
+	for (i = size; i < (POOL_SIZE / 2 / 3); i += size) {
+		ret = kdbus_msg_recv(c, &recv_msg, NULL);
+		ASSERT_RETURN(ret == 0);
+		ASSERT_RETURN(recv_msg->src_id == a->id);
+
+		kdbus_msg_free(recv_msg);
+	}
+
+	ret = kdbus_msg_recv(c, &recv_msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(recv_msg->src_id == b->id);
+
+	kdbus_msg_free(recv_msg);
+
+	ret = kdbus_msg_recv(c, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	free(msg);
+	free(payload);
+
+	kdbus_conn_free(c);
+	kdbus_conn_free(b);
+	kdbus_conn_free(a);
+
+	return 0;
+}
+
+int kdbus_test_message_quota(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *a, *b;
+	uint64_t cookie = 0;
+	int ret;
+	int i;
+
+	ret = kdbus_test_activator_quota(env);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_test_notify_kernel_quota(env);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_test_pool_quota(env);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_test_expected_reply_quota(env);
+	ASSERT_RETURN(ret == 0);
+
+	a = kdbus_hello(env->buspath, 0, NULL, 0);
+	b = kdbus_hello(env->buspath, 0, NULL, 0);
+
+	ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS);
+	ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
+
+	ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	for (i = 0; i < KDBUS_CONN_MAX_MSGS; ++i) {
+		ret = kdbus_msg_recv(a, NULL, NULL);
+		ASSERT_RETURN(ret == 0);
+	}
+
+	ret = kdbus_msg_recv(a, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	ret = kdbus_fill_conn_queue(b, a->id, KDBUS_CONN_MAX_MSGS + 1);
+	ASSERT_RETURN(ret == KDBUS_CONN_MAX_MSGS);
+
+	ret = kdbus_msg_send(b, NULL, ++cookie, 0, 0, 0, a->id);
+	ASSERT_RETURN(ret == -ENOBUFS);
+
+	kdbus_conn_free(a);
+	kdbus_conn_free(b);
+
+	return TEST_OK;
+}
+
+int kdbus_test_memory_access(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *a, *b;
+	struct kdbus_cmd_send cmd = {};
+	struct kdbus_item *item;
+	struct kdbus_msg *msg;
+	uint64_t test_addr = 0;
+	char line[256];
+	uint64_t size;
+	FILE *f;
+	int ret;
+
+	/*
+	 * Search in /proc/kallsyms for the address of a kernel symbol that
+	 * should always be there, regardless of the config. Use that address
+	 * in a PAYLOAD_VEC item and make sure it's inaccessible.
+	 */
+
+	f = fopen("/proc/kallsyms", "r");
+	if (!f)
+		return TEST_SKIP;
+
+	while (fgets(line, sizeof(line), f)) {
+		char *s = line;
+
+		if (!strsep(&s, " "))
+			continue;
+
+		if (!strsep(&s, " "))
+			continue;
+
+		if (!strncmp(s, "mutex_lock", 10)) {
+			test_addr = strtoull(line, NULL, 16);
+			break;
+		}
+	}
+
+	fclose(f);
+
+	if (!test_addr)
+		return TEST_SKIP;
+
+	a = kdbus_hello(env->buspath, 0, NULL, 0);
+	b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(a && b);
+
+	size = sizeof(struct kdbus_msg);
+	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
+
+	msg = alloca(size);
+	ASSERT_RETURN_VAL(msg, -ENOMEM);
+
+	memset(msg, 0, size);
+	msg->size = size;
+	msg->src_id = a->id;
+	msg->dst_id = b->id;
+	msg->payload_type = KDBUS_PAYLOAD_DBUS;
+
+	item = msg->items;
+	item->type = KDBUS_ITEM_PAYLOAD_VEC;
+	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
+	item->vec.address = test_addr;
+	item->vec.size = sizeof(void*);
+	item = KDBUS_ITEM_NEXT(item);
+
+	cmd.size = sizeof(cmd);
+	cmd.msg_address = (uintptr_t)msg;
+
+	ret = kdbus_cmd_send(a->fd, &cmd);
+	ASSERT_RETURN(ret == -EFAULT);
+
+	kdbus_conn_free(b);
+	kdbus_conn_free(a);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c b/tools/testing/selftests/kdbus/test-metadata-ns.c
new file mode 100644
index 000000000000..1f6edc09008a
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-metadata-ns.c
@@ -0,0 +1,500 @@
+/*
+ * Test metadata in new namespaces. Even if our tests can run
+ * in a namespaced setup, this test is necessary so we can inspect
+ * metadata on the same kdbusfs but between multiple namespaces
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sched.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <sys/eventfd.h>
+#include <sys/syscall.h>
+#include <sys/capability.h>
+#include <linux/sched.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+static const struct kdbus_creds privileged_creds = {};
+
+static const struct kdbus_creds unmapped_creds = {
+	.uid	= UNPRIV_UID,
+	.euid	= UNPRIV_UID,
+	.suid	= UNPRIV_UID,
+	.fsuid	= UNPRIV_UID,
+	.gid	= UNPRIV_GID,
+	.egid	= UNPRIV_GID,
+	.sgid	= UNPRIV_GID,
+	.fsgid	= UNPRIV_GID,
+};
+
+static const struct kdbus_pids unmapped_pids = {};
+
+/* Get only the first item */
+static struct kdbus_item *kdbus_get_item(struct kdbus_msg *msg,
+					 uint64_t type)
+{
+	struct kdbus_item *item;
+
+	KDBUS_ITEM_FOREACH(item, msg, items)
+		if (item->type == type)
+			return item;
+
+	return NULL;
+}
+
+static int kdbus_match_kdbus_creds(struct kdbus_msg *msg,
+				   const struct kdbus_creds *expected_creds)
+{
+	struct kdbus_item *item;
+
+	item = kdbus_get_item(msg, KDBUS_ITEM_CREDS);
+	ASSERT_RETURN(item);
+
+	ASSERT_RETURN(memcmp(&item->creds, expected_creds,
+			     sizeof(struct kdbus_creds)) == 0);
+
+	return 0;
+}
+
+static int kdbus_match_kdbus_pids(struct kdbus_msg *msg,
+				  const struct kdbus_pids *expected_pids)
+{
+	struct kdbus_item *item;
+
+	item = kdbus_get_item(msg, KDBUS_ITEM_PIDS);
+	ASSERT_RETURN(item);
+
+	ASSERT_RETURN(memcmp(&item->pids, expected_pids,
+			     sizeof(struct kdbus_pids)) == 0);
+
+	return 0;
+}
+
+static int __kdbus_clone_userns_test(const char *bus,
+				     struct kdbus_conn *conn,
+				     uint64_t grandpa_pid,
+				     int signal_fd)
+{
+	int clone_ret;
+	int ret;
+	struct kdbus_msg *msg = NULL;
+	const struct kdbus_item *item;
+	uint64_t cookie = time(NULL) ^ 0xdeadbeef;
+	struct kdbus_conn *unpriv_conn = NULL;
+	struct kdbus_pids parent_pids = {
+		.pid = getppid(),
+		.tid = getppid(),
+		.ppid = grandpa_pid,
+	};
+
+	ret = drop_privileges(UNPRIV_UID, UNPRIV_GID);
+	ASSERT_EXIT(ret == 0);
+
+	unpriv_conn = kdbus_hello(bus, 0, NULL, 0);
+	ASSERT_EXIT(unpriv_conn);
+
+	ret = kdbus_add_match_empty(unpriv_conn);
+	ASSERT_EXIT(ret == 0);
+
+	/*
+	 * ping privileged connection from this new unprivileged
+	 * one
+	 */
+
+	ret = kdbus_msg_send(unpriv_conn, NULL, cookie, 0, 0,
+			     0, conn->id);
+	ASSERT_EXIT(ret == 0);
+
+	/*
+	 * Since we just dropped privileges, the dumpable flag
+	 * was just cleared which makes the /proc/$clone_child/uid_map
+	 * to be owned by root, hence any userns uid mapping will fail
+	 * with -EPERM since the mapping will be done by uid 65534.
+	 *
+	 * To avoid this set the dumpable flag again which makes
+	 * procfs update the /proc/$clone_child/ inodes owner to 65534.
+	 *
+	 * Using this we will be able write to /proc/$clone_child/uid_map
+	 * as uid 65534 and map the uid 65534 to 0 inside the user namespace.
+	 */
+	ret = prctl(PR_SET_DUMPABLE, SUID_DUMP_USER);
+	ASSERT_EXIT(ret == 0);
+
+	/* Make child privileged in its new userns and run tests */
+
+	ret = RUN_CLONE_CHILD(&clone_ret,
+			      SIGCHLD | CLONE_NEWUSER | CLONE_NEWPID,
+	({ 0;  /* Clone setup, nothing */ }),
+	({
+		eventfd_t event_status = 0;
+		struct kdbus_conn *userns_conn;
+
+		/* ping connection from the new user namespace */
+		userns_conn = kdbus_hello(bus, 0, NULL, 0);
+		ASSERT_EXIT(userns_conn);
+
+		ret = kdbus_add_match_empty(userns_conn);
+		ASSERT_EXIT(ret == 0);
+
+		cookie++;
+		ret = kdbus_msg_send(userns_conn, NULL, cookie,
+				     0, 0, 0, conn->id);
+		ASSERT_EXIT(ret == 0);
+
+		/* Parent did send */
+		ret = eventfd_read(signal_fd, &event_status);
+		ASSERT_RETURN(ret >= 0 && event_status == 1);
+
+		/*
+		 * Receive from privileged connection
+		 */
+		kdbus_printf("Privileged → unprivileged/privileged "
+			     "in its userns "
+			     "(different userns and pidns):\n");
+		ret = kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL);
+		ASSERT_EXIT(ret == 0);
+		ASSERT_EXIT(msg->dst_id == userns_conn->id);
+
+		item = kdbus_get_item(msg, KDBUS_ITEM_CAPS);
+		ASSERT_EXIT(item);
+
+		/* uid/gid not mapped, so we have unpriv cached creds */
+		ret = kdbus_match_kdbus_creds(msg, &unmapped_creds);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * Diffent pid namepsaces. This is the child pidns
+		 * so it should not see its parent kdbus_pids
+		 */
+		ret = kdbus_match_kdbus_pids(msg, &unmapped_pids);
+		ASSERT_EXIT(ret == 0);
+
+		kdbus_msg_free(msg);
+
+
+		/*
+		 * Receive broadcast from privileged connection
+		 */
+		kdbus_printf("Privileged → unprivileged/privileged "
+			     "in its userns "
+			     "(different userns and pidns):\n");
+		ret = kdbus_msg_recv_poll(userns_conn, 300, &msg, NULL);
+		ASSERT_EXIT(ret == 0);
+		ASSERT_EXIT(msg->dst_id == KDBUS_DST_ID_BROADCAST);
+
+		item = kdbus_get_item(msg, KDBUS_ITEM_CAPS);
+		ASSERT_EXIT(item);
+
+		/* uid/gid not mapped, so we have unpriv cached creds */
+		ret = kdbus_match_kdbus_creds(msg, &unmapped_creds);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * Diffent pid namepsaces. This is the child pidns
+		 * so it should not see its parent kdbus_pids
+		 */
+		ret = kdbus_match_kdbus_pids(msg, &unmapped_pids);
+		ASSERT_EXIT(ret == 0);
+
+		kdbus_msg_free(msg);
+
+		kdbus_conn_free(userns_conn);
+	}),
+	({
+		/* Parent setup map child uid/gid */
+		ret = userns_map_uid_gid(pid, "0 65534 1", "0 65534 1");
+		ASSERT_EXIT(ret == 0);
+	}),
+	({ 0; }));
+	/* Unprivileged was not able to create user namespace */
+	if (clone_ret == -EPERM) {
+		kdbus_printf("-- CLONE_NEWUSER TEST Failed for "
+			     "uid: %u\n -- Make sure that your kernel "
+			     "do not allow CLONE_NEWUSER for "
+			     "unprivileged users\n", UNPRIV_UID);
+		ret = 0;
+		goto out;
+	}
+
+	ASSERT_EXIT(ret == 0);
+
+
+	/*
+	 * Receive from privileged connection
+	 */
+	kdbus_printf("\nPrivileged → unprivileged (same namespaces):\n");
+	ret = kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL);
+
+	ASSERT_EXIT(ret == 0);
+	ASSERT_EXIT(msg->dst_id == unpriv_conn->id);
+
+	/* will get the privileged creds */
+	ret = kdbus_match_kdbus_creds(msg, &privileged_creds);
+	ASSERT_EXIT(ret == 0);
+
+	/* Same pidns so will get the kdbus_pids */
+	ret = kdbus_match_kdbus_pids(msg, &parent_pids);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_msg_free(msg);
+
+
+	/*
+	 * Receive broadcast from privileged connection
+	 */
+	kdbus_printf("\nPrivileged → unprivileged (same namespaces):\n");
+	ret = kdbus_msg_recv_poll(unpriv_conn, 300, &msg, NULL);
+
+	ASSERT_EXIT(ret == 0);
+	ASSERT_EXIT(msg->dst_id == KDBUS_DST_ID_BROADCAST);
+
+	/* will get the privileged creds */
+	ret = kdbus_match_kdbus_creds(msg, &privileged_creds);
+	ASSERT_EXIT(ret == 0);
+
+	ret = kdbus_match_kdbus_pids(msg, &parent_pids);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_msg_free(msg);
+
+out:
+	kdbus_conn_free(unpriv_conn);
+
+	return ret;
+}
+
+static int kdbus_clone_userns_test(const char *bus,
+				   struct kdbus_conn *conn)
+{
+	int ret, status, efd;
+	pid_t pid, ppid;
+	uint64_t unpriv_conn_id, userns_conn_id;
+	struct kdbus_msg *msg;
+	const struct kdbus_item *item;
+	struct kdbus_pids expected_pids;
+	struct kdbus_conn *monitor;
+
+	kdbus_printf("STARTING TEST 'metadata-ns'.\n");
+
+	monitor = kdbus_hello(bus, KDBUS_HELLO_MONITOR, NULL, 0);
+	ASSERT_EXIT(monitor);
+
+	/*
+	 * parent will signal to child that is in its
+	 * userns to read its queue
+	 */
+	efd = eventfd(0, EFD_CLOEXEC);
+	ASSERT_RETURN_VAL(efd >= 0, efd);
+
+	ppid = getppid();
+
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, -errno);
+
+	if (pid == 0) {
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		ASSERT_EXIT_VAL(ret == 0, -errno);
+
+		ret = __kdbus_clone_userns_test(bus, conn, ppid, efd);
+		_exit(ret);
+	}
+
+
+	/* Phase 1) privileged receives from unprivileged */
+
+	/*
+	 * Receive from the unprivileged child
+	 */
+	kdbus_printf("\nUnprivileged → privileged (same namespaces):\n");
+	ret = kdbus_msg_recv_poll(conn, 300, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	unpriv_conn_id = msg->src_id;
+
+	/* Unprivileged user */
+	ret = kdbus_match_kdbus_creds(msg, &unmapped_creds);
+	ASSERT_RETURN(ret == 0);
+
+	/* Set the expected creds_pids */
+	expected_pids = (struct kdbus_pids) {
+		.pid = pid,
+		.tid = pid,
+		.ppid = getpid(),
+	};
+	ret = kdbus_match_kdbus_pids(msg, &expected_pids);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_msg_free(msg);
+
+
+	/*
+	 * Receive from the unprivileged that is in his own
+	 * userns and pidns
+	 */
+
+	kdbus_printf("\nUnprivileged/privileged in its userns → privileged "
+		     "(different userns and pidns)\n");
+	ret = kdbus_msg_recv_poll(conn, 300, &msg, NULL);
+	if (ret == -ETIMEDOUT)
+		/* perhaps unprivileged userns is not allowed */
+		goto wait;
+
+	ASSERT_RETURN(ret == 0);
+
+	userns_conn_id = msg->src_id;
+
+	item = kdbus_get_item(msg, KDBUS_ITEM_CAPS);
+	ASSERT_RETURN(item);
+
+	/*
+	 * Compare received items, creds must be translated into
+	 * the receiver user namespace, so the user is unprivileged
+	 */
+	ret = kdbus_match_kdbus_creds(msg, &unmapped_creds);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * We should have the kdbus_pids since we are the parent
+	 * pidns
+	 */
+	item = kdbus_get_item(msg, KDBUS_ITEM_PIDS);
+	ASSERT_RETURN(item);
+
+	ASSERT_RETURN(memcmp(&item->pids, &unmapped_pids,
+			     sizeof(struct kdbus_pids)) != 0);
+
+	/*
+	 * Parent pid of the unprivileged/privileged in its userns
+	 * is the unprivileged child pid that was forked here.
+	 */
+	ASSERT_RETURN((uint64_t)pid == item->pids.ppid);
+
+	kdbus_msg_free(msg);
+
+
+	/* Phase 2) Privileged connection sends now 3 packets */
+
+	/*
+	 * Sending to unprivileged connections a unicast
+	 */
+	ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
+			     0, unpriv_conn_id);
+	ASSERT_RETURN(ret == 0);
+
+	/* signal to child that is in its userns */
+	ret = eventfd_write(efd, 1);
+	ASSERT_EXIT(ret == 0);
+
+	/*
+	 * Sending to unprivileged/privilged in its userns
+	 * connections a unicast
+	 */
+	ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
+			     0, userns_conn_id);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Sending to unprivileged connections a broadcast
+	 */
+	ret = kdbus_msg_send(conn, NULL, 0xdeadbeef, 0, 0,
+			     0, KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+
+wait:
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN(ret >= 0);
+
+	ASSERT_RETURN(WIFEXITED(status))
+	ASSERT_RETURN(!WEXITSTATUS(status));
+
+	/* Dump monitor queue */
+	kdbus_printf("\n\nMonitor queue:\n");
+	for (;;) {
+		ret = kdbus_msg_recv_poll(monitor, 100, &msg, NULL);
+		if (ret < 0)
+			break;
+
+		if (msg->payload_type == KDBUS_PAYLOAD_DBUS) {
+			/*
+			 * Parent pidns should see all the
+			 * pids
+			 */
+			item = kdbus_get_item(msg, KDBUS_ITEM_PIDS);
+			ASSERT_RETURN(item);
+
+			ASSERT_RETURN(item->pids.pid != 0 &&
+				      item->pids.tid != 0 &&
+				      item->pids.ppid != 0);
+		}
+
+		kdbus_msg_free(msg);
+	}
+
+	kdbus_conn_free(monitor);
+	close(efd);
+
+	return 0;
+}
+
+int kdbus_test_metadata_ns(struct kdbus_test_env *env)
+{
+	int ret;
+	struct kdbus_conn *holder, *conn;
+	struct kdbus_policy_access policy_access = {
+		/* Allow world so we can inspect metadata in namespace */
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	/*
+	 * We require user-namespaces and all uids/gids
+	 * should be mapped (we can just require the necessary ones)
+	 */
+	if (!config_user_ns_is_enabled() ||
+	    !all_uids_gids_are_mapped())
+		return TEST_SKIP;
+
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, CAP_SYS_ADMIN, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	/* no enough privileges, SKIP test */
+	if (!ret)
+		return TEST_SKIP;
+
+	holder = kdbus_hello_registrar(env->buspath, "com.example.metadata",
+				       &policy_access, 1,
+				       KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(holder);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	ret = kdbus_add_match_empty(conn);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(conn, "com.example.metadata", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	ret = kdbus_clone_userns_test(env->buspath, conn);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_conn_free(holder);
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-monitor.c b/tools/testing/selftests/kdbus/test-monitor.c
new file mode 100644
index 000000000000..e00d738a3986
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-monitor.c
@@ -0,0 +1,176 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/capability.h>
+#include <sys/wait.h>
+
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+int kdbus_test_monitor(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *monitor, *conn;
+	unsigned int cookie = 0xdeadbeef;
+	struct kdbus_msg *msg;
+	uint64_t offset = 0;
+	int ret;
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	/* add matches to make sure the monitor do not trigger an item add or
+	 * remove on connect and disconnect, respectively.
+	 */
+	ret = kdbus_add_match_id(conn, 0x1, KDBUS_ITEM_ID_ADD,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_add_match_id(conn, 0x2, KDBUS_ITEM_ID_REMOVE,
+				 KDBUS_MATCH_ID_ANY);
+	ASSERT_RETURN(ret == 0);
+
+	/* register a monitor */
+	monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0);
+	ASSERT_RETURN(monitor);
+
+	/* make sure we did not receive a monitor connect notification */
+	ret = kdbus_msg_recv(conn, &msg, &offset);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/* check that a monitor cannot acquire a name */
+	ret = kdbus_name_acquire(monitor, "foo.bar.baz", NULL);
+	ASSERT_RETURN(ret == -EOPNOTSUPP);
+
+	ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0,  0, conn->id);
+	ASSERT_RETURN(ret == 0);
+
+	/* the recipient should have gotten the message */
+	ret = kdbus_msg_recv(conn, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+	kdbus_msg_free(msg);
+	kdbus_free(conn, offset);
+
+	/* and so should the monitor */
+	ret = kdbus_msg_recv(monitor, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+	kdbus_free(monitor, offset);
+
+	/* Installing matches for monitors must fais must fail */
+	ret = kdbus_add_match_empty(monitor);
+	ASSERT_RETURN(ret == -EOPNOTSUPP);
+
+	cookie++;
+	ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	/* The monitor should get the message. */
+	ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+	kdbus_free(monitor, offset);
+
+	/*
+	 * Since we are the only monitor, update the attach flags
+	 * and tell we are not interessted in attach flags recv
+	 */
+
+	ret = kdbus_conn_update_attach_flags(monitor,
+					     _KDBUS_ATTACH_ALL,
+					     0);
+	ASSERT_RETURN(ret == 0);
+
+	cookie++;
+	ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_msg_free(msg);
+	kdbus_free(monitor, offset);
+
+	/*
+	 * Now we are interested in KDBUS_ITEM_TIMESTAMP and
+	 * KDBUS_ITEM_CREDS
+	 */
+	ret = kdbus_conn_update_attach_flags(monitor,
+					     _KDBUS_ATTACH_ALL,
+					     KDBUS_ATTACH_TIMESTAMP |
+					     KDBUS_ATTACH_CREDS);
+	ASSERT_RETURN(ret == 0);
+
+	cookie++;
+	ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == cookie);
+
+	ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
+	ASSERT_RETURN(ret == 1);
+
+	ret = kdbus_item_in_message(msg, KDBUS_ITEM_CREDS);
+	ASSERT_RETURN(ret == 1);
+
+	/* the KDBUS_ITEM_PID_COMM was not requested */
+	ret = kdbus_item_in_message(msg, KDBUS_ITEM_PID_COMM);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_msg_free(msg);
+	kdbus_free(monitor, offset);
+
+	kdbus_conn_free(monitor);
+	/* make sure we did not receive a monitor disconnect notification */
+	ret = kdbus_msg_recv(conn, &msg, &offset);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	kdbus_conn_free(conn);
+
+	/* Make sure that monitor as unprivileged is not allowed */
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	if (ret && all_uids_gids_are_mapped()) {
+		ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
+			monitor = kdbus_hello(env->buspath,
+					      KDBUS_HELLO_MONITOR,
+					      NULL, 0);
+			ASSERT_EXIT(!monitor && errno == EPERM);
+
+			_exit(EXIT_SUCCESS);
+		}),
+		({ 0; }));
+		ASSERT_RETURN(ret == 0);
+	}
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-names.c b/tools/testing/selftests/kdbus/test-names.c
new file mode 100644
index 000000000000..e400dc86a2f5
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-names.c
@@ -0,0 +1,272 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <getopt.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+struct test_name {
+	const char *name;
+	__u64 owner_id;
+	__u64 flags;
+};
+
+static bool conn_test_names(const struct kdbus_conn *conn,
+			    const struct test_name *tests,
+			    unsigned int n_tests)
+{
+	struct kdbus_cmd_list cmd_list = {};
+	struct kdbus_info *name, *list;
+	unsigned int i;
+	int ret;
+
+	cmd_list.size = sizeof(cmd_list);
+	cmd_list.flags = KDBUS_LIST_NAMES |
+			 KDBUS_LIST_ACTIVATORS |
+			 KDBUS_LIST_QUEUED;
+
+	ret = kdbus_cmd_list(conn->fd, &cmd_list);
+	ASSERT_RETURN(ret == 0);
+
+	list = (struct kdbus_info *)(conn->buf + cmd_list.offset);
+
+	for (i = 0; i < n_tests; i++) {
+		const struct test_name *t = tests + i;
+		bool found = false;
+
+		KDBUS_FOREACH(name, list, cmd_list.list_size) {
+			struct kdbus_item *item;
+
+			KDBUS_ITEM_FOREACH(item, name, items) {
+				if (item->type != KDBUS_ITEM_OWNED_NAME ||
+				    strcmp(item->name.name, t->name) != 0)
+					continue;
+
+				if (t->owner_id == name->id &&
+				    t->flags == item->name.flags) {
+					found = true;
+					break;
+				}
+			}
+		}
+
+		if (!found)
+			return false;
+	}
+
+	return true;
+}
+
+static bool conn_is_name_primary_owner(const struct kdbus_conn *conn,
+				       const char *needle)
+{
+	struct test_name t = {
+		.name = needle,
+		.owner_id = conn->id,
+		.flags = KDBUS_NAME_PRIMARY,
+	};
+
+	return conn_test_names(conn, &t, 1);
+}
+
+int kdbus_test_name_basic(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	char *name, *dot_name, *invalid_name, *wildcard_name;
+	int ret;
+
+	name = "foo.bla.blaz";
+	dot_name = ".bla.blaz";
+	invalid_name = "foo";
+	wildcard_name = "foo.bla.bl.*";
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* acquire name "foo.bar.xxx" name */
+	ret = kdbus_name_acquire(conn, "foo.bar.xxx", NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* Name is not valid, must fail */
+	ret = kdbus_name_acquire(env->conn, dot_name, NULL);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	ret = kdbus_name_acquire(env->conn, invalid_name, NULL);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	ret = kdbus_name_acquire(env->conn, wildcard_name, NULL);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	/* check that we can acquire a name */
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = conn_is_name_primary_owner(env->conn, name);
+	ASSERT_RETURN(ret == true);
+
+	/* ... and release it again */
+	ret = kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	ret = conn_is_name_primary_owner(env->conn, name);
+	ASSERT_RETURN(ret == false);
+
+	/* check that we can't release it again */
+	ret = kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	/* check that we can't release a name that we don't own */
+	ret = kdbus_name_release(env->conn, "foo.bar.xxx");
+	ASSERT_RETURN(ret == -EADDRINUSE);
+
+	/* Name is not valid, must fail */
+	ret = kdbus_name_release(env->conn, dot_name);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	ret = kdbus_name_release(env->conn, invalid_name);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	ret = kdbus_name_release(env->conn, wildcard_name);
+	ASSERT_RETURN(ret == -ESRCH);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+int kdbus_test_name_conflict(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	char *name;
+	int ret;
+
+	name = "foo.bla.blaz";
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* allow the new connection to own the same name */
+	/* acquire name from the 1st connection */
+	ret = kdbus_name_acquire(env->conn, name, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = conn_is_name_primary_owner(env->conn, name);
+	ASSERT_RETURN(ret == true);
+
+	/* check that we also can't acquire it again from the 2nd connection */
+	ret = kdbus_name_acquire(conn, name, NULL);
+	ASSERT_RETURN(ret == -EEXIST);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+int kdbus_test_name_queue(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	struct test_name t[2];
+	const char *name;
+	uint64_t flags;
+	int ret;
+
+	name = "foo.bla.blaz";
+
+	flags = 0;
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* allow the new connection to own the same name */
+	/* acquire name from the 1st connection */
+	ret = kdbus_name_acquire(env->conn, name, &flags);
+	ASSERT_RETURN(ret == 0);
+
+	ret = conn_is_name_primary_owner(env->conn, name);
+	ASSERT_RETURN(ret == true);
+
+	/* queue the 2nd connection as waiting owner */
+	flags = KDBUS_NAME_QUEUE;
+	ret = kdbus_name_acquire(conn, name, &flags);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(flags & KDBUS_NAME_IN_QUEUE);
+
+	t[0].name = name;
+	t[0].owner_id = env->conn->id;
+	t[0].flags = KDBUS_NAME_PRIMARY;
+	t[1].name = name;
+	t[1].owner_id = conn->id;
+	t[1].flags = KDBUS_NAME_QUEUE | KDBUS_NAME_IN_QUEUE;
+	ret = conn_test_names(conn, t, 2);
+	ASSERT_RETURN(ret == true);
+
+	/* release name from 1st connection */
+	ret = kdbus_name_release(env->conn, name);
+	ASSERT_RETURN(ret == 0);
+
+	/* now the name should be owned by the 2nd connection */
+	t[0].name = name;
+	t[0].owner_id = conn->id;
+	t[0].flags = KDBUS_NAME_PRIMARY | KDBUS_NAME_QUEUE;
+	ret = conn_test_names(conn, t, 1);
+	ASSERT_RETURN(ret == true);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
+
+int kdbus_test_name_takeover(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn;
+	struct test_name t;
+	const char *name;
+	uint64_t flags;
+	int ret;
+
+	name = "foo.bla.blaz";
+
+	flags = KDBUS_NAME_ALLOW_REPLACEMENT;
+
+	/* create a 2nd connection */
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn != NULL);
+
+	/* acquire name for 1st connection */
+	ret = kdbus_name_acquire(env->conn, name, &flags);
+	ASSERT_RETURN(ret == 0);
+
+	t.name = name;
+	t.owner_id = env->conn->id;
+	t.flags = KDBUS_NAME_ALLOW_REPLACEMENT | KDBUS_NAME_PRIMARY;
+	ret = conn_test_names(conn, &t, 1);
+	ASSERT_RETURN(ret == true);
+
+	/* now steal name with 2nd connection */
+	flags = KDBUS_NAME_REPLACE_EXISTING;
+	ret = kdbus_name_acquire(conn, name, &flags);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(flags & KDBUS_NAME_ACQUIRED);
+
+	ret = conn_is_name_primary_owner(conn, name);
+	ASSERT_RETURN(ret == true);
+
+	kdbus_conn_free(conn);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-policy-ns.c b/tools/testing/selftests/kdbus/test-policy-ns.c
new file mode 100644
index 000000000000..3437012f90af
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-policy-ns.c
@@ -0,0 +1,632 @@
+/*
+ * Test metadata and policies in new namespaces. Even if our tests
+ * can run in a namespaced setup, this test is necessary so we can
+ * inspect policies on the same kdbusfs but between multiple
+ * namespaces.
+ *
+ * Copyright (C) 2014-2015 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <sys/eventfd.h>
+#include <sys/syscall.h>
+#include <sys/capability.h>
+#include <linux/sched.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+#define MAX_CONN	64
+#define POLICY_NAME	"foo.test.policy-test"
+
+#define KDBUS_CONN_MAX_MSGS_PER_USER            16
+
+/**
+ * Note: this test can be used to inspect policy_db->talk_access_hash
+ *
+ * The purpose of these tests:
+ * 1) Check KDBUS_POLICY_TALK
+ * 2) Check the cache state: kdbus_policy_db->talk_access_hash
+ * Should be extended
+ */
+
+/**
+ * Check a list of connections against conn_db[0]
+ * conn_db[0] will own the name "foo.test.policy-test" and the
+ * policy holder connection for this name will update the policy
+ * entries, so different use cases can be tested.
+ */
+static struct kdbus_conn **conn_db;
+
+static void *kdbus_recv_echo(void *ptr)
+{
+	int ret;
+	struct kdbus_conn *conn = ptr;
+
+	ret = kdbus_msg_recv_poll(conn, 200, NULL, NULL);
+
+	return (void *)(long)ret;
+}
+
+/* Trigger kdbus_policy_set() */
+static int kdbus_set_policy_talk(struct kdbus_conn *conn,
+				 const char *name,
+				 uid_t id, unsigned int type)
+{
+	int ret;
+	struct kdbus_policy_access access = {
+		.type = type,
+		.id = id,
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(conn, name, &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	return TEST_OK;
+}
+
+/* return TEST_OK or TEST_ERR on failure */
+static int kdbus_register_same_activator(char *bus, const char *name,
+					 struct kdbus_conn **c)
+{
+	int ret;
+	struct kdbus_conn *activator;
+
+	activator = kdbus_hello_activator(bus, name, NULL, 0);
+	if (activator) {
+		*c = activator;
+		fprintf(stderr, "--- error was able to register name twice '%s'.\n",
+			name);
+		return TEST_ERR;
+	}
+
+	ret = -errno;
+	/* -EEXIST means test succeeded */
+	if (ret == -EEXIST)
+		return TEST_OK;
+
+	return TEST_ERR;
+}
+
+/* return TEST_OK or TEST_ERR on failure */
+static int kdbus_register_policy_holder(char *bus, const char *name,
+					struct kdbus_conn **conn)
+{
+	struct kdbus_conn *c;
+	struct kdbus_policy_access access[2];
+
+	access[0].type = KDBUS_POLICY_ACCESS_USER;
+	access[0].access = KDBUS_POLICY_OWN;
+	access[0].id = geteuid();
+
+	access[1].type = KDBUS_POLICY_ACCESS_WORLD;
+	access[1].access = KDBUS_POLICY_TALK;
+	access[1].id = geteuid();
+
+	c = kdbus_hello_registrar(bus, name, access, 2,
+				  KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(c);
+
+	*conn = c;
+
+	return TEST_OK;
+}
+
+/**
+ * Create new threads for receiving from multiple senders,
+ * The 'conn_db' will be populated by newly created connections.
+ * Caller should free all allocated connections.
+ *
+ * return 0 on success, negative errno on failure.
+ */
+static int kdbus_recv_in_threads(const char *bus, const char *name,
+				 struct kdbus_conn **conn_db)
+{
+	int ret;
+	bool pool_full = false;
+	unsigned int sent_packets = 0;
+	unsigned int lost_packets = 0;
+	unsigned int i, tid;
+	unsigned long dst_id;
+	unsigned long cookie = 1;
+	unsigned int thread_nr = MAX_CONN - 1;
+	pthread_t thread_id[MAX_CONN - 1] = {'\0'};
+
+	dst_id = name ? KDBUS_DST_ID_NAME : conn_db[0]->id;
+
+	for (tid = 0, i = 1; tid < thread_nr; tid++, i++) {
+		ret = pthread_create(&thread_id[tid], NULL,
+				     kdbus_recv_echo, (void *)conn_db[0]);
+		if (ret < 0) {
+			ret = -errno;
+			kdbus_printf("error pthread_create: %d (%m)\n",
+				      ret);
+			break;
+		}
+
+		/* just free before re-using */
+		kdbus_conn_free(conn_db[i]);
+		conn_db[i] = NULL;
+
+		/* We need to create connections here */
+		conn_db[i] = kdbus_hello(bus, 0, NULL, 0);
+		if (!conn_db[i]) {
+			ret = -errno;
+			break;
+		}
+
+		ret = kdbus_add_match_empty(conn_db[i]);
+		if (ret < 0)
+			break;
+
+		ret = kdbus_msg_send(conn_db[i], name, cookie++,
+				     0, 0, 0, dst_id);
+		if (ret < 0) {
+			/*
+			 * Receivers are not reading their messages,
+			 * not scheduled ?!
+			 *
+			 * So set the pool full here, perhaps the
+			 * connection pool or queue was full, later
+			 * recheck receivers errors
+			 */
+			if (ret == -ENOBUFS || ret == -EXFULL)
+				pool_full = true;
+			break;
+		}
+
+		sent_packets++;
+	}
+
+	for (tid = 0; tid < thread_nr; tid++) {
+		int thread_ret = 0;
+
+		if (thread_id[tid]) {
+			pthread_join(thread_id[tid], (void *)&thread_ret);
+			if (thread_ret < 0) {
+				/* Update only if send did not fail */
+				if (ret == 0)
+					ret = thread_ret;
+
+				lost_packets++;
+			}
+		}
+	}
+
+	/*
+	 * When sending if we did fail with -ENOBUFS or -EXFULL
+	 * then we should have set lost_packet and we should at
+	 * least have sent_packets set to KDBUS_CONN_MAX_MSGS_PER_USER
+	 */
+	if (pool_full) {
+		ASSERT_RETURN(lost_packets > 0);
+
+		/*
+		 * We should at least send KDBUS_CONN_MAX_MSGS_PER_USER
+		 *
+		 * For every send operation we create a thread to
+		 * recv the packet, so we keep the queue clean
+		 */
+		ASSERT_RETURN(sent_packets >= KDBUS_CONN_MAX_MSGS_PER_USER);
+
+		/*
+		 * Set ret to zero since we only failed due to
+		 * the receiving threads that have not been
+		 * scheduled
+		 */
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* Return: TEST_OK or TEST_ERR on failure */
+static int kdbus_normal_test(const char *bus, const char *name,
+			     struct kdbus_conn **conn_db)
+{
+	int ret;
+
+	ret = kdbus_recv_in_threads(bus, name, conn_db);
+	ASSERT_RETURN(ret >= 0);
+
+	return TEST_OK;
+}
+
+static int kdbus_fork_test_by_id(const char *bus,
+				 struct kdbus_conn **conn_db,
+				 int parent_status, int child_status)
+{
+	int ret;
+	pid_t pid;
+	uint64_t cookie = 0x9876ecba;
+	struct kdbus_msg *msg = NULL;
+	uint64_t offset = 0;
+	int status = 0;
+
+	/*
+	 * If the child_status is not EXIT_SUCCESS, then we expect
+	 * that sending from the child will fail, thus receiving
+	 * from parent must error with -ETIMEDOUT, and vice versa.
+	 */
+	bool parent_timedout = !!child_status;
+	bool child_timedout = !!parent_status;
+
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		struct kdbus_conn *conn_src;
+
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		ASSERT_EXIT(ret == 0);
+
+		ret = drop_privileges(65534, 65534);
+		ASSERT_EXIT(ret == 0);
+
+		conn_src = kdbus_hello(bus, 0, NULL, 0);
+		ASSERT_EXIT(conn_src);
+
+		ret = kdbus_add_match_empty(conn_src);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * child_status is always checked against send
+		 * operations, in case it fails always return
+		 * EXIT_FAILURE.
+		 */
+		ret = kdbus_msg_send(conn_src, NULL, cookie,
+				     0, 0, 0, conn_db[0]->id);
+		ASSERT_EXIT(ret == child_status);
+
+		ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL);
+
+		kdbus_conn_free(conn_src);
+
+		/*
+		 * Child kdbus_msg_recv_poll() should timeout since
+		 * the parent_status was set to a non EXIT_SUCCESS
+		 * value.
+		 */
+		if (child_timedout)
+			_exit(ret == -ETIMEDOUT ? EXIT_SUCCESS : EXIT_FAILURE);
+
+		_exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+	}
+
+	ret = kdbus_msg_recv_poll(conn_db[0], 100, &msg, &offset);
+	/*
+	 * If parent_timedout is set then this should fail with
+	 * -ETIMEDOUT since the child_status was set to a non
+	 * EXIT_SUCCESS value. Otherwise, assume
+	 * that kdbus_msg_recv_poll() has succeeded.
+	 */
+	if (parent_timedout) {
+		ASSERT_RETURN_VAL(ret == -ETIMEDOUT, TEST_ERR);
+
+		/* timedout no need to continue, we don't have the
+		 * child connection ID, so just terminate. */
+		goto out;
+	} else {
+		ASSERT_RETURN_VAL(ret == 0, ret);
+	}
+
+	ret = kdbus_msg_send(conn_db[0], NULL, ++cookie,
+			     0, 0, 0, msg->src_id);
+	/*
+	 * parent_status is checked against send operations,
+	 * on failures always return TEST_ERR.
+	 */
+	ASSERT_RETURN_VAL(ret == parent_status, TEST_ERR);
+
+	kdbus_msg_free(msg);
+	kdbus_free(conn_db[0], offset);
+
+out:
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+/*
+ * Return: TEST_OK, TEST_ERR or TEST_SKIP
+ * we return TEST_OK only if the children return with the expected
+ * 'expected_status' that is specified as an argument.
+ */
+static int kdbus_fork_test(const char *bus, const char *name,
+			   struct kdbus_conn **conn_db, int expected_status)
+{
+	pid_t pid;
+	int ret = 0;
+	int status = 0;
+
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		ASSERT_EXIT(ret == 0);
+
+		ret = drop_privileges(65534, 65534);
+		ASSERT_EXIT(ret == 0);
+
+		ret = kdbus_recv_in_threads(bus, name, conn_db);
+		_exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE);
+	}
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN(ret >= 0);
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+/* Return EXIT_SUCCESS, EXIT_FAILURE or negative errno */
+static int __kdbus_clone_userns_test(const char *bus,
+				     const char *name,
+				     struct kdbus_conn **conn_db,
+				     int expected_status)
+{
+	int efd;
+	pid_t pid;
+	int ret = 0;
+	unsigned int uid = 65534;
+	int status;
+
+	ret = drop_privileges(uid, uid);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	/*
+	 * Since we just dropped privileges, the dumpable flag was just
+	 * cleared which makes the /proc/$clone_child/uid_map to be
+	 * owned by root, hence any userns uid mapping will fail with
+	 * -EPERM since the mapping will be done by uid 65534.
+	 *
+	 * To avoid this set the dumpable flag again which makes procfs
+	 * update the /proc/$clone_child/ inodes owner to 65534.
+	 *
+	 * Using this we will be able write to /proc/$clone_child/uid_map
+	 * as uid 65534 and map the uid 65534 to 0 inside the user
+	 * namespace.
+	 */
+	ret = prctl(PR_SET_DUMPABLE, SUID_DUMP_USER);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	/* sync parent/child */
+	efd = eventfd(0, EFD_CLOEXEC);
+	ASSERT_RETURN_VAL(efd >= 0, efd);
+
+	pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWUSER, NULL);
+	if (pid < 0) {
+		ret = -errno;
+		kdbus_printf("error clone: %d (%m)\n", ret);
+		/*
+		 * Normal user not allowed to create userns,
+		 * so nothing to worry about ?
+		 */
+		if (ret == -EPERM) {
+			kdbus_printf("-- CLONE_NEWUSER TEST Failed for uid: %u\n"
+				"-- Make sure that your kernel do not allow "
+				"CLONE_NEWUSER for unprivileged users\n"
+				"-- Upstream Commit: "
+				"https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5eaf563e\n",
+				uid);
+			ret = 0;
+		}
+
+		return ret;
+	}
+
+	if (pid == 0) {
+		struct kdbus_conn *conn_src;
+		eventfd_t event_status = 0;
+
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		ASSERT_EXIT(ret == 0);
+
+		ret = eventfd_read(efd, &event_status);
+		ASSERT_EXIT(ret >= 0 && event_status == 1);
+
+		/* ping connection from the new user namespace */
+		conn_src = kdbus_hello(bus, 0, NULL, 0);
+		ASSERT_EXIT(conn_src);
+
+		ret = kdbus_add_match_empty(conn_src);
+		ASSERT_EXIT(ret == 0);
+
+		ret = kdbus_msg_send(conn_src, name, 0xabcd1234,
+				     0, 0, 0, KDBUS_DST_ID_NAME);
+		kdbus_conn_free(conn_src);
+
+		_exit(ret == expected_status ? EXIT_SUCCESS : EXIT_FAILURE);
+	}
+
+	ret = userns_map_uid_gid(pid, "0 65534 1", "0 65534 1");
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	/* Tell child we are ready */
+	ret = eventfd_write(efd, 1);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	close(efd);
+
+	return status == EXIT_SUCCESS ? TEST_OK : TEST_ERR;
+}
+
+static int kdbus_clone_userns_test(const char *bus,
+				   const char *name,
+				   struct kdbus_conn **conn_db,
+				   int expected_status)
+{
+	pid_t pid;
+	int ret = 0;
+	int status;
+
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, -errno);
+
+	if (pid == 0) {
+		ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
+		if (ret < 0)
+			_exit(EXIT_FAILURE);
+
+		ret = __kdbus_clone_userns_test(bus, name, conn_db,
+						expected_status);
+		_exit(ret);
+	}
+
+	/*
+	 * Receive in the original (root privileged) user namespace,
+	 * must fail with -ETIMEDOUT.
+	 */
+	ret = kdbus_msg_recv_poll(conn_db[0], 100, NULL, NULL);
+	ASSERT_RETURN_VAL(ret == -ETIMEDOUT, ret);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+int kdbus_test_policy_ns(struct kdbus_test_env *env)
+{
+	int i;
+	int ret;
+	struct kdbus_conn *activator = NULL;
+	struct kdbus_conn *policy_holder = NULL;
+	char *bus = env->buspath;
+
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	/* no enough privileges, SKIP test */
+	if (!ret)
+		return TEST_SKIP;
+
+	/* we require user-namespaces */
+	if (access("/proc/self/uid_map", F_OK) != 0)
+		return TEST_SKIP;
+
+	/* uids/gids must be mapped */
+	if (!all_uids_gids_are_mapped())
+		return TEST_SKIP;
+
+	conn_db = calloc(MAX_CONN, sizeof(struct kdbus_conn *));
+	ASSERT_RETURN(conn_db);
+
+	memset(conn_db, 0, MAX_CONN * sizeof(struct kdbus_conn *));
+
+	conn_db[0] = kdbus_hello(bus, 0, NULL, 0);
+	ASSERT_RETURN(conn_db[0]);
+
+	ret = kdbus_add_match_empty(conn_db[0]);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM);
+	ASSERT_EXIT(ret == 0);
+
+	ret = kdbus_register_policy_holder(bus, POLICY_NAME,
+					   &policy_holder);
+	ASSERT_RETURN(ret == 0);
+
+	/* Try to register the same name with an activator */
+	ret = kdbus_register_same_activator(bus, POLICY_NAME,
+					    &activator);
+	ASSERT_RETURN(ret == 0);
+
+	/* Acquire POLICY_NAME */
+	ret = kdbus_name_acquire(conn_db[0], POLICY_NAME, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_normal_test(bus, POLICY_NAME, conn_db);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_list(conn_db[0], KDBUS_LIST_NAMES |
+				     KDBUS_LIST_UNIQUE |
+				     KDBUS_LIST_ACTIVATORS |
+				     KDBUS_LIST_QUEUED);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_fork_test(bus, POLICY_NAME, conn_db, EXIT_SUCCESS);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * children connections are able to talk to conn_db[0] since
+	 * current POLICY_NAME TALK type is KDBUS_POLICY_ACCESS_WORLD,
+	 * so expect EXIT_SUCCESS when sending from child. However,
+	 * since the child's connection does not own any well-known
+	 * name, The parent connection conn_db[0] should fail with
+	 * -EPERM but since it is a privileged bus user the TALK is
+	 *  allowed.
+	 */
+	ret = kdbus_fork_test_by_id(bus, conn_db,
+				    EXIT_SUCCESS, EXIT_SUCCESS);
+	ASSERT_EXIT(ret == 0);
+
+	/*
+	 * Connections that can talk are perhaps being destroyed now.
+	 * Restrict the policy and purge cache entries where the
+	 * conn_db[0] is the destination.
+	 *
+	 * Now only connections with uid == 0 are allowed to talk.
+	 */
+	ret = kdbus_set_policy_talk(policy_holder, POLICY_NAME,
+				    geteuid(), KDBUS_POLICY_ACCESS_USER);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Testing connections (FORK+DROP) again:
+	 * After setting the policy re-check connections
+	 * we expect the children to fail with -EPERM
+	 */
+	ret = kdbus_fork_test(bus, POLICY_NAME, conn_db, -EPERM);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Now expect that both parent and child to fail.
+	 *
+	 * Child should fail with -EPERM since we just restricted
+	 * the POLICY_NAME TALK to uid 0 and its uid is 65534.
+	 *
+	 * Since the parent's connection will timeout when receiving
+	 * from the child, we never continue. FWIW just put -EPERM.
+	 */
+	ret = kdbus_fork_test_by_id(bus, conn_db, -EPERM, -EPERM);
+	ASSERT_EXIT(ret == 0);
+
+	/* Check if the name can be reached in a new userns */
+	ret = kdbus_clone_userns_test(bus, POLICY_NAME, conn_db, -EPERM);
+	ASSERT_RETURN(ret == 0);
+
+	for (i = 0; i < MAX_CONN; i++)
+		kdbus_conn_free(conn_db[i]);
+
+	kdbus_conn_free(activator);
+	kdbus_conn_free(policy_holder);
+
+	free(conn_db);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/kdbus/test-policy-priv.c b/tools/testing/selftests/kdbus/test-policy-priv.c
new file mode 100644
index 000000000000..0208638a7245
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-policy-priv.c
@@ -0,0 +1,1285 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/capability.h>
+#include <sys/eventfd.h>
+#include <sys/wait.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+static int test_policy_priv_by_id(const char *bus,
+				  struct kdbus_conn *conn_dst,
+				  bool drop_second_user,
+				  int parent_status,
+				  int child_status)
+{
+	int ret = 0;
+	uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
+
+	ASSERT_RETURN(conn_dst);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, bus, ({
+		ret = kdbus_msg_send(unpriv, NULL,
+				     expected_cookie, 0, 0, 0,
+				     conn_dst->id);
+		ASSERT_EXIT(ret == child_status);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_dst, 300, NULL, NULL);
+	ASSERT_RETURN(ret == parent_status);
+
+	return 0;
+}
+
+static int test_policy_priv_by_broadcast(const char *bus,
+					 struct kdbus_conn *conn_dst,
+					 int drop_second_user,
+					 int parent_status,
+					 int child_status)
+{
+	int efd;
+	int ret = 0;
+	eventfd_t event_status = 0;
+	struct kdbus_msg *msg = NULL;
+	uid_t second_uid = UNPRIV_UID;
+	gid_t second_gid = UNPRIV_GID;
+	struct kdbus_conn *child_2 = conn_dst;
+	uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
+
+	/* Drop to another unprivileged user other than UNPRIV_UID */
+	if (drop_second_user == DROP_OTHER_UNPRIV) {
+		second_uid = UNPRIV_UID - 1;
+		second_gid = UNPRIV_GID - 1;
+	}
+
+	/* child will signal parent to send broadcast */
+	efd = eventfd(0, EFD_CLOEXEC);
+	ASSERT_RETURN_VAL(efd >= 0, efd);
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
+		struct kdbus_conn *child;
+
+		child = kdbus_hello(bus, 0, NULL, 0);
+		ASSERT_EXIT(child);
+
+		ret = kdbus_add_match_empty(child);
+		ASSERT_EXIT(ret == 0);
+
+		/* signal parent */
+		ret = eventfd_write(efd, 1);
+		ASSERT_EXIT(ret == 0);
+
+		/* Use a little bit high time */
+		ret = kdbus_msg_recv_poll(child, 500, &msg, NULL);
+		ASSERT_EXIT(ret == child_status);
+
+		/*
+		 * If we expect the child to get the broadcast
+		 * message, then check the received cookie.
+		 */
+		if (ret == 0) {
+			ASSERT_EXIT(expected_cookie == msg->cookie);
+		}
+
+		/* Use expected_cookie since 'msg' might be NULL */
+		ret = kdbus_msg_send(child, NULL, expected_cookie + 1,
+				     0, 0, 0, KDBUS_DST_ID_BROADCAST);
+		ASSERT_EXIT(ret == 0);
+
+		kdbus_msg_free(msg);
+		kdbus_conn_free(child);
+	}),
+	({
+		if (drop_second_user == DO_NOT_DROP) {
+			ASSERT_RETURN(child_2);
+
+			ret = eventfd_read(efd, &event_status);
+			ASSERT_RETURN(ret >= 0 && event_status == 1);
+
+			ret = kdbus_msg_send(child_2, NULL,
+					     expected_cookie, 0, 0, 0,
+					     KDBUS_DST_ID_BROADCAST);
+			ASSERT_RETURN(ret == 0);
+
+			/* drop own broadcast */
+			ret = kdbus_msg_recv(child_2, &msg, NULL);
+			ASSERT_RETURN(ret == 0);
+			ASSERT_RETURN(msg->src_id == child_2->id);
+			kdbus_msg_free(msg);
+
+			/* Use a little bit high time */
+			ret = kdbus_msg_recv_poll(child_2, 1000,
+						  &msg, NULL);
+			ASSERT_RETURN(ret == parent_status);
+
+			/*
+			 * Check returned cookie in case we expect
+			 * success.
+			 */
+			if (ret == 0) {
+				ASSERT_RETURN(msg->cookie ==
+					      expected_cookie + 1);
+			}
+
+			kdbus_msg_free(msg);
+		} else {
+			/*
+			 * Two unprivileged users will try to
+			 * communicate using broadcast.
+			 */
+			ret = RUN_UNPRIVILEGED(second_uid, second_gid, ({
+				child_2 = kdbus_hello(bus, 0, NULL, 0);
+				ASSERT_EXIT(child_2);
+
+				ret = kdbus_add_match_empty(child_2);
+				ASSERT_EXIT(ret == 0);
+
+				ret = eventfd_read(efd, &event_status);
+				ASSERT_EXIT(ret >= 0 && event_status == 1);
+
+				ret = kdbus_msg_send(child_2, NULL,
+						expected_cookie, 0, 0, 0,
+						KDBUS_DST_ID_BROADCAST);
+				ASSERT_EXIT(ret == 0);
+
+				/* drop own broadcast */
+				ret = kdbus_msg_recv(child_2, &msg, NULL);
+				ASSERT_RETURN(ret == 0);
+				ASSERT_RETURN(msg->src_id == child_2->id);
+				kdbus_msg_free(msg);
+
+				/* Use a little bit high time */
+				ret = kdbus_msg_recv_poll(child_2, 1000,
+							  &msg, NULL);
+				ASSERT_EXIT(ret == parent_status);
+
+				/*
+				 * Check returned cookie in case we expect
+				 * success.
+				 */
+				if (ret == 0) {
+					ASSERT_EXIT(msg->cookie ==
+						    expected_cookie + 1);
+				}
+
+				kdbus_msg_free(msg);
+				kdbus_conn_free(child_2);
+			}),
+			({ 0; }));
+			ASSERT_RETURN(ret == 0);
+		}
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	close(efd);
+
+	return ret;
+}
+
+static void nosig(int sig)
+{
+}
+
+static int test_priv_before_policy_upload(struct kdbus_test_env *env)
+{
+	int ret = 0;
+	struct kdbus_conn *conn;
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	/*
+	 * Make sure unprivileged bus user cannot acquire names
+	 * before registring any policy holder.
+	 */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret < 0);
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Make sure unprivileged bus users cannot talk by default
+	 * to privileged ones, unless a policy holder that allows
+	 * this was uploaded.
+	 */
+
+	ret = test_policy_priv_by_id(env->buspath, conn, false,
+				     -ETIMEDOUT, -EPERM);
+	ASSERT_RETURN(ret == 0);
+
+	/* Activate matching for a privileged connection */
+	ret = kdbus_add_match_empty(conn);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * First make sure that BROADCAST with msg flag
+	 * KDBUS_MSG_EXPECT_REPLY will fail with -ENOTUNIQ
+	 */
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, NULL, 0xdeadbeef,
+				     KDBUS_MSG_EXPECT_REPLY,
+				     5000000000ULL, 0,
+				     KDBUS_DST_ID_BROADCAST);
+		ASSERT_EXIT(ret == -ENOTUNIQ);
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Test broadcast with a privileged connection.
+	 *
+	 * The first unprivileged receiver should not get the
+	 * broadcast message sent by the privileged connection,
+	 * since there is no a TALK policy that allows the
+	 * unprivileged to TALK to the privileged connection. It
+	 * will fail with -ETIMEDOUT
+	 *
+	 * Then second case:
+	 * The privileged connection should get the broadcast
+	 * message from the unprivileged one. Since the receiver is
+	 * a privileged bus user and it has default TALK access to
+	 * all connections it will receive those.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, conn,
+					    DO_NOT_DROP,
+					    0, -ETIMEDOUT);
+	ASSERT_RETURN(ret == 0);
+
+
+	/*
+	 * Test broadcast with two unprivileged connections running
+	 * under the same user.
+	 *
+	 * Both connections should succeed.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, NULL,
+					    DROP_SAME_UNPRIV, 0, 0);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Test broadcast with two unprivileged connections running
+	 * under different users.
+	 *
+	 * Both connections will fail with -ETIMEDOUT.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, NULL,
+					    DROP_OTHER_UNPRIV,
+					    -ETIMEDOUT, -ETIMEDOUT);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_conn_free(conn);
+
+	return ret;
+}
+
+static int test_broadcast_after_policy_upload(struct kdbus_test_env *env)
+{
+	int ret;
+	int efd;
+	eventfd_t event_status = 0;
+	struct kdbus_msg *msg = NULL;
+	struct kdbus_conn *owner_a, *owner_b;
+	struct kdbus_conn *holder_a, *holder_b;
+	struct kdbus_policy_access access = {};
+	uint64_t expected_cookie = time(NULL) ^ 0xdeadbeef;
+
+	owner_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(owner_a);
+
+	ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users cannot talk by default
+	 * to privileged ones, unless a policy holder that allows
+	 * this was uploaded.
+	 */
+
+	++expected_cookie;
+	ret = test_policy_priv_by_id(env->buspath, owner_a, false,
+				     -ETIMEDOUT, -EPERM);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Make sure that privileged won't receive broadcasts unless
+	 * it installs a match. It will fail with -ETIMEDOUT
+	 *
+	 * At same time check that the unprivileged connection will
+	 * not receive the broadcast message from the privileged one
+	 * since the privileged one owns a name with a restricted
+	 * policy TALK (actually the TALK policy is still not
+	 * registered so we fail by default), thus the unprivileged
+	 * receiver is not able to TALK to that name.
+	 */
+
+	/* Activate matching for a privileged connection */
+	ret = kdbus_add_match_empty(owner_a);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Redo the previous test. The privileged conn owner_a is
+	 * able to TALK to any connection so it will receive the
+	 * broadcast message now.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, owner_a,
+					    DO_NOT_DROP,
+					    0, -ETIMEDOUT);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Test that broadcast between two unprivileged users running
+	 * under the same user still succeed.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, NULL,
+					    DROP_SAME_UNPRIV, 0, 0);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Test broadcast with two unprivileged connections running
+	 * under different users.
+	 *
+	 * Both connections will fail with -ETIMEDOUT.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, NULL,
+					    DROP_OTHER_UNPRIV,
+					    -ETIMEDOUT, -ETIMEDOUT);
+	ASSERT_RETURN(ret == 0);
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	holder_a = kdbus_hello_registrar(env->buspath,
+					 "com.example.broadcastA",
+					 &access, 1,
+					 KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(holder_a);
+
+	holder_b = kdbus_hello_registrar(env->buspath,
+					 "com.example.broadcastB",
+					 &access, 1,
+					 KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(holder_b);
+
+	/* Free connections and their received messages and restart */
+	kdbus_conn_free(owner_a);
+
+	owner_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(owner_a);
+
+	/* Activate matching for a privileged connection */
+	ret = kdbus_add_match_empty(owner_a);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_name_acquire(owner_a, "com.example.broadcastA", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	owner_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(owner_b);
+
+	ret = kdbus_name_acquire(owner_b, "com.example.broadcastB", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/* Activate matching for a privileged connection */
+	ret = kdbus_add_match_empty(owner_b);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Test that even if "com.example.broadcastA" and
+	 * "com.example.broadcastB" do have a TALK access by default
+	 * they are able to signal each other using broadcast due to
+	 * the fact they are privileged connections, they receive
+	 * all broadcasts if the match allows it.
+	 */
+
+	++expected_cookie;
+	ret = kdbus_msg_send(owner_a, NULL, expected_cookie, 0,
+			     0, 0, KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv_poll(owner_a, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == expected_cookie);
+
+	/* Check src ID */
+	ASSERT_RETURN(msg->src_id == owner_a->id);
+
+	kdbus_msg_free(msg);
+
+	ret = kdbus_msg_recv_poll(owner_b, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->cookie == expected_cookie);
+
+	/* Check src ID */
+	ASSERT_RETURN(msg->src_id == owner_a->id);
+
+	kdbus_msg_free(msg);
+
+	/* Release name "com.example.broadcastB" */
+
+	ret = kdbus_name_release(owner_b, "com.example.broadcastB");
+	ASSERT_EXIT(ret >= 0);
+
+	/* KDBUS_POLICY_OWN for unprivileged connections */
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	/* Update the policy so unprivileged will own the name */
+
+	ret = kdbus_conn_update_policy(holder_b,
+				       "com.example.broadcastB",
+				       &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Send broadcasts from an unprivileged connection that
+	 * owns a name "com.example.broadcastB".
+	 *
+	 * We'll have four destinations here:
+	 *
+	 * 1) destination owner_a: privileged connection that owns
+	 * "com.example.broadcastA". It will receive the broadcast
+	 * since it is a privileged has default TALK access to all
+	 * connections, and it is subscribed to the match.
+	 * Will succeed.
+	 *
+	 * owner_b: privileged connection (running under a different
+	 * uid) that do not own names, but with an empty broadcast
+	 * match, so it will receive broadcasts since it has default
+	 * TALK access to all connection.
+	 *
+	 * unpriv_a: unpriv connection that do not own any name.
+	 * It will receive the broadcast since it is running under
+	 * the same user of the one broadcasting and did install
+	 * matches. It should get the message.
+	 *
+	 * unpriv_b: unpriv connection is not interested in broadcast
+	 * messages, so it did not install broadcast matches. Should
+	 * fail with -ETIMEDOUT
+	 */
+
+	++expected_cookie;
+	efd = eventfd(0, EFD_CLOEXEC);
+	ASSERT_RETURN_VAL(efd >= 0, efd);
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
+		struct kdbus_conn *unpriv_owner;
+		struct kdbus_conn *unpriv_a, *unpriv_b;
+
+		unpriv_owner = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_EXIT(unpriv_owner);
+
+		unpriv_a = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_EXIT(unpriv_a);
+
+		unpriv_b = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_EXIT(unpriv_b);
+
+		ret = kdbus_name_acquire(unpriv_owner,
+					 "com.example.broadcastB",
+					 NULL);
+		ASSERT_EXIT(ret >= 0);
+
+		ret = kdbus_add_match_empty(unpriv_a);
+		ASSERT_EXIT(ret == 0);
+
+		/* Signal that we are doing broadcasts */
+		ret = eventfd_write(efd, 1);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * Do broadcast from a connection that owns the
+		 * names "com.example.broadcastB".
+		 */
+		ret = kdbus_msg_send(unpriv_owner, NULL,
+				     expected_cookie,
+				     0, 0, 0,
+				     KDBUS_DST_ID_BROADCAST);
+		ASSERT_EXIT(ret == 0);
+
+		/*
+		 * Unprivileged connection running under the same
+		 * user. It should succeed.
+		 */
+		ret = kdbus_msg_recv_poll(unpriv_a, 300, &msg, NULL);
+		ASSERT_EXIT(ret == 0 && msg->cookie == expected_cookie);
+
+		/*
+		 * Did not install matches, not interested in
+		 * broadcasts
+		 */
+		ret = kdbus_msg_recv_poll(unpriv_b, 300, NULL, NULL);
+		ASSERT_EXIT(ret == -ETIMEDOUT);
+	}),
+	({
+		ret = eventfd_read(efd, &event_status);
+		ASSERT_RETURN(ret >= 0 && event_status == 1);
+
+		/*
+		 * owner_a must fail with -ETIMEDOUT, since it owns
+		 * name "com.example.broadcastA" and its TALK
+		 * access is restriced.
+		 */
+		ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
+		ASSERT_RETURN(ret == 0);
+
+		/* confirm the received cookie */
+		ASSERT_RETURN(msg->cookie == expected_cookie);
+
+		kdbus_msg_free(msg);
+
+		/*
+		 * owner_b got the broadcast from an unprivileged
+		 * connection.
+		 */
+		ret = kdbus_msg_recv_poll(owner_b, 300, &msg, NULL);
+		ASSERT_RETURN(ret == 0);
+
+		/* confirm the received cookie */
+		ASSERT_RETURN(msg->cookie == expected_cookie);
+
+		kdbus_msg_free(msg);
+
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	close(efd);
+
+	/*
+	 * Test broadcast with two unprivileged connections running
+	 * under different users.
+	 *
+	 * Both connections will fail with -ETIMEDOUT.
+	 */
+
+	ret = test_policy_priv_by_broadcast(env->buspath, NULL,
+					    DROP_OTHER_UNPRIV,
+					    -ETIMEDOUT, -ETIMEDOUT);
+	ASSERT_RETURN(ret == 0);
+
+	/* Drop received broadcasts by privileged */
+	ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL);
+	ret = kdbus_msg_recv_poll(owner_a, 100, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(owner_a, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL);
+	ret = kdbus_msg_recv_poll(owner_b, 100, NULL, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_msg_recv(owner_b, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
+	/*
+	 * Perform last tests, allow others to talk to name
+	 * "com.example.broadcastA". So now receiving broadcasts
+	 * from it should succeed since the TALK policy allow it.
+	 */
+
+	/* KDBUS_POLICY_OWN for unprivileged connections */
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(holder_a,
+				       "com.example.broadcastA",
+				       &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Unprivileged is able to TALK to "com.example.broadcastA"
+	 * now so it will receive its broadcasts
+	 */
+	ret = test_policy_priv_by_broadcast(env->buspath, owner_a,
+					    DO_NOT_DROP, 0, 0);
+	ASSERT_RETURN(ret == 0);
+
+	++expected_cookie;
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.broadcastB",
+					 NULL);
+		ASSERT_EXIT(ret >= 0);
+		ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
+				     0, 0, 0, KDBUS_DST_ID_BROADCAST);
+		ASSERT_EXIT(ret == 0);
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	/* owner_a is privileged it will get the broadcast now. */
+	ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* confirm the received cookie */
+	ASSERT_RETURN(msg->cookie == expected_cookie);
+
+	kdbus_msg_free(msg);
+
+	/*
+	 * owner_a released name "com.example.broadcastA". It should
+	 * receive broadcasts since it is still privileged and has
+	 * the right match.
+	 *
+	 * Unprivileged connection will own a name and will try to
+	 * signal to the privileged connection.
+	 */
+
+	ret = kdbus_name_release(owner_a, "com.example.broadcastA");
+	ASSERT_EXIT(ret >= 0);
+
+	++expected_cookie;
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.broadcastB",
+					 NULL);
+		ASSERT_EXIT(ret >= 0);
+		ret = kdbus_msg_send(unpriv, NULL, expected_cookie,
+				     0, 0, 0, KDBUS_DST_ID_BROADCAST);
+		ASSERT_EXIT(ret == 0);
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	/* owner_a will get the broadcast now. */
+	ret = kdbus_msg_recv_poll(owner_a, 300, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+
+	/* confirm the received cookie */
+	ASSERT_RETURN(msg->cookie == expected_cookie);
+
+	kdbus_msg_free(msg);
+
+	kdbus_conn_free(owner_a);
+	kdbus_conn_free(owner_b);
+	kdbus_conn_free(holder_a);
+	kdbus_conn_free(holder_b);
+
+	return 0;
+}
+
+static int test_policy_priv(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn_a, *conn_b, *conn, *owner;
+	struct kdbus_policy_access access, *acc;
+	sigset_t sset;
+	size_t num;
+	int ret;
+
+	/*
+	 * Make sure we have CAP_SETUID/SETGID so we can drop privileges
+	 */
+
+	ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
+	ASSERT_RETURN(ret >= 0);
+
+	if (!ret)
+		return TEST_SKIP;
+
+	/* make sure that uids and gids are mapped */
+	if (!all_uids_gids_are_mapped())
+		return TEST_SKIP;
+
+	/*
+	 * Setup:
+	 *  conn_a: policy holder for com.example.a
+	 *  conn_b: name holder of com.example.b
+	 */
+
+	signal(SIGUSR1, nosig);
+	sigemptyset(&sset);
+	sigaddset(&sset, SIGUSR1);
+	sigprocmask(SIG_BLOCK, &sset, NULL);
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	/*
+	 * Before registering any policy holder, make sure that the
+	 * bus is secure by default. This test is necessary, it catches
+	 * several cases where old D-Bus was vulnerable.
+	 */
+
+	ret = test_priv_before_policy_upload(env);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Make sure unprivileged are not able to register policy
+	 * holders
+	 */
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
+		struct kdbus_conn *holder;
+
+		holder = kdbus_hello_registrar(env->buspath,
+					       "com.example.a", NULL, 0,
+					       KDBUS_HELLO_POLICY_HOLDER);
+		ASSERT_EXIT(holder == NULL && errno == EPERM);
+	}),
+	({ 0; }));
+	ASSERT_RETURN(ret == 0);
+
+
+	/* Register policy holder */
+
+	conn_a = kdbus_hello_registrar(env->buspath, "com.example.a",
+				       NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn_a);
+
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_b);
+
+	ret = kdbus_name_acquire(conn_b, "com.example.b", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure bus-owners can always acquire names.
+	 */
+	ret = kdbus_name_acquire(conn, "com.example.a", NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	kdbus_conn_free(conn);
+
+	/*
+	 * Make sure unprivileged users cannot acquire names with default
+	 * policy assigned.
+	 */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret < 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged users can acquire names if we make them
+	 * world-accessible.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = 0,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	/*
+	 * Make sure unprivileged/normal connections are not able
+	 * to update policies
+	 */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_conn_update_policy(unpriv, "com.example.a",
+					       &access, 1);
+		ASSERT_EXIT(ret == -EOPNOTSUPP);
+	}));
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged users can acquire names if we make them
+	 * gid-accessible. But only if the gid matches.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_GROUP,
+		.id = UNPRIV_GID,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_GROUP,
+		.id = 1,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret < 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged users can acquire names if we make them
+	 * uid-accessible. But only if the uid matches.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = UNPRIV_UID,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = 1,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret < 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged users cannot acquire names if no owner-policy
+	 * matches, even if SEE/TALK policies match.
+	 */
+
+	num = 4;
+	acc = (struct kdbus_policy_access[]){
+		{
+			.type = KDBUS_POLICY_ACCESS_GROUP,
+			.id = UNPRIV_GID,
+			.access = KDBUS_POLICY_SEE,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = UNPRIV_UID,
+			.access = KDBUS_POLICY_TALK,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_WORLD,
+			.id = 0,
+			.access = KDBUS_POLICY_TALK,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_WORLD,
+			.id = 0,
+			.access = KDBUS_POLICY_SEE,
+		},
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret < 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged users can acquire names if the only matching
+	 * policy is somewhere in the middle.
+	 */
+
+	num = 5;
+	acc = (struct kdbus_policy_access[]){
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 1,
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 2,
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = UNPRIV_UID,
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 3,
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 4,
+			.access = KDBUS_POLICY_OWN,
+		},
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", acc, num);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_name_acquire(unpriv, "com.example.a", NULL);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Clear policies
+	 */
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", NULL, 0);
+	ASSERT_RETURN(ret == 0);
+
+	/*
+	 * Make sure privileged bus users can _always_ talk to others.
+	 */
+
+	conn = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn);
+
+	ret = kdbus_msg_send(conn, "com.example.b", 0xdeadbeef, 0, 0, 0, 0);
+	ASSERT_EXIT(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_b, 300, NULL, NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	kdbus_conn_free(conn);
+
+	/*
+	 * Make sure unprivileged bus users cannot talk by default.
+	 */
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users can talk to equals, even without
+	 * policy.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = UNPRIV_UID,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.c", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		struct kdbus_conn *owner;
+
+		owner = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_RETURN(owner);
+
+		ret = kdbus_name_acquire(owner, "com.example.c", NULL);
+		ASSERT_EXIT(ret >= 0);
+
+		ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+		ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
+		ASSERT_EXIT(ret >= 0);
+
+		kdbus_conn_free(owner);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users can talk to privileged users if a
+	 * suitable UID policy is set.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = UNPRIV_UID,
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users can talk to privileged users if a
+	 * suitable GID policy is set.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_GROUP,
+		.id = UNPRIV_GID,
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users can talk to privileged users if a
+	 * suitable WORLD policy is set.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = 0,
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users cannot talk to privileged users if
+	 * no suitable policy is set.
+	 */
+
+	num = 5;
+	acc = (struct kdbus_policy_access[]){
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 0,
+			.access = KDBUS_POLICY_OWN,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 1,
+			.access = KDBUS_POLICY_TALK,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = UNPRIV_UID,
+			.access = KDBUS_POLICY_SEE,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 3,
+			.access = KDBUS_POLICY_TALK,
+		},
+		{
+			.type = KDBUS_POLICY_ACCESS_USER,
+			.id = 4,
+			.access = KDBUS_POLICY_TALK,
+		},
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", acc, num);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure unprivileged bus users can talk to privileged users if a
+	 * suitable OWN privilege overwrites TALK.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = 0,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
+	ASSERT_EXIT(ret >= 0);
+
+	/*
+	 * Make sure the TALK cache is reset correctly when policies are
+	 * updated.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = 0,
+		.access = KDBUS_POLICY_TALK,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.b", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = RUN_UNPRIVILEGED_CONN(unpriv, env->buspath, ({
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+
+		ret = kdbus_msg_recv_poll(conn_b, 100, NULL, NULL);
+		ASSERT_EXIT(ret >= 0);
+
+		ret = kdbus_conn_update_policy(conn_a, "com.example.b",
+					       NULL, 0);
+		ASSERT_RETURN(ret == 0);
+
+		ret = kdbus_msg_send(unpriv, "com.example.b", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret == -EPERM);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+	/*
+	 * Make sure the TALK cache is reset correctly when policy holders
+	 * disconnect.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_WORLD,
+		.id = 0,
+		.access = KDBUS_POLICY_OWN,
+	};
+
+	conn = kdbus_hello_registrar(env->buspath, "com.example.c",
+				     NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn);
+
+	ret = kdbus_conn_update_policy(conn, "com.example.c", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	owner = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(owner);
+
+	ret = kdbus_name_acquire(owner, "com.example.c", NULL);
+	ASSERT_RETURN(ret >= 0);
+
+	ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_GID, ({
+		struct kdbus_conn *unpriv;
+
+		/* wait for parent to be finished */
+		sigemptyset(&sset);
+		ret = sigsuspend(&sset);
+		ASSERT_RETURN(ret == -1 && errno == EINTR);
+
+		unpriv = kdbus_hello(env->buspath, 0, NULL, 0);
+		ASSERT_RETURN(unpriv);
+
+		ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret >= 0);
+
+		ret = kdbus_msg_recv_poll(owner, 100, NULL, NULL);
+		ASSERT_EXIT(ret >= 0);
+
+		/* free policy holder */
+		kdbus_conn_free(conn);
+
+		ret = kdbus_msg_send(unpriv, "com.example.c", 0xdeadbeef, 0, 0,
+				     0, 0);
+		ASSERT_EXIT(ret == -EPERM);
+
+		kdbus_conn_free(unpriv);
+	}), ({
+		/* make sure policy holder is only valid in child */
+		kdbus_conn_free(conn);
+		kill(pid, SIGUSR1);
+	}));
+	ASSERT_RETURN(ret >= 0);
+
+
+	/*
+	 * The following tests are necessary.
+	 */
+
+	ret = test_broadcast_after_policy_upload(env);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_conn_free(owner);
+
+	/*
+	 * cleanup resources
+	 */
+
+	kdbus_conn_free(conn_b);
+	kdbus_conn_free(conn_a);
+
+	return TEST_OK;
+}
+
+int kdbus_test_policy_priv(struct kdbus_test_env *env)
+{
+	pid_t pid;
+	int ret;
+
+	/* make sure to exit() if a child returns from fork() */
+	pid = getpid();
+	ret = test_policy_priv(env);
+	if (pid != getpid())
+		exit(1);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/kdbus/test-policy.c b/tools/testing/selftests/kdbus/test-policy.c
new file mode 100644
index 000000000000..96d20d5e9172
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-policy.c
@@ -0,0 +1,80 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int kdbus_test_policy(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn_a, *conn_b;
+	struct kdbus_policy_access access;
+	int ret;
+
+	/* Invalid name */
+	conn_a = kdbus_hello_registrar(env->buspath, ".example.a",
+				       NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn_a == NULL);
+
+	conn_a = kdbus_hello_registrar(env->buspath, "example",
+				       NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn_a == NULL);
+
+	conn_a = kdbus_hello_registrar(env->buspath, "com.example.a",
+				       NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn_a);
+
+	conn_b = kdbus_hello_registrar(env->buspath, "com.example.b",
+				       NULL, 0, KDBUS_HELLO_POLICY_HOLDER);
+	ASSERT_RETURN(conn_b);
+
+	/*
+	 * Verify there cannot be any duplicate entries, except for specific vs.
+	 * wildcard entries.
+	 */
+
+	access = (struct kdbus_policy_access){
+		.type = KDBUS_POLICY_ACCESS_USER,
+		.id = geteuid(),
+		.access = KDBUS_POLICY_SEE,
+	};
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == -EEXIST);
+
+	ret = kdbus_conn_update_policy(conn_b, "com.example.a.*", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.a.*", &access, 1);
+	ASSERT_RETURN(ret == -EEXIST);
+
+	ret = kdbus_conn_update_policy(conn_a, "com.example.*", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_update_policy(conn_b, "com.example.a", &access, 1);
+	ASSERT_RETURN(ret == 0);
+
+	ret = kdbus_conn_update_policy(conn_b, "com.example.*", &access, 1);
+	ASSERT_RETURN(ret == -EEXIST);
+
+	/* Invalid name */
+	ret = kdbus_conn_update_policy(conn_b, ".example.*", &access, 1);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	ret = kdbus_conn_update_policy(conn_b, "example", &access, 1);
+	ASSERT_RETURN(ret == -EINVAL);
+
+	kdbus_conn_free(conn_b);
+	kdbus_conn_free(conn_a);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-sync.c b/tools/testing/selftests/kdbus/test-sync.c
new file mode 100644
index 000000000000..0655a545fbf1
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-sync.c
@@ -0,0 +1,369 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/eventfd.h>
+
+#include "kdbus-api.h"
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+static struct kdbus_conn *conn_a, *conn_b;
+static unsigned int cookie = 0xdeadbeef;
+
+static void nop_handler(int sig) {}
+
+static int interrupt_sync(struct kdbus_conn *conn_src,
+			  struct kdbus_conn *conn_dst)
+{
+	pid_t pid;
+	int ret, status;
+	struct kdbus_msg *msg = NULL;
+	struct sigaction sa = {
+		.sa_handler = nop_handler,
+		.sa_flags = SA_NOCLDSTOP|SA_RESTART,
+	};
+
+	cookie++;
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		ret = sigaction(SIGINT, &sa, NULL);
+		ASSERT_EXIT(ret == 0);
+
+		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
+					  KDBUS_MSG_EXPECT_REPLY,
+					  100000000ULL, 0, conn_src->id, -1);
+		ASSERT_EXIT(ret == -ETIMEDOUT);
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	ret = kill(pid, SIGINT);
+	ASSERT_RETURN_VAL(ret == 0, ret);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	if (WIFSIGNALED(status))
+		return TEST_ERR;
+
+	ret = kdbus_msg_recv_poll(conn_src, 100, NULL, NULL);
+	ASSERT_RETURN(ret == -ETIMEDOUT);
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+static int close_epipe_sync(const char *bus)
+{
+	pid_t pid;
+	int ret, status;
+	struct kdbus_conn *conn_src;
+	struct kdbus_conn *conn_dst;
+	struct kdbus_msg *msg = NULL;
+
+	conn_src = kdbus_hello(bus, 0, NULL, 0);
+	ASSERT_RETURN(conn_src);
+
+	ret = kdbus_add_match_empty(conn_src);
+	ASSERT_RETURN(ret == 0);
+
+	conn_dst = kdbus_hello(bus, 0, NULL, 0);
+	ASSERT_RETURN(conn_dst);
+
+	cookie++;
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		uint64_t dst_id;
+
+		/* close our reference */
+		dst_id = conn_dst->id;
+		kdbus_conn_free(conn_dst);
+
+		ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
+		ASSERT_EXIT(ret == 0 && msg->cookie == cookie);
+		ASSERT_EXIT(msg->src_id == dst_id);
+
+		cookie++;
+		ret = kdbus_msg_send_sync(conn_src, NULL, cookie,
+					  KDBUS_MSG_EXPECT_REPLY,
+					  100000000ULL, 0, dst_id, -1);
+		ASSERT_EXIT(ret == -EPIPE);
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	ret = kdbus_msg_send(conn_dst, NULL, cookie, 0, 0, 0,
+			     KDBUS_DST_ID_BROADCAST);
+	ASSERT_RETURN(ret == 0);
+
+	cookie++;
+	ret = kdbus_msg_recv_poll(conn_dst, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	/* destroy connection */
+	kdbus_conn_free(conn_dst);
+	kdbus_conn_free(conn_src);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	if (!WIFEXITED(status))
+		return TEST_ERR;
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+static int cancel_fd_sync(struct kdbus_conn *conn_src,
+			  struct kdbus_conn *conn_dst)
+{
+	pid_t pid;
+	int cancel_fd;
+	int ret, status;
+	uint64_t counter = 1;
+	struct kdbus_msg *msg = NULL;
+
+	cancel_fd = eventfd(0, 0);
+	ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd);
+
+	cookie++;
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
+					  KDBUS_MSG_EXPECT_REPLY,
+					  100000000ULL, 0, conn_src->id,
+					  cancel_fd);
+		ASSERT_EXIT(ret == -ECANCELED);
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
+	ASSERT_RETURN(ret == 0 && msg->cookie == cookie);
+
+	kdbus_msg_free(msg);
+
+	ret = write(cancel_fd, &counter, sizeof(counter));
+	ASSERT_RETURN(ret == sizeof(counter));
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	if (WIFSIGNALED(status))
+		return TEST_ERR;
+
+	return (status == EXIT_SUCCESS) ? TEST_OK : TEST_ERR;
+}
+
+static int no_cancel_sync(struct kdbus_conn *conn_src,
+			  struct kdbus_conn *conn_dst)
+{
+	pid_t pid;
+	int cancel_fd;
+	int ret, status;
+	struct kdbus_msg *msg = NULL;
+
+	/* pass eventfd, but never signal it so it shouldn't have any effect */
+
+	cancel_fd = eventfd(0, 0);
+	ASSERT_RETURN_VAL(cancel_fd >= 0, cancel_fd);
+
+	cookie++;
+	pid = fork();
+	ASSERT_RETURN_VAL(pid >= 0, pid);
+
+	if (pid == 0) {
+		ret = kdbus_msg_send_sync(conn_dst, NULL, cookie,
+					  KDBUS_MSG_EXPECT_REPLY,
+					  100000000ULL, 0, conn_src->id,
+					  cancel_fd);
+		ASSERT_EXIT(ret == 0);
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	ret = kdbus_msg_recv_poll(conn_src, 100, &msg, NULL);
+	ASSERT_RETURN_VAL(ret == 0 && msg->cookie == cookie, -1);
+
+	kdbus_msg_free(msg);
+
+	ret = kdbus_msg_send_reply(conn_src, cookie, conn_dst->id);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	ret = waitpid(pid, &status, 0);
+	ASSERT_RETURN_VAL(ret >= 0, ret);
+
+	if (WIFSIGNALED(status))
+		return -1;
+
+	return (status == EXIT_SUCCESS) ? 0 : -1;
+}
+
+static void *run_thread_reply(void *data)
+{
+	int ret;
+	unsigned long status = TEST_OK;
+
+	ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL);
+	if (ret < 0)
+		goto exit_thread;
+
+	kdbus_printf("Thread received message, sending reply ...\n");
+
+	/* using an unknown cookie must fail */
+	ret = kdbus_msg_send_reply(conn_a, ~cookie, conn_b->id);
+	if (ret != -EBADSLT) {
+		status = TEST_ERR;
+		goto exit_thread;
+	}
+
+	ret = kdbus_msg_send_reply(conn_a, cookie, conn_b->id);
+	if (ret != 0) {
+		status = TEST_ERR;
+		goto exit_thread;
+	}
+
+exit_thread:
+	pthread_exit(NULL);
+	return (void *) status;
+}
+
+int kdbus_test_sync_reply(struct kdbus_test_env *env)
+{
+	unsigned long status;
+	pthread_t thread;
+	int ret;
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	pthread_create(&thread, NULL, run_thread_reply, NULL);
+
+	ret = kdbus_msg_send_sync(conn_b, NULL, cookie,
+				  KDBUS_MSG_EXPECT_REPLY,
+				  5000000000ULL, 0, conn_a->id, -1);
+
+	pthread_join(thread, (void *) &status);
+	ASSERT_RETURN(status == 0);
+	ASSERT_RETURN(ret == 0);
+
+	ret = interrupt_sync(conn_a, conn_b);
+	ASSERT_RETURN(ret == 0);
+
+	ret = close_epipe_sync(env->buspath);
+	ASSERT_RETURN(ret == 0);
+
+	ret = cancel_fd_sync(conn_a, conn_b);
+	ASSERT_RETURN(ret == 0);
+
+	ret = no_cancel_sync(conn_a, conn_b);
+	ASSERT_RETURN(ret == 0);
+
+	kdbus_printf("-- closing bus connections\n");
+
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	return TEST_OK;
+}
+
+#define BYEBYE_ME ((void*)0L)
+#define BYEBYE_THEM ((void*)1L)
+
+static void *run_thread_byebye(void *data)
+{
+	struct kdbus_cmd cmd_byebye = { .size = sizeof(cmd_byebye) };
+	int ret;
+
+	ret = kdbus_msg_recv_poll(conn_a, 3000, NULL, NULL);
+	if (ret == 0) {
+		kdbus_printf("Thread received message, invoking BYEBYE ...\n");
+		kdbus_msg_recv(conn_a, NULL, NULL);
+		if (data == BYEBYE_ME)
+			kdbus_cmd_byebye(conn_b->fd, &cmd_byebye);
+		else if (data == BYEBYE_THEM)
+			kdbus_cmd_byebye(conn_a->fd, &cmd_byebye);
+	}
+
+	pthread_exit(NULL);
+	return NULL;
+}
+
+int kdbus_test_sync_byebye(struct kdbus_test_env *env)
+{
+	pthread_t thread;
+	int ret;
+
+	/*
+	 * This sends a synchronous message to a thread, which waits until it
+	 * received the message and then invokes BYEBYE on the *ORIGINAL*
+	 * connection. That is, on the same connection that synchronously waits
+	 * for an reply.
+	 * This should properly wake the connection up and cause ECONNRESET as
+	 * the connection is disconnected now.
+	 *
+	 * The second time, we do the same but invoke BYEBYE on the *TARGET*
+	 * connection. This should also wake up the synchronous sender as the
+	 * reply cannot be sent by a disconnected target.
+	 */
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_ME);
+
+	ret = kdbus_msg_send_sync(conn_b, NULL, cookie,
+				  KDBUS_MSG_EXPECT_REPLY,
+				  5000000000ULL, 0, conn_a->id, -1);
+
+	ASSERT_RETURN(ret == -ECONNRESET);
+
+	pthread_join(thread, NULL);
+
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	pthread_create(&thread, NULL, run_thread_byebye, BYEBYE_THEM);
+
+	ret = kdbus_msg_send_sync(conn_b, NULL, cookie,
+				  KDBUS_MSG_EXPECT_REPLY,
+				  5000000000ULL, 0, conn_a->id, -1);
+
+	ASSERT_RETURN(ret == -EPIPE);
+
+	pthread_join(thread, NULL);
+
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/kdbus/test-timeout.c b/tools/testing/selftests/kdbus/test-timeout.c
new file mode 100644
index 000000000000..cfd193066a64
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-timeout.c
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <poll.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-test.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+
+int timeout_msg_recv(struct kdbus_conn *conn, uint64_t *expected)
+{
+	struct kdbus_cmd_recv recv = { .size = sizeof(recv) };
+	struct kdbus_msg *msg;
+	int ret;
+
+	ret = kdbus_cmd_recv(conn->fd, &recv);
+	if (ret < 0) {
+		kdbus_printf("error receiving message: %d (%m)\n", ret);
+		return ret;
+	}
+
+	msg = (struct kdbus_msg *)(conn->buf + recv.msg.offset);
+
+	ASSERT_RETURN_VAL(msg->payload_type == KDBUS_PAYLOAD_KERNEL, -EINVAL);
+	ASSERT_RETURN_VAL(msg->src_id == KDBUS_SRC_ID_KERNEL, -EINVAL);
+	ASSERT_RETURN_VAL(msg->dst_id == conn->id, -EINVAL);
+
+	*expected &= ~(1ULL << msg->cookie_reply);
+	kdbus_printf("Got message timeout for cookie %llu\n",
+		     msg->cookie_reply);
+
+	ret = kdbus_free(conn, recv.msg.offset);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int kdbus_test_timeout(struct kdbus_test_env *env)
+{
+	struct kdbus_conn *conn_a, *conn_b;
+	struct pollfd fd;
+	int ret, i, n_msgs = 4;
+	uint64_t expected = 0;
+	uint64_t cookie = 0xdeadbeef;
+
+	conn_a = kdbus_hello(env->buspath, 0, NULL, 0);
+	conn_b = kdbus_hello(env->buspath, 0, NULL, 0);
+	ASSERT_RETURN(conn_a && conn_b);
+
+	fd.fd = conn_b->fd;
+
+	/*
+	 * send messages that expect a reply (within 100 msec),
+	 * but never answer it.
+	 */
+	for (i = 0; i < n_msgs; i++, cookie++) {
+		kdbus_printf("Sending message with cookie %llu ...\n",
+			     (unsigned long long)cookie);
+		ASSERT_RETURN(kdbus_msg_send(conn_b, NULL, cookie,
+			      KDBUS_MSG_EXPECT_REPLY,
+			      (i + 1) * 100ULL * 1000000ULL, 0,
+			      conn_a->id) == 0);
+		expected |= 1ULL << cookie;
+	}
+
+	for (;;) {
+		fd.events = POLLIN | POLLPRI | POLLHUP;
+		fd.revents = 0;
+
+		ret = poll(&fd, 1, (n_msgs + 1) * 100);
+		if (ret == 0)
+			kdbus_printf("--- timeout\n");
+		if (ret <= 0)
+			break;
+
+		if (fd.revents & POLLIN)
+			ASSERT_RETURN(!timeout_msg_recv(conn_b, &expected));
+
+		if (expected == 0)
+			break;
+	}
+
+	ASSERT_RETURN(expected == 0);
+
+	kdbus_conn_free(conn_a);
+	kdbus_conn_free(conn_b);
+
+	return TEST_OK;
+}
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
index 9a43a59a9bb4..421c607a8856 100644
--- a/tools/testing/selftests/x86/entry_from_vm86.c
+++ b/tools/testing/selftests/x86/entry_from_vm86.c
@@ -116,8 +116,9 @@ static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
 	v86->regs.eip = eip;
 	ret = vm86(VM86_ENTER, v86);
 
-	if (ret == -1 && errno == ENOSYS) {
-		printf("[SKIP]\tvm86 not supported\n");
+	if (ret == -1 && (errno == ENOSYS || errno == EPERM)) {
+		printf("[SKIP]\tvm86 %s\n",
+		       errno == ENOSYS ? "not supported" : "not allowed");
 		return false;
 	}
 
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 76e38d231e99..48c6e1ac6827 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -200,6 +200,14 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	timer->irq = irq;
 
 	/*
+	 * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
+	 * and to 0 for ARMv7.  We provide an implementation that always
+	 * resets the timer to be disabled and unmasked and is compliant with
+	 * the ARMv7 architecture.
+	 */
+	timer->cntv_ctl = 0;
+
+	/*
 	 * Tell the VGIC that the virtual interrupt is tied to a
 	 * physical interrupt. We do that once per VCPU.
 	 */
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9eb489a2c94c..6bd1c9bf7ae7 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1144,26 +1144,11 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 		struct irq_phys_map *map;
 		map = vgic_irq_map_search(vcpu, irq);
 
-		/*
-		 * If we have a mapping, and the virtual interrupt is
-		 * being injected, then we must set the state to
-		 * active in the physical world. Otherwise the
-		 * physical interrupt will fire and the guest will
-		 * exit before processing the virtual interrupt.
-		 */
 		if (map) {
-			int ret;
-
-			BUG_ON(!map->active);
 			vlr.hwirq = map->phys_irq;
 			vlr.state |= LR_HW;
 			vlr.state &= ~LR_EOI_INT;
 
-			ret = irq_set_irqchip_state(map->irq,
-						    IRQCHIP_STATE_ACTIVE,
-						    true);
-			WARN_ON(ret);
-
 			/*
 			 * Make sure we're not going to sample this
 			 * again, as a HW-backed interrupt cannot be
@@ -1255,7 +1240,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
 	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
 	unsigned long *pa_percpu, *pa_shared;
-	int i, vcpu_id;
+	int i, vcpu_id, lr, ret;
 	int overflow = 0;
 	int nr_shared = vgic_nr_shared_irqs(dist);
 
@@ -1310,6 +1295,31 @@ epilog:
 		 */
 		clear_bit(vcpu_id, dist->irq_pending_on_cpu);
 	}
+
+	for (lr = 0; lr < vgic->nr_lr; lr++) {
+		struct vgic_lr vlr;
+
+		if (!test_bit(lr, vgic_cpu->lr_used))
+			continue;
+
+		vlr = vgic_get_lr(vcpu, lr);
+
+		/*
+		 * If we have a mapping, and the virtual interrupt is
+		 * presented to the guest (as pending or active), then we must
+		 * set the state to active in the physical world. See
+		 * Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
+		 */
+		if (vlr.state & LR_HW) {
+			struct irq_phys_map *map;
+			map = vgic_irq_map_search(vcpu, vlr.irq);
+
+			ret = irq_set_irqchip_state(map->irq,
+						    IRQCHIP_STATE_ACTIVE,
+						    true);
+			WARN_ON(ret);
+		}
+	}
 }
 
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
