Merge tag 'staging-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver updates from Greg KH:
 "Here's the huge drivers/staging/ update for 3.15-rc1.

  Loads of cleanup fixes, a few drivers removed, and some new ones
  added.

  All have been in linux-next for a while"

* tag 'staging-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1375 commits)
  staging: xillybus: XILLYBUS_PCIE depends on PCI_MSI
  staging: xillybus: Added "select CRC32" for XILLYBUS in Kconfig
  staging: comedi: poc: remove obsolete driver
  staging: unisys: replace kzalloc/kfree with UISMALLOC/UISFREE
  staging: octeon-usb: prevent memory corruption
  staging: usbip: fix line over 80 characters
  staging: usbip: fix quoted string split across lines
  Staging: unisys: Remove RETINT macro
  Staging: unisys: Remove FAIL macro
  Staging: unisys: Remove RETVOID macro
  Staging: unisys: Remove RETPTR macro
  Staging: unisys: Remove RETBOOL macro
  Staging: unisys: Remove FAIL_WPOSTCODE_1 macro
  Staging: unisys: Cleanup macros to get rid of goto statements
  Staging: unisys: include: Remove unused macros from timskmod.h
  staging: dgap: fix the rest of the checkpatch warnings in dgap.c
  Staging: bcm: Remove unnecessary parentheses
  staging: wlags49_h2: Delete unnecessary braces
  staging: wlags49_h2: Do not use assignment in if condition
  staging: wlags49_h2: Enclose macro in a do-while loop
  ...
diff --git a/Documentation/devicetree/bindings/arm/atmel-adc.txt b/Documentation/devicetree/bindings/arm/atmel-adc.txt
index d106146..9a1175b 100644
--- a/Documentation/devicetree/bindings/arm/atmel-adc.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-adc.txt
@@ -5,6 +5,9 @@
     <chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
   - reg: Should contain ADC registers location and length
   - interrupts: Should contain the IRQ line for the ADC
+  - clock-names: tuple listing input clock names.
+	Required elements: "adc_clk", "adc_op_clk".
+  - clocks: phandles to input clocks.
   - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
     device
   - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
@@ -44,6 +47,8 @@
 	compatible = "atmel,at91sam9260-adc";
 	reg = <0xfffb0000 0x100>;
 	interrupts = <20 4>;
+	clocks = <&adc_clk>, <&adc_op_clk>;
+	clock-names = "adc_clk", "adc_op_clk";
 	atmel,adc-channel-base = <0x30>;
 	atmel,adc-channels-used = <0xff>;
 	atmel,adc-drdy-mask = <0x10000>;
diff --git a/Documentation/devicetree/bindings/graph.txt b/Documentation/devicetree/bindings/graph.txt
new file mode 100644
index 0000000..1a69c07
--- /dev/null
+++ b/Documentation/devicetree/bindings/graph.txt
@@ -0,0 +1,129 @@
+Common bindings for device graphs
+
+General concept
+---------------
+
+The hierarchical organisation of the device tree is well suited to describe
+control flow to devices, but there can be more complex connections between
+devices that work together to form a logical compound device, following an
+arbitrarily complex graph.
+There already is a simple directed graph between devices tree nodes using
+phandle properties pointing to other nodes to describe connections that
+can not be inferred from device tree parent-child relationships. The device
+tree graph bindings described herein abstract more complex devices that can
+have multiple specifiable ports, each of which can be linked to one or more
+ports of other devices.
+
+These common bindings do not contain any information about the direction or
+type of the connections, they just map their existence. Specific properties
+may be described by specialized bindings depending on the type of connection.
+
+To see how this binding applies to video pipelines, for example, see
+Documentation/device-tree/bindings/media/video-interfaces.txt.
+Here the ports describe data interfaces, and the links between them are
+the connecting data buses. A single port with multiple connections can
+correspond to multiple devices being connected to the same physical bus.
+
+Organisation of ports and endpoints
+-----------------------------------
+
+Ports are described by child 'port' nodes contained in the device node.
+Each port node contains an 'endpoint' subnode for each remote device port
+connected to this port. If a single port is connected to more than one
+remote device, an 'endpoint' child node must be provided for each link.
+If more than one port is present in a device node or there is more than one
+endpoint at a port, or a port node needs to be associated with a selected
+hardware interface, a common scheme using '#address-cells', '#size-cells'
+and 'reg' properties is used number the nodes.
+
+device {
+        ...
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+	        #address-cells = <1>;
+	        #size-cells = <0>;
+		reg = <0>;
+
+                endpoint@0 {
+			reg = <0>;
+			...
+		};
+                endpoint@1 {
+			reg = <1>;
+			...
+		};
+        };
+
+        port@1 {
+		reg = <1>;
+
+		endpoint { ... };
+	};
+};
+
+All 'port' nodes can be grouped under an optional 'ports' node, which
+allows to specify #address-cells, #size-cells properties for the 'port'
+nodes independently from any other child device nodes a device might
+have.
+
+device {
+        ...
+        ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                        ...
+                        endpoint@0 { ... };
+                        endpoint@1 { ... };
+                };
+
+                port@1 { ... };
+        };
+};
+
+Links between endpoints
+-----------------------
+
+Each endpoint should contain a 'remote-endpoint' phandle property that points
+to the corresponding endpoint in the port of the remote device. In turn, the
+remote endpoint should contain a 'remote-endpoint' property. If it has one,
+it must not point to another than the local endpoint. Two endpoints with their
+'remote-endpoint' phandles pointing at each other form a link between the
+containing ports.
+
+device-1 {
+        port {
+                device_1_output: endpoint {
+                        remote-endpoint = <&device_2_input>;
+                };
+        };
+};
+
+device-2 {
+        port {
+                device_2_input: endpoint {
+                        remote-endpoint = <&device_1_output>;
+                };
+        };
+};
+
+
+Required properties
+-------------------
+
+If there is more than one 'port' or more than one 'endpoint' node or 'reg'
+property is present in port and/or endpoint nodes the following properties
+are required in a relevant parent node:
+
+ - #address-cells : number of cells required to define port/endpoint
+                    identifier, should be 1.
+ - #size-cells    : should be zero.
+
+Optional endpoint properties
+----------------------------
+
+- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node.
+
diff --git a/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt b/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt
new file mode 100644
index 0000000..dcebff192
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt
@@ -0,0 +1,22 @@
+Freescale vf610 Analog to Digital Converter bindings
+
+The devicetree bindings are for the new ADC driver written for
+vf610/i.MX6slx and upward SoCs from Freescale.
+
+Required properties:
+- compatible: Should contain "fsl,vf610-adc"
+- reg: Offset and length of the register set for the device
+- interrupts: Should contain the interrupt for the device
+- clocks: The clock is needed by the ADC controller, ADC clock source is ipg clock.
+- clock-names: Must contain "adc", matching entry in the clocks property.
+- vref-supply: The regulator supply ADC refrence voltage.
+
+Example:
+adc0: adc@4003b000 {
+	compatible = "fsl,vf610-adc";
+	reg = <0x4003b000 0x1000>;
+	interrupts = <0 53 0x04>;
+	clocks = <&clks VF610_CLK_ADC0>;
+	clock-names = "adc";
+	vref-supply = <&reg_vcc_3v3_mcu>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt b/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt
new file mode 100644
index 0000000..d9ee909
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/xilinx-xadc.txt
@@ -0,0 +1,113 @@
+Xilinx XADC device driver
+
+This binding document describes the bindings for both of them since the
+bindings are very similar. The Xilinx XADC is a ADC that can be found in the
+series 7 FPGAs from Xilinx. The XADC has a DRP interface for communication.
+Currently two different frontends for the DRP interface exist. One that is only
+available on the ZYNQ family as a hardmacro in the SoC portion of the ZYNQ. The
+other one is available on all series 7 platforms and is a softmacro with a AXI
+interface. This binding document describes the bindings for both of them since
+the bindings are very similar.
+
+Required properties:
+	- compatible: Should be one of
+		* "xlnx,zynq-xadc-1.00.a": When using the ZYNQ device
+		  configuration interface to interface to the XADC hardmacro.
+		* "xlnx,axi-xadc-1.00.a": When using the axi-xadc pcore to
+		  interface to the XADC hardmacro.
+	- reg: Address and length of the register set for the device
+	- interrupts: Interrupt for the XADC control interface.
+	- clocks: When using the ZYNQ this must be the ZYNQ PCAP clock,
+	  when using the AXI-XADC pcore this must be the clock that provides the
+	  clock to the AXI bus interface of the core.
+
+Optional properties:
+	- interrupt-parent: phandle to the parent interrupt controller
+	- xlnx,external-mux:
+		* "none": No external multiplexer is used, this is the default
+		  if the property is omitted.
+		* "single": External multiplexer mode is used with one
+		   multiplexer.
+		* "dual": External multiplexer mode is used with two
+		  multiplexers for simultaneous sampling.
+	- xlnx,external-mux-channel: Configures which pair of pins is used to
+	  sample data in external mux mode.
+	  Valid values for single external multiplexer mode are:
+		0: VP/VN
+		1: VAUXP[0]/VAUXN[0]
+		2: VAUXP[1]/VAUXN[1]
+		...
+		16: VAUXP[15]/VAUXN[15]
+	  Valid values for dual external multiplexer mode are:
+		1: VAUXP[0]/VAUXN[0] - VAUXP[8]/VAUXN[8]
+		2: VAUXP[1]/VAUXN[1] - VAUXP[9]/VAUXN[9]
+		...
+		8: VAUXP[7]/VAUXN[7] - VAUXP[15]/VAUXN[15]
+
+	  This property needs to be present if the device is configured for
+	  external multiplexer mode (either single or dual). If the device is
+	  not using external multiplexer mode the property is ignored.
+	- xnlx,channels: List of external channels that are connected to the ADC
+	  Required properties:
+		* #address-cells: Should be 1.
+		* #size-cells: Should be 0.
+
+	  The child nodes of this node represent the external channels which are
+	  connected to the ADC. If the property is no present no external
+	  channels will be assumed to be connected.
+
+	  Each child node represents one channel and has the following
+	  properties:
+		Required properties:
+			* reg: Pair of pins the the channel is connected to.
+				0: VP/VN
+				1: VAUXP[0]/VAUXN[0]
+				2: VAUXP[1]/VAUXN[1]
+				...
+				16: VAUXP[15]/VAUXN[15]
+			  Note each channel number should only be used at most
+			  once.
+		Optional properties:
+			* xlnx,bipolar: If set the channel is used in bipolar
+			  mode.
+
+
+Examples:
+	xadc@f8007100 {
+		compatible = "xlnx,zynq-xadc-1.00.a";
+		reg = <0xf8007100 0x20>;
+		interrupts = <0 7 4>;
+		interrupt-parent = <&gic>;
+		clocks = <&pcap_clk>;
+
+		xlnx,channels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			channel@0 {
+				reg = <0>;
+			};
+			channel@1 {
+				reg = <1>;
+			};
+			channel@8 {
+				reg = <8>;
+			};
+		};
+	};
+
+	xadc@43200000 {
+		compatible = "xlnx,axi-xadc-1.00.a";
+		reg = <0x43200000 0x1000>;
+		interrupts = <0 53 4>;
+		interrupt-parent = <&gic>;
+		clocks = <&fpga1_clk>;
+
+		xlnx,channels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			channel@0 {
+				reg = <0>;
+				xlnx,bipolar;
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
index b876d49..3be5ce7 100644
--- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
@@ -1,3 +1,22 @@
+Freescale i.MX DRM master device
+================================
+
+The freescale i.MX DRM master device is a virtual device needed to list all
+IPU or other display interface nodes that comprise the graphics subsystem.
+
+Required properties:
+- compatible: Should be "fsl,imx-display-subsystem"
+- ports: Should contain a list of phandles pointing to display interface ports
+  of IPU devices
+
+example:
+
+display-subsystem {
+	compatible = "fsl,display-subsystem";
+	ports = <&ipu_di0>;
+};
+
+
 Freescale i.MX IPUv3
 ====================
 
@@ -7,18 +26,31 @@
   datasheet
 - interrupts: Should contain sync interrupt and error interrupt,
   in this order.
-- #crtc-cells: 1, See below
 - resets: phandle pointing to the system reset controller and
           reset line index, see reset/fsl,imx-src.txt for details
+Optional properties:
+- port@[0-3]: Port nodes with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
+  Ports 0 and 1 should correspond to CSI0 and CSI1,
+  ports 2 and 3 should correspond to DI0 and DI1, respectively.
 
 example:
 
 ipu: ipu@18000000 {
-	#crtc-cells = <1>;
+	#address-cells = <1>;
+	#size-cells = <0>;
 	compatible = "fsl,imx53-ipu";
 	reg = <0x18000000 0x080000000>;
 	interrupts = <11 10>;
 	resets = <&src 2>;
+
+	ipu_di0: port@2 {
+		reg = <2>;
+
+		ipu_di0_disp0: endpoint {
+			remote-endpoint = <&display_in>;
+		};
+	};
 };
 
 Parallel display support
@@ -26,19 +58,25 @@
 
 Required properties:
 - compatible: Should be "fsl,imx-parallel-display"
-- crtc: the crtc this display is connected to, see below
 Optional properties:
 - interface_pix_fmt: How this display is connected to the
-  crtc. Currently supported types: "rgb24", "rgb565", "bgr666"
+  display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
 - edid: verbatim EDID data block describing attached display.
 - ddc: phandle describing the i2c bus handling the display data
   channel
+- port: A port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
 
 example:
 
 display@di0 {
 	compatible = "fsl,imx-parallel-display";
 	edid = [edid-data];
-	crtc = <&ipu 0>;
 	interface-pix-fmt = "rgb24";
+
+	port {
+		display_in: endpoint {
+			remote-endpoint = <&ipu_di0_disp0>;
+		};
+	};
 };
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt b/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
new file mode 100644
index 0000000..1b756cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
@@ -0,0 +1,58 @@
+Device-Tree bindings for HDMI Transmitter
+
+HDMI Transmitter
+================
+
+The HDMI Transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
+with accompanying PHY IP.
+
+Required properties:
+ - #address-cells : should be <1>
+ - #size-cells : should be <0>
+ - compatible : should be "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi".
+ - gpr : should be <&gpr>.
+   The phandle points to the iomuxc-gpr region containing the HDMI
+   multiplexer control register.
+ - clocks, clock-names : phandles to the HDMI iahb and isrf clocks, as described
+   in Documentation/devicetree/bindings/clock/clock-bindings.txt and
+   Documentation/devicetree/bindings/clock/imx6q-clock.txt.
+ - port@[0-4]: Up to four port nodes with endpoint definitions as defined in
+   Documentation/devicetree/bindings/media/video-interfaces.txt,
+   corresponding to the four inputs to the HDMI multiplexer.
+
+Optional properties:
+ - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+
+example:
+
+	gpr: iomuxc-gpr@020e0000 {
+		/* ... */
+	};
+
+        hdmi: hdmi@0120000 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                compatible = "fsl,imx6q-hdmi";
+                reg = <0x00120000 0x9000>;
+                interrupts = <0 115 0x04>;
+                gpr = <&gpr>;
+                clocks = <&clks 123>, <&clks 124>;
+                clock-names = "iahb", "isfr";
+                ddc-i2c-bus = <&i2c2>;
+
+                port@0 {
+                        reg = <0>;
+
+                        hdmi_mux_0: endpoint {
+                                remote-endpoint = <&ipu1_di0_hdmi>;
+                        };
+                };
+
+                port@1 {
+                        reg = <1>;
+
+                        hdmi_mux_1: endpoint {
+                                remote-endpoint = <&ipu1_di1_hdmi>;
+                        };
+                };
+        };
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt b/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt
index ed93778..578a1fc 100644
--- a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt
+++ b/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt
@@ -50,12 +50,14 @@
 
 Required properties:
  - reg : should be <0> or <1>
- - crtcs : a list of phandles with index pointing to the IPU display interfaces
-           that can be used as video source for this channel.
  - fsl,data-mapping : should be "spwg" or "jeida"
                       This describes how the color bits are laid out in the
                       serialized LVDS signal.
  - fsl,data-width : should be <18> or <24>
+ - port: A port node with endpoint definitions as defined in
+   Documentation/devicetree/bindings/media/video-interfaces.txt.
+   On i.MX6, there should be four ports (port@[0-3]) that correspond
+   to the four LVDS multiplexer inputs.
 
 example:
 
@@ -77,23 +79,33 @@
 
 	lvds-channel@0 {
 		reg = <0>;
-		crtcs = <&ipu 0>;
 		fsl,data-mapping = "spwg";
 		fsl,data-width = <24>;
 
 		display-timings {
 			/* ... */
 		};
+
+		port {
+			lvds0_in: endpoint {
+				remote-endpoint = <&ipu_di0_lvds0>;
+			};
+		};
 	};
 
 	lvds-channel@1 {
 		reg = <1>;
-		crtcs = <&ipu 1>;
 		fsl,data-mapping = "spwg";
 		fsl,data-width = <24>;
 
 		display-timings {
 			/* ... */
 		};
+
+		port {
+			lvds1_in: endpoint {
+				remote-endpoint = <&ipu_di1_lvds1>;
+			};
+		};
 	};
 };
diff --git a/MAINTAINERS b/MAINTAINERS
index 4a2ea1a..48a8840 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8394,6 +8394,12 @@
 S:	Odd Fixes
 F:	drivers/staging/sm7xxfb/
 
+STAGING - SLICOSS
+M:	Lior Dotan <liodot@gmail.com>
+M:	Christopher Harrer <charrer@alacritech.com>
+S:	Odd Fixes
+F:	drivers/staging/slicoss/
+
 STAGING - SOFTLOGIC 6x10 MPEG CODEC
 M:	Ismael Luceno <ismael.luceno@corp.bluecherry.net>
 S:	Supported
@@ -9079,6 +9085,13 @@
 F:	include/linux/cdrom.h
 F:	include/uapi/linux/cdrom.h
 
+UNISYS S-PAR DRIVERS
+M:     Benjamin Romer <benjamin.romer@unisys.com>
+M:     David Kershner <david.kershner@unisys.com>
+L:     sparmaintainer@unisys.com (Unisys internal)
+S:     Supported
+F:     drivers/staging/unisys/
+
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
 M:	Vinayak Holikatti <vinholikatti@gmail.com>
 M:	Santosh Y <santoshsy@gmail.com>
diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts
index 5a7f552..d3f9814 100644
--- a/arch/arm/boot/dts/imx51-apf51dev.dts
+++ b/arch/arm/boot/dts/imx51-apf51dev.dts
@@ -18,7 +18,6 @@
 
 	display@di1 {
 		compatible = "fsl,imx-parallel-display";
-		crtcs = <&ipu 0>;
 		interface-pix-fmt = "bgr666";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu_disp1_1>;
@@ -41,6 +40,12 @@
 				pixelclk-active = <0>;
 			};
 		};
+
+		port {
+			display_in: endpoint {
+				remote-endpoint = <&ipu_di0_disp0>;
+			};
+		};
 	};
 
 	gpio-keys {
@@ -122,3 +127,7 @@
 		};
 	};
 };
+
+&ipu_di0_disp0 {
+	remote-endpoint = <&display_in>;
+};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index be1407c..6719271 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -21,9 +21,8 @@
 		reg = <0x90000000 0x20000000>;
 	};
 
-	display@di0 {
+	display0: display@di0 {
 		compatible = "fsl,imx-parallel-display";
-		crtcs = <&ipu 0>;
 		interface-pix-fmt = "rgb24";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu_disp1_1>;
@@ -41,11 +40,16 @@
 				vsync-len = <10>;
 			};
 		};
+
+		port {
+			display0_in: endpoint {
+				remote-endpoint = <&ipu_di0_disp0>;
+			};
+		};
 	};
 
-	display@di1 {
+	display1: display@di1 {
 		compatible = "fsl,imx-parallel-display";
-		crtcs = <&ipu 1>;
 		interface-pix-fmt = "rgb565";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu_disp2_1>;
@@ -68,6 +72,12 @@
 				pixelclk-active = <0>;
 			};
 		};
+
+		port {
+			display1_in: endpoint {
+				remote-endpoint = <&ipu_di1_disp1>;
+			};
+		};
 	};
 
 	gpio-keys {
@@ -258,6 +268,14 @@
 	};
 };
 
+&ipu_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
+&ipu_di1_disp1 {
+	remote-endpoint = <&display1_in>;
+};
+
 &ssi2 {
 	fsl,mode = "i2s-slave";
 	status = "okay";
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 4bcdd3a..28c96aa 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -79,6 +79,11 @@
 		};
 	};
 
+	display-subsystem {
+		compatible = "fsl,imx-display-subsystem";
+		ports = <&ipu_di0>, <&ipu_di1>;
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -92,13 +97,28 @@
 		};
 
 		ipu: ipu@40000000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx51-ipu";
 			reg = <0x40000000 0x20000000>;
 			interrupts = <11 10>;
 			clocks = <&clks 59>, <&clks 110>, <&clks 61>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 2>;
+
+			ipu_di0: port@2 {
+				reg = <2>;
+
+				ipu_di0_disp0: endpoint {
+				};
+			};
+
+			ipu_di1: port@3 {
+				reg = <3>;
+
+				ipu_di1_disp1: endpoint {
+				};
+			};
 		};
 
 		aips@70000000 { /* AIPS1 */
diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts
index 7d304d0..0298adc 100644
--- a/arch/arm/boot/dts/imx53-m53evk.dts
+++ b/arch/arm/boot/dts/imx53-m53evk.dts
@@ -21,9 +21,8 @@
 	};
 
 	soc {
-		display@di1 {
+		display1: display@di1 {
 			compatible = "fsl,imx-parallel-display";
-			crtcs = <&ipu 1>;
 			interface-pix-fmt = "bgr666";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_ipu_disp2_1>;
@@ -44,6 +43,12 @@
 				};
 			};
 		};
+
+		port {
+			display1_in: endpoint {
+				remote-endpoint = <&ipu_di1_disp1>;
+			};
+		};
 	};
 
 	backlight {
@@ -221,6 +226,10 @@
 	};
 };
 
+&ipu_di1_disp1 {
+	remote-endpoint = <&display1_in>;
+};
+
 &nfc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_nand_1>;
diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts
index a630902..a5b55c6 100644
--- a/arch/arm/boot/dts/imx53-mba53.dts
+++ b/arch/arm/boot/dts/imx53-mba53.dts
@@ -38,9 +38,14 @@
 		compatible = "fsl,imx-parallel-display";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_disp1_1>;
-		crtcs = <&ipu 1>;
 		interface-pix-fmt = "rgb24";
 		status = "disabled";
+
+		port {
+			display1_in: endpoint {
+				remote-endpoint = <&ipu_di1_disp1>;
+			};
+		};
 	};
 
 	reg_3p2v: 3p2v {
@@ -141,6 +146,10 @@
 	};
 };
 
+&ipu_di1_disp1 {
+	remote-endpoint = <&display1_in>;
+};
+
 &cspi {
 	status = "okay";
 };
@@ -228,7 +237,7 @@
 &tve {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_vga_sync_1>;
-	ddc = <&i2c3>;
+	i2c-ddc-bus = <&i2c3>;
 	fsl,tve-mode = "vga";
 	fsl,hsync-pin = <4>;
 	fsl,vsync-pin = <6>;
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
index 91a5935..8b25428 100644
--- a/arch/arm/boot/dts/imx53-qsb.dts
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -21,9 +21,8 @@
 		reg = <0x70000000 0x40000000>;
 	};
 
-	display@di0 {
+	display0: display@di0 {
 		compatible = "fsl,imx-parallel-display";
-		crtcs = <&ipu 0>;
 		interface-pix-fmt = "rgb565";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu_disp0_1>;
@@ -46,6 +45,12 @@
 				pixelclk-active = <0>;
 			};
 		};
+
+		port {
+			display0_in: endpoint {
+				remote-endpoint = <&ipu_di0_disp0>;
+			};
+		};
 	};
 
 	gpio-keys {
@@ -126,6 +131,10 @@
 	status = "okay";
 };
 
+&ipu_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
 &ssi2 {
 	fsl,mode = "i2s-slave";
 	status = "okay";
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 4307e80..04d3127 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -45,6 +45,11 @@
 		};
 	};
 
+	display-subsystem {
+		compatible = "fsl,imx-display-subsystem";
+		ports = <&ipu_di0>, <&ipu_di1>;
+	};
+
 	tzic: tz-interrupt-controller@0fffc000 {
 		compatible = "fsl,imx53-tzic", "fsl,tzic";
 		interrupt-controller;
@@ -85,13 +90,49 @@
 		ranges;
 
 		ipu: ipu@18000000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx53-ipu";
 			reg = <0x18000000 0x080000000>;
 			interrupts = <11 10>;
 			clocks = <&clks 59>, <&clks 110>, <&clks 61>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 2>;
+
+			ipu_di0: port@2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <2>;
+
+				ipu_di0_disp0: endpoint@0 {
+					reg = <0>;
+				};
+
+				ipu_di0_lvds0: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&lvds0_in>;
+				};
+			};
+
+			ipu_di1: port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+
+				ipu_di1_disp1: endpoint@0 {
+					reg = <0>;
+				};
+
+				ipu_di1_lvds1: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&lvds1_in>;
+				};
+
+				ipu_di1_tve: endpoint@2 {
+					reg = <2>;
+					remote-endpoint = <&tve_in>;
+				};
+			};
 		};
 
 		aips@50000000 { /* AIPS1 */
@@ -838,14 +879,24 @@
 
 				lvds-channel@0 {
 					reg = <0>;
-					crtcs = <&ipu 0>;
 					status = "disabled";
+
+					port {
+						lvds0_in: endpoint {
+							remote-endpoint = <&ipu_di0_lvds0>;
+						};
+					};
 				};
 
 				lvds-channel@1 {
 					reg = <1>;
-					crtcs = <&ipu 1>;
 					status = "disabled";
+
+					port {
+						lvds1_in: endpoint {
+							remote-endpoint = <&ipu_di0_lvds0>;
+						};
+					};
 				};
 			};
 
@@ -1103,8 +1154,13 @@
 				interrupts = <92>;
 				clocks = <&clks 69>, <&clks 116>;
 				clock-names = "tve", "di_sel";
-				crtcs = <&ipu 1>;
 				status = "disabled";
+
+				port {
+					tve_in: endpoint {
+						remote-endpoint = <&ipu_di1_tve>;
+					};
+				};
 			};
 
 			vpu: vpu@63ff4000 {
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 9e8ae11..25bbdd6 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -70,6 +70,15 @@
 			};
 		};
 	};
+
+	display-subsystem {
+		compatible = "fsl,imx-display-subsystem";
+		ports = <&ipu1_di0>, <&ipu1_di1>;
+	};
+};
+
+&hdmi {
+	compatible = "fsl,imx6dl-hdmi";
 };
 
 &ldb {
@@ -79,12 +88,4 @@
 	clock-names = "di0_pll", "di1_pll",
 		      "di0_sel", "di1_sel",
 		      "di0", "di1";
-
-	lvds-channel@0 {
-		crtcs = <&ipu1 0>, <&ipu1 1>;
-	};
-
-	lvds-channel@1 {
-		crtcs = <&ipu1 0>, <&ipu1 1>;
-	};
 };
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index f024ef2..2a8d9de 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -132,13 +132,84 @@
 		};
 
 		ipu2: ipu@02800000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx6q-ipu";
 			reg = <0x02800000 0x400000>;
 			interrupts = <0 8 0x4 0 7 0x4>;
 			clocks = <&clks 133>, <&clks 134>, <&clks 137>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 4>;
+
+			ipu2_di0: port@2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <2>;
+
+				ipu2_di0_disp0: endpoint@0 {
+				};
+
+				ipu2_di0_hdmi: endpoint@1 {
+					remote-endpoint = <&hdmi_mux_2>;
+				};
+
+				ipu2_di0_mipi: endpoint@2 {
+				};
+
+				ipu2_di0_lvds0: endpoint@3 {
+					remote-endpoint = <&lvds0_mux_2>;
+				};
+
+				ipu2_di0_lvds1: endpoint@4 {
+					remote-endpoint = <&lvds1_mux_2>;
+				};
+			};
+
+			ipu2_di1: port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+
+				ipu2_di1_hdmi: endpoint@1 {
+					remote-endpoint = <&hdmi_mux_3>;
+				};
+
+				ipu2_di1_mipi: endpoint@2 {
+				};
+
+				ipu2_di1_lvds0: endpoint@3 {
+					remote-endpoint = <&lvds0_mux_3>;
+				};
+
+				ipu2_di1_lvds1: endpoint@4 {
+					remote-endpoint = <&lvds1_mux_3>;
+				};
+			};
+		};
+	};
+
+	display-subsystem {
+		compatible = "fsl,imx-display-subsystem";
+		ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
+	};
+};
+
+&hdmi {
+	compatible = "fsl,imx6q-hdmi";
+
+	port@2 {
+		reg = <2>;
+
+		hdmi_mux_2: endpoint {
+			remote-endpoint = <&ipu2_di0_hdmi>;
+		};
+	};
+
+	port@3 {
+		reg = <3>;
+
+		hdmi_mux_3: endpoint {
+			remote-endpoint = <&ipu2_di1_hdmi>;
 		};
 	};
 };
@@ -152,10 +223,56 @@
 		      "di0", "di1";
 
 	lvds-channel@0 {
-		crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+		port@2 {
+			reg = <2>;
+
+			lvds0_mux_2: endpoint {
+				remote-endpoint = <&ipu2_di0_lvds0>;
+			};
+		};
+
+		port@3 {
+			reg = <3>;
+
+			lvds0_mux_3: endpoint {
+				remote-endpoint = <&ipu2_di1_lvds0>;
+			};
+		};
 	};
 
 	lvds-channel@1 {
-		crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+		port@2 {
+			reg = <2>;
+
+			lvds1_mux_2: endpoint {
+				remote-endpoint = <&ipu2_di0_lvds1>;
+			};
+		};
+
+		port@3 {
+			reg = <3>;
+
+			lvds1_mux_3: endpoint {
+				remote-endpoint = <&ipu2_di1_lvds1>;
+			};
+		};
+	};
+};
+
+&mipi_dsi {
+	port@2 {
+		reg = <2>;
+
+		mipi_mux_2: endpoint {
+			remote-endpoint = <&ipu2_di0_mipi>;
+		};
+	};
+
+	port@3 {
+		reg = <3>;
+
+		mipi_mux_3: endpoint {
+			remote-endpoint = <&ipu2_di1_mipi>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index fb28b2e..64a8cbe 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1358,13 +1358,76 @@
 				status = "disabled";
 
 				lvds-channel@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 					reg = <0>;
 					status = "disabled";
+
+					port@0 {
+						reg = <0>;
+
+						lvds0_mux_0: endpoint {
+							remote-endpoint = <&ipu1_di0_lvds0>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+
+						lvds0_mux_1: endpoint {
+							remote-endpoint = <&ipu1_di1_lvds0>;
+						};
+					};
 				};
 
 				lvds-channel@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
 					reg = <1>;
 					status = "disabled";
+
+					port@0 {
+						reg = <0>;
+
+						lvds1_mux_0: endpoint {
+							remote-endpoint = <&ipu1_di0_lvds1>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+
+						lvds1_mux_1: endpoint {
+							remote-endpoint = <&ipu1_di1_lvds1>;
+						};
+					};
+				};
+			};
+
+			hdmi: hdmi@0120000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x00120000 0x9000>;
+				interrupts = <0 115 0x04>;
+				gpr = <&gpr>;
+				clocks = <&clks 123>, <&clks 124>;
+				clock-names = "iahb", "isfr";
+				status = "disabled";
+
+				port@0 {
+					reg = <0>;
+
+					hdmi_mux_0: endpoint {
+						remote-endpoint = <&ipu1_di0_hdmi>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					hdmi_mux_1: endpoint {
+						remote-endpoint = <&ipu1_di1_hdmi>;
+					};
 				};
 			};
 
@@ -1579,8 +1642,27 @@
 				reg = <0x021dc000 0x4000>;
 			};
 
-			mipi@021e0000 { /* MIPI-DSI */
+			mipi_dsi: mipi@021e0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0x021e0000 0x4000>;
+				status = "disabled";
+
+				port@0 {
+					reg = <0>;
+
+					mipi_mux_0: endpoint {
+						remote-endpoint = <&ipu1_di0_mipi>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					mipi_mux_1: endpoint {
+						remote-endpoint = <&ipu1_di1_mipi>;
+					};
+				};
 			};
 
 			vdoa@021e4000 {
@@ -1634,13 +1716,64 @@
 		};
 
 		ipu1: ipu@02400000 {
-			#crtc-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "fsl,imx6q-ipu";
 			reg = <0x02400000 0x400000>;
 			interrupts = <0 6 0x4 0 5 0x4>;
 			clocks = <&clks 130>, <&clks 131>, <&clks 132>;
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 2>;
+
+			ipu1_di0: port@2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <2>;
+
+				ipu1_di0_disp0: endpoint@0 {
+				};
+
+				ipu1_di0_hdmi: endpoint@1 {
+					remote-endpoint = <&hdmi_mux_0>;
+				};
+
+				ipu1_di0_mipi: endpoint@2 {
+					remote-endpoint = <&mipi_mux_0>;
+				};
+
+				ipu1_di0_lvds0: endpoint@3 {
+					remote-endpoint = <&lvds0_mux_0>;
+				};
+
+				ipu1_di0_lvds1: endpoint@4 {
+					remote-endpoint = <&lvds1_mux_0>;
+				};
+			};
+
+			ipu1_di1: port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+
+				ipu1_di0_disp1: endpoint@0 {
+				};
+
+				ipu1_di1_hdmi: endpoint@1 {
+					remote-endpoint = <&hdmi_mux_1>;
+				};
+
+				ipu1_di1_mipi: endpoint@2 {
+					remote-endpoint = <&mipi_mux_1>;
+				};
+
+				ipu1_di1_lvds0: endpoint@3 {
+					remote-endpoint = <&lvds0_mux_1>;
+				};
+
+				ipu1_di1_lvds1: endpoint@4 {
+					remote-endpoint = <&lvds1_mux_1>;
+				};
+			};
 		};
 	};
 };
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index bfec313..a7e68c8 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -451,9 +451,9 @@
 	.type = IIO_ACCEL,						\
 	.modified = 1,							\
 	.channel2 = IIO_MOD_##_axis,					\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
-	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
 	.scan_index = AXIS_##_axis,					\
 	.scan_type = {							\
 		.sign = 's',						\
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 5c63f091..4bf4c16 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -207,6 +207,16 @@
 	  This driver can also be built as a module. If so, the module will be
 	  called twl6030-gpadc.
 
+config VF610_ADC
+	tristate "Freescale vf610 ADC driver"
+	depends on OF
+	help
+	  Say yes here to support for Vybrid board analog-to-digital converter.
+	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called vf610_adc.
+
 config VIPERBOARD_ADC
 	tristate "Viperboard ADC support"
 	depends on MFD_VIPERBOARD && USB
@@ -214,4 +224,17 @@
 	  Say yes here to access the ADC part of the Nano River
 	  Technologies Viperboard.
 
+config XILINX_XADC
+	tristate "Xilinx XADC driver"
+	depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
+	depends on HAS_IOMEM
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to have support for the Xilinx XADC. The driver does support
+	  both the ZYNQ interface to the XADC as well as the AXI-XADC interface.
+
+	  The driver can also be build as a module. If so, the module will be called
+	  xilinx-xadc.
+
 endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 85a4a04..bb25254 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -22,4 +22,7 @@
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
+obj-$(CONFIG_VF610_ADC) += vf610_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
+xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o
+obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 3602592..9cf3229 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -8,17 +8,11 @@
   * based on linux/drivers/acron/char/pcf8583.c
   * Copyright (C) 2000 Russell King
   *
+  * Driver for max1363 and similar chips.
+  *
   * 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.
-  *
-  * max1363.c
-  *
-  * Partial support for max1363 and similar chips.
-  *
-  * Not currently implemented.
-  *
-  * - Control of internal reference.
   */
 
 #include <linux/interrupt.h>
@@ -1253,7 +1247,7 @@
 	},
 	[max11604] = {
 		.bits = 8,
-		.int_vref_mv = 4098,
+		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
@@ -1313,7 +1307,7 @@
 	},
 	[max11610] = {
 		.bits = 10,
-		.int_vref_mv = 4098,
+		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
@@ -1373,7 +1367,7 @@
 	},
 	[max11616] = {
 		.bits = 12,
-		.int_vref_mv = 4098,
+		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 31e786e..a4db302 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -13,7 +13,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/module.h>
diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c
index 53a24eb..15282f1 100644
--- a/drivers/iio/adc/twl6030-gpadc.c
+++ b/drivers/iio/adc/twl6030-gpadc.c
@@ -28,7 +28,6 @@
  * 02110-1301 USA
  *
  */
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
new file mode 100644
index 0000000..44799eb5
--- /dev/null
+++ b/drivers/iio/adc/vf610_adc.c
@@ -0,0 +1,711 @@
+/*
+ * Freescale Vybrid vf610 ADC driver
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_platform.h>
+#include <linux/err.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/driver.h>
+
+/* This will be the driver name the kernel reports */
+#define DRIVER_NAME "vf610-adc"
+
+/* Vybrid/IMX ADC registers */
+#define VF610_REG_ADC_HC0		0x00
+#define VF610_REG_ADC_HC1		0x04
+#define VF610_REG_ADC_HS		0x08
+#define VF610_REG_ADC_R0		0x0c
+#define VF610_REG_ADC_R1		0x10
+#define VF610_REG_ADC_CFG		0x14
+#define VF610_REG_ADC_GC		0x18
+#define VF610_REG_ADC_GS		0x1c
+#define VF610_REG_ADC_CV		0x20
+#define VF610_REG_ADC_OFS		0x24
+#define VF610_REG_ADC_CAL		0x28
+#define VF610_REG_ADC_PCTL		0x30
+
+/* Configuration register field define */
+#define VF610_ADC_MODE_BIT8		0x00
+#define VF610_ADC_MODE_BIT10		0x04
+#define VF610_ADC_MODE_BIT12		0x08
+#define VF610_ADC_MODE_MASK		0x0c
+#define VF610_ADC_BUSCLK2_SEL		0x01
+#define VF610_ADC_ALTCLK_SEL		0x02
+#define VF610_ADC_ADACK_SEL		0x03
+#define VF610_ADC_ADCCLK_MASK		0x03
+#define VF610_ADC_CLK_DIV2		0x20
+#define VF610_ADC_CLK_DIV4		0x40
+#define VF610_ADC_CLK_DIV8		0x60
+#define VF610_ADC_CLK_MASK		0x60
+#define VF610_ADC_ADLSMP_LONG		0x10
+#define VF610_ADC_ADSTS_MASK		0x300
+#define VF610_ADC_ADLPC_EN		0x80
+#define VF610_ADC_ADHSC_EN		0x400
+#define VF610_ADC_REFSEL_VALT		0x100
+#define VF610_ADC_REFSEL_VBG		0x1000
+#define VF610_ADC_ADTRG_HARD		0x2000
+#define VF610_ADC_AVGS_8		0x4000
+#define VF610_ADC_AVGS_16		0x8000
+#define VF610_ADC_AVGS_32		0xC000
+#define VF610_ADC_AVGS_MASK		0xC000
+#define VF610_ADC_OVWREN		0x10000
+
+/* General control register field define */
+#define VF610_ADC_ADACKEN		0x1
+#define VF610_ADC_DMAEN			0x2
+#define VF610_ADC_ACREN			0x4
+#define VF610_ADC_ACFGT			0x8
+#define VF610_ADC_ACFE			0x10
+#define VF610_ADC_AVGEN			0x20
+#define VF610_ADC_ADCON			0x40
+#define VF610_ADC_CAL			0x80
+
+/* Other field define */
+#define VF610_ADC_ADCHC(x)		((x) & 0xF)
+#define VF610_ADC_AIEN			(0x1 << 7)
+#define VF610_ADC_CONV_DISABLE		0x1F
+#define VF610_ADC_HS_COCO0		0x1
+#define VF610_ADC_CALF			0x2
+#define VF610_ADC_TIMEOUT		msecs_to_jiffies(100)
+
+enum clk_sel {
+	VF610_ADCIOC_BUSCLK_SET,
+	VF610_ADCIOC_ALTCLK_SET,
+	VF610_ADCIOC_ADACK_SET,
+};
+
+enum vol_ref {
+	VF610_ADCIOC_VR_VREF_SET,
+	VF610_ADCIOC_VR_VALT_SET,
+	VF610_ADCIOC_VR_VBG_SET,
+};
+
+enum average_sel {
+	VF610_ADC_SAMPLE_1,
+	VF610_ADC_SAMPLE_4,
+	VF610_ADC_SAMPLE_8,
+	VF610_ADC_SAMPLE_16,
+	VF610_ADC_SAMPLE_32,
+};
+
+struct vf610_adc_feature {
+	enum clk_sel	clk_sel;
+	enum vol_ref	vol_ref;
+
+	int	clk_div;
+	int     sample_rate;
+	int	res_mode;
+
+	bool	lpm;
+	bool	calibration;
+	bool	ovwren;
+};
+
+struct vf610_adc {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *clk;
+
+	u32 vref_uv;
+	u32 value;
+	struct regulator *vref;
+	struct vf610_adc_feature adc_feature;
+
+	struct completion completion;
+};
+
+#define VF610_ADC_CHAN(_idx, _chan_type) {			\
+	.type = (_chan_type),					\
+	.indexed = 1,						\
+	.channel = (_idx),					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+}
+
+static const struct iio_chan_spec vf610_adc_iio_channels[] = {
+	VF610_ADC_CHAN(0, IIO_VOLTAGE),
+	VF610_ADC_CHAN(1, IIO_VOLTAGE),
+	VF610_ADC_CHAN(2, IIO_VOLTAGE),
+	VF610_ADC_CHAN(3, IIO_VOLTAGE),
+	VF610_ADC_CHAN(4, IIO_VOLTAGE),
+	VF610_ADC_CHAN(5, IIO_VOLTAGE),
+	VF610_ADC_CHAN(6, IIO_VOLTAGE),
+	VF610_ADC_CHAN(7, IIO_VOLTAGE),
+	VF610_ADC_CHAN(8, IIO_VOLTAGE),
+	VF610_ADC_CHAN(9, IIO_VOLTAGE),
+	VF610_ADC_CHAN(10, IIO_VOLTAGE),
+	VF610_ADC_CHAN(11, IIO_VOLTAGE),
+	VF610_ADC_CHAN(12, IIO_VOLTAGE),
+	VF610_ADC_CHAN(13, IIO_VOLTAGE),
+	VF610_ADC_CHAN(14, IIO_VOLTAGE),
+	VF610_ADC_CHAN(15, IIO_VOLTAGE),
+	/* sentinel */
+};
+
+/*
+ * ADC sample frequency, unit is ADCK cycles.
+ * ADC clk source is ipg clock, which is the same as bus clock.
+ *
+ * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)
+ * SFCAdder: fixed to 6 ADCK cycles
+ * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
+ * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
+ * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
+ *
+ * By default, enable 12 bit resolution mode, clock source
+ * set to ipg clock, So get below frequency group:
+ */
+static const u32 vf610_sample_freq_avail[5] =
+{1941176, 559332, 286957, 145374, 73171};
+
+static inline void vf610_adc_cfg_init(struct vf610_adc *info)
+{
+	/* set default Configuration for ADC controller */
+	info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET;
+	info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET;
+
+	info->adc_feature.calibration = true;
+	info->adc_feature.ovwren = true;
+
+	info->adc_feature.clk_div = 1;
+	info->adc_feature.res_mode = 12;
+	info->adc_feature.sample_rate = 1;
+	info->adc_feature.lpm = true;
+}
+
+static void vf610_adc_cfg_post_set(struct vf610_adc *info)
+{
+	struct vf610_adc_feature *adc_feature = &info->adc_feature;
+	int cfg_data = 0;
+	int gc_data = 0;
+
+	switch (adc_feature->clk_sel) {
+	case VF610_ADCIOC_ALTCLK_SET:
+		cfg_data |= VF610_ADC_ALTCLK_SEL;
+		break;
+	case VF610_ADCIOC_ADACK_SET:
+		cfg_data |= VF610_ADC_ADACK_SEL;
+		break;
+	default:
+		break;
+	}
+
+	/* low power set for calibration */
+	cfg_data |= VF610_ADC_ADLPC_EN;
+
+	/* enable high speed for calibration */
+	cfg_data |= VF610_ADC_ADHSC_EN;
+
+	/* voltage reference */
+	switch (adc_feature->vol_ref) {
+	case VF610_ADCIOC_VR_VREF_SET:
+		break;
+	case VF610_ADCIOC_VR_VALT_SET:
+		cfg_data |= VF610_ADC_REFSEL_VALT;
+		break;
+	case VF610_ADCIOC_VR_VBG_SET:
+		cfg_data |= VF610_ADC_REFSEL_VBG;
+		break;
+	default:
+		dev_err(info->dev, "error voltage reference\n");
+	}
+
+	/* data overwrite enable */
+	if (adc_feature->ovwren)
+		cfg_data |= VF610_ADC_OVWREN;
+
+	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
+	writel(gc_data, info->regs + VF610_REG_ADC_GC);
+}
+
+static void vf610_adc_calibration(struct vf610_adc *info)
+{
+	int adc_gc, hc_cfg;
+	int timeout;
+
+	if (!info->adc_feature.calibration)
+		return;
+
+	/* enable calibration interrupt */
+	hc_cfg = VF610_ADC_AIEN | VF610_ADC_CONV_DISABLE;
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	adc_gc = readl(info->regs + VF610_REG_ADC_GC);
+	writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC);
+
+	timeout = wait_for_completion_timeout
+			(&info->completion, VF610_ADC_TIMEOUT);
+	if (timeout == 0)
+		dev_err(info->dev, "Timeout for adc calibration\n");
+
+	adc_gc = readl(info->regs + VF610_REG_ADC_GS);
+	if (adc_gc & VF610_ADC_CALF)
+		dev_err(info->dev, "ADC calibration failed\n");
+
+	info->adc_feature.calibration = false;
+}
+
+static void vf610_adc_cfg_set(struct vf610_adc *info)
+{
+	struct vf610_adc_feature *adc_feature = &(info->adc_feature);
+	int cfg_data;
+
+	cfg_data = readl(info->regs + VF610_REG_ADC_CFG);
+
+	/* low power configuration */
+	cfg_data &= ~VF610_ADC_ADLPC_EN;
+	if (adc_feature->lpm)
+		cfg_data |= VF610_ADC_ADLPC_EN;
+
+	/* disable high speed */
+	cfg_data &= ~VF610_ADC_ADHSC_EN;
+
+	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
+}
+
+static void vf610_adc_sample_set(struct vf610_adc *info)
+{
+	struct vf610_adc_feature *adc_feature = &(info->adc_feature);
+	int cfg_data, gc_data;
+
+	cfg_data = readl(info->regs + VF610_REG_ADC_CFG);
+	gc_data = readl(info->regs + VF610_REG_ADC_GC);
+
+	/* resolution mode */
+	cfg_data &= ~VF610_ADC_MODE_MASK;
+	switch (adc_feature->res_mode) {
+	case 8:
+		cfg_data |= VF610_ADC_MODE_BIT8;
+		break;
+	case 10:
+		cfg_data |= VF610_ADC_MODE_BIT10;
+		break;
+	case 12:
+		cfg_data |= VF610_ADC_MODE_BIT12;
+		break;
+	default:
+		dev_err(info->dev, "error resolution mode\n");
+		break;
+	}
+
+	/* clock select and clock divider */
+	cfg_data &= ~(VF610_ADC_CLK_MASK | VF610_ADC_ADCCLK_MASK);
+	switch (adc_feature->clk_div) {
+	case 1:
+		break;
+	case 2:
+		cfg_data |= VF610_ADC_CLK_DIV2;
+		break;
+	case 4:
+		cfg_data |= VF610_ADC_CLK_DIV4;
+		break;
+	case 8:
+		cfg_data |= VF610_ADC_CLK_DIV8;
+		break;
+	case 16:
+		switch (adc_feature->clk_sel) {
+		case VF610_ADCIOC_BUSCLK_SET:
+			cfg_data |= VF610_ADC_BUSCLK2_SEL | VF610_ADC_CLK_DIV8;
+			break;
+		default:
+			dev_err(info->dev, "error clk divider\n");
+			break;
+		}
+		break;
+	}
+
+	/* Use the short sample mode */
+	cfg_data &= ~(VF610_ADC_ADLSMP_LONG | VF610_ADC_ADSTS_MASK);
+
+	/* update hardware average selection */
+	cfg_data &= ~VF610_ADC_AVGS_MASK;
+	gc_data &= ~VF610_ADC_AVGEN;
+	switch (adc_feature->sample_rate) {
+	case VF610_ADC_SAMPLE_1:
+		break;
+	case VF610_ADC_SAMPLE_4:
+		gc_data |= VF610_ADC_AVGEN;
+		break;
+	case VF610_ADC_SAMPLE_8:
+		gc_data |= VF610_ADC_AVGEN;
+		cfg_data |= VF610_ADC_AVGS_8;
+		break;
+	case VF610_ADC_SAMPLE_16:
+		gc_data |= VF610_ADC_AVGEN;
+		cfg_data |= VF610_ADC_AVGS_16;
+		break;
+	case VF610_ADC_SAMPLE_32:
+		gc_data |= VF610_ADC_AVGEN;
+		cfg_data |= VF610_ADC_AVGS_32;
+		break;
+	default:
+		dev_err(info->dev,
+			"error hardware sample average select\n");
+	}
+
+	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);
+	writel(gc_data, info->regs + VF610_REG_ADC_GC);
+}
+
+static void vf610_adc_hw_init(struct vf610_adc *info)
+{
+	/* CFG: Feature set */
+	vf610_adc_cfg_post_set(info);
+	vf610_adc_sample_set(info);
+
+	/* adc calibration */
+	vf610_adc_calibration(info);
+
+	/* CFG: power and speed set */
+	vf610_adc_cfg_set(info);
+}
+
+static int vf610_adc_read_data(struct vf610_adc *info)
+{
+	int result;
+
+	result = readl(info->regs + VF610_REG_ADC_R0);
+
+	switch (info->adc_feature.res_mode) {
+	case 8:
+		result &= 0xFF;
+		break;
+	case 10:
+		result &= 0x3FF;
+		break;
+	case 12:
+		result &= 0xFFF;
+		break;
+	default:
+		break;
+	}
+
+	return result;
+}
+
+static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
+{
+	struct vf610_adc *info = (struct vf610_adc *)dev_id;
+	int coco;
+
+	coco = readl(info->regs + VF610_REG_ADC_HS);
+	if (coco & VF610_ADC_HS_COCO0) {
+		info->value = vf610_adc_read_data(info);
+		complete(&info->completion);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171");
+
+static struct attribute *vf610_attributes[] = {
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group vf610_attribute_group = {
+	.attrs = vf610_attributes,
+};
+
+static int vf610_read_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val,
+			int *val2,
+			long mask)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int hc_cfg;
+	long ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&indio_dev->mlock);
+		reinit_completion(&info->completion);
+
+		hc_cfg = VF610_ADC_ADCHC(chan->channel);
+		hc_cfg |= VF610_ADC_AIEN;
+		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+		ret = wait_for_completion_interruptible_timeout
+				(&info->completion, VF610_ADC_TIMEOUT);
+		if (ret == 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return -ETIMEDOUT;
+		}
+		if (ret < 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+
+		*val = info->value;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		*val = info->vref_uv / 1000;
+		*val2 = info->adc_feature.res_mode;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = vf610_sample_freq_avail[info->adc_feature.sample_rate];
+		*val2 = 0;
+		return IIO_VAL_INT;
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int vf610_write_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int val,
+			int val2,
+			long mask)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	int i;
+
+	switch (mask) {
+		case IIO_CHAN_INFO_SAMP_FREQ:
+			for (i = 0;
+				i < ARRAY_SIZE(vf610_sample_freq_avail);
+				i++)
+				if (val == vf610_sample_freq_avail[i]) {
+					info->adc_feature.sample_rate = i;
+					vf610_adc_sample_set(info);
+					return 0;
+				}
+			break;
+
+		default:
+			break;
+	}
+
+	return -EINVAL;
+}
+
+static int vf610_adc_reg_access(struct iio_dev *indio_dev,
+			unsigned reg, unsigned writeval,
+			unsigned *readval)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+
+	if ((readval == NULL) ||
+		(!(reg % 4) || (reg > VF610_REG_ADC_PCTL)))
+		return -EINVAL;
+
+	*readval = readl(info->regs + reg);
+
+	return 0;
+}
+
+static const struct iio_info vf610_adc_iio_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &vf610_read_raw,
+	.write_raw = &vf610_write_raw,
+	.debugfs_reg_access = &vf610_adc_reg_access,
+	.attrs = &vf610_attribute_group,
+};
+
+static const struct of_device_id vf610_adc_match[] = {
+	{ .compatible = "fsl,vf610-adc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vf610_adc_match);
+
+static int vf610_adc_probe(struct platform_device *pdev)
+{
+	struct vf610_adc *info;
+	struct iio_dev *indio_dev;
+	struct resource *mem;
+	int irq;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct vf610_adc));
+	if (!indio_dev) {
+		dev_err(&pdev->dev, "Failed allocating iio device\n");
+		return -ENOMEM;
+	}
+
+	info = iio_priv(indio_dev);
+	info->dev = &pdev->dev;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	info->regs = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(info->regs))
+		return PTR_ERR(info->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0) {
+		dev_err(&pdev->dev, "no irq resource?\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_irq(info->dev, irq,
+				vf610_adc_isr, 0,
+				dev_name(&pdev->dev), info);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
+		return ret;
+	}
+
+	info->clk = devm_clk_get(&pdev->dev, "adc");
+	if (IS_ERR(info->clk)) {
+		dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
+						PTR_ERR(info->clk));
+		ret = PTR_ERR(info->clk);
+		return ret;
+	}
+
+	info->vref = devm_regulator_get(&pdev->dev, "vref");
+	if (IS_ERR(info->vref))
+		return PTR_ERR(info->vref);
+
+	ret = regulator_enable(info->vref);
+	if (ret)
+		return ret;
+
+	info->vref_uv = regulator_get_voltage(info->vref);
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	init_completion(&info->completion);
+
+	indio_dev->name = dev_name(&pdev->dev);
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->dev.of_node = pdev->dev.of_node;
+	indio_dev->info = &vf610_adc_iio_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = vf610_adc_iio_channels;
+	indio_dev->num_channels = ARRAY_SIZE(vf610_adc_iio_channels);
+
+	ret = clk_prepare_enable(info->clk);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Could not prepare or enable the clock.\n");
+		goto error_adc_clk_enable;
+	}
+
+	vf610_adc_cfg_init(info);
+	vf610_adc_hw_init(info);
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Couldn't register the device.\n");
+		goto error_iio_device_register;
+	}
+
+	return 0;
+
+
+error_iio_device_register:
+	clk_disable_unprepare(info->clk);
+error_adc_clk_enable:
+	regulator_disable(info->vref);
+
+	return ret;
+}
+
+static int vf610_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct vf610_adc *info = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	regulator_disable(info->vref);
+	clk_disable_unprepare(info->clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int vf610_adc_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct vf610_adc *info = iio_priv(indio_dev);
+	int hc_cfg;
+
+	/* ADC controller enters to stop mode */
+	hc_cfg = readl(info->regs + VF610_REG_ADC_HC0);
+	hc_cfg |= VF610_ADC_CONV_DISABLE;
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	clk_disable_unprepare(info->clk);
+	regulator_disable(info->vref);
+
+	return 0;
+}
+
+static int vf610_adc_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct vf610_adc *info = iio_priv(indio_dev);
+	int ret;
+
+	ret = regulator_enable(info->vref);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(info->clk);
+	if (ret)
+		return ret;
+
+	vf610_adc_hw_init(info);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops,
+			vf610_adc_suspend,
+			vf610_adc_resume);
+
+static struct platform_driver vf610_adc_driver = {
+	.probe          = vf610_adc_probe,
+	.remove         = vf610_adc_remove,
+	.driver         = {
+		.name   = DRIVER_NAME,
+		.owner  = THIS_MODULE,
+		.of_match_table = vf610_adc_match,
+		.pm     = &vf610_adc_pm_ops,
+	},
+};
+
+module_platform_driver(vf610_adc_driver);
+
+MODULE_AUTHOR("Fugang Duan <B38611@freescale.com>");
+MODULE_DESCRIPTION("Freescale VF610 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c
index d0add8f..9acf6b6 100644
--- a/drivers/iio/adc/viperboard_adc.c
+++ b/drivers/iio/adc/viperboard_adc.c
@@ -139,8 +139,6 @@
 		return ret;
 	}
 
-	platform_set_drvdata(pdev, indio_dev);
-
 	return 0;
 }
 
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c
new file mode 100644
index 0000000..ab52be2
--- /dev/null
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -0,0 +1,1333 @@
+/*
+ * Xilinx XADC driver
+ *
+ * Copyright 2013-2014 Analog Devices Inc.
+ *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ *
+ * Documentation for the parts can be found at:
+ *  - XADC hardmacro: Xilinx UG480
+ *  - ZYNQ XADC interface: Xilinx UG585
+ *  - AXI XADC interface: Xilinx PG019
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include "xilinx-xadc.h"
+
+static const unsigned int XADC_ZYNQ_UNMASK_TIMEOUT = 500;
+
+/* ZYNQ register definitions */
+#define XADC_ZYNQ_REG_CFG	0x00
+#define XADC_ZYNQ_REG_INTSTS	0x04
+#define XADC_ZYNQ_REG_INTMSK	0x08
+#define XADC_ZYNQ_REG_STATUS	0x0c
+#define XADC_ZYNQ_REG_CFIFO	0x10
+#define XADC_ZYNQ_REG_DFIFO	0x14
+#define XADC_ZYNQ_REG_CTL		0x18
+
+#define XADC_ZYNQ_CFG_ENABLE		BIT(31)
+#define XADC_ZYNQ_CFG_CFIFOTH_MASK	(0xf << 20)
+#define XADC_ZYNQ_CFG_CFIFOTH_OFFSET	20
+#define XADC_ZYNQ_CFG_DFIFOTH_MASK	(0xf << 16)
+#define XADC_ZYNQ_CFG_DFIFOTH_OFFSET	16
+#define XADC_ZYNQ_CFG_WEDGE		BIT(13)
+#define XADC_ZYNQ_CFG_REDGE		BIT(12)
+#define XADC_ZYNQ_CFG_TCKRATE_MASK	(0x3 << 8)
+#define XADC_ZYNQ_CFG_TCKRATE_DIV2	(0x0 << 8)
+#define XADC_ZYNQ_CFG_TCKRATE_DIV4	(0x1 << 8)
+#define XADC_ZYNQ_CFG_TCKRATE_DIV8	(0x2 << 8)
+#define XADC_ZYNQ_CFG_TCKRATE_DIV16	(0x3 << 8)
+#define XADC_ZYNQ_CFG_IGAP_MASK		0x1f
+#define XADC_ZYNQ_CFG_IGAP(x)		(x)
+
+#define XADC_ZYNQ_INT_CFIFO_LTH		BIT(9)
+#define XADC_ZYNQ_INT_DFIFO_GTH		BIT(8)
+#define XADC_ZYNQ_INT_ALARM_MASK	0xff
+#define XADC_ZYNQ_INT_ALARM_OFFSET	0
+
+#define XADC_ZYNQ_STATUS_CFIFO_LVL_MASK	(0xf << 16)
+#define XADC_ZYNQ_STATUS_CFIFO_LVL_OFFSET	16
+#define XADC_ZYNQ_STATUS_DFIFO_LVL_MASK	(0xf << 12)
+#define XADC_ZYNQ_STATUS_DFIFO_LVL_OFFSET	12
+#define XADC_ZYNQ_STATUS_CFIFOF		BIT(11)
+#define XADC_ZYNQ_STATUS_CFIFOE		BIT(10)
+#define XADC_ZYNQ_STATUS_DFIFOF		BIT(9)
+#define XADC_ZYNQ_STATUS_DFIFOE		BIT(8)
+#define XADC_ZYNQ_STATUS_OT		BIT(7)
+#define XADC_ZYNQ_STATUS_ALM(x)		BIT(x)
+
+#define XADC_ZYNQ_CTL_RESET		BIT(4)
+
+#define XADC_ZYNQ_CMD_NOP		0x00
+#define XADC_ZYNQ_CMD_READ		0x01
+#define XADC_ZYNQ_CMD_WRITE		0x02
+
+#define XADC_ZYNQ_CMD(cmd, addr, data) (((cmd) << 26) | ((addr) << 16) | (data))
+
+/* AXI register definitions */
+#define XADC_AXI_REG_RESET		0x00
+#define XADC_AXI_REG_STATUS		0x04
+#define XADC_AXI_REG_ALARM_STATUS	0x08
+#define XADC_AXI_REG_CONVST		0x0c
+#define XADC_AXI_REG_XADC_RESET		0x10
+#define XADC_AXI_REG_GIER		0x5c
+#define XADC_AXI_REG_IPISR		0x60
+#define XADC_AXI_REG_IPIER		0x68
+#define XADC_AXI_ADC_REG_OFFSET		0x200
+
+#define XADC_AXI_RESET_MAGIC		0xa
+#define XADC_AXI_GIER_ENABLE		BIT(31)
+
+#define XADC_AXI_INT_EOS		BIT(4)
+#define XADC_AXI_INT_ALARM_MASK		0x3c0f
+
+#define XADC_FLAGS_BUFFERED BIT(0)
+
+static void xadc_write_reg(struct xadc *xadc, unsigned int reg,
+	uint32_t val)
+{
+	writel(val, xadc->base + reg);
+}
+
+static void xadc_read_reg(struct xadc *xadc, unsigned int reg,
+	uint32_t *val)
+{
+	*val = readl(xadc->base + reg);
+}
+
+/*
+ * The ZYNQ interface uses two asynchronous FIFOs for communication with the
+ * XADC. Reads and writes to the XADC register are performed by submitting a
+ * request to the command FIFO (CFIFO), once the request has been completed the
+ * result can be read from the data FIFO (DFIFO). The method currently used in
+ * this driver is to submit the request for a read/write operation, then go to
+ * sleep and wait for an interrupt that signals that a response is available in
+ * the data FIFO.
+ */
+
+static void xadc_zynq_write_fifo(struct xadc *xadc, uint32_t *cmd,
+	unsigned int n)
+{
+	unsigned int i;
+
+	for (i = 0; i < n; i++)
+		xadc_write_reg(xadc, XADC_ZYNQ_REG_CFIFO, cmd[i]);
+}
+
+static void xadc_zynq_drain_fifo(struct xadc *xadc)
+{
+	uint32_t status, tmp;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_STATUS, &status);
+
+	while (!(status & XADC_ZYNQ_STATUS_DFIFOE)) {
+		xadc_read_reg(xadc, XADC_ZYNQ_REG_DFIFO, &tmp);
+		xadc_read_reg(xadc, XADC_ZYNQ_REG_STATUS, &status);
+	}
+}
+
+static void xadc_zynq_update_intmsk(struct xadc *xadc, unsigned int mask,
+	unsigned int val)
+{
+	xadc->zynq_intmask &= ~mask;
+	xadc->zynq_intmask |= val;
+
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTMSK,
+		xadc->zynq_intmask | xadc->zynq_masked_alarm);
+}
+
+static int xadc_zynq_write_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t val)
+{
+	uint32_t cmd[1];
+	uint32_t tmp;
+	int ret;
+
+	spin_lock_irq(&xadc->lock);
+	xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH,
+			XADC_ZYNQ_INT_DFIFO_GTH);
+
+	reinit_completion(&xadc->completion);
+
+	cmd[0] = XADC_ZYNQ_CMD(XADC_ZYNQ_CMD_WRITE, reg, val);
+	xadc_zynq_write_fifo(xadc, cmd, ARRAY_SIZE(cmd));
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_CFG, &tmp);
+	tmp &= ~XADC_ZYNQ_CFG_DFIFOTH_MASK;
+	tmp |= 0 << XADC_ZYNQ_CFG_DFIFOTH_OFFSET;
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_CFG, tmp);
+
+	xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH, 0);
+	spin_unlock_irq(&xadc->lock);
+
+	ret = wait_for_completion_interruptible_timeout(&xadc->completion, HZ);
+	if (ret == 0)
+		ret = -EIO;
+	else
+		ret = 0;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_DFIFO, &tmp);
+
+	return ret;
+}
+
+static int xadc_zynq_read_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t *val)
+{
+	uint32_t cmd[2];
+	uint32_t resp, tmp;
+	int ret;
+
+	cmd[0] = XADC_ZYNQ_CMD(XADC_ZYNQ_CMD_READ, reg, 0);
+	cmd[1] = XADC_ZYNQ_CMD(XADC_ZYNQ_CMD_NOP, 0, 0);
+
+	spin_lock_irq(&xadc->lock);
+	xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH,
+			XADC_ZYNQ_INT_DFIFO_GTH);
+	xadc_zynq_drain_fifo(xadc);
+	reinit_completion(&xadc->completion);
+
+	xadc_zynq_write_fifo(xadc, cmd, ARRAY_SIZE(cmd));
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_CFG, &tmp);
+	tmp &= ~XADC_ZYNQ_CFG_DFIFOTH_MASK;
+	tmp |= 1 << XADC_ZYNQ_CFG_DFIFOTH_OFFSET;
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_CFG, tmp);
+
+	xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH, 0);
+	spin_unlock_irq(&xadc->lock);
+	ret = wait_for_completion_interruptible_timeout(&xadc->completion, HZ);
+	if (ret == 0)
+		ret = -EIO;
+	if (ret < 0)
+		return ret;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_DFIFO, &resp);
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_DFIFO, &resp);
+
+	*val = resp & 0xffff;
+
+	return 0;
+}
+
+static unsigned int xadc_zynq_transform_alarm(unsigned int alarm)
+{
+	return ((alarm & 0x80) >> 4) |
+		((alarm & 0x78) << 1) |
+		(alarm & 0x07);
+}
+
+/*
+ * The ZYNQ threshold interrupts are level sensitive. Since we can't make the
+ * threshold condition go way from within the interrupt handler, this means as
+ * soon as a threshold condition is present we would enter the interrupt handler
+ * again and again. To work around this we mask all active thresholds interrupts
+ * in the interrupt handler and start a timer. In this timer we poll the
+ * interrupt status and only if the interrupt is inactive we unmask it again.
+ */
+static void xadc_zynq_unmask_worker(struct work_struct *work)
+{
+	struct xadc *xadc = container_of(work, struct xadc, zynq_unmask_work.work);
+	unsigned int misc_sts, unmask;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_STATUS, &misc_sts);
+
+	misc_sts &= XADC_ZYNQ_INT_ALARM_MASK;
+
+	spin_lock_irq(&xadc->lock);
+
+	/* Clear those bits which are not active anymore */
+	unmask = (xadc->zynq_masked_alarm ^ misc_sts) & xadc->zynq_masked_alarm;
+	xadc->zynq_masked_alarm &= misc_sts;
+
+	/* Also clear those which are masked out anyway */
+	xadc->zynq_masked_alarm &= ~xadc->zynq_intmask;
+
+	/* Clear the interrupts before we unmask them */
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, unmask);
+
+	xadc_zynq_update_intmsk(xadc, 0, 0);
+
+	spin_unlock_irq(&xadc->lock);
+
+	/* if still pending some alarm re-trigger the timer */
+	if (xadc->zynq_masked_alarm) {
+		schedule_delayed_work(&xadc->zynq_unmask_work,
+				msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
+	}
+}
+
+static irqreturn_t xadc_zynq_threaded_interrupt_handler(int irq, void *devid)
+{
+	struct iio_dev *indio_dev = devid;
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned int alarm;
+
+	spin_lock_irq(&xadc->lock);
+	alarm = xadc->zynq_alarm;
+	xadc->zynq_alarm = 0;
+	spin_unlock_irq(&xadc->lock);
+
+	xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
+
+	/* unmask the required interrupts in timer. */
+	schedule_delayed_work(&xadc->zynq_unmask_work,
+			msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
+{
+	struct iio_dev *indio_dev = devid;
+	struct xadc *xadc = iio_priv(indio_dev);
+	irqreturn_t ret = IRQ_HANDLED;
+	uint32_t status;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
+
+	status &= ~(xadc->zynq_intmask | xadc->zynq_masked_alarm);
+
+	if (!status)
+		return IRQ_NONE;
+
+	spin_lock(&xadc->lock);
+
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, status);
+
+	if (status & XADC_ZYNQ_INT_DFIFO_GTH) {
+		xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH,
+			XADC_ZYNQ_INT_DFIFO_GTH);
+		complete(&xadc->completion);
+	}
+
+	status &= XADC_ZYNQ_INT_ALARM_MASK;
+	if (status) {
+		xadc->zynq_alarm |= status;
+		xadc->zynq_masked_alarm |= status;
+		/*
+		 * mask the current event interrupt,
+		 * unmask it when the interrupt is no more active.
+		 */
+		xadc_zynq_update_intmsk(xadc, 0, 0);
+		ret = IRQ_WAKE_THREAD;
+	}
+	spin_unlock(&xadc->lock);
+
+	return ret;
+}
+
+#define XADC_ZYNQ_TCK_RATE_MAX 50000000
+#define XADC_ZYNQ_IGAP_DEFAULT 20
+
+static int xadc_zynq_setup(struct platform_device *pdev,
+	struct iio_dev *indio_dev, int irq)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned long pcap_rate;
+	unsigned int tck_div;
+	unsigned int div;
+	unsigned int igap;
+	unsigned int tck_rate;
+
+	/* TODO: Figure out how to make igap and tck_rate configurable */
+	igap = XADC_ZYNQ_IGAP_DEFAULT;
+	tck_rate = XADC_ZYNQ_TCK_RATE_MAX;
+
+	xadc->zynq_intmask = ~0;
+
+	pcap_rate = clk_get_rate(xadc->clk);
+
+	if (tck_rate > XADC_ZYNQ_TCK_RATE_MAX)
+		tck_rate = XADC_ZYNQ_TCK_RATE_MAX;
+	if (tck_rate > pcap_rate / 2) {
+		div = 2;
+	} else {
+		div = pcap_rate / tck_rate;
+		if (pcap_rate / div > XADC_ZYNQ_TCK_RATE_MAX)
+			div++;
+	}
+
+	if (div <= 3)
+		tck_div = XADC_ZYNQ_CFG_TCKRATE_DIV2;
+	else if (div <= 7)
+		tck_div = XADC_ZYNQ_CFG_TCKRATE_DIV4;
+	else if (div <= 15)
+		tck_div = XADC_ZYNQ_CFG_TCKRATE_DIV8;
+	else
+		tck_div = XADC_ZYNQ_CFG_TCKRATE_DIV16;
+
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_CTL, XADC_ZYNQ_CTL_RESET);
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_CTL, 0);
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, ~0);
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTMSK, xadc->zynq_intmask);
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_CFG, XADC_ZYNQ_CFG_ENABLE |
+			XADC_ZYNQ_CFG_REDGE | XADC_ZYNQ_CFG_WEDGE |
+			tck_div | XADC_ZYNQ_CFG_IGAP(igap));
+
+	return 0;
+}
+
+static unsigned long xadc_zynq_get_dclk_rate(struct xadc *xadc)
+{
+	unsigned int div;
+	uint32_t val;
+
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_CFG, &val);
+
+	switch (val & XADC_ZYNQ_CFG_TCKRATE_MASK) {
+	case XADC_ZYNQ_CFG_TCKRATE_DIV4:
+		div = 4;
+		break;
+	case XADC_ZYNQ_CFG_TCKRATE_DIV8:
+		div = 8;
+		break;
+	case XADC_ZYNQ_CFG_TCKRATE_DIV16:
+		div = 16;
+		break;
+	default:
+		div = 2;
+		break;
+	}
+
+	return clk_get_rate(xadc->clk) / div;
+}
+
+static void xadc_zynq_update_alarm(struct xadc *xadc, unsigned int alarm)
+{
+	unsigned long flags;
+	uint32_t status;
+
+	/* Move OT to bit 7 */
+	alarm = ((alarm & 0x08) << 4) | ((alarm & 0xf0) >> 1) | (alarm & 0x07);
+
+	spin_lock_irqsave(&xadc->lock, flags);
+
+	/* Clear previous interrupts if any. */
+	xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
+	xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, status & alarm);
+
+	xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_ALARM_MASK,
+		~alarm & XADC_ZYNQ_INT_ALARM_MASK);
+
+	spin_unlock_irqrestore(&xadc->lock, flags);
+}
+
+static const struct xadc_ops xadc_zynq_ops = {
+	.read = xadc_zynq_read_adc_reg,
+	.write = xadc_zynq_write_adc_reg,
+	.setup = xadc_zynq_setup,
+	.get_dclk_rate = xadc_zynq_get_dclk_rate,
+	.interrupt_handler = xadc_zynq_interrupt_handler,
+	.threaded_interrupt_handler = xadc_zynq_threaded_interrupt_handler,
+	.update_alarm = xadc_zynq_update_alarm,
+};
+
+static int xadc_axi_read_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t *val)
+{
+	uint32_t val32;
+
+	xadc_read_reg(xadc, XADC_AXI_ADC_REG_OFFSET + reg * 4, &val32);
+	*val = val32 & 0xffff;
+
+	return 0;
+}
+
+static int xadc_axi_write_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t val)
+{
+	xadc_write_reg(xadc, XADC_AXI_ADC_REG_OFFSET + reg * 4, val);
+
+	return 0;
+}
+
+static int xadc_axi_setup(struct platform_device *pdev,
+	struct iio_dev *indio_dev, int irq)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+
+	xadc_write_reg(xadc, XADC_AXI_REG_RESET, XADC_AXI_RESET_MAGIC);
+	xadc_write_reg(xadc, XADC_AXI_REG_GIER, XADC_AXI_GIER_ENABLE);
+
+	return 0;
+}
+
+static irqreturn_t xadc_axi_interrupt_handler(int irq, void *devid)
+{
+	struct iio_dev *indio_dev = devid;
+	struct xadc *xadc = iio_priv(indio_dev);
+	uint32_t status, mask;
+	unsigned int events;
+
+	xadc_read_reg(xadc, XADC_AXI_REG_IPISR, &status);
+	xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &mask);
+	status &= mask;
+
+	if (!status)
+		return IRQ_NONE;
+
+	if ((status & XADC_AXI_INT_EOS) && xadc->trigger)
+		iio_trigger_poll(xadc->trigger, 0);
+
+	if (status & XADC_AXI_INT_ALARM_MASK) {
+		/*
+		 * The order of the bits in the AXI-XADC status register does
+		 * not match the order of the bits in the XADC alarm enable
+		 * register. xadc_handle_events() expects the events to be in
+		 * the same order as the XADC alarm enable register.
+		 */
+		events = (status & 0x000e) >> 1;
+		events |= (status & 0x0001) << 3;
+		events |= (status & 0x3c00) >> 6;
+		xadc_handle_events(indio_dev, events);
+	}
+
+	xadc_write_reg(xadc, XADC_AXI_REG_IPISR, status);
+
+	return IRQ_HANDLED;
+}
+
+static void xadc_axi_update_alarm(struct xadc *xadc, unsigned int alarm)
+{
+	uint32_t val;
+	unsigned long flags;
+
+	/*
+	 * The order of the bits in the AXI-XADC status register does not match
+	 * the order of the bits in the XADC alarm enable register. We get
+	 * passed the alarm mask in the same order as in the XADC alarm enable
+	 * register.
+	 */
+	alarm = ((alarm & 0x07) << 1) | ((alarm & 0x08) >> 3) |
+			((alarm & 0xf0) << 6);
+
+	spin_lock_irqsave(&xadc->lock, flags);
+	xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
+	val &= ~XADC_AXI_INT_ALARM_MASK;
+	val |= alarm;
+	xadc_write_reg(xadc, XADC_AXI_REG_IPIER, val);
+	spin_unlock_irqrestore(&xadc->lock, flags);
+}
+
+static unsigned long xadc_axi_get_dclk(struct xadc *xadc)
+{
+	return clk_get_rate(xadc->clk);
+}
+
+static const struct xadc_ops xadc_axi_ops = {
+	.read = xadc_axi_read_adc_reg,
+	.write = xadc_axi_write_adc_reg,
+	.setup = xadc_axi_setup,
+	.get_dclk_rate = xadc_axi_get_dclk,
+	.update_alarm = xadc_axi_update_alarm,
+	.interrupt_handler = xadc_axi_interrupt_handler,
+	.flags = XADC_FLAGS_BUFFERED,
+};
+
+static int _xadc_update_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t mask, uint16_t val)
+{
+	uint16_t tmp;
+	int ret;
+
+	ret = _xadc_read_adc_reg(xadc, reg, &tmp);
+	if (ret)
+		return ret;
+
+	return _xadc_write_adc_reg(xadc, reg, (tmp & ~mask) | val);
+}
+
+static int xadc_update_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t mask, uint16_t val)
+{
+	int ret;
+
+	mutex_lock(&xadc->mutex);
+	ret = _xadc_update_adc_reg(xadc, reg, mask, val);
+	mutex_unlock(&xadc->mutex);
+
+	return ret;
+}
+
+static unsigned long xadc_get_dclk_rate(struct xadc *xadc)
+{
+	return xadc->ops->get_dclk_rate(xadc);
+}
+
+static int xadc_update_scan_mode(struct iio_dev *indio_dev,
+	const unsigned long *mask)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned int n;
+
+	n = bitmap_weight(mask, indio_dev->masklength);
+
+	kfree(xadc->data);
+	xadc->data = kcalloc(n, sizeof(*xadc->data), GFP_KERNEL);
+	if (!xadc->data)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static unsigned int xadc_scan_index_to_channel(unsigned int scan_index)
+{
+	switch (scan_index) {
+	case 5:
+		return XADC_REG_VCCPINT;
+	case 6:
+		return XADC_REG_VCCPAUX;
+	case 7:
+		return XADC_REG_VCCO_DDR;
+	case 8:
+		return XADC_REG_TEMP;
+	case 9:
+		return XADC_REG_VCCINT;
+	case 10:
+		return XADC_REG_VCCAUX;
+	case 11:
+		return XADC_REG_VPVN;
+	case 12:
+		return XADC_REG_VREFP;
+	case 13:
+		return XADC_REG_VREFN;
+	case 14:
+		return XADC_REG_VCCBRAM;
+	default:
+		return XADC_REG_VAUX(scan_index - 16);
+	}
+}
+
+static irqreturn_t xadc_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned int chan;
+	int i, j;
+
+	if (!xadc->data)
+		goto out;
+
+	j = 0;
+	for_each_set_bit(i, indio_dev->active_scan_mask,
+		indio_dev->masklength) {
+		chan = xadc_scan_index_to_channel(i);
+		xadc_read_adc_reg(xadc, chan, &xadc->data[j]);
+		j++;
+	}
+
+	iio_push_to_buffers(indio_dev, xadc->data);
+
+out:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static int xadc_trigger_set_state(struct iio_trigger *trigger, bool state)
+{
+	struct xadc *xadc = iio_trigger_get_drvdata(trigger);
+	unsigned long flags;
+	unsigned int convst;
+	unsigned int val;
+	int ret = 0;
+
+	mutex_lock(&xadc->mutex);
+
+	if (state) {
+		/* Only one of the two triggers can be active at the a time. */
+		if (xadc->trigger != NULL) {
+			ret = -EBUSY;
+			goto err_out;
+		} else {
+			xadc->trigger = trigger;
+			if (trigger == xadc->convst_trigger)
+				convst = XADC_CONF0_EC;
+			else
+				convst = 0;
+		}
+		ret = _xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF0_EC,
+					convst);
+		if (ret)
+			goto err_out;
+	} else {
+		xadc->trigger = NULL;
+	}
+
+	spin_lock_irqsave(&xadc->lock, flags);
+	xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
+	xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS);
+	if (state)
+		val |= XADC_AXI_INT_EOS;
+	else
+		val &= ~XADC_AXI_INT_EOS;
+	xadc_write_reg(xadc, XADC_AXI_REG_IPIER, val);
+	spin_unlock_irqrestore(&xadc->lock, flags);
+
+err_out:
+	mutex_unlock(&xadc->mutex);
+
+	return ret;
+}
+
+static const struct iio_trigger_ops xadc_trigger_ops = {
+	.owner = THIS_MODULE,
+	.set_trigger_state = &xadc_trigger_set_state,
+};
+
+static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
+	const char *name)
+{
+	struct iio_trigger *trig;
+	int ret;
+
+	trig = iio_trigger_alloc("%s%d-%s", indio_dev->name,
+				indio_dev->id, name);
+	if (trig == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	trig->dev.parent = indio_dev->dev.parent;
+	trig->ops = &xadc_trigger_ops;
+	iio_trigger_set_drvdata(trig, iio_priv(indio_dev));
+
+	ret = iio_trigger_register(trig);
+	if (ret)
+		goto error_free_trig;
+
+	return trig;
+
+error_free_trig:
+	iio_trigger_free(trig);
+	return ERR_PTR(ret);
+}
+
+static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
+{
+	uint16_t val;
+
+	switch (seq_mode) {
+	case XADC_CONF1_SEQ_SIMULTANEOUS:
+	case XADC_CONF1_SEQ_INDEPENDENT:
+		val = XADC_CONF2_PD_ADC_B;
+		break;
+	default:
+		val = 0;
+		break;
+	}
+
+	return xadc_update_adc_reg(xadc, XADC_REG_CONF2, XADC_CONF2_PD_MASK,
+		val);
+}
+
+static int xadc_get_seq_mode(struct xadc *xadc, unsigned long scan_mode)
+{
+	unsigned int aux_scan_mode = scan_mode >> 16;
+
+	if (xadc->external_mux_mode == XADC_EXTERNAL_MUX_DUAL)
+		return XADC_CONF1_SEQ_SIMULTANEOUS;
+
+	if ((aux_scan_mode & 0xff00) == 0 ||
+		(aux_scan_mode & 0x00ff) == 0)
+		return XADC_CONF1_SEQ_CONTINUOUS;
+
+	return XADC_CONF1_SEQ_SIMULTANEOUS;
+}
+
+static int xadc_postdisable(struct iio_dev *indio_dev)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned long scan_mask;
+	int ret;
+	int i;
+
+	scan_mask = 1; /* Run calibration as part of the sequence */
+	for (i = 0; i < indio_dev->num_channels; i++)
+		scan_mask |= BIT(indio_dev->channels[i].scan_index);
+
+	/* Enable all channels and calibration */
+	ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff);
+	if (ret)
+		return ret;
+
+	ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16);
+	if (ret)
+		return ret;
+
+	ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
+		XADC_CONF1_SEQ_CONTINUOUS);
+	if (ret)
+		return ret;
+
+	return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS);
+}
+
+static int xadc_preenable(struct iio_dev *indio_dev)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned long scan_mask;
+	int seq_mode;
+	int ret;
+
+	ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
+		XADC_CONF1_SEQ_DEFAULT);
+	if (ret)
+		goto err;
+
+	scan_mask = *indio_dev->active_scan_mask;
+	seq_mode = xadc_get_seq_mode(xadc, scan_mask);
+
+	ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff);
+	if (ret)
+		goto err;
+
+	ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16);
+	if (ret)
+		goto err;
+
+	ret = xadc_power_adc_b(xadc, seq_mode);
+	if (ret)
+		goto err;
+
+	ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
+		seq_mode);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	xadc_postdisable(indio_dev);
+	return ret;
+}
+
+static struct iio_buffer_setup_ops xadc_buffer_ops = {
+	.preenable = &xadc_preenable,
+	.postenable = &iio_triggered_buffer_postenable,
+	.predisable = &iio_triggered_buffer_predisable,
+	.postdisable = &xadc_postdisable,
+};
+
+static int xadc_read_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned int div;
+	uint16_t val16;
+	int ret;
+
+	switch (info) {
+	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+		ret = xadc_read_adc_reg(xadc, chan->address, &val16);
+		if (ret < 0)
+			return ret;
+
+		val16 >>= 4;
+		if (chan->scan_type.sign == 'u')
+			*val = val16;
+		else
+			*val = sign_extend32(val16, 11);
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			/* V = (val * 3.0) / 4096 */
+			switch (chan->address) {
+			case XADC_REG_VCCINT:
+			case XADC_REG_VCCAUX:
+			case XADC_REG_VCCBRAM:
+			case XADC_REG_VCCPINT:
+			case XADC_REG_VCCPAUX:
+			case XADC_REG_VCCO_DDR:
+				*val = 3000;
+				break;
+			default:
+				*val = 1000;
+				break;
+			}
+			*val2 = 12;
+			return IIO_VAL_FRACTIONAL_LOG2;
+		case IIO_TEMP:
+			/* Temp in C = (val * 503.975) / 4096 - 273.15 */
+			*val = 503975;
+			*val2 = 12;
+			return IIO_VAL_FRACTIONAL_LOG2;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_OFFSET:
+		/* Only the temperature channel has an offset */
+		*val = -((273150 << 12) / 503975);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = xadc_read_adc_reg(xadc, XADC_REG_CONF2, &val16);
+		if (ret)
+			return ret;
+
+		div = (val16 & XADC_CONF2_DIV_MASK) >> XADC_CONF2_DIV_OFFSET;
+		if (div < 2)
+			div = 2;
+
+		*val = xadc_get_dclk_rate(xadc) / div / 26;
+
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int xadc_write_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	unsigned long clk_rate = xadc_get_dclk_rate(xadc);
+	unsigned int div;
+
+	if (info != IIO_CHAN_INFO_SAMP_FREQ)
+		return -EINVAL;
+
+	if (val <= 0)
+		return -EINVAL;
+
+	/* Max. 150 kSPS */
+	if (val > 150000)
+		val = 150000;
+
+	val *= 26;
+
+	/* Min 1MHz */
+	if (val < 1000000)
+		val = 1000000;
+
+	/*
+	 * We want to round down, but only if we do not exceed the 150 kSPS
+	 * limit.
+	 */
+	div = clk_rate / val;
+	if (clk_rate / div / 26 > 150000)
+		div++;
+	if (div < 2)
+		div = 2;
+	else if (div > 0xff)
+		div = 0xff;
+
+	return xadc_update_adc_reg(xadc, XADC_REG_CONF2, XADC_CONF2_DIV_MASK,
+		div << XADC_CONF2_DIV_OFFSET);
+}
+
+static const struct iio_event_spec xadc_temp_events[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
+				BIT(IIO_EV_INFO_VALUE) |
+				BIT(IIO_EV_INFO_HYSTERESIS),
+	},
+};
+
+/* Separate values for upper and lower thresholds, but only a shared enabled */
+static const struct iio_event_spec xadc_voltage_events[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	}, {
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_FALLING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	}, {
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_EITHER,
+		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
+	},
+};
+
+#define XADC_CHAN_TEMP(_chan, _scan_index, _addr) { \
+	.type = IIO_TEMP, \
+	.indexed = 1, \
+	.channel = (_chan), \
+	.address = (_addr), \
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+		BIT(IIO_CHAN_INFO_SCALE) | \
+		BIT(IIO_CHAN_INFO_OFFSET), \
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.event_spec = xadc_temp_events, \
+	.num_event_specs = ARRAY_SIZE(xadc_temp_events), \
+	.scan_index = (_scan_index), \
+	.scan_type = { \
+		.sign = 'u', \
+		.realbits = 12, \
+		.storagebits = 16, \
+		.shift = 4, \
+		.endianness = IIO_CPU, \
+	}, \
+}
+
+#define XADC_CHAN_VOLTAGE(_chan, _scan_index, _addr, _ext, _alarm) { \
+	.type = IIO_VOLTAGE, \
+	.indexed = 1, \
+	.channel = (_chan), \
+	.address = (_addr), \
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+		BIT(IIO_CHAN_INFO_SCALE), \
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.event_spec = (_alarm) ? xadc_voltage_events : NULL, \
+	.num_event_specs = (_alarm) ? ARRAY_SIZE(xadc_voltage_events) : 0, \
+	.scan_index = (_scan_index), \
+	.scan_type = { \
+		.sign = 'u', \
+		.realbits = 12, \
+		.storagebits = 16, \
+		.shift = 4, \
+		.endianness = IIO_CPU, \
+	}, \
+	.extend_name = _ext, \
+}
+
+static const struct iio_chan_spec xadc_channels[] = {
+	XADC_CHAN_TEMP(0, 8, XADC_REG_TEMP),
+	XADC_CHAN_VOLTAGE(0, 9, XADC_REG_VCCINT, "vccint", true),
+	XADC_CHAN_VOLTAGE(1, 10, XADC_REG_VCCINT, "vccaux", true),
+	XADC_CHAN_VOLTAGE(2, 14, XADC_REG_VCCBRAM, "vccbram", true),
+	XADC_CHAN_VOLTAGE(3, 5, XADC_REG_VCCPINT, "vccpint", true),
+	XADC_CHAN_VOLTAGE(4, 6, XADC_REG_VCCPAUX, "vccpaux", true),
+	XADC_CHAN_VOLTAGE(5, 7, XADC_REG_VCCO_DDR, "vccoddr", true),
+	XADC_CHAN_VOLTAGE(6, 12, XADC_REG_VREFP, "vrefp", false),
+	XADC_CHAN_VOLTAGE(7, 13, XADC_REG_VREFN, "vrefn", false),
+	XADC_CHAN_VOLTAGE(8, 11, XADC_REG_VPVN, NULL, false),
+	XADC_CHAN_VOLTAGE(9, 16, XADC_REG_VAUX(0), NULL, false),
+	XADC_CHAN_VOLTAGE(10, 17, XADC_REG_VAUX(1), NULL, false),
+	XADC_CHAN_VOLTAGE(11, 18, XADC_REG_VAUX(2), NULL, false),
+	XADC_CHAN_VOLTAGE(12, 19, XADC_REG_VAUX(3), NULL, false),
+	XADC_CHAN_VOLTAGE(13, 20, XADC_REG_VAUX(4), NULL, false),
+	XADC_CHAN_VOLTAGE(14, 21, XADC_REG_VAUX(5), NULL, false),
+	XADC_CHAN_VOLTAGE(15, 22, XADC_REG_VAUX(6), NULL, false),
+	XADC_CHAN_VOLTAGE(16, 23, XADC_REG_VAUX(7), NULL, false),
+	XADC_CHAN_VOLTAGE(17, 24, XADC_REG_VAUX(8), NULL, false),
+	XADC_CHAN_VOLTAGE(18, 25, XADC_REG_VAUX(9), NULL, false),
+	XADC_CHAN_VOLTAGE(19, 26, XADC_REG_VAUX(10), NULL, false),
+	XADC_CHAN_VOLTAGE(20, 27, XADC_REG_VAUX(11), NULL, false),
+	XADC_CHAN_VOLTAGE(21, 28, XADC_REG_VAUX(12), NULL, false),
+	XADC_CHAN_VOLTAGE(22, 29, XADC_REG_VAUX(13), NULL, false),
+	XADC_CHAN_VOLTAGE(23, 30, XADC_REG_VAUX(14), NULL, false),
+	XADC_CHAN_VOLTAGE(24, 31, XADC_REG_VAUX(15), NULL, false),
+};
+
+static const struct iio_info xadc_info = {
+	.read_raw = &xadc_read_raw,
+	.write_raw = &xadc_write_raw,
+	.read_event_config = &xadc_read_event_config,
+	.write_event_config = &xadc_write_event_config,
+	.read_event_value = &xadc_read_event_value,
+	.write_event_value = &xadc_write_event_value,
+	.update_scan_mode = &xadc_update_scan_mode,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct of_device_id xadc_of_match_table[] = {
+	{ .compatible = "xlnx,zynq-xadc-1.00.a", (void *)&xadc_zynq_ops },
+	{ .compatible = "xlnx,axi-xadc-1.00.a", (void *)&xadc_axi_ops },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, xadc_of_match_table);
+
+static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np,
+	unsigned int *conf)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+	struct iio_chan_spec *channels, *chan;
+	struct device_node *chan_node, *child;
+	unsigned int num_channels;
+	const char *external_mux;
+	u32 ext_mux_chan;
+	int reg;
+	int ret;
+
+	*conf = 0;
+
+	ret = of_property_read_string(np, "xlnx,external-mux", &external_mux);
+	if (ret < 0 || strcasecmp(external_mux, "none") == 0)
+		xadc->external_mux_mode = XADC_EXTERNAL_MUX_NONE;
+	else if (strcasecmp(external_mux, "single") == 0)
+		xadc->external_mux_mode = XADC_EXTERNAL_MUX_SINGLE;
+	else if (strcasecmp(external_mux, "dual") == 0)
+		xadc->external_mux_mode = XADC_EXTERNAL_MUX_DUAL;
+	else
+		return -EINVAL;
+
+	if (xadc->external_mux_mode != XADC_EXTERNAL_MUX_NONE) {
+		ret = of_property_read_u32(np, "xlnx,external-mux-channel",
+					&ext_mux_chan);
+		if (ret < 0)
+			return ret;
+
+		if (xadc->external_mux_mode == XADC_EXTERNAL_MUX_SINGLE) {
+			if (ext_mux_chan == 0)
+				ext_mux_chan = XADC_REG_VPVN;
+			else if (ext_mux_chan <= 16)
+				ext_mux_chan = XADC_REG_VAUX(ext_mux_chan - 1);
+			else
+				return -EINVAL;
+		} else {
+			if (ext_mux_chan > 0 && ext_mux_chan <= 8)
+				ext_mux_chan = XADC_REG_VAUX(ext_mux_chan - 1);
+			else
+				return -EINVAL;
+		}
+
+		*conf |= XADC_CONF0_MUX | XADC_CONF0_CHAN(ext_mux_chan);
+	}
+
+	channels = kmemdup(xadc_channels, sizeof(xadc_channels), GFP_KERNEL);
+	if (!channels)
+		return -ENOMEM;
+
+	num_channels = 9;
+	chan = &channels[9];
+
+	chan_node = of_get_child_by_name(np, "xlnx,channels");
+	if (chan_node) {
+		for_each_child_of_node(chan_node, child) {
+			if (num_channels >= ARRAY_SIZE(xadc_channels)) {
+				of_node_put(child);
+				break;
+			}
+
+			ret = of_property_read_u32(child, "reg", &reg);
+			if (ret || reg > 16)
+				continue;
+
+			if (of_property_read_bool(child, "xlnx,bipolar"))
+				chan->scan_type.sign = 's';
+
+			if (reg == 0) {
+				chan->scan_index = 11;
+				chan->address = XADC_REG_VPVN;
+			} else {
+				chan->scan_index = 15 + reg;
+				chan->scan_index = XADC_REG_VAUX(reg - 1);
+			}
+			num_channels++;
+			chan++;
+		}
+	}
+	of_node_put(chan_node);
+
+	indio_dev->num_channels = num_channels;
+	indio_dev->channels = krealloc(channels, sizeof(*channels) *
+					num_channels, GFP_KERNEL);
+	/* If we can't resize the channels array, just use the original */
+	if (!indio_dev->channels)
+		indio_dev->channels = channels;
+
+	return 0;
+}
+
+static int xadc_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *id;
+	struct iio_dev *indio_dev;
+	unsigned int bipolar_mask;
+	struct resource *mem;
+	unsigned int conf0;
+	struct xadc *xadc;
+	int ret;
+	int irq;
+	int i;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	id = of_match_node(xadc_of_match_table, pdev->dev.of_node);
+	if (!id)
+		return -EINVAL;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return -ENXIO;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*xadc));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	xadc = iio_priv(indio_dev);
+	xadc->ops = id->data;
+	init_completion(&xadc->completion);
+	mutex_init(&xadc->mutex);
+	spin_lock_init(&xadc->lock);
+	INIT_DELAYED_WORK(&xadc->zynq_unmask_work, xadc_zynq_unmask_worker);
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xadc->base = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(xadc->base))
+		return PTR_ERR(xadc->base);
+
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->dev.of_node = pdev->dev.of_node;
+	indio_dev->name = "xadc";
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &xadc_info;
+
+	ret = xadc_parse_dt(indio_dev, pdev->dev.of_node, &conf0);
+	if (ret)
+		goto err_device_free;
+
+	if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
+		ret = iio_triggered_buffer_setup(indio_dev,
+			&iio_pollfunc_store_time, &xadc_trigger_handler,
+			&xadc_buffer_ops);
+		if (ret)
+			goto err_device_free;
+
+		xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst");
+		if (IS_ERR(xadc->convst_trigger))
+			goto err_triggered_buffer_cleanup;
+		xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev,
+			"samplerate");
+		if (IS_ERR(xadc->samplerate_trigger))
+			goto err_free_convst_trigger;
+	}
+
+	xadc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(xadc->clk)) {
+		ret = PTR_ERR(xadc->clk);
+		goto err_free_samplerate_trigger;
+	}
+	clk_prepare_enable(xadc->clk);
+
+	ret = xadc->ops->setup(pdev, indio_dev, irq);
+	if (ret)
+		goto err_free_samplerate_trigger;
+
+	ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
+				xadc->ops->threaded_interrupt_handler,
+				0, dev_name(&pdev->dev), indio_dev);
+	if (ret)
+		goto err_clk_disable_unprepare;
+
+	for (i = 0; i < 16; i++)
+		xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i),
+			&xadc->threshold[i]);
+
+	ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0);
+	if (ret)
+		goto err_free_irq;
+
+	bipolar_mask = 0;
+	for (i = 0; i < indio_dev->num_channels; i++) {
+		if (indio_dev->channels[i].scan_type.sign == 's')
+			bipolar_mask |= BIT(indio_dev->channels[i].scan_index);
+	}
+
+	ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(0), bipolar_mask);
+	if (ret)
+		goto err_free_irq;
+	ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1),
+		bipolar_mask >> 16);
+	if (ret)
+		goto err_free_irq;
+
+	/* Disable all alarms */
+	xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK,
+		XADC_CONF1_ALARM_MASK);
+
+	/* Set thresholds to min/max */
+	for (i = 0; i < 16; i++) {
+		/*
+		 * Set max voltage threshold and both temperature thresholds to
+		 * 0xffff, min voltage threshold to 0.
+		 */
+		if (i % 8 < 4 || i == 7)
+			xadc->threshold[i] = 0xffff;
+		else
+			xadc->threshold[i] = 0;
+		xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i),
+			xadc->threshold[i]);
+	}
+
+	/* Go to non-buffered mode */
+	xadc_postdisable(indio_dev);
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto err_free_irq;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	return 0;
+
+err_free_irq:
+	free_irq(irq, indio_dev);
+err_free_samplerate_trigger:
+	if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
+		iio_trigger_free(xadc->samplerate_trigger);
+err_free_convst_trigger:
+	if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
+		iio_trigger_free(xadc->convst_trigger);
+err_triggered_buffer_cleanup:
+	if (xadc->ops->flags & XADC_FLAGS_BUFFERED)
+		iio_triggered_buffer_cleanup(indio_dev);
+err_clk_disable_unprepare:
+	clk_disable_unprepare(xadc->clk);
+err_device_free:
+	kfree(indio_dev->channels);
+
+	return ret;
+}
+
+static int xadc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct xadc *xadc = iio_priv(indio_dev);
+	int irq = platform_get_irq(pdev, 0);
+
+	iio_device_unregister(indio_dev);
+	if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
+		iio_trigger_free(xadc->samplerate_trigger);
+		iio_trigger_free(xadc->convst_trigger);
+		iio_triggered_buffer_cleanup(indio_dev);
+	}
+	free_irq(irq, indio_dev);
+	clk_disable_unprepare(xadc->clk);
+	cancel_delayed_work(&xadc->zynq_unmask_work);
+	kfree(xadc->data);
+	kfree(indio_dev->channels);
+
+	return 0;
+}
+
+static struct platform_driver xadc_driver = {
+	.probe = xadc_probe,
+	.remove = xadc_remove,
+	.driver = {
+		.name = "xadc",
+		.owner = THIS_MODULE,
+		.of_match_table = xadc_of_match_table,
+	},
+};
+module_platform_driver(xadc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Xilinx XADC IIO driver");
diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c
new file mode 100644
index 0000000..3e7f0d7
--- /dev/null
+++ b/drivers/iio/adc/xilinx-xadc-events.c
@@ -0,0 +1,254 @@
+/*
+ * Xilinx XADC driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/kernel.h>
+
+#include "xilinx-xadc.h"
+
+static const struct iio_chan_spec *xadc_event_to_channel(
+	struct iio_dev *indio_dev, unsigned int event)
+{
+	switch (event) {
+	case XADC_THRESHOLD_OT_MAX:
+	case XADC_THRESHOLD_TEMP_MAX:
+		return &indio_dev->channels[0];
+	case XADC_THRESHOLD_VCCINT_MAX:
+	case XADC_THRESHOLD_VCCAUX_MAX:
+		return &indio_dev->channels[event];
+	default:
+		return &indio_dev->channels[event-1];
+	}
+}
+
+static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)
+{
+	const struct iio_chan_spec *chan;
+	unsigned int offset;
+
+	/* Temperature threshold error, we don't handle this yet */
+	if (event == 0)
+		return;
+
+	if (event < 4)
+		offset = event;
+	else
+		offset = event + 4;
+
+	chan = xadc_event_to_channel(indio_dev, event);
+
+	if (chan->type == IIO_TEMP) {
+		/*
+		 * The temperature channel only supports over-temperature
+		 * events.
+		 */
+		iio_push_event(indio_dev,
+			IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
+				IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
+			iio_get_time_ns());
+	} else {
+		/*
+		 * For other channels we don't know whether it is a upper or
+		 * lower threshold event. Userspace will have to check the
+		 * channel value if it wants to know.
+		 */
+		iio_push_event(indio_dev,
+			IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
+				IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER),
+			iio_get_time_ns());
+	}
+}
+
+void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events)
+{
+	unsigned int i;
+
+	for_each_set_bit(i, &events, 8)
+		xadc_handle_event(indio_dev, i);
+}
+
+static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan,
+	enum iio_event_direction dir)
+{
+	unsigned int offset;
+
+	if (chan->type == IIO_TEMP) {
+		offset = XADC_THRESHOLD_OT_MAX;
+	} else {
+		if (chan->channel < 2)
+			offset = chan->channel + 1;
+		else
+			offset = chan->channel + 6;
+	}
+
+	if (dir == IIO_EV_DIR_FALLING)
+		offset += 4;
+
+	return offset;
+}
+
+static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan)
+{
+	if (chan->type == IIO_TEMP) {
+		return XADC_ALARM_OT_MASK;
+	} else {
+		switch (chan->channel) {
+		case 0:
+			return XADC_ALARM_VCCINT_MASK;
+		case 1:
+			return XADC_ALARM_VCCAUX_MASK;
+		case 2:
+			return XADC_ALARM_VCCBRAM_MASK;
+		case 3:
+			return XADC_ALARM_VCCPINT_MASK;
+		case 4:
+			return XADC_ALARM_VCCPAUX_MASK;
+		case 5:
+			return XADC_ALARM_VCCODDR_MASK;
+		default:
+			/* We will never get here */
+			return 0;
+		}
+	}
+}
+
+int xadc_read_event_config(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir)
+{
+	struct xadc *xadc = iio_priv(indio_dev);
+
+	return (bool)(xadc->alarm_mask & xadc_get_alarm_mask(chan));
+}
+
+int xadc_write_event_config(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, int state)
+{
+	unsigned int alarm = xadc_get_alarm_mask(chan);
+	struct xadc *xadc = iio_priv(indio_dev);
+	uint16_t cfg, old_cfg;
+	int ret;
+
+	mutex_lock(&xadc->mutex);
+
+	if (state)
+		xadc->alarm_mask |= alarm;
+	else
+		xadc->alarm_mask &= ~alarm;
+
+	xadc->ops->update_alarm(xadc, xadc->alarm_mask);
+
+	ret = _xadc_read_adc_reg(xadc, XADC_REG_CONF1, &cfg);
+	if (ret)
+		goto err_out;
+
+	old_cfg = cfg;
+	cfg |= XADC_CONF1_ALARM_MASK;
+	cfg &= ~((xadc->alarm_mask & 0xf0) << 4); /* bram, pint, paux, ddr */
+	cfg &= ~((xadc->alarm_mask & 0x08) >> 3); /* ot */
+	cfg &= ~((xadc->alarm_mask & 0x07) << 1); /* temp, vccint, vccaux */
+	if (old_cfg != cfg)
+		ret = _xadc_write_adc_reg(xadc, XADC_REG_CONF1, cfg);
+
+err_out:
+	mutex_unlock(&xadc->mutex);
+
+	return ret;
+}
+
+/* Register value is msb aligned, the lower 4 bits are ignored */
+#define XADC_THRESHOLD_VALUE_SHIFT 4
+
+int xadc_read_event_value(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, enum iio_event_info info,
+	int *val, int *val2)
+{
+	unsigned int offset = xadc_get_threshold_offset(chan, dir);
+	struct xadc *xadc = iio_priv(indio_dev);
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		*val = xadc->threshold[offset];
+		break;
+	case IIO_EV_INFO_HYSTERESIS:
+		*val = xadc->temp_hysteresis;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	*val >>= XADC_THRESHOLD_VALUE_SHIFT;
+
+	return IIO_VAL_INT;
+}
+
+int xadc_write_event_value(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, enum iio_event_info info,
+	int val, int val2)
+{
+	unsigned int offset = xadc_get_threshold_offset(chan, dir);
+	struct xadc *xadc = iio_priv(indio_dev);
+	int ret = 0;
+
+	val <<= XADC_THRESHOLD_VALUE_SHIFT;
+
+	if (val < 0 || val > 0xffff)
+		return -EINVAL;
+
+	mutex_lock(&xadc->mutex);
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		xadc->threshold[offset] = val;
+		break;
+	case IIO_EV_INFO_HYSTERESIS:
+		xadc->temp_hysteresis = val;
+		break;
+	default:
+		mutex_unlock(&xadc->mutex);
+		return -EINVAL;
+	}
+
+	if (chan->type == IIO_TEMP) {
+		/*
+		 * According to the datasheet we need to set the lower 4 bits to
+		 * 0x3, otherwise 125 degree celsius will be used as the
+		 * threshold.
+		 */
+		val |= 0x3;
+
+		/*
+		 * Since we store the hysteresis as relative (to the threshold)
+		 * value, but the hardware expects an absolute value we need to
+		 * recalcualte this value whenever the hysteresis or the
+		 * threshold changes.
+		 */
+		if (xadc->threshold[offset] < xadc->temp_hysteresis)
+			xadc->threshold[offset + 4] = 0;
+		else
+			xadc->threshold[offset + 4] = xadc->threshold[offset] -
+					xadc->temp_hysteresis;
+		ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset + 4),
+			xadc->threshold[offset + 4]);
+		if (ret)
+			goto out_unlock;
+	}
+
+	if (info == IIO_EV_INFO_VALUE)
+		ret = _xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(offset), val);
+
+out_unlock:
+	mutex_unlock(&xadc->mutex);
+
+	return ret;
+}
diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h
new file mode 100644
index 0000000..c7487e8
--- /dev/null
+++ b/drivers/iio/adc/xilinx-xadc.h
@@ -0,0 +1,209 @@
+/*
+ * Xilinx XADC driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clauen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __IIO_XILINX_XADC__
+#define __IIO_XILINX_XADC__
+
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+struct iio_dev;
+struct clk;
+struct xadc_ops;
+struct platform_device;
+
+void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events);
+
+int xadc_read_event_config(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir);
+int xadc_write_event_config(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, int state);
+int xadc_read_event_value(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, enum iio_event_info info,
+	int *val, int *val2);
+int xadc_write_event_value(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, enum iio_event_type type,
+	enum iio_event_direction dir, enum iio_event_info info,
+	int val, int val2);
+
+enum xadc_external_mux_mode {
+	XADC_EXTERNAL_MUX_NONE,
+	XADC_EXTERNAL_MUX_SINGLE,
+	XADC_EXTERNAL_MUX_DUAL,
+};
+
+struct xadc {
+	void __iomem *base;
+	struct clk *clk;
+
+	const struct xadc_ops *ops;
+
+	uint16_t threshold[16];
+	uint16_t temp_hysteresis;
+	unsigned int alarm_mask;
+
+	uint16_t *data;
+
+	struct iio_trigger *trigger;
+	struct iio_trigger *convst_trigger;
+	struct iio_trigger *samplerate_trigger;
+
+	enum xadc_external_mux_mode external_mux_mode;
+
+	unsigned int zynq_alarm;
+	unsigned int zynq_masked_alarm;
+	unsigned int zynq_intmask;
+	struct delayed_work zynq_unmask_work;
+
+	struct mutex mutex;
+	spinlock_t lock;
+
+	struct completion completion;
+};
+
+struct xadc_ops {
+	int (*read)(struct xadc *, unsigned int, uint16_t *);
+	int (*write)(struct xadc *, unsigned int, uint16_t);
+	int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev,
+			int irq);
+	void (*update_alarm)(struct xadc *, unsigned int);
+	unsigned long (*get_dclk_rate)(struct xadc *);
+	irqreturn_t (*interrupt_handler)(int, void *);
+	irqreturn_t (*threaded_interrupt_handler)(int, void *);
+
+	unsigned int flags;
+};
+
+static inline int _xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t *val)
+{
+	lockdep_assert_held(&xadc->mutex);
+	return xadc->ops->read(xadc, reg, val);
+}
+
+static inline int _xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t val)
+{
+	lockdep_assert_held(&xadc->mutex);
+	return xadc->ops->write(xadc, reg, val);
+}
+
+static inline int xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t *val)
+{
+	int ret;
+
+	mutex_lock(&xadc->mutex);
+	ret = _xadc_read_adc_reg(xadc, reg, val);
+	mutex_unlock(&xadc->mutex);
+	return ret;
+}
+
+static inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
+	uint16_t val)
+{
+	int ret;
+
+	mutex_lock(&xadc->mutex);
+	ret = _xadc_write_adc_reg(xadc, reg, val);
+	mutex_unlock(&xadc->mutex);
+	return ret;
+}
+
+/* XADC hardmacro register definitions */
+#define XADC_REG_TEMP		0x00
+#define XADC_REG_VCCINT		0x01
+#define XADC_REG_VCCAUX		0x02
+#define XADC_REG_VPVN		0x03
+#define XADC_REG_VREFP		0x04
+#define XADC_REG_VREFN		0x05
+#define XADC_REG_VCCBRAM	0x06
+
+#define XADC_REG_VCCPINT	0x0d
+#define XADC_REG_VCCPAUX	0x0e
+#define XADC_REG_VCCO_DDR	0x0f
+#define XADC_REG_VAUX(x)	(0x10 + (x))
+
+#define XADC_REG_MAX_TEMP	0x20
+#define XADC_REG_MAX_VCCINT	0x21
+#define XADC_REG_MAX_VCCAUX	0x22
+#define XADC_REG_MAX_VCCBRAM	0x23
+#define XADC_REG_MIN_TEMP	0x24
+#define XADC_REG_MIN_VCCINT	0x25
+#define XADC_REG_MIN_VCCAUX	0x26
+#define XADC_REG_MIN_VCCBRAM	0x27
+#define XADC_REG_MAX_VCCPINT	0x28
+#define XADC_REG_MAX_VCCPAUX	0x29
+#define XADC_REG_MAX_VCCO_DDR	0x2a
+#define XADC_REG_MIN_VCCPINT	0x2b
+#define XADC_REG_MIN_VCCPAUX	0x2c
+#define XADC_REG_MIN_VCCO_DDR	0x2d
+
+#define XADC_REG_CONF0		0x40
+#define XADC_REG_CONF1		0x41
+#define XADC_REG_CONF2		0x42
+#define XADC_REG_SEQ(x)		(0x48 + (x))
+#define XADC_REG_INPUT_MODE(x)	(0x4c + (x))
+#define XADC_REG_THRESHOLD(x)	(0x50 + (x))
+
+#define XADC_REG_FLAG		0x3f
+
+#define XADC_CONF0_EC			BIT(9)
+#define XADC_CONF0_ACQ			BIT(8)
+#define XADC_CONF0_MUX			BIT(11)
+#define XADC_CONF0_CHAN(x)		(x)
+
+#define XADC_CONF1_SEQ_MASK		(0xf << 12)
+#define XADC_CONF1_SEQ_DEFAULT		(0 << 12)
+#define XADC_CONF1_SEQ_SINGLE_PASS	(1 << 12)
+#define XADC_CONF1_SEQ_CONTINUOUS	(2 << 12)
+#define XADC_CONF1_SEQ_SINGLE_CHANNEL	(3 << 12)
+#define XADC_CONF1_SEQ_SIMULTANEOUS	(4 << 12)
+#define XADC_CONF1_SEQ_INDEPENDENT	(8 << 12)
+#define XADC_CONF1_ALARM_MASK		0x0f0f
+
+#define XADC_CONF2_DIV_MASK	0xff00
+#define XADC_CONF2_DIV_OFFSET	8
+
+#define XADC_CONF2_PD_MASK	(0x3 << 4)
+#define XADC_CONF2_PD_NONE	(0x0 << 4)
+#define XADC_CONF2_PD_ADC_B	(0x2 << 4)
+#define XADC_CONF2_PD_BOTH	(0x3 << 4)
+
+#define XADC_ALARM_TEMP_MASK		BIT(0)
+#define XADC_ALARM_VCCINT_MASK		BIT(1)
+#define XADC_ALARM_VCCAUX_MASK		BIT(2)
+#define XADC_ALARM_OT_MASK		BIT(3)
+#define XADC_ALARM_VCCBRAM_MASK		BIT(4)
+#define XADC_ALARM_VCCPINT_MASK		BIT(5)
+#define XADC_ALARM_VCCPAUX_MASK		BIT(6)
+#define XADC_ALARM_VCCODDR_MASK		BIT(7)
+
+#define XADC_THRESHOLD_TEMP_MAX		0x0
+#define XADC_THRESHOLD_VCCINT_MAX	0x1
+#define XADC_THRESHOLD_VCCAUX_MAX	0x2
+#define XADC_THRESHOLD_OT_MAX		0x3
+#define XADC_THRESHOLD_TEMP_MIN		0x4
+#define XADC_THRESHOLD_VCCINT_MIN	0x5
+#define XADC_THRESHOLD_VCCAUX_MIN	0x6
+#define XADC_THRESHOLD_OT_MIN		0x7
+#define XADC_THRESHOLD_VCCBRAM_MAX	0x8
+#define XADC_THRESHOLD_VCCPINT_MAX	0x9
+#define XADC_THRESHOLD_VCCPAUX_MAX	0xa
+#define XADC_THRESHOLD_VCCODDR_MAX	0xb
+#define XADC_THRESHOLD_VCCBRAM_MIN	0xc
+#define XADC_THRESHOLD_VCCPINT_MIN	0xd
+#define XADC_THRESHOLD_VCCPAUX_MIN	0xe
+#define XADC_THRESHOLD_VCCODDR_MIN	0xf
+
+#endif
diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c
index 2d9c6f8..eb46e72 100644
--- a/drivers/iio/buffer_cb.c
+++ b/drivers/iio/buffer_cb.c
@@ -46,10 +46,8 @@
 	struct iio_channel *chan;
 
 	cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
-	if (cb_buff == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (cb_buff == NULL)
+		return ERR_PTR(-ENOMEM);
 
 	iio_buffer_init(&cb_buff->buffer);
 
@@ -91,7 +89,6 @@
 	iio_channel_release_all(cb_buff->channels);
 error_free_cb_buff:
 	kfree(cb_buff);
-error_ret:
 	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c
index d0505fd..fa28100 100644
--- a/drivers/iio/dac/ad7303.c
+++ b/drivers/iio/dac/ad7303.c
@@ -92,7 +92,7 @@
 	ad7303_write(st, chan->channel, st->dac_cache[chan->channel]);
 
 	mutex_unlock(&indio_dev->mlock);
-	return ret ? ret : len;
+	return len;
 }
 
 static int ad7303_get_vref(struct ad7303_state *st,
diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c
index de76e6a..9a82a72 100644
--- a/drivers/iio/dac/max517.c
+++ b/drivers/iio/dac/max517.c
@@ -19,7 +19,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/i2c.h>
diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c
index 7d9f5c3..43d1458 100644
--- a/drivers/iio/dac/mcp4725.c
+++ b/drivers/iio/dac/mcp4725.c
@@ -15,7 +15,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/delay.h>
diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig
index 463c4d9..e116bd8 100644
--- a/drivers/iio/humidity/Kconfig
+++ b/drivers/iio/humidity/Kconfig
@@ -12,4 +12,14 @@
 	  Other sensors should work as well as long as they speak the
 	  same protocol.
 
+config SI7005
+	tristate "SI7005 relative humidity and temperature sensor"
+	depends on I2C
+	help
+	  Say yes here to build support for the Silabs Si7005 relative
+	  humidity and temperature sensor.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called si7005.
+
 endmenu
diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile
index d5d36c0..e3f3d94 100644
--- a/drivers/iio/humidity/Makefile
+++ b/drivers/iio/humidity/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_DHT11) += dht11.o
+obj-$(CONFIG_SI7005) += si7005.o
diff --git a/drivers/iio/humidity/si7005.c b/drivers/iio/humidity/si7005.c
new file mode 100644
index 0000000..bdd586e
--- /dev/null
+++ b/drivers/iio/humidity/si7005.c
@@ -0,0 +1,189 @@
+/*
+ * si7005.c - Support for Silabs Si7005 humidity and temperature sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * (7-bit I2C slave address 0x40)
+ *
+ * TODO: heater, fast mode, processed mode (temp. / linearity compensation)
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define SI7005_STATUS 0x00
+#define SI7005_DATA 0x01 /* 16-bit, MSB */
+#define SI7005_CONFIG 0x03
+#define SI7005_ID 0x11
+
+#define SI7005_STATUS_NRDY BIT(0)
+#define SI7005_CONFIG_TEMP BIT(4)
+#define SI7005_CONFIG_START BIT(0)
+
+#define SI7005_ID_7005 0x50
+#define SI7005_ID_7015 0xf0
+
+struct si7005_data {
+	struct i2c_client *client;
+	struct mutex lock;
+	u8 config;
+};
+
+static int si7005_read_measurement(struct si7005_data *data, bool temp)
+{
+	int tries = 50;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = i2c_smbus_write_byte_data(data->client, SI7005_CONFIG,
+		data->config | SI7005_CONFIG_START |
+		(temp ? SI7005_CONFIG_TEMP : 0));
+	if (ret < 0)
+		goto done;
+
+	while (tries-- > 0) {
+		msleep(20);
+		ret = i2c_smbus_read_byte_data(data->client, SI7005_STATUS);
+		if (ret < 0)
+			goto done;
+		if (!(ret & SI7005_STATUS_NRDY))
+			break;
+	}
+	if (tries < 0) {
+		ret = -EIO;
+		goto done;
+	}
+
+	ret = i2c_smbus_read_word_swapped(data->client, SI7005_DATA);
+
+done:
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int si7005_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan, int *val,
+			    int *val2, long mask)
+{
+	struct si7005_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = si7005_read_measurement(data, chan->type == IIO_TEMP);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		if (chan->type == IIO_TEMP) {
+			*val = 7;
+			*val2 = 812500;
+		} else {
+			*val = 3;
+			*val2 = 906250;
+		}
+		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_OFFSET:
+		if (chan->type == IIO_TEMP)
+			*val = -50 * 32 * 4;
+		else
+			*val = -24 * 16 * 16;
+		return IIO_VAL_INT;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_chan_spec si7005_channels[] = {
+	{
+		.type = IIO_HUMIDITYRELATIVE,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),
+	},
+	{
+		.type = IIO_TEMP,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),
+	}
+};
+
+static const struct iio_info si7005_info = {
+	.read_raw = si7005_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static int si7005_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct iio_dev *indio_dev;
+	struct si7005_data *data;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+	mutex_init(&data->lock);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = dev_name(&client->dev);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &si7005_info;
+
+	indio_dev->channels = si7005_channels;
+	indio_dev->num_channels = ARRAY_SIZE(si7005_channels);
+
+	ret = i2c_smbus_read_byte_data(client, SI7005_ID);
+	if (ret < 0)
+		return ret;
+	if (ret != SI7005_ID_7005 && ret != SI7005_ID_7015)
+		return -ENODEV;
+
+	ret = i2c_smbus_read_byte_data(client, SI7005_CONFIG);
+	if (ret < 0)
+		return ret;
+	data->config = ret;
+
+	return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id si7005_id[] = {
+	{ "si7005", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, si7005_id);
+
+static struct i2c_driver si7005_driver = {
+	.driver = {
+		.name	= "si7005",
+		.owner	= THIS_MODULE,
+	},
+	.probe = si7005_probe,
+	.id_table = si7005_id,
+};
+module_i2c_driver(si7005_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Silabs Si7005 humidity and temperature sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 663e88a..2b0e451 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -25,6 +25,8 @@
 	  Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
 	  ADIS16485, ADIS16488 inertial sensors.
 
+source "drivers/iio/imu/inv_mpu6050/Kconfig"
+
 endmenu
 
 config IIO_ADIS_LIB
@@ -38,5 +40,3 @@
 	help
 	  A set of buffer helper functions for the Analog Devices ADIS* device
 	  family.
-
-source "drivers/iio/imu/inv_mpu6050/Kconfig"
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index 7c582f7..433583b 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -281,7 +281,7 @@
 	st->variant->set_freq(st, val);
 	mutex_unlock(&indio_dev->mlock);
 
-	return ret ? ret : len;
+	return len;
 }
 
 /* Power down the device */
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index df7f1e1..cb9f96b 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -12,7 +12,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
@@ -117,7 +116,7 @@
 		return result;
 
 	if (en) {
-		/* Wait for output stablize */
+		/* Wait for output stabilize */
 		msleep(INV_MPU6050_TEMP_UP_TIME);
 		if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) {
 			/* switch internal clock to PLL */
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index f383955..0ab382b 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -126,35 +126,35 @@
 #define INV_MPU6050_REG_SAMPLE_RATE_DIV     0x19
 #define INV_MPU6050_REG_CONFIG              0x1A
 #define INV_MPU6050_REG_GYRO_CONFIG         0x1B
-#define INV_MPU6050_REG_ACCEL_CONFIG	    0x1C
+#define INV_MPU6050_REG_ACCEL_CONFIG        0x1C
 
 #define INV_MPU6050_REG_FIFO_EN             0x23
-#define INV_MPU6050_BIT_ACCEL_OUT                   0x08
-#define INV_MPU6050_BITS_GYRO_OUT                   0x70
+#define INV_MPU6050_BIT_ACCEL_OUT           0x08
+#define INV_MPU6050_BITS_GYRO_OUT           0x70
 
 #define INV_MPU6050_REG_INT_ENABLE          0x38
-#define INV_MPU6050_BIT_DATA_RDY_EN                 0x01
-#define INV_MPU6050_BIT_DMP_INT_EN                  0x02
+#define INV_MPU6050_BIT_DATA_RDY_EN         0x01
+#define INV_MPU6050_BIT_DMP_INT_EN          0x02
 
 #define INV_MPU6050_REG_RAW_ACCEL           0x3B
 #define INV_MPU6050_REG_TEMPERATURE         0x41
 #define INV_MPU6050_REG_RAW_GYRO            0x43
 
 #define INV_MPU6050_REG_USER_CTRL           0x6A
-#define INV_MPU6050_BIT_FIFO_RST                    0x04
-#define INV_MPU6050_BIT_DMP_RST                     0x08
-#define INV_MPU6050_BIT_I2C_MST_EN                  0x20
-#define INV_MPU6050_BIT_FIFO_EN                     0x40
-#define INV_MPU6050_BIT_DMP_EN                      0x80
+#define INV_MPU6050_BIT_FIFO_RST            0x04
+#define INV_MPU6050_BIT_DMP_RST             0x08
+#define INV_MPU6050_BIT_I2C_MST_EN          0x20
+#define INV_MPU6050_BIT_FIFO_EN             0x40
+#define INV_MPU6050_BIT_DMP_EN              0x80
 
 #define INV_MPU6050_REG_PWR_MGMT_1          0x6B
-#define INV_MPU6050_BIT_H_RESET                     0x80
-#define INV_MPU6050_BIT_SLEEP                       0x40
-#define INV_MPU6050_BIT_CLK_MASK                    0x7
+#define INV_MPU6050_BIT_H_RESET             0x80
+#define INV_MPU6050_BIT_SLEEP               0x40
+#define INV_MPU6050_BIT_CLK_MASK            0x7
 
 #define INV_MPU6050_REG_PWR_MGMT_2          0x6C
-#define INV_MPU6050_BIT_PWR_ACCL_STBY               0x38
-#define INV_MPU6050_BIT_PWR_GYRO_STBY               0x07
+#define INV_MPU6050_BIT_PWR_ACCL_STBY       0x38
+#define INV_MPU6050_BIT_PWR_GYRO_STBY       0x07
 
 #define INV_MPU6050_REG_FIFO_COUNT_H        0x72
 #define INV_MPU6050_REG_FIFO_R_W            0x74
@@ -180,10 +180,10 @@
 
 /* init parameters */
 #define INV_MPU6050_INIT_FIFO_RATE           50
-#define INV_MPU6050_TIME_STAMP_TOR                        5
-#define INV_MPU6050_MAX_FIFO_RATE                         1000
-#define INV_MPU6050_MIN_FIFO_RATE                         4
-#define INV_MPU6050_ONE_K_HZ                              1000
+#define INV_MPU6050_TIME_STAMP_TOR           5
+#define INV_MPU6050_MAX_FIFO_RATE            1000
+#define INV_MPU6050_MIN_FIFO_RATE            4
+#define INV_MPU6050_ONE_K_HZ                 1000
 
 /* scan element definition */
 enum inv_mpu6050_scan {
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index 4295171..0cd306a 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -12,7 +12,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index c67d83b..e108f2a 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -264,7 +264,7 @@
 				     &indio_dev->dev,
 				     &buffer->scan_el_dev_attr_list);
 	if (ret)
-		goto error_ret;
+		return ret;
 	attrcount++;
 	ret = __iio_add_chan_devattr("type",
 				     chan,
@@ -275,7 +275,7 @@
 				     &indio_dev->dev,
 				     &buffer->scan_el_dev_attr_list);
 	if (ret)
-		goto error_ret;
+		return ret;
 	attrcount++;
 	if (chan->type != IIO_TIMESTAMP)
 		ret = __iio_add_chan_devattr("en",
@@ -296,10 +296,9 @@
 					     &indio_dev->dev,
 					     &buffer->scan_el_dev_attr_list);
 	if (ret)
-		goto error_ret;
+		return ret;
 	attrcount++;
 	ret = attrcount;
-error_ret:
 	return ret;
 }
 
@@ -553,13 +552,13 @@
 		if (indio_dev->setup_ops->predisable) {
 			ret = indio_dev->setup_ops->predisable(indio_dev);
 			if (ret)
-				goto error_ret;
+				return ret;
 		}
 		indio_dev->currentmode = INDIO_DIRECT_MODE;
 		if (indio_dev->setup_ops->postdisable) {
 			ret = indio_dev->setup_ops->postdisable(indio_dev);
 			if (ret)
-				goto error_ret;
+				return ret;
 		}
 	}
 	/* Keep a copy of current setup to allow roll back */
@@ -613,7 +612,7 @@
 			else {
 				kfree(compound_mask);
 				ret = -EINVAL;
-				goto error_ret;
+				return ret;
 			}
 		}
 	} else {
@@ -696,13 +695,10 @@
 	if (indio_dev->setup_ops->postdisable)
 		indio_dev->setup_ops->postdisable(indio_dev);
 error_remove_inserted:
-
 	if (insert_buffer)
 		iio_buffer_deactivate(insert_buffer);
 	indio_dev->active_scan_mask = old_mask;
 	kfree(compound_mask);
-error_ret:
-
 	return ret;
 }
 
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index acc911a..ede16aec 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -540,7 +540,7 @@
 			   enum iio_shared_by shared_by)
 {
 	int ret = 0;
-	char *name_format = NULL;
+	char *name = NULL;
 	char *full_postfix;
 	sysfs_attr_init(&dev_attr->attr);
 
@@ -558,7 +558,7 @@
 								    ->channel2],
 						 postfix);
 	} else {
-		if (chan->extend_name == NULL)
+		if (chan->extend_name == NULL || shared_by != IIO_SEPARATE)
 			full_postfix = kstrdup(postfix, GFP_KERNEL);
 		else
 			full_postfix = kasprintf(GFP_KERNEL,
@@ -572,16 +572,15 @@
 	if (chan->differential) { /* Differential can not have modifier */
 		switch (shared_by) {
 		case IIO_SHARED_BY_ALL:
-			name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+			name = kasprintf(GFP_KERNEL, "%s", full_postfix);
 			break;
 		case IIO_SHARED_BY_DIR:
-			name_format = kasprintf(GFP_KERNEL, "%s_%s",
+			name = kasprintf(GFP_KERNEL, "%s_%s",
 						iio_direction[chan->output],
 						full_postfix);
 			break;
 		case IIO_SHARED_BY_TYPE:
-			name_format
-				= kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
+			name = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
 					    iio_direction[chan->output],
 					    iio_chan_type_name_spec[chan->type],
 					    iio_chan_type_name_spec[chan->type],
@@ -593,8 +592,7 @@
 				ret = -EINVAL;
 				goto error_free_full_postfix;
 			}
-			name_format
-				= kasprintf(GFP_KERNEL,
+			name = kasprintf(GFP_KERNEL,
 					    "%s_%s%d-%s%d_%s",
 					    iio_direction[chan->output],
 					    iio_chan_type_name_spec[chan->type],
@@ -607,16 +605,15 @@
 	} else { /* Single ended */
 		switch (shared_by) {
 		case IIO_SHARED_BY_ALL:
-			name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+			name = kasprintf(GFP_KERNEL, "%s", full_postfix);
 			break;
 		case IIO_SHARED_BY_DIR:
-			name_format = kasprintf(GFP_KERNEL, "%s_%s",
+			name = kasprintf(GFP_KERNEL, "%s_%s",
 						iio_direction[chan->output],
 						full_postfix);
 			break;
 		case IIO_SHARED_BY_TYPE:
-			name_format
-				= kasprintf(GFP_KERNEL, "%s_%s_%s",
+			name = kasprintf(GFP_KERNEL, "%s_%s_%s",
 					    iio_direction[chan->output],
 					    iio_chan_type_name_spec[chan->type],
 					    full_postfix);
@@ -624,33 +621,24 @@
 
 		case IIO_SEPARATE:
 			if (chan->indexed)
-				name_format
-					= kasprintf(GFP_KERNEL, "%s_%s%d_%s",
+				name = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
 						    iio_direction[chan->output],
 						    iio_chan_type_name_spec[chan->type],
 						    chan->channel,
 						    full_postfix);
 			else
-				name_format
-					= kasprintf(GFP_KERNEL, "%s_%s_%s",
+				name = kasprintf(GFP_KERNEL, "%s_%s_%s",
 						    iio_direction[chan->output],
 						    iio_chan_type_name_spec[chan->type],
 						    full_postfix);
 			break;
 		}
 	}
-	if (name_format == NULL) {
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_free_full_postfix;
 	}
-	dev_attr->attr.name = kasprintf(GFP_KERNEL,
-					name_format,
-					chan->channel,
-					chan->channel2);
-	if (dev_attr->attr.name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_name_format;
-	}
+	dev_attr->attr.name = name;
 
 	if (readfunc) {
 		dev_attr->attr.mode |= S_IRUGO;
@@ -661,8 +649,7 @@
 		dev_attr->attr.mode |= S_IWUSR;
 		dev_attr->store = writefunc;
 	}
-error_free_name_format:
-	kfree(name_format);
+
 error_free_full_postfix:
 	kfree(full_postfix);
 
@@ -692,10 +679,8 @@
 	struct iio_dev_attr *iio_attr, *t;
 
 	iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL);
-	if (iio_attr == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (iio_attr == NULL)
+		return -ENOMEM;
 	ret = __iio_device_attr_init(&iio_attr->dev_attr,
 				     postfix, chan,
 				     readfunc, writefunc, shared_by);
@@ -720,7 +705,6 @@
 	__iio_device_attr_deinit(&iio_attr->dev_attr);
 error_iio_dev_attr_free:
 	kfree(iio_attr);
-error_ret:
 	return ret;
 }
 
@@ -1134,7 +1118,7 @@
 	if (ret) {
 		dev_err(indio_dev->dev.parent,
 			"Failed to register debugfs interfaces\n");
-		goto error_ret;
+		return ret;
 	}
 	ret = iio_device_register_sysfs(indio_dev);
 	if (ret) {
@@ -1175,7 +1159,6 @@
 	iio_device_unregister_sysfs(indio_dev);
 error_unreg_debugfs:
 	iio_device_unregister_debugfs(indio_dev);
-error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_device_register);
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index c9c1419..ea6e06b 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -40,6 +40,7 @@
 	struct list_head	dev_attr_list;
 	unsigned long		flags;
 	struct attribute_group	group;
+	struct mutex		read_lock;
 };
 
 /**
@@ -47,16 +48,17 @@
  * @indio_dev:		IIO device structure
  * @ev_code:		What event
  * @timestamp:		When the event occurred
+ *
+ * Note: The caller must make sure that this function is not running
+ * concurrently for the same indio_dev more than once.
  **/
 int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
 {
 	struct iio_event_interface *ev_int = indio_dev->event_interface;
 	struct iio_event_data ev;
-	unsigned long flags;
 	int copied;
 
 	/* Does anyone care? */
-	spin_lock_irqsave(&ev_int->wait.lock, flags);
 	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
 
 		ev.id = ev_code;
@@ -64,9 +66,8 @@
 
 		copied = kfifo_put(&ev_int->det_events, ev);
 		if (copied != 0)
-			wake_up_locked_poll(&ev_int->wait, POLLIN);
+			wake_up_poll(&ev_int->wait, POLLIN);
 	}
-	spin_unlock_irqrestore(&ev_int->wait.lock, flags);
 
 	return 0;
 }
@@ -87,10 +88,8 @@
 
 	poll_wait(filep, &ev_int->wait, wait);
 
-	spin_lock_irq(&ev_int->wait.lock);
 	if (!kfifo_is_empty(&ev_int->det_events))
 		events = POLLIN | POLLRDNORM;
-	spin_unlock_irq(&ev_int->wait.lock);
 
 	return events;
 }
@@ -111,31 +110,40 @@
 	if (count < sizeof(struct iio_event_data))
 		return -EINVAL;
 
-	spin_lock_irq(&ev_int->wait.lock);
-	if (kfifo_is_empty(&ev_int->det_events)) {
-		if (filep->f_flags & O_NONBLOCK) {
-			ret = -EAGAIN;
-			goto error_unlock;
-		}
-		/* Blocking on device; waiting for something to be there */
-		ret = wait_event_interruptible_locked_irq(ev_int->wait,
+	do {
+		if (kfifo_is_empty(&ev_int->det_events)) {
+			if (filep->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			ret = wait_event_interruptible(ev_int->wait,
 					!kfifo_is_empty(&ev_int->det_events) ||
 					indio_dev->info == NULL);
-		if (ret)
-			goto error_unlock;
-		if (indio_dev->info == NULL) {
-			ret = -ENODEV;
-			goto error_unlock;
+			if (ret)
+				return ret;
+			if (indio_dev->info == NULL)
+				return -ENODEV;
 		}
-		/* Single access device so no one else can get the data */
-	}
 
-	ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);
+		if (mutex_lock_interruptible(&ev_int->read_lock))
+			return -ERESTARTSYS;
+		ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);
+		mutex_unlock(&ev_int->read_lock);
 
-error_unlock:
-	spin_unlock_irq(&ev_int->wait.lock);
+		if (ret)
+			return ret;
 
-	return ret ? ret : copied;
+		/*
+		 * If we couldn't read anything from the fifo (a different
+		 * thread might have been faster) we either return -EAGAIN if
+		 * the file descriptor is non-blocking, otherwise we go back to
+		 * sleep and wait for more data to arrive.
+		 */
+		if (copied == 0 && (filep->f_flags & O_NONBLOCK))
+			return -EAGAIN;
+
+	} while (copied == 0);
+
+	return copied;
 }
 
 static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
@@ -143,15 +151,7 @@
 	struct iio_dev *indio_dev = filep->private_data;
 	struct iio_event_interface *ev_int = indio_dev->event_interface;
 
-	spin_lock_irq(&ev_int->wait.lock);
-	__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
-	/*
-	 * In order to maintain a clean state for reopening,
-	 * clear out any awaiting events. The mask will prevent
-	 * any new __iio_push_event calls running.
-	 */
-	kfifo_reset_out(&ev_int->det_events);
-	spin_unlock_irq(&ev_int->wait.lock);
+	clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 
 	iio_device_put(indio_dev);
 
@@ -174,22 +174,20 @@
 	if (ev_int == NULL)
 		return -ENODEV;
 
-	spin_lock_irq(&ev_int->wait.lock);
-	if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
-		spin_unlock_irq(&ev_int->wait.lock);
+	if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags))
 		return -EBUSY;
-	}
-	spin_unlock_irq(&ev_int->wait.lock);
+
 	iio_device_get(indio_dev);
 
 	fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
 				indio_dev, O_RDONLY | O_CLOEXEC);
 	if (fd < 0) {
-		spin_lock_irq(&ev_int->wait.lock);
-		__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
-		spin_unlock_irq(&ev_int->wait.lock);
+		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 		iio_device_put(indio_dev);
+	} else {
+		kfifo_reset_out(&ev_int->det_events);
 	}
+
 	return fd;
 }
 
@@ -366,32 +364,31 @@
 		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
 			IIO_SEPARATE, &chan->event_spec[i].mask_separate);
 		if (ret < 0)
-			goto error_ret;
+			return ret;
 		attrcount += ret;
 
 		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
 			IIO_SHARED_BY_TYPE,
 			&chan->event_spec[i].mask_shared_by_type);
 		if (ret < 0)
-			goto error_ret;
+			return ret;
 		attrcount += ret;
 
 		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
 			IIO_SHARED_BY_DIR,
 			&chan->event_spec[i].mask_shared_by_dir);
 		if (ret < 0)
-			goto error_ret;
+			return ret;
 		attrcount += ret;
 
 		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
 			IIO_SHARED_BY_ALL,
 			&chan->event_spec[i].mask_shared_by_all);
 		if (ret < 0)
-			goto error_ret;
+			return ret;
 		attrcount += ret;
 	}
 	ret = attrcount;
-error_ret:
 	return ret;
 }
 
@@ -425,6 +422,7 @@
 {
 	INIT_KFIFO(ev_int->det_events);
 	init_waitqueue_head(&ev_int->wait);
+	mutex_init(&ev_int->read_lock);
 }
 
 static const char *iio_event_group_name = "events";
@@ -440,10 +438,8 @@
 
 	indio_dev->event_interface =
 		kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL);
-	if (indio_dev->event_interface == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (indio_dev->event_interface == NULL)
+		return -ENOMEM;
 
 	INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list);
 
@@ -489,8 +485,6 @@
 error_free_setup_event_lines:
 	iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
 	kfree(indio_dev->event_interface);
-error_ret:
-
 	return ret;
 }
 
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 766fab2..3383b02 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -62,10 +62,9 @@
 	int ret;
 
 	trig_info->id = ida_simple_get(&iio_trigger_ida, 0, 0, GFP_KERNEL);
-	if (trig_info->id < 0) {
-		ret = trig_info->id;
-		goto error_ret;
-	}
+	if (trig_info->id < 0)
+		return trig_info->id;
+
 	/* Set the name used for the sysfs directory etc */
 	dev_set_name(&trig_info->dev, "trigger%ld",
 		     (unsigned long) trig_info->id);
@@ -83,7 +82,6 @@
 
 error_unregister_id:
 	ida_simple_remove(&iio_trigger_ida, trig_info->id);
-error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_trigger_register);
@@ -234,13 +232,12 @@
 	if (trig->ops && trig->ops->set_trigger_state && no_other_users) {
 		ret = trig->ops->set_trigger_state(trig, false);
 		if (ret)
-			goto error_ret;
+			return ret;
 	}
 	iio_trigger_put_irq(trig, pf->irq);
 	free_irq(pf->irq, pf);
 	module_put(pf->indio_dev->info->driver_module);
 
-error_ret:
 	return ret;
 }
 
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index d12b2a0..c89740d 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -73,6 +73,20 @@
 	  Say yes here to build support for the HID SENSOR
 	  Ambient light sensor.
 
+config HID_SENSOR_PROX
+	depends on HID_SENSOR_HUB
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select HID_SENSOR_IIO_COMMON
+	select HID_SENSOR_IIO_TRIGGER
+	tristate "HID PROX"
+	help
+	  Say yes here to build support for the HID SENSOR
+	  Proximity sensor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hid-sensor-prox.
+
 config SENSORS_LM3533
 	tristate "LM3533 ambient light sensor"
 	depends on MFD_LM3533
@@ -90,6 +104,18 @@
 	  changes. The ALS-control output values can be set per zone for the
 	  three current output channels.
 
+config LTR501
+	tristate "LTR-501ALS-01 light sensor"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	 If you say yes here you get support for the Lite-On LTR-501ALS-01
+	 ambient light and proximity sensor.
+
+	 This driver can also be built as a module.  If so, the module
+         will be called ltr501.
+
 config TCS3472
 	tristate "TAOS TCS3472 color light-to-digital converter"
 	depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 60e35ac..3eb36e5 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -9,7 +9,9 @@
 obj-$(CONFIG_CM36651)		+= cm36651.o
 obj-$(CONFIG_GP2AP020A00F)	+= gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)	+= hid-sensor-als.o
+obj-$(CONFIG_HID_SENSOR_PROX)	+= hid-sensor-prox.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
+obj-$(CONFIG_LTR501)		+= ltr501.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_TCS3472)		+= tcs3472.o
 obj-$(CONFIG_TSL4531)		+= tsl4531.o
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c
index f306847..09ad5f1 100644
--- a/drivers/iio/light/adjd_s311.c
+++ b/drivers/iio/light/adjd_s311.c
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
@@ -120,7 +119,6 @@
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct adjd_s311_data *data = iio_priv(indio_dev);
 	s64 time_ns = iio_get_time_ns();
-	int len = 0;
 	int i, j = 0;
 
 	int ret = adjd_s311_req_data(indio_dev);
@@ -135,7 +133,6 @@
 			goto done;
 
 		data->buffer[j++] = ret & ADJD_S311_DATA_MASK;
-		len += 2;
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns);
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
new file mode 100644
index 0000000..1894ab1
--- /dev/null
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -0,0 +1,375 @@
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2014, 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.
+ *
+ */
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+#define CHANNEL_SCAN_INDEX_PRESENCE 0
+
+struct prox_state {
+	struct hid_sensor_hub_callbacks callbacks;
+	struct hid_sensor_common common_attributes;
+	struct hid_sensor_hub_attribute_info prox_attr;
+	u32 human_presence;
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec prox_channels[] = {
+	{
+		.type = IIO_PROXIMITY,
+		.modified = 1,
+		.channel2 = IIO_NO_MOD,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+		BIT(IIO_CHAN_INFO_SCALE) |
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+		BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_PRESENCE,
+	}
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void prox_adjust_channel_bit_mask(struct iio_chan_spec *channels,
+					int channel, int size)
+{
+	channels[channel].scan_type.sign = 's';
+	/* Real storage bits will change based on the report desc. */
+	channels[channel].scan_type.realbits = size * 8;
+	/* Maximum size of a sample to capture is u32 */
+	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+}
+
+/* Channel read_raw handler */
+static int prox_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	struct prox_state *prox_state = iio_priv(indio_dev);
+	int report_id = -1;
+	u32 address;
+	int ret;
+	int ret_type;
+
+	*val = 0;
+	*val2 = 0;
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->scan_index) {
+		case  CHANNEL_SCAN_INDEX_PRESENCE:
+			report_id = prox_state->prox_attr.report_id;
+			address =
+			HID_USAGE_SENSOR_HUMAN_PRESENCE;
+			break;
+		default:
+			report_id = -1;
+			break;
+		}
+		if (report_id >= 0)
+			*val = sensor_hub_input_attr_get_raw_value(
+				prox_state->common_attributes.hsdev,
+				HID_USAGE_SENSOR_PROX, address,
+				report_id);
+		else {
+			*val = 0;
+			return -EINVAL;
+		}
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SCALE:
+		*val = prox_state->prox_attr.units;
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_OFFSET:
+		*val = hid_sensor_convert_exponent(
+				prox_state->prox_attr.unit_expo);
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_read_samp_freq_value(
+				&prox_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_read_raw_hyst_value(
+				&prox_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	default:
+		ret_type = -EINVAL;
+		break;
+	}
+
+	return ret_type;
+}
+
+/* Channel write_raw handler */
+static int prox_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct prox_state *prox_state = iio_priv(indio_dev);
+	int ret = 0;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_write_samp_freq_value(
+				&prox_state->common_attributes, val, val2);
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_write_raw_hyst_value(
+				&prox_state->common_attributes, val, val2);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static const struct iio_info prox_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &prox_read_raw,
+	.write_raw = &prox_write_raw,
+};
+
+/* Function to push data to buffer */
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+					int len)
+{
+	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
+	iio_push_to_buffers(indio_dev, data);
+}
+
+/* Callback handler to send event after all samples are received and captured */
+static int prox_proc_event(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct prox_state *prox_state = iio_priv(indio_dev);
+
+	dev_dbg(&indio_dev->dev, "prox_proc_event [%d]\n",
+				prox_state->common_attributes.data_ready);
+	if (prox_state->common_attributes.data_ready)
+		hid_sensor_push_data(indio_dev,
+				&prox_state->human_presence,
+				sizeof(prox_state->human_presence));
+
+	return 0;
+}
+
+/* Capture samples in local storage */
+static int prox_capture_sample(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				size_t raw_len, char *raw_data,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct prox_state *prox_state = iio_priv(indio_dev);
+	int ret = -EINVAL;
+
+	switch (usage_id) {
+	case HID_USAGE_SENSOR_HUMAN_PRESENCE:
+		prox_state->human_presence = *(u32 *)raw_data;
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/* Parse report which is specific to an usage id*/
+static int prox_parse_report(struct platform_device *pdev,
+				struct hid_sensor_hub_device *hsdev,
+				struct iio_chan_spec *channels,
+				unsigned usage_id,
+				struct prox_state *st)
+{
+	int ret;
+
+	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
+			usage_id,
+			HID_USAGE_SENSOR_HUMAN_PRESENCE,
+			&st->prox_attr);
+	if (ret < 0)
+		return ret;
+	prox_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_PRESENCE,
+					st->prox_attr.size);
+
+	dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr.index,
+			st->prox_attr.report_id);
+
+	/* Set Sensitivity field ids, when there is no individual modifier */
+	if (st->common_attributes.sensitivity.index < 0) {
+		sensor_hub_input_get_attribute_info(hsdev,
+			HID_FEATURE_REPORT, usage_id,
+			HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+			HID_USAGE_SENSOR_DATA_PRESENCE,
+			&st->common_attributes.sensitivity);
+		dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+			st->common_attributes.sensitivity.index,
+			st->common_attributes.sensitivity.report_id);
+	}
+	return ret;
+}
+
+/* Function to initialize the processing for usage id */
+static int hid_prox_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	static const char *name = "prox";
+	struct iio_dev *indio_dev;
+	struct prox_state *prox_state;
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_chan_spec *channels;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev,
+				sizeof(struct prox_state));
+	if (!indio_dev)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, indio_dev);
+
+	prox_state = iio_priv(indio_dev);
+	prox_state->common_attributes.hsdev = hsdev;
+	prox_state->common_attributes.pdev = pdev;
+
+	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_PROX,
+					&prox_state->common_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup common attributes\n");
+		return ret;
+	}
+
+	channels = kmemdup(prox_channels, sizeof(prox_channels), GFP_KERNEL);
+	if (!channels) {
+		dev_err(&pdev->dev, "failed to duplicate channels\n");
+		return -ENOMEM;
+	}
+
+	ret = prox_parse_report(pdev, hsdev, channels,
+				HID_USAGE_SENSOR_PROX, prox_state);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup attributes\n");
+		goto error_free_dev_mem;
+	}
+
+	indio_dev->channels = channels;
+	indio_dev->num_channels =
+				ARRAY_SIZE(prox_channels);
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->info = &prox_info;
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		NULL, NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
+		goto error_free_dev_mem;
+	}
+	prox_state->common_attributes.data_ready = false;
+	ret = hid_sensor_setup_trigger(indio_dev, name,
+				&prox_state->common_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "trigger setup failed\n");
+		goto error_unreg_buffer_funcs;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "device register failed\n");
+		goto error_remove_trigger;
+	}
+
+	prox_state->callbacks.send_event = prox_proc_event;
+	prox_state->callbacks.capture_sample = prox_capture_sample;
+	prox_state->callbacks.pdev = pdev;
+	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_PROX,
+					&prox_state->callbacks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "callback reg failed\n");
+		goto error_iio_unreg;
+	}
+
+	return ret;
+
+error_iio_unreg:
+	iio_device_unregister(indio_dev);
+error_remove_trigger:
+	hid_sensor_remove_trigger(&prox_state->common_attributes);
+error_unreg_buffer_funcs:
+	iio_triggered_buffer_cleanup(indio_dev);
+error_free_dev_mem:
+	kfree(indio_dev->channels);
+	return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_prox_remove(struct platform_device *pdev)
+{
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct prox_state *prox_state = iio_priv(indio_dev);
+
+	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PROX);
+	iio_device_unregister(indio_dev);
+	hid_sensor_remove_trigger(&prox_state->common_attributes);
+	iio_triggered_buffer_cleanup(indio_dev);
+	kfree(indio_dev->channels);
+
+	return 0;
+}
+
+static struct platform_device_id hid_prox_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200011",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_prox_ids);
+
+static struct platform_driver hid_prox_platform_driver = {
+	.id_table = hid_prox_ids,
+	.driver = {
+		.name	= KBUILD_MODNAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= hid_prox_probe,
+	.remove		= hid_prox_remove,
+};
+module_platform_driver(hid_prox_platform_driver);
+
+MODULE_DESCRIPTION("HID Sensor Proximity");
+MODULE_AUTHOR("Archana Patni <archana.patni@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
new file mode 100644
index 0000000..62b7072
--- /dev/null
+++ b/drivers/iio/light/ltr501.c
@@ -0,0 +1,445 @@
+/*
+ * ltr501.c - Support for Lite-On LTR501 ambient light and proximity sensor
+ *
+ * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * 7-bit I2C slave address 0x23
+ *
+ * TODO: interrupt, threshold, measurement rate, IR LED characteristics
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define LTR501_DRV_NAME "ltr501"
+
+#define LTR501_ALS_CONTR 0x80 /* ALS operation mode, SW reset */
+#define LTR501_PS_CONTR 0x81 /* PS operation mode */
+#define LTR501_PART_ID 0x86
+#define LTR501_MANUFAC_ID 0x87
+#define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */
+#define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */
+#define LTR501_ALS_PS_STATUS 0x8c
+#define LTR501_PS_DATA 0x8d /* 16-bit, little endian */
+
+#define LTR501_ALS_CONTR_SW_RESET BIT(2)
+#define LTR501_CONTR_PS_GAIN_MASK (BIT(3) | BIT(2))
+#define LTR501_CONTR_PS_GAIN_SHIFT 2
+#define LTR501_CONTR_ALS_GAIN_MASK BIT(3)
+#define LTR501_CONTR_ACTIVE BIT(1)
+
+#define LTR501_STATUS_ALS_RDY BIT(2)
+#define LTR501_STATUS_PS_RDY BIT(0)
+
+#define LTR501_PS_DATA_MASK 0x7ff
+
+struct ltr501_data {
+	struct i2c_client *client;
+	struct mutex lock_als, lock_ps;
+	u8 als_contr, ps_contr;
+};
+
+static int ltr501_drdy(struct ltr501_data *data, u8 drdy_mask)
+{
+	int tries = 100;
+	int ret;
+
+	while (tries--) {
+		ret = i2c_smbus_read_byte_data(data->client,
+			LTR501_ALS_PS_STATUS);
+		if (ret < 0)
+			return ret;
+		if ((ret & drdy_mask) == drdy_mask)
+			return 0;
+		msleep(25);
+	}
+
+	dev_err(&data->client->dev, "ltr501_drdy() failed, data not ready\n");
+	return -EIO;
+}
+
+static int ltr501_read_als(struct ltr501_data *data, __le16 buf[2])
+{
+	int ret = ltr501_drdy(data, LTR501_STATUS_ALS_RDY);
+	if (ret < 0)
+		return ret;
+	/* always read both ALS channels in given order */
+	return i2c_smbus_read_i2c_block_data(data->client,
+		LTR501_ALS_DATA1, 2 * sizeof(__le16), (u8 *) buf);
+}
+
+static int ltr501_read_ps(struct ltr501_data *data)
+{
+	int ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY);
+	if (ret < 0)
+		return ret;
+	return i2c_smbus_read_word_data(data->client, LTR501_PS_DATA);
+}
+
+#define LTR501_INTENSITY_CHANNEL(_idx, _addr, _mod, _shared) { \
+	.type = IIO_INTENSITY, \
+	.modified = 1, \
+	.address = (_addr), \
+	.channel2 = (_mod), \
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+	.info_mask_shared_by_type = (_shared), \
+	.scan_index = (_idx), \
+	.scan_type = { \
+		.sign = 'u', \
+		.realbits = 16, \
+		.storagebits = 16, \
+		.endianness = IIO_CPU, \
+	} \
+}
+
+static const struct iio_chan_spec ltr501_channels[] = {
+	LTR501_INTENSITY_CHANNEL(0, LTR501_ALS_DATA0, IIO_MOD_LIGHT_BOTH, 0),
+	LTR501_INTENSITY_CHANNEL(1, LTR501_ALS_DATA1, IIO_MOD_LIGHT_IR,
+		BIT(IIO_CHAN_INFO_SCALE)),
+	{
+		.type = IIO_PROXIMITY,
+		.address = LTR501_PS_DATA,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
+		.scan_index = 2,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = 11,
+			.storagebits = 16,
+			.endianness = IIO_CPU,
+		},
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const int ltr501_ps_gain[4][2] = {
+	{1, 0}, {0, 250000}, {0, 125000}, {0, 62500}
+};
+
+static int ltr501_read_raw(struct iio_dev *indio_dev,
+				struct iio_chan_spec const *chan,
+				int *val, int *val2, long mask)
+{
+	struct ltr501_data *data = iio_priv(indio_dev);
+	__le16 buf[2];
+	int ret, i;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+
+		switch (chan->type) {
+		case IIO_INTENSITY:
+			mutex_lock(&data->lock_als);
+			ret = ltr501_read_als(data, buf);
+			mutex_unlock(&data->lock_als);
+			if (ret < 0)
+				return ret;
+			*val = le16_to_cpu(chan->address == LTR501_ALS_DATA1 ?
+				buf[0] : buf[1]);
+			return IIO_VAL_INT;
+		case IIO_PROXIMITY:
+			mutex_lock(&data->lock_ps);
+			ret = ltr501_read_ps(data);
+			mutex_unlock(&data->lock_ps);
+			if (ret < 0)
+				return ret;
+			*val = ret & LTR501_PS_DATA_MASK;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_INTENSITY:
+			if (data->als_contr & LTR501_CONTR_ALS_GAIN_MASK) {
+				*val = 0;
+				*val2 = 5000;
+				return IIO_VAL_INT_PLUS_MICRO;
+			} else {
+				*val = 1;
+				*val2 = 0;
+				return IIO_VAL_INT;
+			}
+		case IIO_PROXIMITY:
+			i = (data->ps_contr & LTR501_CONTR_PS_GAIN_MASK) >>
+				LTR501_CONTR_PS_GAIN_SHIFT;
+			*val = ltr501_ps_gain[i][0];
+			*val2 = ltr501_ps_gain[i][1];
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	}
+	return -EINVAL;
+}
+
+static int ltr501_get_ps_gain_index(int val, int val2)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ltr501_ps_gain); i++)
+		if (val == ltr501_ps_gain[i][0] && val2 == ltr501_ps_gain[i][1])
+			return i;
+
+	return -1;
+}
+
+static int ltr501_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val, int val2, long mask)
+{
+	struct ltr501_data *data = iio_priv(indio_dev);
+	int i;
+
+	if (iio_buffer_enabled(indio_dev))
+		return -EBUSY;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_INTENSITY:
+			if (val == 0 && val2 == 5000)
+				data->als_contr |= LTR501_CONTR_ALS_GAIN_MASK;
+			else if (val == 1 && val2 == 0)
+				data->als_contr &= ~LTR501_CONTR_ALS_GAIN_MASK;
+			else
+				return -EINVAL;
+			return i2c_smbus_write_byte_data(data->client,
+				LTR501_ALS_CONTR, data->als_contr);
+		case IIO_PROXIMITY:
+			i = ltr501_get_ps_gain_index(val, val2);
+			if (i < 0)
+				return -EINVAL;
+			data->ps_contr &= ~LTR501_CONTR_PS_GAIN_MASK;
+			data->ps_contr |= i << LTR501_CONTR_PS_GAIN_SHIFT;
+			return i2c_smbus_write_byte_data(data->client,
+				LTR501_PS_CONTR, data->ps_contr);
+		default:
+			return -EINVAL;
+		}
+	}
+	return -EINVAL;
+}
+
+static IIO_CONST_ATTR(in_proximity_scale_available, "1 0.25 0.125 0.0625");
+static IIO_CONST_ATTR(in_intensity_scale_available, "1 0.005");
+
+static struct attribute *ltr501_attributes[] = {
+	&iio_const_attr_in_proximity_scale_available.dev_attr.attr,
+	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group ltr501_attribute_group = {
+	.attrs = ltr501_attributes,
+};
+
+static const struct iio_info ltr501_info = {
+	.read_raw = ltr501_read_raw,
+	.write_raw = ltr501_write_raw,
+	.attrs = &ltr501_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static int ltr501_write_contr(struct i2c_client *client, u8 als_val, u8 ps_val)
+{
+	int ret = i2c_smbus_write_byte_data(client, LTR501_ALS_CONTR, als_val);
+	if (ret < 0)
+		return ret;
+
+	return i2c_smbus_write_byte_data(client, LTR501_PS_CONTR, ps_val);
+}
+
+static irqreturn_t ltr501_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct ltr501_data *data = iio_priv(indio_dev);
+	u16 buf[8];
+	__le16 als_buf[2];
+	u8 mask = 0;
+	int j = 0;
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	/* figure out which data needs to be ready */
+	if (test_bit(0, indio_dev->active_scan_mask) ||
+		test_bit(1, indio_dev->active_scan_mask))
+		mask |= LTR501_STATUS_ALS_RDY;
+	if (test_bit(2, indio_dev->active_scan_mask))
+		mask |= LTR501_STATUS_PS_RDY;
+
+	ret = ltr501_drdy(data, mask);
+	if (ret < 0)
+		goto done;
+
+	if (mask & LTR501_STATUS_ALS_RDY) {
+		ret = i2c_smbus_read_i2c_block_data(data->client,
+			LTR501_ALS_DATA1, sizeof(als_buf), (u8 *) als_buf);
+		if (ret < 0)
+			return ret;
+		if (test_bit(0, indio_dev->active_scan_mask))
+			buf[j++] = le16_to_cpu(als_buf[1]);
+		if (test_bit(1, indio_dev->active_scan_mask))
+			buf[j++] = le16_to_cpu(als_buf[0]);
+	}
+
+	if (mask & LTR501_STATUS_PS_RDY) {
+		ret = i2c_smbus_read_word_data(data->client, LTR501_PS_DATA);
+		if (ret < 0)
+			goto done;
+		buf[j++] = ret & LTR501_PS_DATA_MASK;
+	}
+
+	iio_push_to_buffers_with_timestamp(indio_dev, buf,
+		iio_get_time_ns());
+
+done:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static int ltr501_init(struct ltr501_data *data)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, LTR501_ALS_CONTR);
+	if (ret < 0)
+		return ret;
+	data->als_contr = ret | LTR501_CONTR_ACTIVE;
+
+	ret = i2c_smbus_read_byte_data(data->client, LTR501_PS_CONTR);
+	if (ret < 0)
+		return ret;
+	data->ps_contr = ret | LTR501_CONTR_ACTIVE;
+
+	return ltr501_write_contr(data->client, data->als_contr,
+		data->ps_contr);
+}
+
+static int ltr501_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	struct ltr501_data *data;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+	mutex_init(&data->lock_als);
+	mutex_init(&data->lock_ps);
+
+	ret = i2c_smbus_read_byte_data(data->client, LTR501_PART_ID);
+	if (ret < 0)
+		return ret;
+	if ((ret >> 4) != 0x8)
+		return -ENODEV;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->info = &ltr501_info;
+	indio_dev->channels = ltr501_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ltr501_channels);
+	indio_dev->name = LTR501_DRV_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ltr501_init(data);
+	if (ret < 0)
+		return ret;
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+		ltr501_trigger_handler, NULL);
+	if (ret)
+		return ret;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_buffer;
+
+	return 0;
+
+error_unreg_buffer:
+	iio_triggered_buffer_cleanup(indio_dev);
+	return ret;
+}
+
+static int ltr501_powerdown(struct ltr501_data *data)
+{
+	return ltr501_write_contr(data->client,
+		data->als_contr & ~LTR501_CONTR_ACTIVE,
+		data->ps_contr & ~LTR501_CONTR_ACTIVE);
+}
+
+static int ltr501_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	ltr501_powerdown(iio_priv(indio_dev));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ltr501_suspend(struct device *dev)
+{
+	struct ltr501_data *data = iio_priv(i2c_get_clientdata(
+		to_i2c_client(dev)));
+	return ltr501_powerdown(data);
+}
+
+static int ltr501_resume(struct device *dev)
+{
+	struct ltr501_data *data = iio_priv(i2c_get_clientdata(
+		to_i2c_client(dev)));
+
+	return ltr501_write_contr(data->client, data->als_contr,
+		data->ps_contr);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume);
+
+static const struct i2c_device_id ltr501_id[] = {
+	{ "ltr501", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ltr501_id);
+
+static struct i2c_driver ltr501_driver = {
+	.driver = {
+		.name   = LTR501_DRV_NAME,
+		.pm	= &ltr501_pm_ops,
+		.owner  = THIS_MODULE,
+	},
+	.probe  = ltr501_probe,
+	.remove	= ltr501_remove,
+	.id_table = ltr501_id,
+};
+
+module_i2c_driver(ltr501_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Lite-On LTR501 ambient light and proximity sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
index 887fecf..fe063a0 100644
--- a/drivers/iio/light/tcs3472.c
+++ b/drivers/iio/light/tcs3472.c
@@ -179,7 +179,6 @@
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct tcs3472_data *data = iio_priv(indio_dev);
-	int len = 0;
 	int i, j = 0;
 
 	int ret = tcs3472_req_data(data);
@@ -194,7 +193,6 @@
 			goto done;
 
 		data->buffer[j++] = ret;
-		len += 2;
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index 0542354..74866d1 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -513,6 +513,7 @@
 	indio_dev->channels = ak8975_channels;
 	indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
 	indio_dev->info = &ak8975_info;
+	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	err = iio_device_register(indio_dev);
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
index f66955f..8b77782 100644
--- a/drivers/iio/magnetometer/mag3110.c
+++ b/drivers/iio/magnetometer/mag3110.c
@@ -183,9 +183,17 @@
 			return -EINVAL;
 		}
 	case IIO_CHAN_INFO_SCALE:
-		*val = 0;
-		*val2 = 1000;
-		return IIO_VAL_INT_PLUS_MICRO;
+		switch (chan->type) {
+		case IIO_MAGN:
+			*val = 0;
+			*val2 = 1000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 1000;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_SAMP_FREQ:
 		i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
 		*val = mag3110_samp_freq[i][0];
@@ -270,7 +278,8 @@
 	MAG3110_CHANNEL(Z, 2),
 	{
 		.type = IIO_TEMP,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
 		.scan_index = 3,
 		.scan_type = {
 			.sign = 's',
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index a8b9cae..d88ff17 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -5,6 +5,20 @@
 
 menu "Pressure sensors"
 
+config HID_SENSOR_PRESS
+	depends on HID_SENSOR_HUB
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select HID_SENSOR_IIO_COMMON
+	select HID_SENSOR_IIO_TRIGGER
+	tristate "HID PRESS"
+	help
+	  Say yes here to build support for the HID SENSOR
+	  Pressure driver
+
+          To compile this driver as a module, choose M here: the module
+          will be called hid-sensor-press.
+
 config MPL3115
 	tristate "Freescale MPL3115A2 pressure sensor driver"
 	depends on I2C
@@ -26,7 +40,7 @@
 	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
 	help
 	  Say yes here to build support for STMicroelectronics pressure
-	  sensors: LPS001WP, LPS331AP.
+	  sensors: LPS001WP, LPS25H, LPS331AP.
 
 	  This driver can also be built as a module. If so, these modules
 	  will be created:
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 42bb9fc..4a57bf6 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -3,6 +3,7 @@
 #
 
 # When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
 obj-$(CONFIG_MPL3115) += mpl3115.o
 obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
 st_pressure-y := st_pressure_core.o
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
new file mode 100644
index 0000000..e0e6409
--- /dev/null
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -0,0 +1,376 @@
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2014, 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.
+ *
+ */
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+#define CHANNEL_SCAN_INDEX_PRESSURE 0
+
+struct press_state {
+	struct hid_sensor_hub_callbacks callbacks;
+	struct hid_sensor_common common_attributes;
+	struct hid_sensor_hub_attribute_info press_attr;
+	u32 press_data;
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec press_channels[] = {
+	{
+		.type = IIO_PRESSURE,
+		.modified = 1,
+		.channel2 = IIO_NO_MOD,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+		BIT(IIO_CHAN_INFO_SCALE) |
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+		BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_PRESSURE,
+	}
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void press_adjust_channel_bit_mask(struct iio_chan_spec *channels,
+					int channel, int size)
+{
+	channels[channel].scan_type.sign = 's';
+	/* Real storage bits will change based on the report desc. */
+	channels[channel].scan_type.realbits = size * 8;
+	/* Maximum size of a sample to capture is u32 */
+	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+}
+
+/* Channel read_raw handler */
+static int press_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	struct press_state *press_state = iio_priv(indio_dev);
+	int report_id = -1;
+	u32 address;
+	int ret;
+	int ret_type;
+
+	*val = 0;
+	*val2 = 0;
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->scan_index) {
+		case  CHANNEL_SCAN_INDEX_PRESSURE:
+			report_id = press_state->press_attr.report_id;
+			address =
+			HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE;
+			break;
+		default:
+			report_id = -1;
+			break;
+		}
+		if (report_id >= 0)
+			*val = sensor_hub_input_attr_get_raw_value(
+				press_state->common_attributes.hsdev,
+				HID_USAGE_SENSOR_PRESSURE, address,
+				report_id);
+		else {
+			*val = 0;
+			return -EINVAL;
+		}
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SCALE:
+		*val = press_state->press_attr.units;
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_OFFSET:
+		*val = hid_sensor_convert_exponent(
+				press_state->press_attr.unit_expo);
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_read_samp_freq_value(
+				&press_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_read_raw_hyst_value(
+				&press_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	default:
+		ret_type = -EINVAL;
+		break;
+	}
+
+	return ret_type;
+}
+
+/* Channel write_raw handler */
+static int press_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct press_state *press_state = iio_priv(indio_dev);
+	int ret = 0;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_write_samp_freq_value(
+				&press_state->common_attributes, val, val2);
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_write_raw_hyst_value(
+				&press_state->common_attributes, val, val2);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static const struct iio_info press_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &press_read_raw,
+	.write_raw = &press_write_raw,
+};
+
+/* Function to push data to buffer */
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+					int len)
+{
+	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
+	iio_push_to_buffers(indio_dev, data);
+}
+
+/* Callback handler to send event after all samples are received and captured */
+static int press_proc_event(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct press_state *press_state = iio_priv(indio_dev);
+
+	dev_dbg(&indio_dev->dev, "press_proc_event [%d]\n",
+				press_state->common_attributes.data_ready);
+	if (press_state->common_attributes.data_ready)
+		hid_sensor_push_data(indio_dev,
+				&press_state->press_data,
+				sizeof(press_state->press_data));
+
+	return 0;
+}
+
+/* Capture samples in local storage */
+static int press_capture_sample(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				size_t raw_len, char *raw_data,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct press_state *press_state = iio_priv(indio_dev);
+	int ret = -EINVAL;
+
+	switch (usage_id) {
+	case HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE:
+		press_state->press_data = *(u32 *)raw_data;
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/* Parse report which is specific to an usage id*/
+static int press_parse_report(struct platform_device *pdev,
+				struct hid_sensor_hub_device *hsdev,
+				struct iio_chan_spec *channels,
+				unsigned usage_id,
+				struct press_state *st)
+{
+	int ret;
+
+	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
+			usage_id,
+			HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE,
+			&st->press_attr);
+	if (ret < 0)
+		return ret;
+	press_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_PRESSURE,
+					st->press_attr.size);
+
+	dev_dbg(&pdev->dev, "press %x:%x\n", st->press_attr.index,
+			st->press_attr.report_id);
+
+	/* Set Sensitivity field ids, when there is no individual modifier */
+	if (st->common_attributes.sensitivity.index < 0) {
+		sensor_hub_input_get_attribute_info(hsdev,
+			HID_FEATURE_REPORT, usage_id,
+			HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+			HID_USAGE_SENSOR_DATA_ATMOSPHERIC_PRESSURE,
+			&st->common_attributes.sensitivity);
+		dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+			st->common_attributes.sensitivity.index,
+			st->common_attributes.sensitivity.report_id);
+	}
+	return ret;
+}
+
+/* Function to initialize the processing for usage id */
+static int hid_press_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	static const char *name = "press";
+	struct iio_dev *indio_dev;
+	struct press_state *press_state;
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_chan_spec *channels;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev,
+				sizeof(struct press_state));
+	if (!indio_dev)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, indio_dev);
+
+	press_state = iio_priv(indio_dev);
+	press_state->common_attributes.hsdev = hsdev;
+	press_state->common_attributes.pdev = pdev;
+
+	ret = hid_sensor_parse_common_attributes(hsdev,
+					HID_USAGE_SENSOR_PRESSURE,
+					&press_state->common_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup common attributes\n");
+		return ret;
+	}
+
+	channels = kmemdup(press_channels, sizeof(press_channels), GFP_KERNEL);
+	if (!channels) {
+		dev_err(&pdev->dev, "failed to duplicate channels\n");
+		return -ENOMEM;
+	}
+
+	ret = press_parse_report(pdev, hsdev, channels,
+				HID_USAGE_SENSOR_PRESSURE, press_state);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup attributes\n");
+		goto error_free_dev_mem;
+	}
+
+	indio_dev->channels = channels;
+	indio_dev->num_channels =
+				ARRAY_SIZE(press_channels);
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->info = &press_info;
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		NULL, NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
+		goto error_free_dev_mem;
+	}
+	press_state->common_attributes.data_ready = false;
+	ret = hid_sensor_setup_trigger(indio_dev, name,
+				&press_state->common_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "trigger setup failed\n");
+		goto error_unreg_buffer_funcs;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "device register failed\n");
+		goto error_remove_trigger;
+	}
+
+	press_state->callbacks.send_event = press_proc_event;
+	press_state->callbacks.capture_sample = press_capture_sample;
+	press_state->callbacks.pdev = pdev;
+	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_PRESSURE,
+					&press_state->callbacks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "callback reg failed\n");
+		goto error_iio_unreg;
+	}
+
+	return ret;
+
+error_iio_unreg:
+	iio_device_unregister(indio_dev);
+error_remove_trigger:
+	hid_sensor_remove_trigger(&press_state->common_attributes);
+error_unreg_buffer_funcs:
+	iio_triggered_buffer_cleanup(indio_dev);
+error_free_dev_mem:
+	kfree(indio_dev->channels);
+	return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_press_remove(struct platform_device *pdev)
+{
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct press_state *press_state = iio_priv(indio_dev);
+
+	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
+	iio_device_unregister(indio_dev);
+	hid_sensor_remove_trigger(&press_state->common_attributes);
+	iio_triggered_buffer_cleanup(indio_dev);
+	kfree(indio_dev->channels);
+
+	return 0;
+}
+
+static struct platform_device_id hid_press_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200031",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_press_ids);
+
+static struct platform_driver hid_press_platform_driver = {
+	.id_table = hid_press_ids,
+	.driver = {
+		.name	= KBUILD_MODNAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= hid_press_probe,
+	.remove		= hid_press_remove,
+};
+module_platform_driver(hid_press_platform_driver);
+
+MODULE_DESCRIPTION("HID Sensor Pressure");
+MODULE_AUTHOR("Archana Patni <archana.patni@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index ac8c8ab..ba6d0c5 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -77,7 +77,7 @@
 			    int *val, int *val2, long mask)
 {
 	struct mpl3115_data *data = iio_priv(indio_dev);
-	s32 tmp = 0;
+	__be32 tmp = 0;
 	int ret;
 
 	switch (mask) {
diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h
index 049c21a..242943c 100644
--- a/drivers/iio/pressure/st_pressure.h
+++ b/drivers/iio/pressure/st_pressure.h
@@ -15,6 +15,7 @@
 #include <linux/iio/common/st_sensors.h>
 
 #define LPS001WP_PRESS_DEV_NAME		"lps001wp"
+#define LPS25H_PRESS_DEV_NAME		"lps25h"
 #define LPS331AP_PRESS_DEV_NAME		"lps331ap"
 
 /**
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index 58083f9..7418768 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -40,6 +40,9 @@
 /* FULLSCALE */
 #define ST_PRESS_FS_AVL_1260MB			1260
 
+#define ST_PRESS_1_OUT_XL_ADDR			0x28
+#define ST_TEMP_1_OUT_L_ADDR			0x2b
+
 /* CUSTOM VALUES FOR LPS331AP SENSOR */
 #define ST_PRESS_LPS331AP_WAI_EXP		0xbb
 #define ST_PRESS_LPS331AP_ODR_ADDR		0x20
@@ -62,8 +65,6 @@
 #define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK	0x20
 #define ST_PRESS_LPS331AP_MULTIREAD_BIT		true
 #define ST_PRESS_LPS331AP_TEMP_OFFSET		42500
-#define ST_PRESS_LPS331AP_OUT_XL_ADDR		0x28
-#define ST_TEMP_LPS331AP_OUT_L_ADDR		0x2b
 
 /* CUSTOM VALUES FOR LPS001WP SENSOR */
 #define ST_PRESS_LPS001WP_WAI_EXP		0xba
@@ -80,11 +81,36 @@
 #define ST_PRESS_LPS001WP_OUT_L_ADDR		0x28
 #define ST_TEMP_LPS001WP_OUT_L_ADDR		0x2a
 
-static const struct iio_chan_spec st_press_lps331ap_channels[] = {
+/* CUSTOM VALUES FOR LPS25H SENSOR */
+#define ST_PRESS_LPS25H_WAI_EXP			0xbd
+#define ST_PRESS_LPS25H_ODR_ADDR		0x20
+#define ST_PRESS_LPS25H_ODR_MASK		0x70
+#define ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL		0x01
+#define ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL		0x02
+#define ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL	0x03
+#define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL	0x04
+#define ST_PRESS_LPS25H_PW_ADDR			0x20
+#define ST_PRESS_LPS25H_PW_MASK			0x80
+#define ST_PRESS_LPS25H_FS_ADDR			0x00
+#define ST_PRESS_LPS25H_FS_MASK			0x00
+#define ST_PRESS_LPS25H_FS_AVL_1260_VAL		0x00
+#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN	ST_PRESS_KPASCAL_NANO_SCALE
+#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN	ST_PRESS_CELSIUS_NANO_SCALE
+#define ST_PRESS_LPS25H_BDU_ADDR		0x20
+#define ST_PRESS_LPS25H_BDU_MASK		0x04
+#define ST_PRESS_LPS25H_DRDY_IRQ_ADDR		0x23
+#define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK	0x01
+#define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK	0x10
+#define ST_PRESS_LPS25H_MULTIREAD_BIT		true
+#define ST_PRESS_LPS25H_TEMP_OFFSET		42500
+#define ST_PRESS_LPS25H_OUT_XL_ADDR		0x28
+#define ST_TEMP_LPS25H_OUT_L_ADDR		0x2b
+
+static const struct iio_chan_spec st_press_1_channels[] = {
 	{
 		.type = IIO_PRESSURE,
 		.channel2 = IIO_NO_MOD,
-		.address = ST_PRESS_LPS331AP_OUT_XL_ADDR,
+		.address = ST_PRESS_1_OUT_XL_ADDR,
 		.scan_index = ST_SENSORS_SCAN_X,
 		.scan_type = {
 			.sign = 'u',
@@ -99,7 +125,7 @@
 	{
 		.type = IIO_TEMP,
 		.channel2 = IIO_NO_MOD,
-		.address = ST_TEMP_LPS331AP_OUT_L_ADDR,
+		.address = ST_TEMP_1_OUT_L_ADDR,
 		.scan_index = -1,
 		.scan_type = {
 			.sign = 'u',
@@ -156,8 +182,8 @@
 		.sensors_supported = {
 			[0] = LPS331AP_PRESS_DEV_NAME,
 		},
-		.ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
-		.num_ch = ARRAY_SIZE(st_press_lps331ap_channels),
+		.ch = (struct iio_chan_spec *)st_press_1_channels,
+		.num_ch = ARRAY_SIZE(st_press_1_channels),
 		.odr = {
 			.addr = ST_PRESS_LPS331AP_ODR_ADDR,
 			.mask = ST_PRESS_LPS331AP_ODR_MASK,
@@ -233,6 +259,53 @@
 		.multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
 		.bootime = 2,
 	},
+	{
+		.wai = ST_PRESS_LPS25H_WAI_EXP,
+		.sensors_supported = {
+			[0] = LPS25H_PRESS_DEV_NAME,
+		},
+		.ch = (struct iio_chan_spec *)st_press_1_channels,
+		.num_ch = ARRAY_SIZE(st_press_1_channels),
+		.odr = {
+			.addr = ST_PRESS_LPS25H_ODR_ADDR,
+			.mask = ST_PRESS_LPS25H_ODR_MASK,
+			.odr_avl = {
+				{ 1, ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL, },
+				{ 7, ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL, },
+				{ 13, ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL, },
+				{ 25, ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL, },
+			},
+		},
+		.pw = {
+			.addr = ST_PRESS_LPS25H_PW_ADDR,
+			.mask = ST_PRESS_LPS25H_PW_MASK,
+			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+		},
+		.fs = {
+			.addr = ST_PRESS_LPS25H_FS_ADDR,
+			.mask = ST_PRESS_LPS25H_FS_MASK,
+			.fs_avl = {
+				[0] = {
+					.num = ST_PRESS_FS_AVL_1260MB,
+					.value = ST_PRESS_LPS25H_FS_AVL_1260_VAL,
+					.gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN,
+					.gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN,
+				},
+			},
+		},
+		.bdu = {
+			.addr = ST_PRESS_LPS25H_BDU_ADDR,
+			.mask = ST_PRESS_LPS25H_BDU_MASK,
+		},
+		.drdy_irq = {
+			.addr = ST_PRESS_LPS25H_DRDY_IRQ_ADDR,
+			.mask_int1 = ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK,
+			.mask_int2 = ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK,
+		},
+		.multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT,
+		.bootime = 2,
+	},
 };
 
 static int st_press_read_raw(struct iio_dev *indio_dev,
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 51eab7f..3cd73e3 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -50,6 +50,7 @@
 
 static const struct i2c_device_id st_press_id_table[] = {
 	{ LPS001WP_PRESS_DEV_NAME },
+	{ LPS25H_PRESS_DEV_NAME },
 	{ LPS331AP_PRESS_DEV_NAME },
 	{},
 };
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c
index 27322af..f45d430 100644
--- a/drivers/iio/pressure/st_pressure_spi.c
+++ b/drivers/iio/pressure/st_pressure_spi.c
@@ -49,6 +49,7 @@
 
 static const struct spi_device_id st_press_id_table[] = {
 	{ LPS001WP_PRESS_DEV_NAME },
+	{ LPS25H_PRESS_DEV_NAME },
 	{ LPS331AP_PRESS_DEV_NAME },
 	{},
 };
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index d4e15a6..9d38f7b 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -26,12 +26,12 @@
 #include <linux/videodev2.h>
 #include <linux/uaccess.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <media/adv7343.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
 
 #include "adv7343_regs.h"
 
@@ -410,7 +410,7 @@
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index e5ddf47..192c4aa 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/of_graph.h>
 #include <linux/pm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -29,7 +30,6 @@
 #include <media/mt9p031.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
 #include <media/v4l2-subdev.h>
 
 #include "aptina-pll.h"
@@ -943,7 +943,7 @@
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 77e10e0..2d768ef 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -21,6 +21,7 @@
 #include <linux/media.h>
 #include <linux/module.h>
 #include <linux/of_gpio.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
@@ -1855,7 +1856,7 @@
 	if (ret < 0)
 		return ret;
 
-	node_ep = v4l2_of_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_next_endpoint(node, NULL);
 	if (!node_ep) {
 		dev_err(dev, "no endpoint defined at node %s\n",
 			node->full_name);
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 83d85df..ca00117 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -36,6 +36,7 @@
 #include <linux/module.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
@@ -1068,7 +1069,7 @@
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 912e1cc..c4e1e2c 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -30,6 +30,7 @@
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/v4l2-dv-timings.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-async.h>
@@ -957,7 +958,7 @@
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 13a4228..9bdfa45 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -24,13 +24,13 @@
 #include <linux/i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-of.h>
 #include <media/videobuf2-dma-contig.h>
 
 #include "media-dev.h"
@@ -167,10 +167,10 @@
 	u32 tmp = 0;
 	int ret;
 
-	np = v4l2_of_get_next_endpoint(np, NULL);
+	np = of_graph_get_next_endpoint(np, NULL);
 	if (!np)
 		return -ENXIO;
-	np = v4l2_of_get_remote_port(np);
+	np = of_graph_get_remote_port(np);
 	if (!np)
 		return -ENXIO;
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index c1bce17..04d6ecd 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
+#include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
@@ -468,12 +469,12 @@
 		return 0;
 
 	v4l2_of_parse_endpoint(ep, &endpoint);
-	if (WARN_ON(endpoint.port == 0) || index >= FIMC_MAX_SENSORS)
+	if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS)
 		return -EINVAL;
 
-	pd->mux_id = (endpoint.port - 1) & 0x1;
+	pd->mux_id = (endpoint.base.port - 1) & 0x1;
 
-	rem = v4l2_of_get_remote_port_parent(ep);
+	rem = of_graph_get_remote_port_parent(ep);
 	of_node_put(ep);
 	if (rem == NULL) {
 		v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n",
@@ -493,13 +494,13 @@
 		return -EINVAL;
 	}
 
-	if (fimc_input_is_parallel(endpoint.port)) {
+	if (fimc_input_is_parallel(endpoint.base.port)) {
 		if (endpoint.bus_type == V4L2_MBUS_PARALLEL)
 			pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601;
 		else
 			pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656;
 		pd->flags = endpoint.bus.parallel.flags;
-	} else if (fimc_input_is_mipi_csi(endpoint.port)) {
+	} else if (fimc_input_is_mipi_csi(endpoint.base.port)) {
 		/*
 		 * MIPI CSI-2: only input mux selection and
 		 * the sensor's clock frequency is needed.
@@ -507,7 +508,7 @@
 		pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2;
 	} else {
 		v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n",
-			 endpoint.port, rem->full_name);
+			 endpoint.base.port, rem->full_name);
 	}
 	/*
 	 * For FIMC-IS handled sensors, that are placed under i2c-isp device
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index f3c3591..3678ba5 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -20,6 +20,7 @@
 #include <linux/memory.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_data/mipi-csis.h>
 #include <linux/platform_device.h>
@@ -762,7 +763,7 @@
 				 &state->max_num_lanes))
 		return -EINVAL;
 
-	node = v4l2_of_get_next_endpoint(node, NULL);
+	node = of_graph_get_next_endpoint(node, NULL);
 	if (!node) {
 		dev_err(&pdev->dev, "No port node at %s\n",
 				pdev->dev.of_node->full_name);
@@ -771,7 +772,7 @@
 	/* Get port node and validate MIPI-CSI channel id. */
 	v4l2_of_parse_endpoint(node, &endpoint);
 
-	state->index = endpoint.port - FIMC_INPUT_MIPI_CSI2_0;
+	state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0;
 	if (state->index < 0 || state->index >= CSIS_MAX_ENTITIES)
 		return -ENXIO;
 
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
index 42e3e8a..b4ed9a9 100644
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ b/drivers/media/v4l2-core/v4l2-of.c
@@ -127,17 +127,9 @@
 int v4l2_of_parse_endpoint(const struct device_node *node,
 			   struct v4l2_of_endpoint *endpoint)
 {
-	struct device_node *port_node = of_get_parent(node);
-
-	memset(endpoint, 0, offsetof(struct v4l2_of_endpoint, head));
-
-	endpoint->local_node = node;
-	/*
-	 * It doesn't matter whether the two calls below succeed.
-	 * If they don't then the default value 0 is used.
-	 */
-	of_property_read_u32(port_node, "reg", &endpoint->port);
-	of_property_read_u32(node, "reg", &endpoint->id);
+	of_graph_parse_endpoint(node, &endpoint->base);
+	endpoint->bus_type = 0;
+	memset(&endpoint->bus, 0, sizeof(endpoint->bus));
 
 	v4l2_of_parse_csi_bus(node, endpoint);
 	/*
@@ -147,125 +139,6 @@
 	if (endpoint->bus.mipi_csi2.flags == 0)
 		v4l2_of_parse_parallel_bus(node, endpoint);
 
-	of_node_put(port_node);
-
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
-
-/**
- * v4l2_of_get_next_endpoint() - get next endpoint node
- * @parent: pointer to the parent device node
- * @prev: previous endpoint node, or NULL to get first
- *
- * Return: An 'endpoint' node pointer with refcount incremented. Refcount
- * of the passed @prev node is not decremented, the caller have to use
- * of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
-					struct device_node *prev)
-{
-	struct device_node *endpoint;
-	struct device_node *port = NULL;
-
-	if (!parent)
-		return NULL;
-
-	if (!prev) {
-		struct device_node *node;
-		/*
-		 * It's the first call, we have to find a port subnode
-		 * within this node or within an optional 'ports' node.
-		 */
-		node = of_get_child_by_name(parent, "ports");
-		if (node)
-			parent = node;
-
-		port = of_get_child_by_name(parent, "port");
-
-		if (port) {
-			/* Found a port, get an endpoint. */
-			endpoint = of_get_next_child(port, NULL);
-			of_node_put(port);
-		} else {
-			endpoint = NULL;
-		}
-
-		if (!endpoint)
-			pr_err("%s(): no endpoint nodes specified for %s\n",
-			       __func__, parent->full_name);
-		of_node_put(node);
-	} else {
-		port = of_get_parent(prev);
-		if (!port)
-			/* Hm, has someone given us the root node ?... */
-			return NULL;
-
-		/* Avoid dropping prev node refcount to 0. */
-		of_node_get(prev);
-		endpoint = of_get_next_child(port, prev);
-		if (endpoint) {
-			of_node_put(port);
-			return endpoint;
-		}
-
-		/* No more endpoints under this port, try the next one. */
-		do {
-			port = of_get_next_child(parent, port);
-			if (!port)
-				return NULL;
-		} while (of_node_cmp(port->name, "port"));
-
-		/* Pick up the first endpoint in this port. */
-		endpoint = of_get_next_child(port, NULL);
-		of_node_put(port);
-	}
-
-	return endpoint;
-}
-EXPORT_SYMBOL(v4l2_of_get_next_endpoint);
-
-/**
- * v4l2_of_get_remote_port_parent() - get remote port's parent node
- * @node: pointer to a local endpoint device_node
- *
- * Return: Remote device node associated with remote endpoint node linked
- *	   to @node. Use of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_remote_port_parent(
-			       const struct device_node *node)
-{
-	struct device_node *np;
-	unsigned int depth;
-
-	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
-
-	/* Walk 3 levels up only if there is 'ports' node. */
-	for (depth = 3; depth && np; depth--) {
-		np = of_get_next_parent(np);
-		if (depth == 2 && of_node_cmp(np->name, "ports"))
-			break;
-	}
-	return np;
-}
-EXPORT_SYMBOL(v4l2_of_get_remote_port_parent);
-
-/**
- * v4l2_of_get_remote_port() - get remote port node
- * @node: pointer to a local endpoint device_node
- *
- * Return: Remote port node associated with remote endpoint node linked
- *	   to @node. Use of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_remote_port(const struct device_node *node)
-{
-	struct device_node *np;
-
-	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
-	if (!np)
-		return NULL;
-	return of_get_next_parent(np);
-}
-EXPORT_SYMBOL(v4l2_of_get_remote_port);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 809afeb..1cb7408 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -526,4 +526,5 @@
 source "drivers/misc/vmw_vmci/Kconfig"
 source "drivers/misc/mic/Kconfig"
 source "drivers/misc/genwqe/Kconfig"
+source "drivers/misc/echo/Kconfig"
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 99b9424..7eb4b69 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,3 +54,4 @@
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-y				+= mic/
 obj-$(CONFIG_GENWQE)		+= genwqe/
+obj-$(CONFIG_ECHO)		+= echo/
diff --git a/drivers/staging/echo/Kconfig b/drivers/misc/echo/Kconfig
similarity index 100%
rename from drivers/staging/echo/Kconfig
rename to drivers/misc/echo/Kconfig
diff --git a/drivers/staging/echo/Makefile b/drivers/misc/echo/Makefile
similarity index 100%
rename from drivers/staging/echo/Makefile
rename to drivers/misc/echo/Makefile
diff --git a/drivers/staging/echo/echo.c b/drivers/misc/echo/echo.c
similarity index 100%
rename from drivers/staging/echo/echo.c
rename to drivers/misc/echo/echo.c
diff --git a/drivers/staging/echo/echo.h b/drivers/misc/echo/echo.h
similarity index 100%
rename from drivers/staging/echo/echo.h
rename to drivers/misc/echo/echo.h
diff --git a/drivers/staging/echo/fir.h b/drivers/misc/echo/fir.h
similarity index 100%
rename from drivers/staging/echo/fir.h
rename to drivers/misc/echo/fir.h
diff --git a/drivers/staging/echo/oslec.h b/drivers/misc/echo/oslec.h
similarity index 100%
rename from drivers/staging/echo/oslec.h
rename to drivers/misc/echo/oslec.h
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1b95a40..5f81bfe 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -21,6 +21,7 @@
 #include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
@@ -2014,3 +2015,153 @@
 
 	return NULL;
 }
+
+/**
+ * of_graph_parse_endpoint() - parse common endpoint node properties
+ * @node: pointer to endpoint device_node
+ * @endpoint: pointer to the OF endpoint data structure
+ *
+ * The caller should hold a reference to @node.
+ */
+int of_graph_parse_endpoint(const struct device_node *node,
+			    struct of_endpoint *endpoint)
+{
+	struct device_node *port_node = of_get_parent(node);
+
+	WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n",
+		  __func__, node->full_name);
+
+	memset(endpoint, 0, sizeof(*endpoint));
+
+	endpoint->local_node = node;
+	/*
+	 * It doesn't matter whether the two calls below succeed.
+	 * If they don't then the default value 0 is used.
+	 */
+	of_property_read_u32(port_node, "reg", &endpoint->port);
+	of_property_read_u32(node, "reg", &endpoint->id);
+
+	of_node_put(port_node);
+
+	return 0;
+}
+EXPORT_SYMBOL(of_graph_parse_endpoint);
+
+/**
+ * of_graph_get_next_endpoint() - get next endpoint node
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is not decremented, the caller have to use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
+					struct device_node *prev)
+{
+	struct device_node *endpoint;
+	struct device_node *port = NULL;
+
+	if (!parent)
+		return NULL;
+
+	if (!prev) {
+		struct device_node *node;
+		/*
+		 * It's the first call, we have to find a port subnode
+		 * within this node or within an optional 'ports' node.
+		 */
+		node = of_get_child_by_name(parent, "ports");
+		if (node)
+			parent = node;
+
+		port = of_get_child_by_name(parent, "port");
+
+		if (port) {
+			/* Found a port, get an endpoint. */
+			endpoint = of_get_next_child(port, NULL);
+			of_node_put(port);
+		} else {
+			endpoint = NULL;
+		}
+
+		if (!endpoint)
+			pr_err("%s(): no endpoint nodes specified for %s\n",
+			       __func__, parent->full_name);
+		of_node_put(node);
+
+		return endpoint;
+	}
+
+	port = of_get_parent(prev);
+	if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
+		      __func__, prev->full_name))
+		return NULL;
+
+	/* Avoid dropping prev node refcount to 0. */
+	of_node_get(prev);
+	endpoint = of_get_next_child(port, prev);
+	if (endpoint) {
+		of_node_put(port);
+		return endpoint;
+	}
+
+	/* No more endpoints under this port, try the next one. */
+	do {
+		port = of_get_next_child(parent, port);
+		if (!port)
+			return NULL;
+	} while (of_node_cmp(port->name, "port"));
+
+	/* Pick up the first endpoint in this port. */
+	endpoint = of_get_next_child(port, NULL);
+	of_node_put(port);
+
+	return endpoint;
+}
+EXPORT_SYMBOL(of_graph_get_next_endpoint);
+
+/**
+ * of_graph_get_remote_port_parent() - get remote port's parent node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote device node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_port_parent(
+			       const struct device_node *node)
+{
+	struct device_node *np;
+	unsigned int depth;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+
+	/* Walk 3 levels up only if there is 'ports' node. */
+	for (depth = 3; depth && np; depth--) {
+		np = of_get_next_parent(np);
+		if (depth == 2 && of_node_cmp(np->name, "ports"))
+			break;
+	}
+	return np;
+}
+EXPORT_SYMBOL(of_graph_get_remote_port_parent);
+
+/**
+ * of_graph_get_remote_port() - get remote port node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote port node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_port(const struct device_node *node)
+{
+	struct device_node *np;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!np)
+		return NULL;
+	return of_get_next_parent(np);
+}
+EXPORT_SYMBOL(of_graph_get_remote_port);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 99375f0..47cf175 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -34,8 +34,6 @@
 
 source "drivers/staging/wlan-ng/Kconfig"
 
-source "drivers/staging/echo/Kconfig"
-
 source "drivers/staging/comedi/Kconfig"
 
 source "drivers/staging/olpc_dcon/Kconfig"
@@ -82,8 +80,6 @@
 
 source "drivers/staging/wlags49_h25/Kconfig"
 
-source "drivers/staging/sm7xxfb/Kconfig"
-
 source "drivers/staging/crystalhd/Kconfig"
 
 source "drivers/staging/cxt1e1/Kconfig"
@@ -128,8 +124,6 @@
 
 source "drivers/staging/dgrp/Kconfig"
 
-source "drivers/staging/sb105x/Kconfig"
-
 source "drivers/staging/fwserial/Kconfig"
 
 source "drivers/staging/goldfish/Kconfig"
@@ -146,4 +140,10 @@
 
 source "drivers/staging/dgap/Kconfig"
 
+source "drivers/staging/gs_fpgaboot/Kconfig"
+
+source "drivers/staging/nokia_h4p/Kconfig"
+
+source "drivers/staging/unisys/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ddc3c4a..d12f618 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -9,7 +9,6 @@
 obj-$(CONFIG_USBIP_CORE)	+= usbip/
 obj-$(CONFIG_W35UND)		+= winbond/
 obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
-obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
 obj-$(CONFIG_PANEL)		+= panel/
@@ -35,7 +34,6 @@
 obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_WLAGS49_H2)	+= wlags49_h2/
 obj-$(CONFIG_WLAGS49_H25)	+= wlags49_h25/
-obj-$(CONFIG_FB_SM7XX)		+= sm7xxfb/
 obj-$(CONFIG_CRYSTALHD)		+= crystalhd/
 obj-$(CONFIG_CXT1E1)		+= cxt1e1/
 obj-$(CONFIG_FB_XGI)		+= xgifb/
@@ -57,7 +55,6 @@
 obj-$(CONFIG_CED1401)		+= ced1401/
 obj-$(CONFIG_DRM_IMX)		+= imx-drm/
 obj-$(CONFIG_DGRP)		+= dgrp/
-obj-$(CONFIG_SB105X)		+= sb105x/
 obj-$(CONFIG_FIREWIRE_SERIAL)	+= fwserial/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
 obj-$(CONFIG_LUSTRE_FS)		+= lustre/
@@ -65,3 +62,6 @@
 obj-$(CONFIG_DGNC)			+= dgnc/
 obj-$(CONFIG_DGAP)			+= dgap/
 obj-$(CONFIG_MTD_SPINAND_MT29F)	+= mt29f_spinand/
+obj-$(CONFIG_GS_FPGABOOT)	+= gs_fpgaboot/
+obj-$(CONFIG_BT_NOKIA_H4P)	+= nokia_h4p/
+obj-$(CONFIG_UNISYSSPAR)	+= unisys/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index b91c758..ab28d2b 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -20,6 +20,19 @@
 	  Android process, using Binder to identify, invoke and pass arguments
 	  between said processes.
 
+config ANDROID_BINDER_IPC_32BIT
+	bool
+	depends on !64BIT && ANDROID_BINDER_IPC
+	default y
+	---help---
+	  The Binder API has been changed to support both 32 and 64bit
+	  applications in a mixed environment.
+
+	  Enable this to support an old 32-bit Android user-space (v4.4 and
+	  earlier).
+
+	  Note that enabling this will break newer Android user-space.
+
 config ASHMEM
 	bool "Enable the Anonymous Shared Memory Subsystem"
 	default n
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
index 4fd32f3..495b20c 100644
--- a/drivers/staging/android/android_alarm.h
+++ b/drivers/staging/android/android_alarm.h
@@ -16,50 +16,10 @@
 #ifndef _LINUX_ANDROID_ALARM_H
 #define _LINUX_ANDROID_ALARM_H
 
-#include <linux/ioctl.h>
-#include <linux/time.h>
 #include <linux/compat.h>
+#include <linux/ioctl.h>
 
-enum android_alarm_type {
-	/* return code bit numbers or set alarm arg */
-	ANDROID_ALARM_RTC_WAKEUP,
-	ANDROID_ALARM_RTC,
-	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
-	ANDROID_ALARM_ELAPSED_REALTIME,
-	ANDROID_ALARM_SYSTEMTIME,
-
-	ANDROID_ALARM_TYPE_COUNT,
-
-	/* return code bit numbers */
-	/* ANDROID_ALARM_TIME_CHANGE = 16 */
-};
-
-enum android_alarm_return_flags {
-	ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
-	ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
-	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
-				1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
-	ANDROID_ALARM_ELAPSED_REALTIME_MASK =
-				1U << ANDROID_ALARM_ELAPSED_REALTIME,
-	ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
-	ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
-};
-
-/* Disable alarm */
-#define ANDROID_ALARM_CLEAR(type)           _IO('a', 0 | ((type) << 4))
-
-/* Ack last alarm and wait for next */
-#define ANDROID_ALARM_WAIT                  _IO('a', 1)
-
-#define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
-/* Set alarm */
-#define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
-#define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
-#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
-#define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
-#define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
-#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
-
+#include "uapi/android_alarm.h"
 
 #ifdef CONFIG_COMPAT
 #define ANDROID_ALARM_SET_COMPAT(type)		ALARM_IOW(2, type, \
diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h
index 8dc0f0d..5abcfd7 100644
--- a/drivers/staging/android/ashmem.h
+++ b/drivers/staging/android/ashmem.h
@@ -16,35 +16,7 @@
 #include <linux/ioctl.h>
 #include <linux/compat.h>
 
-#define ASHMEM_NAME_LEN		256
-
-#define ASHMEM_NAME_DEF		"dev/ashmem"
-
-/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
-#define ASHMEM_NOT_PURGED	0
-#define ASHMEM_WAS_PURGED	1
-
-/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */
-#define ASHMEM_IS_UNPINNED	0
-#define ASHMEM_IS_PINNED	1
-
-struct ashmem_pin {
-	__u32 offset;	/* offset into region, in bytes, page-aligned */
-	__u32 len;	/* length forward from offset, in bytes, page-aligned */
-};
-
-#define __ASHMEMIOC		0x77
-
-#define ASHMEM_SET_NAME		_IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
-#define ASHMEM_GET_NAME		_IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
-#define ASHMEM_SET_SIZE		_IOW(__ASHMEMIOC, 3, size_t)
-#define ASHMEM_GET_SIZE		_IO(__ASHMEMIOC, 4)
-#define ASHMEM_SET_PROT_MASK	_IOW(__ASHMEMIOC, 5, unsigned long)
-#define ASHMEM_GET_PROT_MASK	_IO(__ASHMEMIOC, 6)
-#define ASHMEM_PIN		_IOW(__ASHMEMIOC, 7, struct ashmem_pin)
-#define ASHMEM_UNPIN		_IOW(__ASHMEMIOC, 8, struct ashmem_pin)
-#define ASHMEM_GET_PIN_STATUS	_IO(__ASHMEMIOC, 9)
-#define ASHMEM_PURGE_ALL_CACHES	_IO(__ASHMEMIOC, 10)
+#include "uapi/ashmem.h"
 
 /* support of 32bit userspace on 64bit platforms */
 #ifdef CONFIG_COMPAT
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 1432d95..cfe4bc8 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -228,8 +228,8 @@
 	int internal_strong_refs;
 	int local_weak_refs;
 	int local_strong_refs;
-	void __user *ptr;
-	void __user *cookie;
+	binder_uintptr_t ptr;
+	binder_uintptr_t cookie;
 	unsigned has_strong_ref:1;
 	unsigned pending_strong_ref:1;
 	unsigned has_weak_ref:1;
@@ -242,7 +242,7 @@
 
 struct binder_ref_death {
 	struct binder_work work;
-	void __user *cookie;
+	binder_uintptr_t cookie;
 };
 
 struct binder_ref {
@@ -515,14 +515,14 @@
 }
 
 static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc,
-						  void __user *user_ptr)
+						  uintptr_t user_ptr)
 {
 	struct rb_node *n = proc->allocated_buffers.rb_node;
 	struct binder_buffer *buffer;
 	struct binder_buffer *kern_ptr;
 
-	kern_ptr = user_ptr - proc->user_buffer_offset
-		- offsetof(struct binder_buffer, data);
+	kern_ptr = (struct binder_buffer *)(user_ptr - proc->user_buffer_offset
+		- offsetof(struct binder_buffer, data));
 
 	while (n) {
 		buffer = rb_entry(n, struct binder_buffer, rb_node);
@@ -856,7 +856,7 @@
 }
 
 static struct binder_node *binder_get_node(struct binder_proc *proc,
-					   void __user *ptr)
+					   binder_uintptr_t ptr)
 {
 	struct rb_node *n = proc->nodes.rb_node;
 	struct binder_node *node;
@@ -875,8 +875,8 @@
 }
 
 static struct binder_node *binder_new_node(struct binder_proc *proc,
-					   void __user *ptr,
-					   void __user *cookie)
+					   binder_uintptr_t ptr,
+					   binder_uintptr_t cookie)
 {
 	struct rb_node **p = &proc->nodes.rb_node;
 	struct rb_node *parent = NULL;
@@ -908,9 +908,9 @@
 	INIT_LIST_HEAD(&node->work.entry);
 	INIT_LIST_HEAD(&node->async_todo);
 	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-		     "%d:%d node %d u%p c%p created\n",
+		     "%d:%d node %d u%016llx c%016llx created\n",
 		     proc->pid, current->pid, node->debug_id,
-		     node->ptr, node->cookie);
+		     (u64)node->ptr, (u64)node->cookie);
 	return node;
 }
 
@@ -1226,9 +1226,9 @@
 
 static void binder_transaction_buffer_release(struct binder_proc *proc,
 					      struct binder_buffer *buffer,
-					      size_t *failed_at)
+					      binder_size_t *failed_at)
 {
-	size_t *offp, *off_end;
+	binder_size_t *offp, *off_end;
 	int debug_id = buffer->debug_id;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1239,7 +1239,8 @@
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
-	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+	offp = (binder_size_t *)(buffer->data +
+				 ALIGN(buffer->data_size, sizeof(void *)));
 	if (failed_at)
 		off_end = failed_at;
 	else
@@ -1249,8 +1250,8 @@
 		if (*offp > buffer->data_size - sizeof(*fp) ||
 		    buffer->data_size < sizeof(*fp) ||
 		    !IS_ALIGNED(*offp, sizeof(u32))) {
-			pr_err("transaction release %d bad offset %zd, size %zd\n",
-			 debug_id, *offp, buffer->data_size);
+			pr_err("transaction release %d bad offset %lld, size %zd\n",
+			       debug_id, (u64)*offp, buffer->data_size);
 			continue;
 		}
 		fp = (struct flat_binder_object *)(buffer->data + *offp);
@@ -1259,13 +1260,13 @@
 		case BINDER_TYPE_WEAK_BINDER: {
 			struct binder_node *node = binder_get_node(proc, fp->binder);
 			if (node == NULL) {
-				pr_err("transaction release %d bad node %p\n",
-					debug_id, fp->binder);
+				pr_err("transaction release %d bad node %016llx\n",
+				       debug_id, (u64)fp->binder);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        node %d u%p\n",
-				     node->debug_id, node->ptr);
+				     "        node %d u%016llx\n",
+				     node->debug_id, (u64)node->ptr);
 			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
 		} break;
 		case BINDER_TYPE_HANDLE:
@@ -1303,7 +1304,7 @@
 {
 	struct binder_transaction *t;
 	struct binder_work *tcomplete;
-	size_t *offp, *off_end;
+	binder_size_t *offp, *off_end;
 	struct binder_proc *target_proc;
 	struct binder_thread *target_thread = NULL;
 	struct binder_node *target_node = NULL;
@@ -1432,18 +1433,20 @@
 
 	if (reply)
 		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "%d:%d BC_REPLY %d -> %d:%d, data %p-%p size %zd-%zd\n",
+			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_thread->pid,
-			     tr->data.ptr.buffer, tr->data.ptr.offsets,
-			     tr->data_size, tr->offsets_size);
+			     (u64)tr->data.ptr.buffer,
+			     (u64)tr->data.ptr.offsets,
+			     (u64)tr->data_size, (u64)tr->offsets_size);
 	else
 		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %p-%p size %zd-%zd\n",
+			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_node->debug_id,
-			     tr->data.ptr.buffer, tr->data.ptr.offsets,
-			     tr->data_size, tr->offsets_size);
+			     (u64)tr->data.ptr.buffer,
+			     (u64)tr->data.ptr.offsets,
+			     (u64)tr->data_size, (u64)tr->offsets_size);
 
 	if (!reply && !(tr->flags & TF_ONE_WAY))
 		t->from = thread;
@@ -1472,23 +1475,26 @@
 	if (target_node)
 		binder_inc_node(target_node, 1, 0, NULL);
 
-	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
+	offp = (binder_size_t *)(t->buffer->data +
+				 ALIGN(tr->data_size, sizeof(void *)));
 
-	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
+	if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
+			   tr->data.ptr.buffer, tr->data_size)) {
 		binder_user_error("%d:%d got transaction with invalid data ptr\n",
 				proc->pid, thread->pid);
 		return_error = BR_FAILED_REPLY;
 		goto err_copy_data_failed;
 	}
-	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
+	if (copy_from_user(offp, (const void __user *)(uintptr_t)
+			   tr->data.ptr.offsets, tr->offsets_size)) {
 		binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
 				proc->pid, thread->pid);
 		return_error = BR_FAILED_REPLY;
 		goto err_copy_data_failed;
 	}
-	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
-		binder_user_error("%d:%d got transaction with invalid offsets size, %zd\n",
-				proc->pid, thread->pid, tr->offsets_size);
+	if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
+		binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n",
+				proc->pid, thread->pid, (u64)tr->offsets_size);
 		return_error = BR_FAILED_REPLY;
 		goto err_bad_offset;
 	}
@@ -1498,8 +1504,8 @@
 		if (*offp > t->buffer->data_size - sizeof(*fp) ||
 		    t->buffer->data_size < sizeof(*fp) ||
 		    !IS_ALIGNED(*offp, sizeof(u32))) {
-			binder_user_error("%d:%d got transaction with invalid offset, %zd\n",
-					proc->pid, thread->pid, *offp);
+			binder_user_error("%d:%d got transaction with invalid offset, %lld\n",
+					  proc->pid, thread->pid, (u64)*offp);
 			return_error = BR_FAILED_REPLY;
 			goto err_bad_offset;
 		}
@@ -1519,10 +1525,10 @@
 				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
 			}
 			if (fp->cookie != node->cookie) {
-				binder_user_error("%d:%d sending u%p node %d, cookie mismatch %p != %p\n",
+				binder_user_error("%d:%d sending u%016llx node %d, cookie mismatch %016llx != %016llx\n",
 					proc->pid, thread->pid,
-					fp->binder, node->debug_id,
-					fp->cookie, node->cookie);
+					(u64)fp->binder, node->debug_id,
+					(u64)fp->cookie, (u64)node->cookie);
 				goto err_binder_get_ref_for_node_failed;
 			}
 			ref = binder_get_ref_for_node(target_proc, node);
@@ -1540,9 +1546,9 @@
 
 			trace_binder_transaction_node_to_ref(t, node, ref);
 			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        node %d u%p -> ref %d desc %d\n",
-				     node->debug_id, node->ptr, ref->debug_id,
-				     ref->desc);
+				     "        node %d u%016llx -> ref %d desc %d\n",
+				     node->debug_id, (u64)node->ptr,
+				     ref->debug_id, ref->desc);
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
@@ -1564,9 +1570,9 @@
 				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
 				trace_binder_transaction_ref_to_node(t, ref);
 				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> node %d u%p\n",
+					     "        ref %d desc %d -> node %d u%016llx\n",
 					     ref->debug_id, ref->desc, ref->node->debug_id,
-					     ref->node->ptr);
+					     (u64)ref->node->ptr);
 			} else {
 				struct binder_ref *new_ref;
 				new_ref = binder_get_ref_for_node(target_proc, ref->node);
@@ -1682,9 +1688,9 @@
 err_invalid_target_handle:
 err_no_context_mgr_node:
 	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-		     "%d:%d transaction failed %d, size %zd-%zd\n",
+		     "%d:%d transaction failed %d, size %lld-%lld\n",
 		     proc->pid, thread->pid, return_error,
-		     tr->data_size, tr->offsets_size);
+		     (u64)tr->data_size, (u64)tr->offsets_size);
 
 	{
 		struct binder_transaction_log_entry *fe;
@@ -1702,9 +1708,11 @@
 
 static int binder_thread_write(struct binder_proc *proc,
 			struct binder_thread *thread,
-			void __user *buffer, size_t size, size_t *consumed)
+			binder_uintptr_t binder_buffer, size_t size,
+			binder_size_t *consumed)
 {
 	uint32_t cmd;
+	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
 	void __user *ptr = buffer + *consumed;
 	void __user *end = buffer + size;
 
@@ -1773,33 +1781,33 @@
 		}
 		case BC_INCREFS_DONE:
 		case BC_ACQUIRE_DONE: {
-			void __user *node_ptr;
-			void __user *cookie;
+			binder_uintptr_t node_ptr;
+			binder_uintptr_t cookie;
 			struct binder_node *node;
 
-			if (get_user(node_ptr, (void * __user *)ptr))
+			if (get_user(node_ptr, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
-			ptr += sizeof(void *);
-			if (get_user(cookie, (void * __user *)ptr))
+			ptr += sizeof(binder_uintptr_t);
+			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
-			ptr += sizeof(void *);
+			ptr += sizeof(binder_uintptr_t);
 			node = binder_get_node(proc, node_ptr);
 			if (node == NULL) {
-				binder_user_error("%d:%d %s u%p no match\n",
+				binder_user_error("%d:%d %s u%016llx no match\n",
 					proc->pid, thread->pid,
 					cmd == BC_INCREFS_DONE ?
 					"BC_INCREFS_DONE" :
 					"BC_ACQUIRE_DONE",
-					node_ptr);
+					(u64)node_ptr);
 				break;
 			}
 			if (cookie != node->cookie) {
-				binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != %p\n",
+				binder_user_error("%d:%d %s u%016llx node %d cookie mismatch %016llx != %016llx\n",
 					proc->pid, thread->pid,
 					cmd == BC_INCREFS_DONE ?
 					"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
-					node_ptr, node->debug_id,
-					cookie, node->cookie);
+					(u64)node_ptr, node->debug_id,
+					(u64)cookie, (u64)node->cookie);
 				break;
 			}
 			if (cmd == BC_ACQUIRE_DONE) {
@@ -1835,27 +1843,28 @@
 			return -EINVAL;
 
 		case BC_FREE_BUFFER: {
-			void __user *data_ptr;
+			binder_uintptr_t data_ptr;
 			struct binder_buffer *buffer;
 
-			if (get_user(data_ptr, (void * __user *)ptr))
+			if (get_user(data_ptr, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
-			ptr += sizeof(void *);
+			ptr += sizeof(binder_uintptr_t);
 
 			buffer = binder_buffer_lookup(proc, data_ptr);
 			if (buffer == NULL) {
-				binder_user_error("%d:%d BC_FREE_BUFFER u%p no match\n",
-					proc->pid, thread->pid, data_ptr);
+				binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n",
+					proc->pid, thread->pid, (u64)data_ptr);
 				break;
 			}
 			if (!buffer->allow_user_free) {
-				binder_user_error("%d:%d BC_FREE_BUFFER u%p matched unreturned buffer\n",
-					proc->pid, thread->pid, data_ptr);
+				binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n",
+					proc->pid, thread->pid, (u64)data_ptr);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_FREE_BUFFER,
-				     "%d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
-				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
+				     "%d:%d BC_FREE_BUFFER u%016llx found buffer %d for %s transaction\n",
+				     proc->pid, thread->pid, (u64)data_ptr,
+				     buffer->debug_id,
 				     buffer->transaction ? "active" : "finished");
 
 			if (buffer->transaction) {
@@ -1925,16 +1934,16 @@
 		case BC_REQUEST_DEATH_NOTIFICATION:
 		case BC_CLEAR_DEATH_NOTIFICATION: {
 			uint32_t target;
-			void __user *cookie;
+			binder_uintptr_t cookie;
 			struct binder_ref *ref;
 			struct binder_ref_death *death;
 
 			if (get_user(target, (uint32_t __user *)ptr))
 				return -EFAULT;
 			ptr += sizeof(uint32_t);
-			if (get_user(cookie, (void __user * __user *)ptr))
+			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
-			ptr += sizeof(void *);
+			ptr += sizeof(binder_uintptr_t);
 			ref = binder_get_ref(proc, target);
 			if (ref == NULL) {
 				binder_user_error("%d:%d %s invalid ref %d\n",
@@ -1947,12 +1956,12 @@
 			}
 
 			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "%d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+				     "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d\n",
 				     proc->pid, thread->pid,
 				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
 				     "BC_REQUEST_DEATH_NOTIFICATION" :
 				     "BC_CLEAR_DEATH_NOTIFICATION",
-				     cookie, ref->debug_id, ref->desc,
+				     (u64)cookie, ref->debug_id, ref->desc,
 				     ref->strong, ref->weak, ref->node->debug_id);
 
 			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
@@ -1990,9 +1999,10 @@
 				}
 				death = ref->death;
 				if (death->cookie != cookie) {
-					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n",
+					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %016llx != %016llx\n",
 						proc->pid, thread->pid,
-						death->cookie, cookie);
+						(u64)death->cookie,
+						(u64)cookie);
 					break;
 				}
 				ref->death = NULL;
@@ -2012,9 +2022,9 @@
 		} break;
 		case BC_DEAD_BINDER_DONE: {
 			struct binder_work *w;
-			void __user *cookie;
+			binder_uintptr_t cookie;
 			struct binder_ref_death *death = NULL;
-			if (get_user(cookie, (void __user * __user *)ptr))
+			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
 
 			ptr += sizeof(void *);
@@ -2026,11 +2036,12 @@
 				}
 			}
 			binder_debug(BINDER_DEBUG_DEAD_BINDER,
-				     "%d:%d BC_DEAD_BINDER_DONE %p found %p\n",
-				     proc->pid, thread->pid, cookie, death);
+				     "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
+				     proc->pid, thread->pid, (u64)cookie,
+				     death);
 			if (death == NULL) {
-				binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n",
-					proc->pid, thread->pid, cookie);
+				binder_user_error("%d:%d BC_DEAD_BINDER_DONE %016llx not found\n",
+					proc->pid, thread->pid, (u64)cookie);
 				break;
 			}
 
@@ -2082,9 +2093,10 @@
 
 static int binder_thread_read(struct binder_proc *proc,
 			      struct binder_thread *thread,
-			      void  __user *buffer, size_t size,
-			      size_t *consumed, int non_block)
+			      binder_uintptr_t binder_buffer, size_t size,
+			      binder_size_t *consumed, int non_block)
 {
+	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
 	void __user *ptr = buffer + *consumed;
 	void __user *end = buffer + size;
 
@@ -2229,32 +2241,40 @@
 				if (put_user(cmd, (uint32_t __user *)ptr))
 					return -EFAULT;
 				ptr += sizeof(uint32_t);
-				if (put_user(node->ptr, (void * __user *)ptr))
+				if (put_user(node->ptr,
+					     (binder_uintptr_t __user *)ptr))
 					return -EFAULT;
-				ptr += sizeof(void *);
-				if (put_user(node->cookie, (void * __user *)ptr))
+				ptr += sizeof(binder_uintptr_t);
+				if (put_user(node->cookie,
+					     (binder_uintptr_t __user *)ptr))
 					return -EFAULT;
-				ptr += sizeof(void *);
+				ptr += sizeof(binder_uintptr_t);
 
 				binder_stat_br(proc, thread, cmd);
 				binder_debug(BINDER_DEBUG_USER_REFS,
-					     "%d:%d %s %d u%p c%p\n",
-					     proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
+					     "%d:%d %s %d u%016llx c%016llx\n",
+					     proc->pid, thread->pid, cmd_name,
+					     node->debug_id,
+					     (u64)node->ptr, (u64)node->cookie);
 			} else {
 				list_del_init(&w->entry);
 				if (!weak && !strong) {
 					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-						     "%d:%d node %d u%p c%p deleted\n",
-						     proc->pid, thread->pid, node->debug_id,
-						     node->ptr, node->cookie);
+						     "%d:%d node %d u%016llx c%016llx deleted\n",
+						     proc->pid, thread->pid,
+						     node->debug_id,
+						     (u64)node->ptr,
+						     (u64)node->cookie);
 					rb_erase(&node->rb_node, &proc->nodes);
 					kfree(node);
 					binder_stats_deleted(BINDER_STAT_NODE);
 				} else {
 					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-						     "%d:%d node %d u%p c%p state unchanged\n",
-						     proc->pid, thread->pid, node->debug_id, node->ptr,
-						     node->cookie);
+						     "%d:%d node %d u%016llx c%016llx state unchanged\n",
+						     proc->pid, thread->pid,
+						     node->debug_id,
+						     (u64)node->ptr,
+						     (u64)node->cookie);
 				}
 			}
 		} break;
@@ -2272,17 +2292,18 @@
 			if (put_user(cmd, (uint32_t __user *)ptr))
 				return -EFAULT;
 			ptr += sizeof(uint32_t);
-			if (put_user(death->cookie, (void * __user *)ptr))
+			if (put_user(death->cookie,
+				     (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
-			ptr += sizeof(void *);
+			ptr += sizeof(binder_uintptr_t);
 			binder_stat_br(proc, thread, cmd);
 			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "%d:%d %s %p\n",
+				     "%d:%d %s %016llx\n",
 				      proc->pid, thread->pid,
 				      cmd == BR_DEAD_BINDER ?
 				      "BR_DEAD_BINDER" :
 				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
-				      death->cookie);
+				      (u64)death->cookie);
 
 			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
 				list_del(&w->entry);
@@ -2312,8 +2333,8 @@
 				binder_set_nice(target_node->min_priority);
 			cmd = BR_TRANSACTION;
 		} else {
-			tr.target.ptr = NULL;
-			tr.cookie = NULL;
+			tr.target.ptr = 0;
+			tr.cookie = 0;
 			cmd = BR_REPLY;
 		}
 		tr.code = t->code;
@@ -2330,8 +2351,9 @@
 
 		tr.data_size = t->buffer->data_size;
 		tr.offsets_size = t->buffer->offsets_size;
-		tr.data.ptr.buffer = (void *)t->buffer->data +
-					proc->user_buffer_offset;
+		tr.data.ptr.buffer = (binder_uintptr_t)(
+					(uintptr_t)t->buffer->data +
+					proc->user_buffer_offset);
 		tr.data.ptr.offsets = tr.data.ptr.buffer +
 					ALIGN(t->buffer->data_size,
 					    sizeof(void *));
@@ -2346,14 +2368,14 @@
 		trace_binder_transaction_received(t);
 		binder_stat_br(proc, thread, cmd);
 		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %p-%p\n",
+			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n",
 			     proc->pid, thread->pid,
 			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
 			     "BR_REPLY",
 			     t->debug_id, t->from ? t->from->proc->pid : 0,
 			     t->from ? t->from->pid : 0, cmd,
 			     t->buffer->data_size, t->buffer->offsets_size,
-			     tr.data.ptr.buffer, tr.data.ptr.offsets);
+			     (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets);
 
 		list_del(&t->work.entry);
 		t->buffer->allow_user_free = 1;
@@ -2423,8 +2445,8 @@
 
 			death = container_of(w, struct binder_ref_death, work);
 			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
-				"undelivered death notification, %p\n",
-				death->cookie);
+				"undelivered death notification, %016llx\n",
+				(u64)death->cookie);
 			kfree(death);
 			binder_stats_deleted(BINDER_STAT_DEATH);
 		} break;
@@ -2580,12 +2602,16 @@
 			goto err;
 		}
 		binder_debug(BINDER_DEBUG_READ_WRITE,
-			     "%d:%d write %zd at %016lx, read %zd at %016lx\n",
-			     proc->pid, thread->pid, bwr.write_size,
-			     bwr.write_buffer, bwr.read_size, bwr.read_buffer);
+			     "%d:%d write %lld at %016llx, read %lld at %016llx\n",
+			     proc->pid, thread->pid,
+			     (u64)bwr.write_size, (u64)bwr.write_buffer,
+			     (u64)bwr.read_size, (u64)bwr.read_buffer);
 
 		if (bwr.write_size > 0) {
-			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
+			ret = binder_thread_write(proc, thread,
+						  bwr.write_buffer,
+						  bwr.write_size,
+						  &bwr.write_consumed);
 			trace_binder_write_done(ret);
 			if (ret < 0) {
 				bwr.read_consumed = 0;
@@ -2595,7 +2621,10 @@
 			}
 		}
 		if (bwr.read_size > 0) {
-			ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
+			ret = binder_thread_read(proc, thread, bwr.read_buffer,
+						 bwr.read_size,
+						 &bwr.read_consumed,
+						 filp->f_flags & O_NONBLOCK);
 			trace_binder_read_done(ret);
 			if (!list_empty(&proc->todo))
 				wake_up_interruptible(&proc->wait);
@@ -2606,9 +2635,10 @@
 			}
 		}
 		binder_debug(BINDER_DEBUG_READ_WRITE,
-			     "%d:%d wrote %zd of %zd, read return %zd of %zd\n",
-			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
-			     bwr.read_consumed, bwr.read_size);
+			     "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
+			     proc->pid, thread->pid,
+			     (u64)bwr.write_consumed, (u64)bwr.write_size,
+			     (u64)bwr.read_consumed, (u64)bwr.read_size);
 		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
 			ret = -EFAULT;
 			goto err;
@@ -2637,7 +2667,7 @@
 			}
 		} else
 			binder_context_mgr_uid = current->cred->euid;
-		binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
+		binder_context_mgr_node = binder_new_node(proc, 0, 0);
 		if (binder_context_mgr_node == NULL) {
 			ret = -ENOMEM;
 			goto err;
@@ -3132,8 +3162,9 @@
 		break;
 	case BINDER_WORK_NODE:
 		node = container_of(w, struct binder_node, work);
-		seq_printf(m, "%snode work %d: u%p c%p\n",
-			   prefix, node->debug_id, node->ptr, node->cookie);
+		seq_printf(m, "%snode work %d: u%016llx c%016llx\n",
+			   prefix, node->debug_id,
+			   (u64)node->ptr, (u64)node->cookie);
 		break;
 	case BINDER_WORK_DEAD_BINDER:
 		seq_printf(m, "%shas dead binder\n", prefix);
@@ -3193,8 +3224,8 @@
 	hlist_for_each_entry(ref, &node->refs, node_entry)
 		count++;
 
-	seq_printf(m, "  node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d",
-		   node->debug_id, node->ptr, node->cookie,
+	seq_printf(m, "  node %d: u%016llx c%016llx hs %d hw %d ls %d lw %d is %d iw %d",
+		   node->debug_id, (u64)node->ptr, (u64)node->cookie,
 		   node->has_strong_ref, node->has_weak_ref,
 		   node->local_strong_refs, node->local_weak_refs,
 		   node->internal_strong_refs, count);
@@ -3496,6 +3527,7 @@
 	.owner = THIS_MODULE,
 	.poll = binder_poll,
 	.unlocked_ioctl = binder_ioctl,
+	.compat_ioctl = binder_ioctl,
 	.mmap = binder_mmap,
 	.open = binder_open,
 	.flush = binder_flush,
diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h
index cbe3451..eb08346 100644
--- a/drivers/staging/android/binder.h
+++ b/drivers/staging/android/binder.h
@@ -20,311 +20,11 @@
 #ifndef _LINUX_BINDER_H
 #define _LINUX_BINDER_H
 
-#include <linux/ioctl.h>
+#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
+#define BINDER_IPC_32BIT 1
+#endif
 
-#define B_PACK_CHARS(c1, c2, c3, c4) \
-	((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
-#define B_TYPE_LARGE 0x85
-
-enum {
-	BINDER_TYPE_BINDER	= B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
-	BINDER_TYPE_WEAK_BINDER	= B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
-	BINDER_TYPE_HANDLE	= B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
-	BINDER_TYPE_WEAK_HANDLE	= B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
-	BINDER_TYPE_FD		= B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
-};
-
-enum {
-	FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
-	FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
-};
-
-/*
- * This is the flattened representation of a Binder object for transfer
- * between processes.  The 'offsets' supplied as part of a binder transaction
- * contains offsets into the data where these structures occur.  The Binder
- * driver takes care of re-writing the structure type and data as it moves
- * between processes.
- */
-struct flat_binder_object {
-	/* 8 bytes for large_flat_header. */
-	__u32		type;
-	__u32		flags;
-
-	/* 8 bytes of data. */
-	union {
-		void __user	*binder;	/* local object */
-		__u32	    handle;		/* remote object */
-	};
-
-	/* extra data associated with local object */
-	void __user		*cookie;
-};
-
-/*
- * On 64-bit platforms where user code may run in 32-bits the driver must
- * translate the buffer (and local binder) addresses appropriately.
- */
-
-struct binder_write_read {
-	size_t write_size;	/* bytes to write */
-	size_t write_consumed;	/* bytes consumed by driver */
-	unsigned long	write_buffer;
-	size_t read_size;	/* bytes to read */
-	size_t read_consumed;	/* bytes consumed by driver */
-	unsigned long	read_buffer;
-};
-
-/* Use with BINDER_VERSION, driver fills in fields. */
-struct binder_version {
-	/* driver protocol version -- increment with incompatible change */
-	__s32       protocol_version;
-};
-
-/* This is the current protocol version. */
-#define BINDER_CURRENT_PROTOCOL_VERSION 7
-
-#define BINDER_WRITE_READ		_IOWR('b', 1, struct binder_write_read)
-#define	BINDER_SET_IDLE_TIMEOUT		_IOW('b', 3, __s64)
-#define	BINDER_SET_MAX_THREADS		_IOW('b', 5, __u32)
-#define	BINDER_SET_IDLE_PRIORITY	_IOW('b', 6, __s32)
-#define	BINDER_SET_CONTEXT_MGR		_IOW('b', 7, __s32)
-#define	BINDER_THREAD_EXIT		_IOW('b', 8, __s32)
-#define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
-
-/*
- * NOTE: Two special error codes you should check for when calling
- * in to the driver are:
- *
- * EINTR -- The operation has been interupted.  This should be
- * handled by retrying the ioctl() until a different error code
- * is returned.
- *
- * ECONNREFUSED -- The driver is no longer accepting operations
- * from your process.  That is, the process is being destroyed.
- * You should handle this by exiting from your process.  Note
- * that once this error code is returned, all further calls to
- * the driver from any thread will return this same code.
- */
-
-enum transaction_flags {
-	TF_ONE_WAY	= 0x01,	/* this is a one-way call: async, no return */
-	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
-	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
-	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
-};
-
-struct binder_transaction_data {
-	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
-	 * identifying the target and contents of the transaction.
-	 */
-	union {
-		__u32	handle;	/* target descriptor of command transaction */
-		void	*ptr;	/* target descriptor of return transaction */
-	} target;
-	void		*cookie;	/* target object cookie */
-	__u32		code;		/* transaction command */
-
-	/* General information about the transaction. */
-	__u32	        flags;
-	pid_t		sender_pid;
-	uid_t		sender_euid;
-	size_t		data_size;	/* number of bytes of data */
-	size_t		offsets_size;	/* number of bytes of offsets */
-
-	/* If this transaction is inline, the data immediately
-	 * follows here; otherwise, it ends with a pointer to
-	 * the data buffer.
-	 */
-	union {
-		struct {
-			/* transaction data */
-			const void __user	*buffer;
-			/* offsets from buffer to flat_binder_object structs */
-			const void __user	*offsets;
-		} ptr;
-		__u8	buf[8];
-	} data;
-};
-
-struct binder_ptr_cookie {
-	void *ptr;
-	void *cookie;
-};
-
-struct binder_pri_desc {
-	__s32 priority;
-	__u32 desc;
-};
-
-struct binder_pri_ptr_cookie {
-	__s32 priority;
-	void *ptr;
-	void *cookie;
-};
-
-enum binder_driver_return_protocol {
-	BR_ERROR = _IOR('r', 0, __s32),
-	/*
-	 * int: error code
-	 */
-
-	BR_OK = _IO('r', 1),
-	/* No parameters! */
-
-	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
-	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
-	/*
-	 * binder_transaction_data: the received command.
-	 */
-
-	BR_ACQUIRE_RESULT = _IOR('r', 4, __s32),
-	/*
-	 * not currently supported
-	 * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
-	 * Else the remote object has acquired a primary reference.
-	 */
-
-	BR_DEAD_REPLY = _IO('r', 5),
-	/*
-	 * The target of the last transaction (either a bcTRANSACTION or
-	 * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
-	 */
-
-	BR_TRANSACTION_COMPLETE = _IO('r', 6),
-	/*
-	 * No parameters... always refers to the last transaction requested
-	 * (including replies).  Note that this will be sent even for
-	 * asynchronous transactions.
-	 */
-
-	BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
-	BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
-	BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
-	BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
-	/*
-	 * void *:	ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
-	/*
-	 * not currently supported
-	 * int:	priority
-	 * void *: ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BR_NOOP = _IO('r', 12),
-	/*
-	 * No parameters.  Do nothing and examine the next command.  It exists
-	 * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
-	 */
-
-	BR_SPAWN_LOOPER = _IO('r', 13),
-	/*
-	 * No parameters.  The driver has determined that a process has no
-	 * threads waiting to service incoming transactions.  When a process
-	 * receives this command, it must spawn a new service thread and
-	 * register it via bcENTER_LOOPER.
-	 */
-
-	BR_FINISHED = _IO('r', 14),
-	/*
-	 * not currently supported
-	 * stop threadpool thread
-	 */
-
-	BR_DEAD_BINDER = _IOR('r', 15, void *),
-	/*
-	 * void *: cookie
-	 */
-	BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *),
-	/*
-	 * void *: cookie
-	 */
-
-	BR_FAILED_REPLY = _IO('r', 17),
-	/*
-	 * The the last transaction (either a bcTRANSACTION or
-	 * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
-	 */
-};
-
-enum binder_driver_command_protocol {
-	BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
-	BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
-	/*
-	 * binder_transaction_data: the sent command.
-	 */
-
-	BC_ACQUIRE_RESULT = _IOW('c', 2, __s32),
-	/*
-	 * not currently supported
-	 * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
-	 * Else you have acquired a primary reference on the object.
-	 */
-
-	BC_FREE_BUFFER = _IOW('c', 3, void *),
-	/*
-	 * void *: ptr to transaction data received on a read
-	 */
-
-	BC_INCREFS = _IOW('c', 4, __u32),
-	BC_ACQUIRE = _IOW('c', 5, __u32),
-	BC_RELEASE = _IOW('c', 6, __u32),
-	BC_DECREFS = _IOW('c', 7, __u32),
-	/*
-	 * int:	descriptor
-	 */
-
-	BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
-	BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
-	/*
-	 * not currently supported
-	 * int: priority
-	 * int: descriptor
-	 */
-
-	BC_REGISTER_LOOPER = _IO('c', 11),
-	/*
-	 * No parameters.
-	 * Register a spawned looper thread with the device.
-	 */
-
-	BC_ENTER_LOOPER = _IO('c', 12),
-	BC_EXIT_LOOPER = _IO('c', 13),
-	/*
-	 * No parameters.
-	 * These two commands are sent as an application-level thread
-	 * enters and exits the binder loop, respectively.  They are
-	 * used so the binder can have an accurate count of the number
-	 * of looping threads it has available.
-	 */
-
-	BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie
-	 */
-
-	BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie
-	 */
-
-	BC_DEAD_BINDER_DONE = _IOW('c', 16, void *),
-	/*
-	 * void *: cookie
-	 */
-};
+#include "uapi/binder.h"
 
 #endif /* _LINUX_BINDER_H */
 
diff --git a/drivers/staging/android/binder_trace.h b/drivers/staging/android/binder_trace.h
index 82a567c..7f20f3d 100644
--- a/drivers/staging/android/binder_trace.h
+++ b/drivers/staging/android/binder_trace.h
@@ -152,7 +152,7 @@
 	TP_STRUCT__entry(
 		__field(int, debug_id)
 		__field(int, node_debug_id)
-		__field(void __user *, node_ptr)
+		__field(binder_uintptr_t, node_ptr)
 		__field(int, ref_debug_id)
 		__field(uint32_t, ref_desc)
 	),
@@ -163,8 +163,9 @@
 		__entry->ref_debug_id = ref->debug_id;
 		__entry->ref_desc = ref->desc;
 	),
-	TP_printk("transaction=%d node=%d src_ptr=0x%p ==> dest_ref=%d dest_desc=%d",
-		  __entry->debug_id, __entry->node_debug_id, __entry->node_ptr,
+	TP_printk("transaction=%d node=%d src_ptr=0x%016llx ==> dest_ref=%d dest_desc=%d",
+		  __entry->debug_id, __entry->node_debug_id,
+		  (u64)__entry->node_ptr,
 		  __entry->ref_debug_id, __entry->ref_desc)
 );
 
@@ -177,7 +178,7 @@
 		__field(int, ref_debug_id)
 		__field(uint32_t, ref_desc)
 		__field(int, node_debug_id)
-		__field(void __user *, node_ptr)
+		__field(binder_uintptr_t, node_ptr)
 	),
 	TP_fast_assign(
 		__entry->debug_id = t->debug_id;
@@ -186,9 +187,10 @@
 		__entry->node_debug_id = ref->node->debug_id;
 		__entry->node_ptr = ref->node->ptr;
 	),
-	TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%p",
+	TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%016llx",
 		  __entry->debug_id, __entry->node_debug_id,
-		  __entry->ref_debug_id, __entry->ref_desc, __entry->node_ptr)
+		  __entry->ref_debug_id, __entry->ref_desc,
+		  (u64)__entry->node_ptr)
 );
 
 TRACE_EVENT(binder_transaction_ref_to_ref,
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 574066f..3d5bf14 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -16,6 +16,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/file.h>
 #include <linux/freezer.h>
 #include <linux/fs.h>
@@ -55,10 +56,12 @@
 	struct mutex buffer_lock;
 	struct rw_semaphore lock;
 	struct plist_head heaps;
-	long (*custom_ioctl) (struct ion_client *client, unsigned int cmd,
-			      unsigned long arg);
+	long (*custom_ioctl)(struct ion_client *client, unsigned int cmd,
+			     unsigned long arg);
 	struct rb_root clients;
 	struct dentry *debug_root;
+	struct dentry *heaps_debug_root;
+	struct dentry *clients_debug_root;
 };
 
 /**
@@ -69,6 +72,8 @@
  * @idr:		an idr space for allocating handle ids
  * @lock:		lock protecting the tree of handles
  * @name:		used for debugging
+ * @display_name:	used for debugging (unique version of @name)
+ * @display_serial:	used for debugging (to make display_name unique)
  * @task:		used for debugging
  *
  * A client represents a list of buffers this client may access.
@@ -82,6 +87,8 @@
 	struct idr idr;
 	struct mutex lock;
 	const char *name;
+	char *display_name;
+	int display_serial;
 	struct task_struct *task;
 	pid_t pid;
 	struct dentry *debug_root;
@@ -208,7 +215,7 @@
 	if (IS_ERR(table)) {
 		heap->ops->free(buffer);
 		kfree(buffer);
-		return ERR_PTR(PTR_ERR(table));
+		return ERR_CAST(table);
 	}
 	buffer->sg_table = table;
 	if (ion_buffer_fault_user_mappings(buffer)) {
@@ -429,7 +436,7 @@
 				struct ion_handle *handle)
 {
 	WARN_ON(!mutex_is_locked(&client->lock));
-	return (idr_find(&client->idr, handle->id) == handle);
+	return idr_find(&client->idr, handle->id) == handle;
 }
 
 static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
@@ -501,7 +508,7 @@
 		return ERR_PTR(-ENODEV);
 
 	if (IS_ERR(buffer))
-		return ERR_PTR(PTR_ERR(buffer));
+		return ERR_CAST(buffer);
 
 	handle = ion_handle_create(client, buffer);
 
@@ -708,6 +715,21 @@
 	.release = single_release,
 };
 
+static int ion_get_client_serial(const struct rb_root *root,
+					const unsigned char *name)
+{
+	int serial = -1;
+	struct rb_node *node;
+	for (node = rb_first(root); node; node = rb_next(node)) {
+		struct ion_client *client = rb_entry(node, struct ion_client,
+						node);
+		if (strcmp(client->name, name))
+			continue;
+		serial = max(serial, client->display_serial);
+	}
+	return serial + 1;
+}
+
 struct ion_client *ion_client_create(struct ion_device *dev,
 				     const char *name)
 {
@@ -716,9 +738,13 @@
 	struct rb_node **p;
 	struct rb_node *parent = NULL;
 	struct ion_client *entry;
-	char debug_name[64];
 	pid_t pid;
 
+	if (!name) {
+		pr_err("%s: Name cannot be null\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
 	get_task_struct(current->group_leader);
 	task_lock(current->group_leader);
 	pid = task_pid_nr(current->group_leader);
@@ -733,21 +759,27 @@
 	task_unlock(current->group_leader);
 
 	client = kzalloc(sizeof(struct ion_client), GFP_KERNEL);
-	if (!client) {
-		if (task)
-			put_task_struct(current->group_leader);
-		return ERR_PTR(-ENOMEM);
-	}
+	if (!client)
+		goto err_put_task_struct;
 
 	client->dev = dev;
 	client->handles = RB_ROOT;
 	idr_init(&client->idr);
 	mutex_init(&client->lock);
-	client->name = name;
 	client->task = task;
 	client->pid = pid;
+	client->name = kstrdup(name, GFP_KERNEL);
+	if (!client->name)
+		goto err_free_client;
 
 	down_write(&dev->lock);
+	client->display_serial = ion_get_client_serial(&dev->clients, name);
+	client->display_name = kasprintf(
+		GFP_KERNEL, "%s-%d", name, client->display_serial);
+	if (!client->display_name) {
+		up_write(&dev->lock);
+		goto err_free_client_name;
+	}
 	p = &dev->clients.rb_node;
 	while (*p) {
 		parent = *p;
@@ -761,13 +793,28 @@
 	rb_link_node(&client->node, parent, p);
 	rb_insert_color(&client->node, &dev->clients);
 
-	snprintf(debug_name, 64, "%u", client->pid);
-	client->debug_root = debugfs_create_file(debug_name, 0664,
-						 dev->debug_root, client,
-						 &debug_client_fops);
+	client->debug_root = debugfs_create_file(client->display_name, 0664,
+						dev->clients_debug_root,
+						client, &debug_client_fops);
+	if (!client->debug_root) {
+		char buf[256], *path;
+		path = dentry_path(dev->clients_debug_root, buf, 256);
+		pr_err("Failed to create client debugfs at %s/%s\n",
+			path, client->display_name);
+	}
+
 	up_write(&dev->lock);
 
 	return client;
+
+err_free_client_name:
+	kfree(client->name);
+err_free_client:
+	kfree(client);
+err_put_task_struct:
+	if (task)
+		put_task_struct(current->group_leader);
+	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL(ion_client_create);
 
@@ -792,6 +839,8 @@
 	debugfs_remove_recursive(client->debug_root);
 	up_write(&dev->lock);
 
+	kfree(client->display_name);
+	kfree(client->name);
 	kfree(client);
 }
 EXPORT_SYMBOL(ion_client_destroy);
@@ -954,8 +1003,8 @@
 	int ret = 0;
 
 	if (!buffer->heap->ops->map_user) {
-		pr_err("%s: this heap does not define a method for mapping "
-		       "to userspace\n", __func__);
+		pr_err("%s: this heap does not define a method for mapping to userspace\n",
+			__func__);
 		return -EINVAL;
 	}
 
@@ -1017,9 +1066,7 @@
 	mutex_lock(&buffer->lock);
 	vaddr = ion_buffer_kmap_get(buffer);
 	mutex_unlock(&buffer->lock);
-	if (IS_ERR(vaddr))
-		return PTR_ERR(vaddr);
-	return 0;
+	return PTR_ERR_OR_ZERO(vaddr);
 }
 
 static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start,
@@ -1100,7 +1147,7 @@
 
 	dmabuf = dma_buf_get(fd);
 	if (IS_ERR(dmabuf))
-		return ERR_PTR(PTR_ERR(dmabuf));
+		return ERR_CAST(dmabuf);
 	/* if this memory came from ion */
 
 	if (dmabuf->ops != &dma_buf_ops) {
@@ -1293,9 +1340,11 @@
 	struct miscdevice *miscdev = file->private_data;
 	struct ion_device *dev = container_of(miscdev, struct ion_device, dev);
 	struct ion_client *client;
+	char debug_name[64];
 
 	pr_debug("%s: %d\n", __func__, __LINE__);
-	client = ion_client_create(dev, "user");
+	snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
+	client = ion_client_create(dev, debug_name);
 	if (IS_ERR(client))
 		return PTR_ERR(client);
 	file->private_data = client;
@@ -1338,7 +1387,7 @@
 	size_t total_orphaned_size = 0;
 
 	seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size");
-	seq_printf(s, "----------------------------------------------------\n");
+	seq_puts(s, "----------------------------------------------------\n");
 
 	for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
 		struct ion_client *client = rb_entry(n, struct ion_client,
@@ -1357,9 +1406,8 @@
 				   client->pid, size);
 		}
 	}
-	seq_printf(s, "----------------------------------------------------\n");
-	seq_printf(s, "orphaned allocations (info is from last known client):"
-		   "\n");
+	seq_puts(s, "----------------------------------------------------\n");
+	seq_puts(s, "orphaned allocations (info is from last known client):\n");
 	mutex_lock(&dev->buffer_lock);
 	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
 		struct ion_buffer *buffer = rb_entry(n, struct ion_buffer,
@@ -1376,14 +1424,14 @@
 		}
 	}
 	mutex_unlock(&dev->buffer_lock);
-	seq_printf(s, "----------------------------------------------------\n");
+	seq_puts(s, "----------------------------------------------------\n");
 	seq_printf(s, "%16.s %16zu\n", "total orphaned",
 		   total_orphaned_size);
 	seq_printf(s, "%16.s %16zu\n", "total ", total_size);
 	if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
 		seq_printf(s, "%16.s %16zu\n", "deferred free",
 				heap->free_list_size);
-	seq_printf(s, "----------------------------------------------------\n");
+	seq_puts(s, "----------------------------------------------------\n");
 
 	if (heap->debug_show)
 		heap->debug_show(heap, s, unused);
@@ -1443,6 +1491,8 @@
 
 void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 {
+	struct dentry *debug_file;
+
 	if (!heap->ops->allocate || !heap->ops->free || !heap->ops->map_dma ||
 	    !heap->ops->unmap_dma)
 		pr_err("%s: can not add heap with invalid ops struct.\n",
@@ -1451,21 +1501,40 @@
 	if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
 		ion_heap_init_deferred_free(heap);
 
+	if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink)
+		ion_heap_init_shrinker(heap);
+
 	heap->dev = dev;
 	down_write(&dev->lock);
 	/* use negative heap->id to reverse the priority -- when traversing
 	   the list later attempt higher id numbers first */
 	plist_node_init(&heap->node, -heap->id);
 	plist_add(&heap->node, &dev->heaps);
-	debugfs_create_file(heap->name, 0664, dev->debug_root, heap,
-			    &debug_heap_fops);
+	debug_file = debugfs_create_file(heap->name, 0664,
+					dev->heaps_debug_root, heap,
+					&debug_heap_fops);
+
+	if (!debug_file) {
+		char buf[256], *path;
+		path = dentry_path(dev->heaps_debug_root, buf, 256);
+		pr_err("Failed to create heap debugfs at %s/%s\n",
+			path, heap->name);
+	}
+
 #ifdef DEBUG_HEAP_SHRINKER
 	if (heap->shrinker.shrink) {
 		char debug_name[64];
 
 		snprintf(debug_name, 64, "%s_shrink", heap->name);
-		debugfs_create_file(debug_name, 0644, dev->debug_root, heap,
-				    &debug_shrink_fops);
+		debug_file = debugfs_create_file(
+			debug_name, 0644, dev->heaps_debug_root, heap,
+			&debug_shrink_fops);
+		if (!debug_file) {
+			char buf[256], *path;
+			path = dentry_path(dev->heaps_debug_root, buf, 256);
+			pr_err("Failed to create heap shrinker debugfs at %s/%s\n",
+				path, debug_name);
+		}
 	}
 #endif
 	up_write(&dev->lock);
@@ -1494,8 +1563,21 @@
 	}
 
 	idev->debug_root = debugfs_create_dir("ion", NULL);
-	if (!idev->debug_root)
-		pr_err("ion: failed to create debug files.\n");
+	if (!idev->debug_root) {
+		pr_err("ion: failed to create debugfs root directory.\n");
+		goto debugfs_done;
+	}
+	idev->heaps_debug_root = debugfs_create_dir("heaps", idev->debug_root);
+	if (!idev->heaps_debug_root) {
+		pr_err("ion: failed to create debugfs heaps directory.\n");
+		goto debugfs_done;
+	}
+	idev->clients_debug_root = debugfs_create_dir("clients",
+						idev->debug_root);
+	if (!idev->clients_debug_root)
+		pr_err("ion: failed to create debugfs clients directory.\n");
+
+debugfs_done:
 
 	idev->custom_ioctl = custom_ioctl;
 	idev->buffers = RB_ROOT;
@@ -1509,6 +1591,7 @@
 void ion_device_destroy(struct ion_device *dev)
 {
 	misc_deregister(&dev->dev);
+	debugfs_remove_recursive(dev->debug_root);
 	/* XXX need to free the heaps and clients ? */
 	kfree(dev);
 }
@@ -1527,8 +1610,7 @@
 						    data->heaps[i].align,
 						    MEMBLOCK_ALLOC_ANYWHERE);
 			if (!paddr) {
-				pr_err("%s: error allocating memblock for "
-				       "heap %d\n",
+				pr_err("%s: error allocating memblock for heap %d\n",
 					__func__, i);
 				continue;
 			}
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index f0f9889..ce68ecf 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -135,7 +135,7 @@
 	struct device *dev = cma_heap->dev;
 	struct ion_cma_buffer_info *info = buffer->priv_virt;
 
-	dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer,
+	dev_dbg(dev, "Return buffer %p physical address %pa\n", buffer,
 		&info->handle);
 
 	*addr = info->handle;
diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c
index 01cdc8a..3a45e79 100644
--- a/drivers/staging/android/ion/ion_dummy_driver.c
+++ b/drivers/staging/android/ion/ion_dummy_driver.c
@@ -25,13 +25,13 @@
 #include "ion.h"
 #include "ion_priv.h"
 
-struct ion_device *idev;
-struct ion_heap **heaps;
+static struct ion_device *idev;
+static struct ion_heap **heaps;
 
-void *carveout_ptr;
-void *chunk_ptr;
+static void *carveout_ptr;
+static void *chunk_ptr;
 
-struct ion_platform_heap dummy_heaps[] = {
+static struct ion_platform_heap dummy_heaps[] = {
 		{
 			.id	= ION_HEAP_TYPE_SYSTEM,
 			.type	= ION_HEAP_TYPE_SYSTEM,
@@ -58,7 +58,7 @@
 		},
 };
 
-struct ion_platform_data dummy_ion_pdata = {
+static struct ion_platform_data dummy_ion_pdata = {
 	.nr = ARRAY_SIZE(dummy_heaps),
 	.heaps = dummy_heaps,
 };
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index 37e64d5..bdc6a28 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -178,7 +178,8 @@
 	return size;
 }
 
-size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size)
+static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size,
+				bool skip_pools)
 {
 	struct ion_buffer *buffer;
 	size_t total_drained = 0;
@@ -197,6 +198,8 @@
 					  list);
 		list_del(&buffer->list);
 		heap->free_list_size -= buffer->size;
+		if (skip_pools)
+			buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE;
 		total_drained += buffer->size;
 		spin_unlock(&heap->free_lock);
 		ion_buffer_destroy(buffer);
@@ -207,6 +210,16 @@
 	return total_drained;
 }
 
+size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size)
+{
+	return _ion_heap_freelist_drain(heap, size, false);
+}
+
+size_t ion_heap_freelist_shrink(struct ion_heap *heap, size_t size)
+{
+	return _ion_heap_freelist_drain(heap, size, true);
+}
+
 static int ion_heap_deferred_free(void *data)
 {
 	struct ion_heap *heap = data;
@@ -246,12 +259,62 @@
 	if (IS_ERR(heap->task)) {
 		pr_err("%s: creating thread for deferred free failed\n",
 		       __func__);
-		return PTR_RET(heap->task);
+		return PTR_ERR_OR_ZERO(heap->task);
 	}
 	sched_setscheduler(heap->task, SCHED_IDLE, &param);
 	return 0;
 }
 
+static unsigned long ion_heap_shrink_count(struct shrinker *shrinker,
+						struct shrink_control *sc)
+{
+	struct ion_heap *heap = container_of(shrinker, struct ion_heap,
+					     shrinker);
+	int total = 0;
+
+	total = ion_heap_freelist_size(heap) / PAGE_SIZE;
+	if (heap->ops->shrink)
+		total += heap->ops->shrink(heap, sc->gfp_mask, 0);
+	return total;
+}
+
+static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker,
+						struct shrink_control *sc)
+{
+	struct ion_heap *heap = container_of(shrinker, struct ion_heap,
+					     shrinker);
+	int freed = 0;
+	int to_scan = sc->nr_to_scan;
+
+	if (to_scan == 0)
+		return 0;
+
+	/*
+	 * shrink the free list first, no point in zeroing the memory if we're
+	 * just going to reclaim it. Also, skip any possible page pooling.
+	 */
+	if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
+		freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) /
+				PAGE_SIZE;
+
+	to_scan -= freed;
+	if (to_scan <= 0)
+		return freed;
+
+	if (heap->ops->shrink)
+		freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan);
+	return freed;
+}
+
+void ion_heap_init_shrinker(struct ion_heap *heap)
+{
+	heap->shrinker.count_objects = ion_heap_shrink_count;
+	heap->shrinker.scan_objects = ion_heap_shrink_scan;
+	heap->shrinker.seeks = DEFAULT_SEEKS;
+	heap->shrinker.batch = 0;
+	register_shrinker(&heap->shrinker);
+}
+
 struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
 {
 	struct ion_heap *heap = NULL;
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c
index fa693c2..ecb5fc3 100644
--- a/drivers/staging/android/ion/ion_page_pool.c
+++ b/drivers/staging/android/ion/ion_page_pool.c
@@ -130,8 +130,7 @@
 int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
 				int nr_to_scan)
 {
-	int nr_freed = 0;
-	int i;
+	int freed;
 	bool high;
 
 	high = !!(gfp_mask & __GFP_HIGHMEM);
@@ -139,7 +138,7 @@
 	if (nr_to_scan == 0)
 		return ion_page_pool_total(pool, high);
 
-	for (i = 0; i < nr_to_scan; i++) {
+	for (freed = 0; freed < nr_to_scan; freed++) {
 		struct page *page;
 
 		mutex_lock(&pool->mutex);
@@ -153,10 +152,9 @@
 		}
 		mutex_unlock(&pool->mutex);
 		ion_page_pool_free_pages(pool, page);
-		nr_freed += (1 << pool->order);
 	}
 
-	return nr_freed;
+	return freed;
 }
 
 struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index fc2e4fc..1eba3f2 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -38,6 +38,7 @@
  * @dev:		back pointer to the ion_device
  * @heap:		back pointer to the heap the buffer came from
  * @flags:		buffer specific flags
+ * @private_flags:	internal buffer specific flags
  * @size:		size of the buffer
  * @priv_virt:		private data to the buffer representable as
  *			a void *
@@ -66,6 +67,7 @@
 	struct ion_device *dev;
 	struct ion_heap *heap;
 	unsigned long flags;
+	unsigned long private_flags;
 	size_t size;
 	union {
 		void *priv_virt;
@@ -98,22 +100,27 @@
  * @map_user		map memory to userspace
  *
  * allocate, phys, and map_user return 0 on success, -errno on error.
- * map_dma and map_kernel return pointer on success, ERR_PTR on error.
+ * map_dma and map_kernel return pointer on success, ERR_PTR on
+ * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in
+ * the buffer's private_flags when called from a shrinker. In that
+ * case, the pages being free'd must be truly free'd back to the
+ * system, not put in a page pool or otherwise cached.
  */
 struct ion_heap_ops {
-	int (*allocate) (struct ion_heap *heap,
-			 struct ion_buffer *buffer, unsigned long len,
-			 unsigned long align, unsigned long flags);
-	void (*free) (struct ion_buffer *buffer);
-	int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer,
-		     ion_phys_addr_t *addr, size_t *len);
-	struct sg_table *(*map_dma) (struct ion_heap *heap,
-					struct ion_buffer *buffer);
-	void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer);
-	void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
-	void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
-	int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer,
-			 struct vm_area_struct *vma);
+	int (*allocate)(struct ion_heap *heap,
+			struct ion_buffer *buffer, unsigned long len,
+			unsigned long align, unsigned long flags);
+	void (*free)(struct ion_buffer *buffer);
+	int (*phys)(struct ion_heap *heap, struct ion_buffer *buffer,
+		    ion_phys_addr_t *addr, size_t *len);
+	struct sg_table * (*map_dma)(struct ion_heap *heap,
+				     struct ion_buffer *buffer);
+	void (*unmap_dma)(struct ion_heap *heap, struct ion_buffer *buffer);
+	void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
+	void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
+	int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer,
+			struct vm_area_struct *vma);
+	int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan);
 };
 
 /**
@@ -122,6 +129,17 @@
 #define ION_HEAP_FLAG_DEFER_FREE (1 << 0)
 
 /**
+ * private flags - flags internal to ion
+ */
+/*
+ * Buffer is being freed from a shrinker function. Skip any possible
+ * heap-specific caching mechanism (e.g. page pools). Guarantees that
+ * any buffer storage that came from the system allocator will be
+ * returned to the system allocator.
+ */
+#define ION_PRIV_FLAG_SHRINKER_FREE (1 << 0)
+
+/**
  * struct ion_heap - represents a heap in the system
  * @node:		rb node to put the heap on the device's tree of heaps
  * @dev:		back pointer to the ion_device
@@ -132,10 +150,7 @@
  *			allocating.  These are specified by platform data and
  *			MUST be unique
  * @name:		used for debugging
- * @shrinker:		a shrinker for the heap, if the heap caches system
- *			memory, it must define a shrinker to return it on low
- *			memory conditions, this includes system memory cached
- *			in the deferred free lists for heaps that support it
+ * @shrinker:		a shrinker for the heap
  * @free_list:		free list head if deferred free is used
  * @free_list_size	size of the deferred free list in bytes
  * @lock:		protects the free list
@@ -219,6 +234,16 @@
 int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
 
 /**
+ * ion_heap_init_shrinker
+ * @heap:		the heap
+ *
+ * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op
+ * this function will be called to setup a shrinker to shrink the freelists
+ * and call the heap's shrink op.
+ */
+void ion_heap_init_shrinker(struct ion_heap *heap);
+
+/**
  * ion_heap_init_deferred_free -- initialize deferred free functionality
  * @heap:		the heap
  *
@@ -250,6 +275,29 @@
 size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size);
 
 /**
+ * ion_heap_freelist_shrink - drain the deferred free
+ *				list, skipping any heap-specific
+ *				pooling or caching mechanisms
+ *
+ * @heap:		the heap
+ * @size:		amount of memory to drain in bytes
+ *
+ * Drains the indicated amount of memory from the deferred freelist immediately.
+ * Returns the total amount freed.  The total freed may be higher depending
+ * on the size of the items in the list, or lower if there is insufficient
+ * total memory on the freelist.
+ *
+ * Unlike with @ion_heap_freelist_drain, don't put any pages back into
+ * page pools or otherwise cache the pages. Everything must be
+ * genuinely free'd back to the system. If you're free'ing from a
+ * shrinker you probably want to use this. Note that this relies on
+ * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE
+ * flag.
+ */
+size_t ion_heap_freelist_shrink(struct ion_heap *heap,
+					size_t size);
+
+/**
  * ion_heap_freelist_size - returns the size of the freelist in bytes
  * @heap:		the heap
  */
@@ -305,13 +353,8 @@
  * @low_count:		number of lowmem items in the pool
  * @high_items:		list of highmem items
  * @low_items:		list of lowmem items
- * @shrinker:		a shrinker for the items
  * @mutex:		lock protecting this struct and especially the count
  *			item list
- * @alloc:		function to be used to allocate pageory when the pool
- *			is empty
- * @free:		function to be used to free pageory back to the system
- *			when the shrinker fires
  * @gfp_mask:		gfp_mask to use from alloc
  * @order:		order of pages in the pool
  * @list:		plist node for list of pools
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 9849f39..c923633 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -90,7 +90,7 @@
 {
 	bool cached = ion_buffer_cached(buffer);
 
-	if (!cached) {
+	if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) {
 		struct ion_page_pool *pool = heap->pools[order_to_index(order)];
 		ion_page_pool_free(pool, page);
 	} else {
@@ -209,7 +209,7 @@
 
 	/* uncached pages come from the page pools, zero them before returning
 	   for security purposes (other allocations are zerod at alloc time */
-	if (!cached)
+	if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE))
 		ion_heap_buffer_zero(buffer);
 
 	for_each_sg(table->sgl, sg, table->nents, i)
@@ -231,6 +231,23 @@
 	return;
 }
 
+static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
+					int nr_to_scan)
+{
+	struct ion_system_heap *sys_heap;
+	int nr_total = 0;
+	int i;
+
+	sys_heap = container_of(heap, struct ion_system_heap, heap);
+
+	for (i = 0; i < num_orders; i++) {
+		struct ion_page_pool *pool = sys_heap->pools[i];
+		nr_total += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
+	}
+
+	return nr_total;
+}
+
 static struct ion_heap_ops system_heap_ops = {
 	.allocate = ion_system_heap_allocate,
 	.free = ion_system_heap_free,
@@ -239,67 +256,9 @@
 	.map_kernel = ion_heap_map_kernel,
 	.unmap_kernel = ion_heap_unmap_kernel,
 	.map_user = ion_heap_map_user,
+	.shrink = ion_system_heap_shrink,
 };
 
-static unsigned long ion_system_heap_shrink_count(struct shrinker *shrinker,
-				  struct shrink_control *sc)
-{
-	struct ion_heap *heap = container_of(shrinker, struct ion_heap,
-					     shrinker);
-	struct ion_system_heap *sys_heap = container_of(heap,
-							struct ion_system_heap,
-							heap);
-	int nr_total = 0;
-	int i;
-
-	/* total number of items is whatever the page pools are holding
-	   plus whatever's in the freelist */
-	for (i = 0; i < num_orders; i++) {
-		struct ion_page_pool *pool = sys_heap->pools[i];
-		nr_total += ion_page_pool_shrink(pool, sc->gfp_mask, 0);
-	}
-	nr_total += ion_heap_freelist_size(heap) / PAGE_SIZE;
-	return nr_total;
-
-}
-
-static unsigned long ion_system_heap_shrink_scan(struct shrinker *shrinker,
-				  struct shrink_control *sc)
-{
-
-	struct ion_heap *heap = container_of(shrinker, struct ion_heap,
-					     shrinker);
-	struct ion_system_heap *sys_heap = container_of(heap,
-							struct ion_system_heap,
-							heap);
-	int nr_freed = 0;
-	int i;
-
-	if (sc->nr_to_scan == 0)
-		goto end;
-
-	/* shrink the free list first, no point in zeroing the memory if
-	   we're just going to reclaim it */
-	nr_freed += ion_heap_freelist_drain(heap, sc->nr_to_scan * PAGE_SIZE) /
-		PAGE_SIZE;
-
-	if (nr_freed >= sc->nr_to_scan)
-		goto end;
-
-	for (i = 0; i < num_orders; i++) {
-		struct ion_page_pool *pool = sys_heap->pools[i];
-
-		nr_freed += ion_page_pool_shrink(pool, sc->gfp_mask,
-						 sc->nr_to_scan);
-		if (nr_freed >= sc->nr_to_scan)
-			break;
-	}
-
-end:
-	return nr_freed;
-
-}
-
 static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
 				      void *unused)
 {
@@ -347,11 +306,6 @@
 		heap->pools[i] = pool;
 	}
 
-	heap->heap.shrinker.scan_objects = ion_system_heap_shrink_scan;
-	heap->heap.shrinker.count_objects = ion_system_heap_shrink_count;
-	heap->heap.shrinker.seeks = DEFAULT_SEEKS;
-	heap->heap.shrinker.batch = 0;
-	register_shrinker(&heap->heap.shrinker);
 	heap->heap.debug_show = ion_system_heap_debug_show;
 	return &heap->heap;
 err_create_pool:
diff --git a/drivers/staging/android/ion/tegra/tegra_ion.c b/drivers/staging/android/ion/tegra/tegra_ion.c
index 3474c65..11c7cce 100644
--- a/drivers/staging/android/ion/tegra/tegra_ion.c
+++ b/drivers/staging/android/ion/tegra/tegra_ion.c
@@ -32,13 +32,13 @@
 
 	num_heaps = pdata->nr;
 
-	heaps = kzalloc(sizeof(struct ion_heap *) * pdata->nr, GFP_KERNEL);
+	heaps = devm_kzalloc(&pdev->dev,
+			     sizeof(struct ion_heap *) * pdata->nr,
+			     GFP_KERNEL);
 
 	idev = ion_device_create(NULL);
-	if (IS_ERR_OR_NULL(idev)) {
-		kfree(heaps);
+	if (IS_ERR_OR_NULL(idev))
 		return PTR_ERR(idev);
-	}
 
 	/* create the heaps as specified in the board file */
 	for (i = 0; i < num_heaps; i++) {
@@ -58,7 +58,6 @@
 		if (heaps[i])
 			ion_heap_destroy(heaps[i]);
 	}
-	kfree(heaps);
 	return err;
 }
 
@@ -70,7 +69,6 @@
 	ion_device_destroy(idev);
 	for (i = 0; i < num_heaps; i++)
 		ion_heap_destroy(heaps[i]);
-	kfree(heaps);
 	return 0;
 }
 
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 6f094b3..b545d3d 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -88,7 +88,8 @@
 	int array_size = ARRAY_SIZE(lowmem_adj);
 	int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
 	int other_file = global_page_state(NR_FILE_PAGES) -
-						global_page_state(NR_SHMEM);
+						global_page_state(NR_SHMEM) -
+						total_swapcache_pages();
 
 	if (lowmem_adj_size < array_size)
 		array_size = lowmem_adj_size;
@@ -159,8 +160,8 @@
 			     selected->pid, selected->comm,
 			     selected_oom_score_adj, selected_tasksize);
 		lowmem_deathpending_timeout = jiffies + HZ;
-		send_sig(SIGKILL, selected, 0);
 		set_tsk_thread_flag(selected, TIF_MEMDIE);
+		send_sig(SIGKILL, selected, 0);
 		rem += selected_tasksize;
 	}
 
diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h
index 5aaf71d..1a50669 100644
--- a/drivers/staging/android/sw_sync.h
+++ b/drivers/staging/android/sw_sync.h
@@ -18,10 +18,9 @@
 #define _LINUX_SW_SYNC_H
 
 #include <linux/types.h>
-
-#ifdef __KERNEL__
-
+#include <linux/kconfig.h>
 #include "sync.h"
+#include "uapi/sw_sync.h"
 
 struct sw_sync_timeline {
 	struct	sync_timeline	obj;
@@ -57,19 +56,4 @@
 }
 #endif /* IS_ENABLED(CONFIG_SW_SYNC) */
 
-#endif /* __KERNEL __ */
-
-struct sw_sync_create_fence_data {
-	__u32	value;
-	char	name[32];
-	__s32	fence; /* fd of new fence */
-};
-
-#define SW_SYNC_IOC_MAGIC	'W'
-
-#define SW_SYNC_IOC_CREATE_FENCE	_IOWR(SW_SYNC_IOC_MAGIC, 0,\
-		struct sw_sync_create_fence_data)
-#define SW_SYNC_IOC_INC			_IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
-
-
 #endif /* _LINUX_SW_SYNC_H */
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index 62e2255b..eaf57ccc 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -14,14 +14,14 @@
 #define _LINUX_SYNC_H
 
 #include <linux/types.h>
-#ifdef __KERNEL__
-
 #include <linux/kref.h>
 #include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 
+#include "uapi/sync.h"
+
 struct sync_timeline;
 struct sync_pt;
 struct sync_fence;
@@ -53,7 +53,7 @@
 	const char *driver_name;
 
 	/* required */
-	struct sync_pt *(*dup)(struct sync_pt *pt);
+	struct sync_pt * (*dup)(struct sync_pt *pt);
 
 	/* required */
 	int (*has_signaled)(struct sync_pt *pt);
@@ -341,86 +341,4 @@
  */
 int sync_fence_wait(struct sync_fence *fence, long timeout);
 
-#endif /* __KERNEL__ */
-
-/**
- * struct sync_merge_data - data passed to merge ioctl
- * @fd2:	file descriptor of second fence
- * @name:	name of new fence
- * @fence:	returns the fd of the new fence to userspace
- */
-struct sync_merge_data {
-	__s32	fd2; /* fd of second fence */
-	char	name[32]; /* name of new fence */
-	__s32	fence; /* fd on newly created fence */
-};
-
-/**
- * struct sync_pt_info - detailed sync_pt information
- * @len:		length of sync_pt_info including any driver_data
- * @obj_name:		name of parent sync_timeline
- * @driver_name:	name of driver implementing the parent
- * @status:		status of the sync_pt 0:active 1:signaled <0:error
- * @timestamp_ns:	timestamp of status change in nanoseconds
- * @driver_data:	any driver dependent data
- */
-struct sync_pt_info {
-	__u32	len;
-	char	obj_name[32];
-	char	driver_name[32];
-	__s32	status;
-	__u64	timestamp_ns;
-
-	__u8	driver_data[0];
-};
-
-/**
- * struct sync_fence_info_data - data returned from fence info ioctl
- * @len:	ioctl caller writes the size of the buffer its passing in.
- *		ioctl returns length of sync_fence_data returned to userspace
- *		including pt_info.
- * @name:	name of fence
- * @status:	status of fence. 1: signaled 0:active <0:error
- * @pt_info:	a sync_pt_info struct for every sync_pt in the fence
- */
-struct sync_fence_info_data {
-	__u32	len;
-	char	name[32];
-	__s32	status;
-
-	__u8	pt_info[0];
-};
-
-#define SYNC_IOC_MAGIC		'>'
-
-/**
- * DOC: SYNC_IOC_WAIT - wait for a fence to signal
- *
- * pass timeout in milliseconds.  Waits indefinitely timeout < 0.
- */
-#define SYNC_IOC_WAIT		_IOW(SYNC_IOC_MAGIC, 0, __s32)
-
-/**
- * DOC: SYNC_IOC_MERGE - merge two fences
- *
- * Takes a struct sync_merge_data.  Creates a new fence containing copies of
- * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
- * new fence's fd in sync_merge_data.fence
- */
-#define SYNC_IOC_MERGE		_IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
-
-/**
- * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
- *
- * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
- * Caller should write the size of the buffer into len.  On return, len is
- * updated to reflect the total size of the sync_fence_info_data including
- * pt_info.
- *
- * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
- * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
- */
-#define SYNC_IOC_FENCE_INFO	_IOWR(SYNC_IOC_MAGIC, 2,\
-	struct sync_fence_info_data)
-
 #endif /* _LINUX_SYNC_H */
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index e814514..0c7fdc8 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -90,8 +90,9 @@
 	if (!pdata)
 		return -EBUSY;
 
-	gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios,
-			GFP_KERNEL);
+	gpio_data = devm_kzalloc(&pdev->dev,
+				sizeof(struct timed_gpio_data) * pdata->num_gpios,
+				GFP_KERNEL);
 	if (!gpio_data)
 		return -ENOMEM;
 
@@ -131,7 +132,6 @@
 		timed_output_dev_unregister(&gpio_data[i].dev);
 		gpio_free(gpio_data[i].gpio);
 	}
-	kfree(gpio_data);
 
 	return ret;
 }
@@ -147,8 +147,6 @@
 		gpio_free(gpio_data[i].gpio);
 	}
 
-	kfree(gpio_data);
-
 	return 0;
 }
 
diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h
index 905c7cc..13d2ca5 100644
--- a/drivers/staging/android/timed_output.h
+++ b/drivers/staging/android/timed_output.h
@@ -20,10 +20,10 @@
 	const char	*name;
 
 	/* enable the output and set the timer */
-	void	(*enable)(struct timed_output_dev *sdev, int timeout);
+	void (*enable)(struct timed_output_dev *sdev, int timeout);
 
 	/* returns the current number of milliseconds remaining on the timer */
-	int		(*get_time)(struct timed_output_dev *sdev);
+	int (*get_time)(struct timed_output_dev *sdev);
 
 	/* private data */
 	struct device	*dev;
diff --git a/drivers/staging/android/uapi/android_alarm.h b/drivers/staging/android/uapi/android_alarm.h
new file mode 100644
index 0000000..aa013f6
--- /dev/null
+++ b/drivers/staging/android/uapi/android_alarm.h
@@ -0,0 +1,62 @@
+/* drivers/staging/android/uapi/android_alarm.h
+ *
+ * Copyright (C) 2006-2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ANDROID_ALARM_H
+#define _UAPI_LINUX_ANDROID_ALARM_H
+
+#include <linux/ioctl.h>
+#include <linux/time.h>
+
+enum android_alarm_type {
+	/* return code bit numbers or set alarm arg */
+	ANDROID_ALARM_RTC_WAKEUP,
+	ANDROID_ALARM_RTC,
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+	ANDROID_ALARM_ELAPSED_REALTIME,
+	ANDROID_ALARM_SYSTEMTIME,
+
+	ANDROID_ALARM_TYPE_COUNT,
+
+	/* return code bit numbers */
+	/* ANDROID_ALARM_TIME_CHANGE = 16 */
+};
+
+enum android_alarm_return_flags {
+	ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
+	ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
+				1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+	ANDROID_ALARM_ELAPSED_REALTIME_MASK =
+				1U << ANDROID_ALARM_ELAPSED_REALTIME,
+	ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
+	ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
+};
+
+/* Disable alarm */
+#define ANDROID_ALARM_CLEAR(type)           _IO('a', 0 | ((type) << 4))
+
+/* Ack last alarm and wait for next */
+#define ANDROID_ALARM_WAIT                  _IO('a', 1)
+
+#define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
+/* Set alarm */
+#define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
+#define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
+#define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
+#define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
+
+#endif
diff --git a/drivers/staging/android/uapi/ashmem.h b/drivers/staging/android/uapi/ashmem.h
new file mode 100644
index 0000000..ba4743c
--- /dev/null
+++ b/drivers/staging/android/uapi/ashmem.h
@@ -0,0 +1,47 @@
+/*
+ * drivers/staging/android/uapi/ashmem.h
+ *
+ * Copyright 2008 Google Inc.
+ * Author: Robert Love
+ *
+ * This file is dual licensed.  It may be redistributed and/or modified
+ * under the terms of the Apache 2.0 License OR version 2 of the GNU
+ * General Public License.
+ */
+
+#ifndef _UAPI_LINUX_ASHMEM_H
+#define _UAPI_LINUX_ASHMEM_H
+
+#include <linux/ioctl.h>
+
+#define ASHMEM_NAME_LEN		256
+
+#define ASHMEM_NAME_DEF		"dev/ashmem"
+
+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
+#define ASHMEM_NOT_PURGED	0
+#define ASHMEM_WAS_PURGED	1
+
+/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */
+#define ASHMEM_IS_UNPINNED	0
+#define ASHMEM_IS_PINNED	1
+
+struct ashmem_pin {
+	__u32 offset;	/* offset into region, in bytes, page-aligned */
+	__u32 len;	/* length forward from offset, in bytes, page-aligned */
+};
+
+#define __ASHMEMIOC		0x77
+
+#define ASHMEM_SET_NAME		_IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME		_IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE		_IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE		_IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK	_IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK	_IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN		_IOW(__ASHMEMIOC, 7, struct ashmem_pin)
+#define ASHMEM_UNPIN		_IOW(__ASHMEMIOC, 8, struct ashmem_pin)
+#define ASHMEM_GET_PIN_STATUS	_IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES	_IO(__ASHMEMIOC, 10)
+
+#endif	/* _UAPI_LINUX_ASHMEM_H */
diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h
new file mode 100644
index 0000000..904adb76
--- /dev/null
+++ b/drivers/staging/android/uapi/binder.h
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * Based on, but no longer compatible with, the original
+ * OpenBinder.org binder driver interface, which is:
+ *
+ * Copyright (c) 2005 Palmsource, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_BINDER_H
+#define _UAPI_LINUX_BINDER_H
+
+#include <linux/ioctl.h>
+
+#define B_PACK_CHARS(c1, c2, c3, c4) \
+	((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+#define B_TYPE_LARGE 0x85
+
+enum {
+	BINDER_TYPE_BINDER	= B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
+	BINDER_TYPE_WEAK_BINDER	= B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
+	BINDER_TYPE_HANDLE	= B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
+	BINDER_TYPE_WEAK_HANDLE	= B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
+	BINDER_TYPE_FD		= B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
+};
+
+enum {
+	FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
+	FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+};
+
+#ifdef BINDER_IPC_32BIT
+typedef __u32 binder_size_t;
+typedef __u32 binder_uintptr_t;
+#else
+typedef __u64 binder_size_t;
+typedef __u64 binder_uintptr_t;
+#endif
+
+/*
+ * This is the flattened representation of a Binder object for transfer
+ * between processes.  The 'offsets' supplied as part of a binder transaction
+ * contains offsets into the data where these structures occur.  The Binder
+ * driver takes care of re-writing the structure type and data as it moves
+ * between processes.
+ */
+struct flat_binder_object {
+	/* 8 bytes for large_flat_header. */
+	__u32		type;
+	__u32		flags;
+
+	/* 8 bytes of data. */
+	union {
+		binder_uintptr_t	binder;	/* local object */
+		__u32			handle;	/* remote object */
+	};
+
+	/* extra data associated with local object */
+	binder_uintptr_t	cookie;
+};
+
+/*
+ * On 64-bit platforms where user code may run in 32-bits the driver must
+ * translate the buffer (and local binder) addresses appropriately.
+ */
+
+struct binder_write_read {
+	binder_size_t		write_size;	/* bytes to write */
+	binder_size_t		write_consumed;	/* bytes consumed by driver */
+	binder_uintptr_t	write_buffer;
+	binder_size_t		read_size;	/* bytes to read */
+	binder_size_t		read_consumed;	/* bytes consumed by driver */
+	binder_uintptr_t	read_buffer;
+};
+
+/* Use with BINDER_VERSION, driver fills in fields. */
+struct binder_version {
+	/* driver protocol version -- increment with incompatible change */
+	__s32       protocol_version;
+};
+
+/* This is the current protocol version. */
+#ifdef BINDER_IPC_32BIT
+#define BINDER_CURRENT_PROTOCOL_VERSION 7
+#else
+#define BINDER_CURRENT_PROTOCOL_VERSION 8
+#endif
+
+#define BINDER_WRITE_READ		_IOWR('b', 1, struct binder_write_read)
+#define BINDER_SET_IDLE_TIMEOUT		_IOW('b', 3, __s64)
+#define BINDER_SET_MAX_THREADS		_IOW('b', 5, __u32)
+#define BINDER_SET_IDLE_PRIORITY	_IOW('b', 6, __s32)
+#define BINDER_SET_CONTEXT_MGR		_IOW('b', 7, __s32)
+#define BINDER_THREAD_EXIT		_IOW('b', 8, __s32)
+#define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
+
+/*
+ * NOTE: Two special error codes you should check for when calling
+ * in to the driver are:
+ *
+ * EINTR -- The operation has been interupted.  This should be
+ * handled by retrying the ioctl() until a different error code
+ * is returned.
+ *
+ * ECONNREFUSED -- The driver is no longer accepting operations
+ * from your process.  That is, the process is being destroyed.
+ * You should handle this by exiting from your process.  Note
+ * that once this error code is returned, all further calls to
+ * the driver from any thread will return this same code.
+ */
+
+enum transaction_flags {
+	TF_ONE_WAY	= 0x01,	/* this is a one-way call: async, no return */
+	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
+	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
+	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
+};
+
+struct binder_transaction_data {
+	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
+	 * identifying the target and contents of the transaction.
+	 */
+	union {
+		/* target descriptor of command transaction */
+		__u32	handle;
+		/* target descriptor of return transaction */
+		binder_uintptr_t ptr;
+	} target;
+	binder_uintptr_t	cookie;	/* target object cookie */
+	__u32		code;		/* transaction command */
+
+	/* General information about the transaction. */
+	__u32	        flags;
+	pid_t		sender_pid;
+	uid_t		sender_euid;
+	binder_size_t	data_size;	/* number of bytes of data */
+	binder_size_t	offsets_size;	/* number of bytes of offsets */
+
+	/* If this transaction is inline, the data immediately
+	 * follows here; otherwise, it ends with a pointer to
+	 * the data buffer.
+	 */
+	union {
+		struct {
+			/* transaction data */
+			binder_uintptr_t	buffer;
+			/* offsets from buffer to flat_binder_object structs */
+			binder_uintptr_t	offsets;
+		} ptr;
+		__u8	buf[8];
+	} data;
+};
+
+struct binder_ptr_cookie {
+	binder_uintptr_t ptr;
+	binder_uintptr_t cookie;
+};
+
+struct binder_handle_cookie {
+	__u32 handle;
+	binder_uintptr_t cookie;
+} __attribute__((packed));
+
+struct binder_pri_desc {
+	__s32 priority;
+	__u32 desc;
+};
+
+struct binder_pri_ptr_cookie {
+	__s32 priority;
+	binder_uintptr_t ptr;
+	binder_uintptr_t cookie;
+};
+
+enum binder_driver_return_protocol {
+	BR_ERROR = _IOR('r', 0, __s32),
+	/*
+	 * int: error code
+	 */
+
+	BR_OK = _IO('r', 1),
+	/* No parameters! */
+
+	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
+	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
+	/*
+	 * binder_transaction_data: the received command.
+	 */
+
+	BR_ACQUIRE_RESULT = _IOR('r', 4, __s32),
+	/*
+	 * not currently supported
+	 * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
+	 * Else the remote object has acquired a primary reference.
+	 */
+
+	BR_DEAD_REPLY = _IO('r', 5),
+	/*
+	 * The target of the last transaction (either a bcTRANSACTION or
+	 * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
+	 */
+
+	BR_TRANSACTION_COMPLETE = _IO('r', 6),
+	/*
+	 * No parameters... always refers to the last transaction requested
+	 * (including replies).  Note that this will be sent even for
+	 * asynchronous transactions.
+	 */
+
+	BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
+	BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
+	BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
+	BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
+	/*
+	 * void *:	ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
+	/*
+	 * not currently supported
+	 * int:	priority
+	 * void *: ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BR_NOOP = _IO('r', 12),
+	/*
+	 * No parameters.  Do nothing and examine the next command.  It exists
+	 * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
+	 */
+
+	BR_SPAWN_LOOPER = _IO('r', 13),
+	/*
+	 * No parameters.  The driver has determined that a process has no
+	 * threads waiting to service incoming transactions.  When a process
+	 * receives this command, it must spawn a new service thread and
+	 * register it via bcENTER_LOOPER.
+	 */
+
+	BR_FINISHED = _IO('r', 14),
+	/*
+	 * not currently supported
+	 * stop threadpool thread
+	 */
+
+	BR_DEAD_BINDER = _IOR('r', 15, binder_uintptr_t),
+	/*
+	 * void *: cookie
+	 */
+	BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, binder_uintptr_t),
+	/*
+	 * void *: cookie
+	 */
+
+	BR_FAILED_REPLY = _IO('r', 17),
+	/*
+	 * The the last transaction (either a bcTRANSACTION or
+	 * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
+	 */
+};
+
+enum binder_driver_command_protocol {
+	BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
+	BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
+	/*
+	 * binder_transaction_data: the sent command.
+	 */
+
+	BC_ACQUIRE_RESULT = _IOW('c', 2, __s32),
+	/*
+	 * not currently supported
+	 * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
+	 * Else you have acquired a primary reference on the object.
+	 */
+
+	BC_FREE_BUFFER = _IOW('c', 3, binder_uintptr_t),
+	/*
+	 * void *: ptr to transaction data received on a read
+	 */
+
+	BC_INCREFS = _IOW('c', 4, __u32),
+	BC_ACQUIRE = _IOW('c', 5, __u32),
+	BC_RELEASE = _IOW('c', 6, __u32),
+	BC_DECREFS = _IOW('c', 7, __u32),
+	/*
+	 * int:	descriptor
+	 */
+
+	BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
+	BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
+	/*
+	 * void *: ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
+	/*
+	 * not currently supported
+	 * int: priority
+	 * int: descriptor
+	 */
+
+	BC_REGISTER_LOOPER = _IO('c', 11),
+	/*
+	 * No parameters.
+	 * Register a spawned looper thread with the device.
+	 */
+
+	BC_ENTER_LOOPER = _IO('c', 12),
+	BC_EXIT_LOOPER = _IO('c', 13),
+	/*
+	 * No parameters.
+	 * These two commands are sent as an application-level thread
+	 * enters and exits the binder loop, respectively.  They are
+	 * used so the binder can have an accurate count of the number
+	 * of looping threads it has available.
+	 */
+
+	BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14,
+						struct binder_handle_cookie),
+	/*
+	 * int: handle
+	 * void *: cookie
+	 */
+
+	BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15,
+						struct binder_handle_cookie),
+	/*
+	 * int: handle
+	 * void *: cookie
+	 */
+
+	BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t),
+	/*
+	 * void *: cookie
+	 */
+};
+
+#endif /* _UAPI_LINUX_BINDER_H */
+
diff --git a/drivers/staging/android/uapi/sw_sync.h b/drivers/staging/android/uapi/sw_sync.h
new file mode 100644
index 0000000..9b5d486
--- /dev/null
+++ b/drivers/staging/android/uapi/sw_sync.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_SW_SYNC_H
+#define _UAPI_LINUX_SW_SYNC_H
+
+#include <linux/types.h>
+
+struct sw_sync_create_fence_data {
+	__u32	value;
+	char	name[32];
+	__s32	fence; /* fd of new fence */
+};
+
+#define SW_SYNC_IOC_MAGIC	'W'
+
+#define SW_SYNC_IOC_CREATE_FENCE	_IOWR(SW_SYNC_IOC_MAGIC, 0,\
+		struct sw_sync_create_fence_data)
+#define SW_SYNC_IOC_INC			_IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
+
+#endif /* _UAPI_LINUX_SW_SYNC_H */
diff --git a/drivers/staging/android/uapi/sync.h b/drivers/staging/android/uapi/sync.h
new file mode 100644
index 0000000..e964c75
--- /dev/null
+++ b/drivers/staging/android/uapi/sync.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_SYNC_H
+#define _UAPI_LINUX_SYNC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/**
+ * struct sync_merge_data - data passed to merge ioctl
+ * @fd2:	file descriptor of second fence
+ * @name:	name of new fence
+ * @fence:	returns the fd of the new fence to userspace
+ */
+struct sync_merge_data {
+	__s32	fd2; /* fd of second fence */
+	char	name[32]; /* name of new fence */
+	__s32	fence; /* fd on newly created fence */
+};
+
+/**
+ * struct sync_pt_info - detailed sync_pt information
+ * @len:		length of sync_pt_info including any driver_data
+ * @obj_name:		name of parent sync_timeline
+ * @driver_name:	name of driver implementing the parent
+ * @status:		status of the sync_pt 0:active 1:signaled <0:error
+ * @timestamp_ns:	timestamp of status change in nanoseconds
+ * @driver_data:	any driver dependent data
+ */
+struct sync_pt_info {
+	__u32	len;
+	char	obj_name[32];
+	char	driver_name[32];
+	__s32	status;
+	__u64	timestamp_ns;
+
+	__u8	driver_data[0];
+};
+
+/**
+ * struct sync_fence_info_data - data returned from fence info ioctl
+ * @len:	ioctl caller writes the size of the buffer its passing in.
+ *		ioctl returns length of sync_fence_data returned to userspace
+ *		including pt_info.
+ * @name:	name of fence
+ * @status:	status of fence. 1: signaled 0:active <0:error
+ * @pt_info:	a sync_pt_info struct for every sync_pt in the fence
+ */
+struct sync_fence_info_data {
+	__u32	len;
+	char	name[32];
+	__s32	status;
+
+	__u8	pt_info[0];
+};
+
+#define SYNC_IOC_MAGIC		'>'
+
+/**
+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal
+ *
+ * pass timeout in milliseconds.  Waits indefinitely timeout < 0.
+ */
+#define SYNC_IOC_WAIT		_IOW(SYNC_IOC_MAGIC, 0, __s32)
+
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data.  Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
+ * new fence's fd in sync_merge_data.fence
+ */
+#define SYNC_IOC_MERGE		_IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
+
+/**
+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len.  On return, len is
+ * updated to reflect the total size of the sync_fence_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
+ */
+#define SYNC_IOC_FENCE_INFO	_IOWR(SYNC_IOC_MAGIC, 2,\
+	struct sync_fence_info_data)
+
+#endif /* _UAPI_LINUX_SYNC_H */
diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h
index f0d6f0c..1b2d9f3 100644
--- a/drivers/staging/bcm/Adapter.h
+++ b/drivers/staging/bcm/Adapter.h
@@ -37,8 +37,10 @@
 
 union u_ip_address {
 	struct {
-		ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH]; /* Source Ip Address Range */
-		ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH]; /* Source Ip Mask Address Range */
+		/* Source Ip Address Range */
+		ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH];
+		 /* Source Ip Mask Address Range */
+		ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH];
 	};
 	struct {
 		ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4]; /* Source Ip Address Range */
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index f1b6de0..ae7490b 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -150,15 +150,2146 @@
 	return PktLen;
 }
 
+static int bcm_char_ioctl_reg_read_private(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_rdm_buffer sRdmBuffer = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	PCHAR temp_buff;
+	INT Status = STATUS_FAILURE;
+	UINT Bufflen;
+	u16 temp_value;
+	int bytes;
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
+		return -EINVAL;
+
+	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength > USHRT_MAX ||
+		IoBuffer.OutputLength == 0) {
+		return -EINVAL;
+	}
+
+	Bufflen = IoBuffer.OutputLength;
+	temp_value = 4 - (Bufflen % 4);
+	Bufflen += temp_value % 4;
+
+	temp_buff = kmalloc(Bufflen, GFP_KERNEL);
+	if (!temp_buff)
+		return -ENOMEM;
+
+	bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
+			(PUINT)temp_buff, Bufflen);
+	if (bytes > 0) {
+		Status = STATUS_SUCCESS;
+		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
+			kfree(temp_buff);
+			return -EFAULT;
+		}
+	} else {
+		Status = bytes;
+	}
+
+	kfree(temp_buff);
+	return Status;
+}
+
+static int bcm_char_ioctl_reg_write_private(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_wrm_buffer sWrmBuffer = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	UINT uiTempVar = 0;
+	INT Status;
+
+	/* Copy Ioctl Buffer structure */
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
+		return -EINVAL;
+
+	/* Get WrmBuffer structure */
+	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
+	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
+		((uiTempVar == EEPROM_REJECT_REG_1) ||
+			(uiTempVar == EEPROM_REJECT_REG_2) ||
+			(uiTempVar == EEPROM_REJECT_REG_3) ||
+			(uiTempVar == EEPROM_REJECT_REG_4))) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"EEPROM Access Denied, not in VSG Mode\n");
+		return -EFAULT;
+	}
+
+	Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
+			(PUINT)sWrmBuffer.Data, sizeof(ULONG));
+
+	if (Status == STATUS_SUCCESS) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL, "WRM Done\n");
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL, "WRM Failed\n");
+		Status = -EFAULT;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_eeprom_reg_read(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_rdm_buffer sRdmBuffer = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	PCHAR temp_buff = NULL;
+	UINT uiTempVar = 0;
+	INT Status;
+	int bytes;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Device in Idle Mode, Blocking Rdms\n");
+		return -EACCES;
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
+		return -EINVAL;
+
+	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength > USHRT_MAX ||
+		IoBuffer.OutputLength == 0) {
+		return -EINVAL;
+	}
+
+	temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
+	if (!temp_buff)
+		return STATUS_FAILURE;
+
+	if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+		((ULONG)sRdmBuffer.Register & 0x3)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"RDM Done On invalid Address : %x Access Denied.\n",
+				(int)sRdmBuffer.Register);
+
+		kfree(temp_buff);
+		return -EINVAL;
+	}
+
+	uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
+	bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
+			       (PUINT)temp_buff, IoBuffer.OutputLength);
+
+	if (bytes > 0) {
+		Status = STATUS_SUCCESS;
+		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
+			kfree(temp_buff);
+			return -EFAULT;
+		}
+	} else {
+		Status = bytes;
+	}
+
+	kfree(temp_buff);
+	return Status;
+}
+
+static int bcm_char_ioctl_eeprom_reg_write(void __user *argp,
+	struct bcm_mini_adapter *Adapter, UINT cmd)
+{
+	struct bcm_wrm_buffer sWrmBuffer = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	UINT uiTempVar = 0;
+	INT Status;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Device in Idle Mode, Blocking Wrms\n");
+		return -EACCES;
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
+		return -EINVAL;
+
+	/* Get WrmBuffer structure */
+	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+		((ULONG)sWrmBuffer.Register & 0x3)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"WRM Done On invalid Address : %x Access Denied.\n",
+				(int)sWrmBuffer.Register);
+		return -EINVAL;
+	}
+
+	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
+	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
+			((uiTempVar == EEPROM_REJECT_REG_1) ||
+			(uiTempVar == EEPROM_REJECT_REG_2) ||
+			(uiTempVar == EEPROM_REJECT_REG_3) ||
+			(uiTempVar == EEPROM_REJECT_REG_4)) &&
+			(cmd == IOCTL_BCM_REGISTER_WRITE)) {
+
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+					"EEPROM Access Denied, not in VSG Mode\n");
+			return -EFAULT;
+	}
+
+	Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
+				(PUINT)sWrmBuffer.Data,
+				sWrmBuffer.Length);
+
+	if (Status == STATUS_SUCCESS) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG,
+				DBG_LVL_ALL, "WRM Done\n");
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL, "WRM Failed\n");
+		Status = -EFAULT;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_gpio_set_request(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_gpio_info gpio_info = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	UCHAR ucResetValue[4];
+	UINT value = 0;
+	UINT uiBit = 0;
+	UINT uiOperation = 0;
+	INT Status;
+	int bytes;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"GPIO Can't be set/clear in Low power Mode");
+		return -EACCES;
+	}
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(gpio_info))
+		return -EINVAL;
+
+	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
+		return -EFAULT;
+
+	uiBit  = gpio_info.uiGpioNumber;
+	uiOperation = gpio_info.uiGpioValue;
+	value = (1<<uiBit);
+
+	if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
+				value);
+		return -EINVAL;
+	}
+
+	/* Set - setting 1 */
+	if (uiOperation) {
+		/* Set the gpio output register */
+		Status = wrmaltWithLock(Adapter,
+					BCM_GPIO_OUTPUT_SET_REG,
+					(PUINT)(&value), sizeof(UINT));
+
+		if (Status == STATUS_SUCCESS) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"Set the GPIO bit\n");
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"Failed to set the %dth GPIO\n",
+					uiBit);
+			return Status;
+		}
+	} else {
+		/* Set the gpio output register */
+		Status = wrmaltWithLock(Adapter,
+					BCM_GPIO_OUTPUT_CLR_REG,
+					(PUINT)(&value), sizeof(UINT));
+
+		if (Status == STATUS_SUCCESS) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"Set the GPIO bit\n");
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"Failed to clear the %dth GPIO\n",
+					uiBit);
+			return Status;
+		}
+	}
+
+	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
+			       (PUINT)ucResetValue, sizeof(UINT));
+	if (bytes < 0) {
+		Status = bytes;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"GPIO_MODE_REGISTER read failed");
+		return Status;
+	} else {
+		Status = STATUS_SUCCESS;
+	}
+
+	/* Set the gpio mode register to output */
+	*(UINT *)ucResetValue |= (1<<uiBit);
+	Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
+				(PUINT)ucResetValue, sizeof(UINT));
+
+	if (Status == STATUS_SUCCESS) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"Set the GPIO to output Mode\n");
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"Failed to put GPIO in Output Mode\n");
+	}
+
+	return Status;
+}
+
+static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_user_thread_req threadReq = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"User made LED thread InActive");
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"GPIO Can't be set/clear in Low power Mode");
+		return -EACCES;
+	}
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(threadReq))
+		return -EINVAL;
+
+	if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
+		return -EFAULT;
+
+	/* if LED thread is running(Actively or Inactively)
+	 * set it state to make inactive
+	 */
+	if (Adapter->LEDInfo.led_thread_running) {
+		if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"Activating thread req");
+			Adapter->DriverState = LED_THREAD_ACTIVE;
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					OSAL_DBG, DBG_LVL_ALL,
+					"DeActivating Thread req.....");
+			Adapter->DriverState = LED_THREAD_INACTIVE;
+		}
+
+		/* signal thread. */
+		wake_up(&Adapter->LEDInfo.notify_led_event);
+	}
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_gpio_status_request(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_gpio_info gpio_info = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	ULONG uiBit = 0;
+	UCHAR ucRead[4];
+	INT Status;
+	int bytes;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE))
+		return -EACCES;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(gpio_info))
+		return -EINVAL;
+
+	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	uiBit = gpio_info.uiGpioNumber;
+
+	/* Set the gpio output register */
+	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
+				(PUINT)ucRead, sizeof(UINT));
+
+	if (bytes < 0) {
+		Status = bytes;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"RDM Failed\n");
+		return Status;
+	} else {
+		Status = STATUS_SUCCESS;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_gpio_multi_request(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
+	struct bcm_gpio_multi_info *pgpio_multi_info =
+		(struct bcm_gpio_multi_info *)gpio_multi_info;
+	struct bcm_ioctl_buffer IoBuffer;
+	UCHAR ucResetValue[4];
+	INT Status = STATUS_FAILURE;
+	int bytes;
+
+	memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE))
+		return -EINVAL;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(gpio_multi_info))
+		return -EINVAL;
+	if (IoBuffer.OutputLength > sizeof(gpio_multi_info))
+		IoBuffer.OutputLength = sizeof(gpio_multi_info);
+
+	if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	if (IsReqGpioIsLedInNVM(Adapter,
+		pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL,
+				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
+				pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
+				Adapter->gpioBitMap);
+		return -EINVAL;
+	}
+
+	/* Set the gpio output register */
+	if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
+		(pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
+		/* Set 1's in GPIO OUTPUT REGISTER */
+		*(UINT *)ucResetValue =  pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
+			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
+			pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
+
+		if (*(UINT *) ucResetValue)
+			Status = wrmaltWithLock(Adapter,
+				BCM_GPIO_OUTPUT_SET_REG,
+				(PUINT)ucResetValue, sizeof(ULONG));
+
+		if (Status != STATUS_SUCCESS) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
+			return Status;
+		}
+
+		/* Clear to 0's in GPIO OUTPUT REGISTER */
+		*(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
+			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
+			(~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
+
+		if (*(UINT *) ucResetValue)
+			Status = wrmaltWithLock(Adapter,
+				BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue,
+				sizeof(ULONG));
+
+		if (Status != STATUS_SUCCESS) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+					"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
+			return Status;
+		}
+	}
+
+	if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
+		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
+			(PUINT)ucResetValue, sizeof(UINT));
+
+		if (bytes < 0) {
+			Status = bytes;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+					"RDM to GPIO_PIN_STATE_REGISTER Failed.");
+			return Status;
+		} else {
+			Status = STATUS_SUCCESS;
+		}
+
+		pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
+			pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
+	}
+
+	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info,
+		IoBuffer.OutputLength);
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Failed while copying Content to IOBufer for user space err:%d",
+			Status);
+		return -EFAULT;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_gpio_mode_request(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
+	struct bcm_gpio_multi_mode *pgpio_multi_mode =
+		(struct bcm_gpio_multi_mode *)gpio_multi_mode;
+	struct bcm_ioctl_buffer IoBuffer;
+	UCHAR ucResetValue[4];
+	INT Status;
+	int bytes;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE))
+		return -EINVAL;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
+		return -EINVAL;
+	if (IoBuffer.OutputLength > sizeof(gpio_multi_mode))
+		IoBuffer.OutputLength = sizeof(gpio_multi_mode);
+
+	if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer,
+		IoBuffer.InputLength))
+		return -EFAULT;
+
+	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
+		(PUINT)ucResetValue, sizeof(UINT));
+
+	if (bytes < 0) {
+		Status = bytes;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Read of GPIO_MODE_REGISTER failed");
+		return Status;
+	} else {
+		Status = STATUS_SUCCESS;
+	}
+
+	/* Validating the request */
+	if (IsReqGpioIsLedInNVM(Adapter,
+		pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
+				pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,
+				Adapter->gpioBitMap);
+		return -EINVAL;
+	}
+
+	if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
+		/* write all OUT's (1's) */
+		*(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
+					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
+
+		/* write all IN's (0's) */
+		*(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
+					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
+
+		/* Currently implemented return the modes of all GPIO's
+		 * else needs to bit AND with  mask
+		 */
+		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
+
+		Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
+			(PUINT)ucResetValue, sizeof(ULONG));
+		if (Status == STATUS_SUCCESS) {
+			BCM_DEBUG_PRINT(Adapter,
+				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"WRM to GPIO_MODE_REGISTER Done");
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+					"WRM to GPIO_MODE_REGISTER Failed");
+			return -EFAULT;
+		}
+	} else {
+		/* if uiGPIOMask is 0 then return mode register configuration */
+		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
+	}
+
+	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode,
+		IoBuffer.OutputLength);
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Failed while copying Content to IOBufer for user space err:%d",
+			Status);
+		return -EFAULT;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_misc_request(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	PVOID pvBuffer = NULL;
+	INT Status;
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
+		return -EINVAL;
+
+	if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
+		return -EINVAL;
+
+	pvBuffer = memdup_user(IoBuffer.InputBuffer,
+			       IoBuffer.InputLength);
+	if (IS_ERR(pvBuffer))
+		return PTR_ERR(pvBuffer);
+
+	down(&Adapter->LowPowerModeSync);
+	Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
+		!Adapter->bPreparingForLowPowerMode,
+		(1 * HZ));
+	if (Status == -ERESTARTSYS)
+		goto cntrlEnd;
+
+	if (Adapter->bPreparingForLowPowerMode) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Preparing Idle Mode is still True - Hence Rejecting control message\n");
+		Status = STATUS_FAILURE;
+		goto cntrlEnd;
+	}
+	Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
+
+cntrlEnd:
+	up(&Adapter->LowPowerModeSync);
+	kfree(pvBuffer);
+	return Status;
+}
+
+static int bcm_char_ioctl_buffer_download_start(
+	struct bcm_mini_adapter *Adapter)
+{
+	INT Status;
+
+	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
+		return -EACCES;
+	}
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+		"Starting the firmware download PID =0x%x!!!!\n", current->pid);
+
+	if (down_trylock(&Adapter->fw_download_sema))
+		return -EBUSY;
+
+	Adapter->bBinDownloaded = false;
+	Adapter->fw_download_process_pid = current->pid;
+	Adapter->bCfgDownloaded = false;
+	Adapter->fw_download_done = false;
+	netif_carrier_off(Adapter->dev);
+	netif_stop_queue(Adapter->dev);
+	Status = reset_card_proc(Adapter);
+	if (Status) {
+		pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
+		up(&Adapter->fw_download_sema);
+		up(&Adapter->NVMRdmWrmLock);
+		return Status;
+	}
+	mdelay(10);
+
+	up(&Adapter->NVMRdmWrmLock);
+	return Status;
+}
+
+static int bcm_char_ioctl_buffer_download(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_firmware_info *psFwInfo = NULL;
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+		"Starting the firmware download PID =0x%x!!!!\n", current->pid);
+
+	if (!down_trylock(&Adapter->fw_download_sema)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Invalid way to download buffer. Use Start and then call this!!!\n");
+		up(&Adapter->fw_download_sema);
+		return -EINVAL;
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
+		up(&Adapter->fw_download_sema);
+		return -EFAULT;
+	}
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Length for FW DLD is : %lx\n", IoBuffer.InputLength);
+
+	if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) {
+		up(&Adapter->fw_download_sema);
+		return -EINVAL;
+	}
+
+	psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
+	if (!psFwInfo) {
+		up(&Adapter->fw_download_sema);
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(psFwInfo, IoBuffer.InputBuffer,
+		IoBuffer.InputLength)) {
+		up(&Adapter->fw_download_sema);
+		kfree(psFwInfo);
+		return -EFAULT;
+	}
+
+	if (!psFwInfo->pvMappedFirmwareAddress ||
+		(psFwInfo->u32FirmwareLength == 0)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Something else is wrong %lu\n",
+				psFwInfo->u32FirmwareLength);
+		up(&Adapter->fw_download_sema);
+		kfree(psFwInfo);
+		Status = -EINVAL;
+		return Status;
+	}
+
+	Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
+
+	if (Status != STATUS_SUCCESS) {
+		if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"IOCTL: Configuration File Upload Failed\n");
+		else
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"IOCTL: Firmware File Upload Failed\n");
+
+		/* up(&Adapter->fw_download_sema); */
+
+		if (Adapter->LEDInfo.led_thread_running &
+			BCM_LED_THREAD_RUNNING_ACTIVELY) {
+			Adapter->DriverState = DRIVER_INIT;
+			Adapter->LEDInfo.bLedInitDone = false;
+			wake_up(&Adapter->LEDInfo.notify_led_event);
+		}
+	}
+
+	if (Status != STATUS_SUCCESS)
+		up(&Adapter->fw_download_sema);
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL: Firmware File Uploaded\n");
+	kfree(psFwInfo);
+	return Status;
+}
+
+static int bcm_char_ioctl_buffer_download_stop(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	INT Status;
+	int timeout = 0;
+
+	if (!down_trylock(&Adapter->fw_download_sema)) {
+		up(&Adapter->fw_download_sema);
+		return -EINVAL;
+	}
+
+	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"FW download blocked as EEPROM Read/Write is in progress\n");
+		up(&Adapter->fw_download_sema);
+		return -EACCES;
+	}
+
+	Adapter->bBinDownloaded = TRUE;
+	Adapter->bCfgDownloaded = TRUE;
+	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+	Adapter->CurrNumRecvDescs = 0;
+	Adapter->downloadDDR = 0;
+
+	/* setting the Mips to Run */
+	Status = run_card_proc(Adapter);
+
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Firm Download Failed\n");
+		up(&Adapter->fw_download_sema);
+		up(&Adapter->NVMRdmWrmLock);
+		return Status;
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+				DBG_LVL_ALL, "Firm Download Over...\n");
+	}
+
+	mdelay(10);
+
+	/* Wait for MailBox Interrupt */
+	if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Unable to send interrupt...\n");
+
+	timeout = 5*HZ;
+	Adapter->waiting_to_fw_download_done = false;
+	wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
+			Adapter->waiting_to_fw_download_done, timeout);
+	Adapter->fw_download_process_pid = INVALID_PID;
+	Adapter->fw_download_done = TRUE;
+	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+	Adapter->CurrNumRecvDescs = 0;
+	Adapter->PrevNumRecvDescs = 0;
+	atomic_set(&Adapter->cntrlpktCnt, 0);
+	Adapter->LinkUpStatus = 0;
+	Adapter->LinkStatus = 0;
+
+	if (Adapter->LEDInfo.led_thread_running &
+		BCM_LED_THREAD_RUNNING_ACTIVELY) {
+		Adapter->DriverState = FW_DOWNLOAD_DONE;
+		wake_up(&Adapter->LEDInfo.notify_led_event);
+	}
+
+	if (!timeout)
+		Status = -ENODEV;
+
+	up(&Adapter->fw_download_sema);
+	up(&Adapter->NVMRdmWrmLock);
+	return Status;
+}
+
+static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *Adapter)
+{
+	INT Status;
+	INT NVMAccess;
+
+	NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+	if (NVMAccess) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			" IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
+		return -EACCES;
+	}
+
+	down(&Adapter->RxAppControlQueuelock);
+	Status = reset_card_proc(Adapter);
+	flushAllAppQ();
+	up(&Adapter->RxAppControlQueuelock);
+	up(&Adapter->NVMRdmWrmLock);
+	ResetCounters(Adapter);
+	return Status;
+}
+
+static int bcm_char_ioctl_qos_threshold(ULONG arg,
+	struct bcm_mini_adapter *Adapter)
+{
+	USHORT uiLoopIndex;
+
+	for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
+		if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
+				(unsigned long __user *)arg)) {
+			return -EFAULT;
+		}
+	}
+	return 0;
+}
+
+static int bcm_char_ioctl_switch_transfer_mode(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	UINT uiData = 0;
+
+	if (copy_from_user(&uiData, argp, sizeof(UINT)))
+		return -EFAULT;
+
+	if (uiData) {
+		/* Allow All Packets */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
+			Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
+	} else {
+		/* Allow IP only Packets */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
+		Adapter->TransferMode = IP_PACKET_ONLY_MODE;
+	}
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_get_driver_version(void __user *argp)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	ulong len;
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	len = min_t(ulong, IoBuffer.OutputLength, strlen(DRV_VERSION) + 1);
+
+	if (copy_to_user(IoBuffer.OutputBuffer, DRV_VERSION, len))
+		return -EFAULT;
+
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_get_current_status(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_link_state link_state;
+	struct bcm_ioctl_buffer IoBuffer;
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"copy_from_user failed..\n");
+		return -EFAULT;
+	}
+
+	if (IoBuffer.OutputLength != sizeof(link_state))
+		return -EINVAL;
+
+	memset(&link_state, 0, sizeof(link_state));
+	link_state.bIdleMode = Adapter->IdleMode;
+	link_state.bShutdownMode = Adapter->bShutStatus;
+	link_state.ucLinkStatus = Adapter->LinkStatus;
+
+	if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t,
+		sizeof(link_state), IoBuffer.OutputLength))) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy_to_user Failed..\n");
+		return -EFAULT;
+	}
+	return STATUS_SUCCESS;
+}
+
+
+static int bcm_char_ioctl_set_mac_tracing(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	UINT tracing_flag;
+
+	/* copy ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
+		return -EFAULT;
+
+	if (tracing_flag)
+		Adapter->pTarangs->MacTracingEnabled = TRUE;
+	else
+		Adapter->pTarangs->MacTracingEnabled = false;
+
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_get_dsx_indication(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	ULONG ulSFId = 0;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Mismatch req: %lx needed is =0x%zx!!!",
+			IoBuffer.OutputLength,
+			sizeof(struct bcm_add_indication_alt));
+		return -EINVAL;
+	}
+
+	if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
+		return -EFAULT;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"Get DSX Data SF ID is =%lx\n", ulSFId);
+	get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_get_host_mibs(void __user *argp,
+	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_FAILURE;
+	PVOID temp_buff;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Length Check failed %lu %zd\n", IoBuffer.OutputLength,
+			sizeof(struct bcm_host_stats_mibs));
+		return -EINVAL;
+	}
+
+	/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
+	temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
+	if (!temp_buff)
+		return STATUS_FAILURE;
+
+	Status = ProcessGetHostMibs(Adapter, temp_buff);
+	GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
+
+	if (Status != STATUS_FAILURE) {
+		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff,
+			sizeof(struct bcm_host_stats_mibs))) {
+			kfree(temp_buff);
+			return -EFAULT;
+		}
+	}
+
+	kfree(temp_buff);
+	return Status;
+}
+
+static int bcm_char_ioctl_bulk_wrm(void __user *argp,
+	struct bcm_mini_adapter *Adapter, UINT cmd)
+{
+	struct bcm_bulk_wrm_buffer *pBulkBuffer;
+	struct bcm_ioctl_buffer IoBuffer;
+	UINT uiTempVar = 0;
+	INT Status = STATUS_FAILURE;
+	PCHAR pvBuffer = NULL;
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Device in Idle/Shutdown Mode, Blocking Wrms\n");
+		return -EACCES;
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.InputLength < sizeof(ULONG) * 2)
+		return -EINVAL;
+
+	pvBuffer = memdup_user(IoBuffer.InputBuffer,
+			       IoBuffer.InputLength);
+	if (IS_ERR(pvBuffer))
+		return PTR_ERR(pvBuffer);
+
+	pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;
+
+	if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
+		((ULONG)pBulkBuffer->Register & 0x3)) {
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"WRM Done On invalid Address : %x Access Denied.\n",
+			(int)pBulkBuffer->Register);
+		kfree(pvBuffer);
+		return -EINVAL;
+	}
+
+	uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
+	if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) &&
+		((uiTempVar == EEPROM_REJECT_REG_1) ||
+			(uiTempVar == EEPROM_REJECT_REG_2) ||
+			(uiTempVar == EEPROM_REJECT_REG_3) ||
+			(uiTempVar == EEPROM_REJECT_REG_4)) &&
+		(cmd == IOCTL_BCM_REGISTER_WRITE)) {
+
+		kfree(pvBuffer);
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"EEPROM Access Denied, not in VSG Mode\n");
+		return -EFAULT;
+	}
+
+	if (pBulkBuffer->SwapEndian == false)
+		Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register,
+			(PCHAR)pBulkBuffer->Values,
+			IoBuffer.InputLength - 2*sizeof(ULONG));
+	else
+		Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register,
+			(PUINT)pBulkBuffer->Values,
+			IoBuffer.InputLength - 2*sizeof(ULONG));
+
+	if (Status != STATUS_SUCCESS)
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
+
+	kfree(pvBuffer);
+	return Status;
+}
+
+static int bcm_char_ioctl_get_nvm_size(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
+		if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize,
+			sizeof(UINT)))
+			return -EFAULT;
+	}
+
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_cal_init(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	UINT uiSectorSize = 0;
+	INT Status = STATUS_FAILURE;
+
+	if (Adapter->eNVMType == NVM_FLASH) {
+		if (copy_from_user(&IoBuffer, argp,
+			sizeof(struct bcm_ioctl_buffer)))
+			return -EFAULT;
+
+		if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer,
+			sizeof(UINT)))
+			return -EFAULT;
+
+		if ((uiSectorSize < MIN_SECTOR_SIZE) ||
+			(uiSectorSize > MAX_SECTOR_SIZE)) {
+			if (copy_to_user(IoBuffer.OutputBuffer,
+				&Adapter->uiSectorSize, sizeof(UINT)))
+				return -EFAULT;
+		} else {
+			if (IsFlash2x(Adapter)) {
+				if (copy_to_user(IoBuffer.OutputBuffer,
+					&Adapter->uiSectorSize, sizeof(UINT)))
+					return -EFAULT;
+			} else {
+				if ((TRUE == Adapter->bShutStatus) ||
+					(TRUE == Adapter->IdleMode)) {
+					BCM_DEBUG_PRINT(Adapter,
+						DBG_TYPE_PRINTK, 0, 0,
+						"Device is in Idle/Shutdown Mode\n");
+					return -EACCES;
+				}
+
+				Adapter->uiSectorSize = uiSectorSize;
+				BcmUpdateSectorSize(Adapter,
+					Adapter->uiSectorSize);
+			}
+		}
+		Status = STATUS_SUCCESS;
+	} else {
+		Status = STATUS_FAILURE;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_set_debug(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+#ifdef DEBUG
+	struct bcm_ioctl_buffer IoBuffer;
+	struct bcm_user_debug_state sUserDebugState;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"In SET_DEBUG ioctl\n");
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer,
+		sizeof(struct bcm_user_debug_state)))
+		return -EFAULT;
+
+	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
+			sUserDebugState.OnOff, sUserDebugState.Type);
+	/* sUserDebugState.Subtype <<= 1; */
+	sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
+	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
+		"actual Subtype=0x%x\n", sUserDebugState.Subtype);
+
+	/* Update new 'DebugState' in the Adapter */
+	Adapter->stDebugState.type |= sUserDebugState.Type;
+	/* Subtype: A bitmap of 32 bits for Subtype per Type.
+	 * Valid indexes in 'subtype' array: 1,2,4,8
+	 * corresponding to valid Type values. Hence we can use the 'Type' field
+	 * as the index value, ignoring the array entries 0,3,5,6,7 !
+	 */
+	if (sUserDebugState.OnOff)
+		Adapter->stDebugState.subtype[sUserDebugState.Type] |=
+			sUserDebugState.Subtype;
+	else
+		Adapter->stDebugState.subtype[sUserDebugState.Type] &=
+			~sUserDebugState.Subtype;
+
+	BCM_SHOW_DEBUG_BITMAP(Adapter);
+#endif
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_nvm_rw(void __user *argp,
+	struct bcm_mini_adapter *Adapter, UINT cmd)
+{
+	struct bcm_nvm_readwrite stNVMReadWrite;
+	struct timeval tv0, tv1;
+	struct bcm_ioctl_buffer IoBuffer;
+	PUCHAR pReadData = NULL;
+	ULONG ulDSDMagicNumInUsrBuff = 0;
+	INT Status = STATUS_FAILURE;
+
+	memset(&tv0, 0, sizeof(struct timeval));
+	memset(&tv1, 0, sizeof(struct timeval));
+	if ((Adapter->eNVMType == NVM_FLASH) &&
+		(Adapter->uiFlashLayoutMajorVersion == 0)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
+		return -EFAULT;
+	}
+
+	if (IsFlash2x(Adapter)) {
+		if ((Adapter->eActiveDSD != DSD0) &&
+			(Adapter->eActiveDSD != DSD1) &&
+			(Adapter->eActiveDSD != DSD2)) {
+
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"No DSD is active..hence NVM Command is blocked");
+			return STATUS_FAILURE;
+		}
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (copy_from_user(&stNVMReadWrite,
+				(IOCTL_BCM_NVM_READ == cmd) ?
+				IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
+				sizeof(struct bcm_nvm_readwrite)))
+		return -EFAULT;
+
+	/*
+	 * Deny the access if the offset crosses the cal area limit.
+	 */
+	if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
+		return STATUS_FAILURE;
+
+	if (stNVMReadWrite.uiOffset >
+		Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes)
+		return STATUS_FAILURE;
+
+	pReadData = memdup_user(stNVMReadWrite.pBuffer,
+				stNVMReadWrite.uiNumBytes);
+	if (IS_ERR(pReadData))
+		return PTR_ERR(pReadData);
+
+	do_gettimeofday(&tv0);
+	if (IOCTL_BCM_NVM_READ == cmd) {
+		down(&Adapter->NVMRdmWrmLock);
+
+		if ((Adapter->IdleMode == TRUE) ||
+			(Adapter->bShutStatus == TRUE) ||
+			(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+			BCM_DEBUG_PRINT(Adapter,
+				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Device is in Idle/Shutdown Mode\n");
+			up(&Adapter->NVMRdmWrmLock);
+			kfree(pReadData);
+			return -EACCES;
+		}
+
+		Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
+			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
+		up(&Adapter->NVMRdmWrmLock);
+
+		if (Status != STATUS_SUCCESS) {
+			kfree(pReadData);
+			return Status;
+		}
+
+		if (copy_to_user(stNVMReadWrite.pBuffer, pReadData,
+			stNVMReadWrite.uiNumBytes)) {
+			kfree(pReadData);
+			return -EFAULT;
+		}
+	} else {
+		down(&Adapter->NVMRdmWrmLock);
+
+		if ((Adapter->IdleMode == TRUE) ||
+			(Adapter->bShutStatus == TRUE) ||
+			(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+			BCM_DEBUG_PRINT(Adapter,
+				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Device is in Idle/Shutdown Mode\n");
+			up(&Adapter->NVMRdmWrmLock);
+			kfree(pReadData);
+			return -EACCES;
+		}
+
+		Adapter->bHeaderChangeAllowed = TRUE;
+		if (IsFlash2x(Adapter)) {
+			/*
+			 * New Requirement:-
+			 * DSD section updation will be allowed in two case:-
+			 * 1.  if DSD sig is present in DSD header means dongle
+			 * is ok and updation is fruitfull
+			 * 2.  if point 1 failes then user buff should have
+			 * DSD sig. this point ensures that if dongle is
+			 * corrupted then user space program first modify
+			 * the DSD header with valid DSD sig so that this
+			 * as well as further write may be worthwhile.
+			 *
+			 * This restriction has been put assuming that
+			 * if DSD sig is corrupted, DSD data won't be
+			 * considered valid.
+			 */
+
+			Status = BcmFlash2xCorruptSig(Adapter,
+				Adapter->eActiveDSD);
+			if (Status != STATUS_SUCCESS) {
+				if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) !=
+					Adapter->uiNVMDSDSize) ||
+					(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {
+
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+						OSAL_DBG, DBG_LVL_ALL,
+						"DSD Sig is present neither in Flash nor User provided Input..");
+					up(&Adapter->NVMRdmWrmLock);
+					kfree(pReadData);
+					return Status;
+				}
+
+				ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
+				if (ulDSDMagicNumInUsrBuff !=
+					DSD_IMAGE_MAGIC_NUMBER) {
+					BCM_DEBUG_PRINT(Adapter,
+					DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+						"DSD Sig is present neither in Flash nor User provided Input..");
+					up(&Adapter->NVMRdmWrmLock);
+					kfree(pReadData);
+					return Status;
+				}
+			}
+		}
+
+		Status = BeceemNVMWrite(Adapter, (PUINT)pReadData,
+			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes,
+			stNVMReadWrite.bVerify);
+		if (IsFlash2x(Adapter))
+			BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
+
+		Adapter->bHeaderChangeAllowed = false;
+
+		up(&Adapter->NVMRdmWrmLock);
+
+		if (Status != STATUS_SUCCESS) {
+			kfree(pReadData);
+			return Status;
+		}
+	}
+
+	do_gettimeofday(&tv1);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		" timetaken by Write/read :%ld msec\n",
+		(tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
+
+	kfree(pReadData);
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_flash2x_section_read(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_flash2x_readwrite sFlash2xRead = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	PUCHAR pReadBuff = NULL;
+	UINT NOB = 0;
+	UINT BuffSize = 0;
+	UINT ReadBytes = 0;
+	UINT ReadOffset = 0;
+	INT Status = STATUS_FAILURE;
+	void __user *OutPutBuff;
+
+	if (IsFlash2x(Adapter) != TRUE)	{
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Flash Does not have 2.x map");
+		return -EINVAL;
+	}
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+		DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	/* Reading FLASH 2.x READ structure */
+	if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,
+		sizeof(struct bcm_flash2x_readwrite)))
+		return -EFAULT;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.offset :%x", sFlash2xRead.offset);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify);
+
+	/* This was internal to driver for raw read.
+	 * now it has ben exposed to user space app.
+	 */
+	if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == false)
+		return STATUS_FAILURE;
+
+	NOB = sFlash2xRead.numOfBytes;
+	if (NOB > Adapter->uiSectorSize)
+		BuffSize = Adapter->uiSectorSize;
+	else
+		BuffSize = NOB;
+
+	ReadOffset = sFlash2xRead.offset;
+	OutPutBuff = IoBuffer.OutputBuffer;
+	pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
+
+	if (pReadBuff == NULL) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Memory allocation failed for Flash 2.x Read Structure");
+		return -ENOMEM;
+	}
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
+		up(&Adapter->NVMRdmWrmLock);
+		kfree(pReadBuff);
+		return -EACCES;
+	}
+
+	while (NOB) {
+		if (NOB > Adapter->uiSectorSize)
+			ReadBytes = Adapter->uiSectorSize;
+		else
+			ReadBytes = NOB;
+
+		/* Reading the data from Flash 2.x */
+		Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff,
+			sFlash2xRead.Section, ReadOffset, ReadBytes);
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter,
+				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Flash 2x read err with Status :%d",
+				Status);
+			break;
+		}
+
+		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+			DBG_LVL_ALL, pReadBuff, ReadBytes);
+
+		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter,
+				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Copy to use failed with status :%d", Status);
+			up(&Adapter->NVMRdmWrmLock);
+			kfree(pReadBuff);
+			return -EFAULT;
+		}
+		NOB = NOB - ReadBytes;
+		if (NOB) {
+			ReadOffset = ReadOffset + ReadBytes;
+			OutPutBuff = OutPutBuff + ReadBytes;
+		}
+	}
+
+	up(&Adapter->NVMRdmWrmLock);
+	kfree(pReadBuff);
+	return Status;
+}
+
+static int bcm_char_ioctl_flash2x_section_write(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_flash2x_readwrite sFlash2xWrite = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	PUCHAR pWriteBuff;
+	void __user *InputAddr;
+	UINT NOB = 0;
+	UINT BuffSize = 0;
+	UINT WriteOffset = 0;
+	UINT WriteBytes = 0;
+	INT Status = STATUS_FAILURE;
+
+	if (IsFlash2x(Adapter) != TRUE) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Flash Does not have 2.x map");
+		return -EINVAL;
+	}
+
+	/* First make this False so that we can enable the Sector
+	 * Permission Check in BeceemFlashBulkWrite
+	 */
+	Adapter->bAllDSDWriteAllow = false;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	/* Reading FLASH 2.x READ structure */
+	if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer,
+		sizeof(struct bcm_flash2x_readwrite)))
+		return -EFAULT;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.offset :%d", sFlash2xWrite.offset);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify);
+
+	if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1)
+		&& (sFlash2xWrite.Section != VSA2)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Only VSA write is allowed");
+		return -EINVAL;
+	}
+
+	if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == false)
+		return STATUS_FAILURE;
+
+	InputAddr = sFlash2xWrite.pDataBuff;
+	WriteOffset = sFlash2xWrite.offset;
+	NOB = sFlash2xWrite.numOfBytes;
+
+	if (NOB > Adapter->uiSectorSize)
+		BuffSize = Adapter->uiSectorSize;
+	else
+		BuffSize = NOB;
+
+	pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
+
+	if (pWriteBuff == NULL)
+		return -ENOMEM;
+
+	/* extracting the remainder of the given offset. */
+	WriteBytes = Adapter->uiSectorSize;
+	if (WriteOffset % Adapter->uiSectorSize)
+		WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
+
+	if (NOB < WriteBytes)
+		WriteBytes = NOB;
+
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Device is in Idle/Shutdown Mode\n");
+		up(&Adapter->NVMRdmWrmLock);
+		kfree(pWriteBuff);
+		return -EACCES;
+	}
+
+	BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section);
+	do {
+		Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes);
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Copy to user failed with status :%d", Status);
+			up(&Adapter->NVMRdmWrmLock);
+			kfree(pWriteBuff);
+			return -EFAULT;
+		}
+		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS,
+			OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes);
+
+		/* Writing the data from Flash 2.x */
+		Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff,
+			sFlash2xWrite.Section, WriteOffset, WriteBytes,
+			sFlash2xWrite.bVerify);
+
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Flash 2x read err with Status :%d", Status);
+			break;
+		}
+
+		NOB = NOB - WriteBytes;
+		if (NOB) {
+			WriteOffset = WriteOffset + WriteBytes;
+			InputAddr = InputAddr + WriteBytes;
+			if (NOB > Adapter->uiSectorSize)
+				WriteBytes = Adapter->uiSectorSize;
+			else
+				WriteBytes = NOB;
+		}
+	} while (NOB > 0);
+
+	BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section);
+	up(&Adapter->NVMRdmWrmLock);
+	kfree(pWriteBuff);
+	return Status;
+}
+
+static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_flash2x_bitmap *psFlash2xBitMap;
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_FAILURE;
+
+BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+	"IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
+		return -EINVAL;
+
+	psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
+	if (psFlash2xBitMap == NULL) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Memory is not available");
+		return -ENOMEM;
+	}
+
+	/* Reading the Flash Sectio Bit map */
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Device is in Idle/Shutdown Mode\n");
+		up(&Adapter->NVMRdmWrmLock);
+		kfree(psFlash2xBitMap);
+		return -EACCES;
+	}
+
+	BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
+	up(&Adapter->NVMRdmWrmLock);
+	if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap,
+		sizeof(struct bcm_flash2x_bitmap))) {
+		kfree(psFlash2xBitMap);
+		return -EFAULT;
+	}
+
+	kfree(psFlash2xBitMap);
+	return Status;
+}
+
+static int bcm_char_ioctl_set_active_section(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
+	INT Status = STATUS_FAILURE;
+	struct bcm_ioctl_buffer IoBuffer;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL_BCM_SET_ACTIVE_SECTION Called");
+
+	if (IsFlash2x(Adapter) != TRUE) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Flash Does not have 2.x map");
+		return -EINVAL;
+	}
+
+	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of IOCTL BUFFER failed");
+		return -EFAULT;
+	}
+
+	Status = copy_from_user(&eFlash2xSectionVal,
+		IoBuffer.InputBuffer, sizeof(INT));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of flash section val failed");
+		return -EFAULT;
+	}
+
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Device is in Idle/Shutdown Mode\n");
+		up(&Adapter->NVMRdmWrmLock);
+		return -EACCES;
+	}
+
+	Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal);
+	if (Status)
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Failed to make it's priority Highest. Status %d",
+			Status);
+
+	up(&Adapter->NVMRdmWrmLock);
+
+	return Status;
+}
+
+static int bcm_char_ioctl_copy_section(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_flash2x_copy_section sCopySectStrut = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_SUCCESS;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL_BCM_COPY_SECTION  Called");
+
+	Adapter->bAllDSDWriteAllow = false;
+	if (IsFlash2x(Adapter) != TRUE) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Flash Does not have 2.x map");
+		return -EINVAL;
+	}
+
+	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of IOCTL BUFFER failed Status :%d", Status);
+		return -EFAULT;
+	}
+
+	Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer,
+			sizeof(struct bcm_flash2x_copy_section));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of Copy_Section_Struct failed with Status :%d",
+			Status);
+		return -EFAULT;
+	}
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"Source SEction :%x", sCopySectStrut.SrcSection);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"Destination SEction :%x", sCopySectStrut.DstSection);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"offset :%x", sCopySectStrut.offset);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"NOB :%x", sCopySectStrut.numOfBytes);
+
+	if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Source Section<%x> does not exist in Flash ",
+			sCopySectStrut.SrcSection);
+		return -EINVAL;
+	}
+
+	if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Destinatio Section<%x> does not exist in Flash ",
+			sCopySectStrut.DstSection);
+		return -EINVAL;
+	}
+
+	if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Source and Destination section should be different");
+		return -EINVAL;
+	}
+
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"Device is in Idle/Shutdown Mode\n");
+		up(&Adapter->NVMRdmWrmLock);
+		return -EACCES;
+	}
+
+	if (sCopySectStrut.SrcSection == ISO_IMAGE1 ||
+		sCopySectStrut.SrcSection == ISO_IMAGE2) {
+		if (IsNonCDLessDevice(Adapter)) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Device is Non-CDLess hence won't have ISO !!");
+			Status = -EINVAL;
+		} else if (sCopySectStrut.numOfBytes == 0) {
+			Status = BcmCopyISO(Adapter, sCopySectStrut);
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Partial Copy of ISO section is not Allowed..");
+			Status = STATUS_FAILURE;
+		}
+		up(&Adapter->NVMRdmWrmLock);
+		return Status;
+	}
+
+	Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
+				sCopySectStrut.DstSection,
+				sCopySectStrut.offset,
+				sCopySectStrut.numOfBytes);
+	up(&Adapter->NVMRdmWrmLock);
+	return Status;
+}
+
+static int bcm_char_ioctl_get_flash_cs_info(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_SUCCESS;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		" IOCTL_BCM_GET_FLASH_CS_INFO Called");
+
+	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of IOCTL BUFFER failed");
+		return -EFAULT;
+	}
+
+	if (Adapter->eNVMType != NVM_FLASH) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Connected device does not have flash");
+		return -EINVAL;
+	}
+
+	if (IsFlash2x(Adapter) == TRUE) {
+		if (IoBuffer.OutputLength < sizeof(struct bcm_flash2x_cs_info))
+			return -EINVAL;
+
+		if (copy_to_user(IoBuffer.OutputBuffer,
+			Adapter->psFlash2xCSInfo,
+			sizeof(struct bcm_flash2x_cs_info)))
+			return -EFAULT;
+	} else {
+		if (IoBuffer.OutputLength < sizeof(struct bcm_flash_cs_info))
+			return -EINVAL;
+
+		if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo,
+			sizeof(struct bcm_flash_cs_info)))
+			return -EFAULT;
+	}
+	return Status;
+}
+
+static int bcm_char_ioctl_select_dsd(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_FAILURE;
+	UINT SectOfset = 0;
+	enum bcm_flash2x_section_val eFlash2xSectionVal;
+
+	eFlash2xSectionVal = NO_SECTION_VAL;
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL_BCM_SELECT_DSD Called");
+
+	if (IsFlash2x(Adapter) != TRUE) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Flash Does not have 2.x map");
+		return -EINVAL;
+	}
+
+	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of IOCTL BUFFER failed");
+		return -EFAULT;
+	}
+	Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer,
+		sizeof(INT));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Copy of flash section val failed");
+		return -EFAULT;
+	}
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"Read Section :%d", eFlash2xSectionVal);
+	if ((eFlash2xSectionVal != DSD0) &&
+		(eFlash2xSectionVal != DSD1) &&
+		(eFlash2xSectionVal != DSD2)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Passed section<%x> is not DSD section",
+			eFlash2xSectionVal);
+		return STATUS_FAILURE;
+	}
+
+	SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
+	if (SectOfset == INVALID_OFFSET) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Provided Section val <%d> does not exist in Flash 2.x",
+			eFlash2xSectionVal);
+		return -EINVAL;
+	}
+
+	Adapter->bAllDSDWriteAllow = TRUE;
+	Adapter->ulFlashCalStart = SectOfset;
+	Adapter->eActiveDSD = eFlash2xSectionVal;
+
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_nvm_raw_read(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_nvm_readwrite stNVMRead;
+	struct bcm_ioctl_buffer IoBuffer;
+	unsigned int NOB;
+	INT BuffSize;
+	INT ReadOffset = 0;
+	UINT ReadBytes = 0;
+	PUCHAR pReadBuff;
+	void __user *OutPutBuff;
+	INT Status = STATUS_FAILURE;
+
+	if (Adapter->eNVMType != NVM_FLASH) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"NVM TYPE is not Flash");
+		return -EINVAL;
+	}
+
+	/* Copy Ioctl Buffer structure */
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"copy_from_user 1 failed\n");
+		return -EFAULT;
+	}
+
+	if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,
+		sizeof(struct bcm_nvm_readwrite)))
+		return -EFAULT;
+
+	NOB = stNVMRead.uiNumBytes;
+	/* In Raw-Read max Buff size : 64MB */
+
+	if (NOB > DEFAULT_BUFF_SIZE)
+		BuffSize = DEFAULT_BUFF_SIZE;
+	else
+		BuffSize = NOB;
+
+	ReadOffset = stNVMRead.uiOffset;
+	OutPutBuff = stNVMRead.pBuffer;
+
+	pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
+	if (pReadBuff == NULL) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+			"Memory allocation failed for Flash 2.x Read Structure");
+		return -ENOMEM;
+	}
+	down(&Adapter->NVMRdmWrmLock);
+
+	if ((Adapter->IdleMode == TRUE) ||
+		(Adapter->bShutStatus == TRUE) ||
+		(Adapter->bPreparingForLowPowerMode == TRUE)) {
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
+		kfree(pReadBuff);
+		up(&Adapter->NVMRdmWrmLock);
+		return -EACCES;
+	}
+
+	Adapter->bFlashRawRead = TRUE;
+
+	while (NOB) {
+		if (NOB > DEFAULT_BUFF_SIZE)
+			ReadBytes = DEFAULT_BUFF_SIZE;
+		else
+			ReadBytes = NOB;
+
+		/* Reading the data from Flash 2.x */
+		Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff,
+			ReadOffset, ReadBytes);
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Flash 2x read err with Status :%d", Status);
+			break;
+		}
+
+		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+			DBG_LVL_ALL, pReadBuff, ReadBytes);
+
+		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Copy to use failed with status :%d", Status);
+			up(&Adapter->NVMRdmWrmLock);
+			kfree(pReadBuff);
+			return -EFAULT;
+		}
+		NOB = NOB - ReadBytes;
+		if (NOB) {
+			ReadOffset = ReadOffset + ReadBytes;
+			OutPutBuff = OutPutBuff + ReadBytes;
+		}
+	}
+	Adapter->bFlashRawRead = false;
+	up(&Adapter->NVMRdmWrmLock);
+	kfree(pReadBuff);
+	return Status;
+}
+
+static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp,
+	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
+{
+	struct bcm_ioctl_buffer IoBuffer;
+	INT Status = STATUS_FAILURE;
+	ULONG RxCntrlMsgBitMask = 0;
+
+	/* Copy Ioctl Buffer structure */
+	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"copy of Ioctl buffer is failed from user space");
+		return -EFAULT;
+	}
+
+	if (IoBuffer.InputLength != sizeof(unsigned long))
+		return -EINVAL;
+
+	Status = copy_from_user(&RxCntrlMsgBitMask,
+		IoBuffer.InputBuffer, IoBuffer.InputLength);
+	if (Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"copy of control bit mask failed from user space");
+		return -EFAULT;
+	}
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"\n Got user defined cntrl msg bit mask :%lx",
+		RxCntrlMsgBitMask);
+	pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask;
+
+	return Status;
+}
+
+static int bcm_char_ioctl_get_device_driver_info(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_driver_info DevInfo;
+	struct bcm_ioctl_buffer IoBuffer;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+		DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
+
+	memset(&DevInfo, 0, sizeof(DevInfo));
+	DevInfo.MaxRDMBufferSize = BUFFER_4K;
+	DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
+	DevInfo.u32RxAlignmentCorrection = 0;
+	DevInfo.u32NVMType = Adapter->eNVMType;
+	DevInfo.u32InterfaceType = BCM_USB;
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength < sizeof(DevInfo))
+		return -EINVAL;
+
+	if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
+		return -EFAULT;
+
+	return STATUS_SUCCESS;
+}
+
+static int bcm_char_ioctl_time_since_net_entry(void __user *argp,
+	struct bcm_mini_adapter *Adapter)
+{
+	struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
+	struct bcm_ioctl_buffer IoBuffer;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+		"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
+
+	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+		return -EFAULT;
+
+	if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
+		return -EINVAL;
+
+	stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry =
+		get_seconds() - Adapter->liTimeSinceLastNetEntry;
+
+	if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry,
+		sizeof(struct bcm_time_elapsed)))
+		return -EFAULT;
+
+	return STATUS_SUCCESS;
+}
+
+
 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 {
 	struct bcm_tarang_data *pTarang = filp->private_data;
 	void __user *argp = (void __user *)arg;
 	struct bcm_mini_adapter *Adapter = pTarang->Adapter;
 	INT Status = STATUS_FAILURE;
-	int timeout = 0;
-	struct bcm_ioctl_buffer IoBuffer;
-	int bytes;
 
 	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 			"Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX",
@@ -201,778 +2332,65 @@
 
 	switch (cmd) {
 	/* Rdms for Swin Idle... */
-	case IOCTL_BCM_REGISTER_READ_PRIVATE: {
-		struct bcm_rdm_buffer sRdmBuffer = {0};
-		PCHAR temp_buff;
-		UINT Bufflen;
-		u16 temp_value;
+	case IOCTL_BCM_REGISTER_READ_PRIVATE:
+		Status = bcm_char_ioctl_reg_read_private(argp, Adapter);
+		return Status;
 
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(sRdmBuffer))
-			return -EINVAL;
-
-		if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength > USHRT_MAX ||
-			IoBuffer.OutputLength == 0) {
-			return -EINVAL;
-		}
-
-		Bufflen = IoBuffer.OutputLength;
-		temp_value = 4 - (Bufflen % 4);
-		Bufflen += temp_value % 4;
-
-		temp_buff = kmalloc(Bufflen, GFP_KERNEL);
-		if (!temp_buff)
-			return -ENOMEM;
-
-		bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
-				(PUINT)temp_buff, Bufflen);
-		if (bytes > 0) {
-			Status = STATUS_SUCCESS;
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
-				kfree(temp_buff);
-				return -EFAULT;
-			}
-		} else {
-			Status = bytes;
-		}
-
-		kfree(temp_buff);
-		break;
-	}
-
-	case IOCTL_BCM_REGISTER_WRITE_PRIVATE: {
-		struct bcm_wrm_buffer sWrmBuffer = {0};
-		UINT uiTempVar = 0;
-		/* Copy Ioctl Buffer structure */
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(sWrmBuffer))
-			return -EINVAL;
-
-		/* Get WrmBuffer structure */
-		if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
-		if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
-			((uiTempVar == EEPROM_REJECT_REG_1) ||
-				(uiTempVar == EEPROM_REJECT_REG_2) ||
-				(uiTempVar == EEPROM_REJECT_REG_3) ||
-				(uiTempVar == EEPROM_REJECT_REG_4))) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"EEPROM Access Denied, not in VSG Mode\n");
-			return -EFAULT;
-		}
-
-		Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
-				(PUINT)sWrmBuffer.Data, sizeof(ULONG));
-
-		if (Status == STATUS_SUCCESS) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL, "WRM Done\n");
-		} else {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL, "WRM Failed\n");
-			Status = -EFAULT;
-		}
-		break;
-	}
+	case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
+		Status = bcm_char_ioctl_reg_write_private(argp, Adapter);
+		return Status;
 
 	case IOCTL_BCM_REGISTER_READ:
-	case IOCTL_BCM_EEPROM_REGISTER_READ: {
-		struct bcm_rdm_buffer sRdmBuffer = {0};
-		PCHAR temp_buff = NULL;
-		UINT uiTempVar = 0;
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
+	case IOCTL_BCM_EEPROM_REGISTER_READ:
+		Status = bcm_char_ioctl_eeprom_reg_read(argp, Adapter);
+		return Status;
 
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Device in Idle Mode, Blocking Rdms\n");
-			return -EACCES;
-		}
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(sRdmBuffer))
-			return -EINVAL;
-
-		if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength > USHRT_MAX ||
-			IoBuffer.OutputLength == 0) {
-			return -EINVAL;
-		}
-
-		temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
-		if (!temp_buff)
-			return STATUS_FAILURE;
-
-		if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
-			((ULONG)sRdmBuffer.Register & 0x3)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"RDM Done On invalid Address : %x Access Denied.\n",
-					(int)sRdmBuffer.Register);
-
-			kfree(temp_buff);
-			return -EINVAL;
-		}
-
-		uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
-		bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
-				       (PUINT)temp_buff, IoBuffer.OutputLength);
-
-		if (bytes > 0) {
-			Status = STATUS_SUCCESS;
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
-				kfree(temp_buff);
-				return -EFAULT;
-			}
-		} else {
-			Status = bytes;
-		}
-
-		kfree(temp_buff);
-		break;
-	}
 	case IOCTL_BCM_REGISTER_WRITE:
-	case IOCTL_BCM_EEPROM_REGISTER_WRITE: {
-		struct bcm_wrm_buffer sWrmBuffer = {0};
-		UINT uiTempVar = 0;
+	case IOCTL_BCM_EEPROM_REGISTER_WRITE:
+		Status = bcm_char_ioctl_eeprom_reg_write(argp, Adapter, cmd);
+		return Status;
 
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
+	case IOCTL_BCM_GPIO_SET_REQUEST:
+		Status = bcm_char_ioctl_gpio_set_request(argp, Adapter);
+		return Status;
 
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Device in Idle Mode, Blocking Wrms\n");
-			return -EACCES;
-		}
+	case BCM_LED_THREAD_STATE_CHANGE_REQ:
+		Status = bcm_char_ioctl_led_thread_state_change_req(argp, Adapter);
+		return Status;
 
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
+	case IOCTL_BCM_GPIO_STATUS_REQUEST:
+		Status = bcm_char_ioctl_gpio_status_request(argp, Adapter);
+		return Status;
 
-		if (IoBuffer.InputLength > sizeof(sWrmBuffer))
-			return -EINVAL;
+	case IOCTL_BCM_GPIO_MULTI_REQUEST:
+		Status = bcm_char_ioctl_gpio_multi_request(argp, Adapter);
+		return Status;
 
-		/* Get WrmBuffer structure */
-		if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
-			((ULONG)sWrmBuffer.Register & 0x3)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"WRM Done On invalid Address : %x Access Denied.\n",
-					(int)sWrmBuffer.Register);
-			return -EINVAL;
-		}
-
-		uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
-		if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
-				((uiTempVar == EEPROM_REJECT_REG_1) ||
-				(uiTempVar == EEPROM_REJECT_REG_2) ||
-				(uiTempVar == EEPROM_REJECT_REG_3) ||
-				(uiTempVar == EEPROM_REJECT_REG_4)) &&
-				(cmd == IOCTL_BCM_REGISTER_WRITE)) {
-
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"EEPROM Access Denied, not in VSG Mode\n");
-				return -EFAULT;
-		}
-
-		Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
-					(PUINT)sWrmBuffer.Data,
-					sWrmBuffer.Length);
-
-		if (Status == STATUS_SUCCESS) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG,
-					DBG_LVL_ALL, "WRM Done\n");
-		} else {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL, "WRM Failed\n");
-			Status = -EFAULT;
-		}
-		break;
-	}
-	case IOCTL_BCM_GPIO_SET_REQUEST: {
-		UCHAR ucResetValue[4];
-		UINT value = 0;
-		UINT uiBit = 0;
-		UINT uiOperation = 0;
-		struct bcm_gpio_info gpio_info = {0};
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"GPIO Can't be set/clear in Low power Mode");
-			return -EACCES;
-		}
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(gpio_info))
-			return -EINVAL;
-
-		if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		uiBit  = gpio_info.uiGpioNumber;
-		uiOperation = gpio_info.uiGpioValue;
-		value = (1<<uiBit);
-
-		if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
-					value);
-			Status = -EINVAL;
-			break;
-		}
-
-		/* Set - setting 1 */
-		if (uiOperation) {
-			/* Set the gpio output register */
-			Status = wrmaltWithLock(Adapter,
-						BCM_GPIO_OUTPUT_SET_REG,
-						(PUINT)(&value), sizeof(UINT));
-
-			if (Status == STATUS_SUCCESS) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"Set the GPIO bit\n");
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"Failed to set the %dth GPIO\n",
-						uiBit);
-				break;
-			}
-		} else {
-			/* Set the gpio output register */
-			Status = wrmaltWithLock(Adapter,
-						BCM_GPIO_OUTPUT_CLR_REG,
-						(PUINT)(&value), sizeof(UINT));
-
-			if (Status == STATUS_SUCCESS) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"Set the GPIO bit\n");
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"Failed to clear the %dth GPIO\n",
-						uiBit);
-				break;
-			}
-		}
-
-		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
-				       (PUINT)ucResetValue, sizeof(UINT));
-		if (bytes < 0) {
-			Status = bytes;
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-					"GPIO_MODE_REGISTER read failed");
-			break;
-		} else {
-			Status = STATUS_SUCCESS;
-		}
-
-		/* Set the gpio mode register to output */
-		*(UINT *)ucResetValue |= (1<<uiBit);
-		Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
-					(PUINT)ucResetValue, sizeof(UINT));
-
-		if (Status == STATUS_SUCCESS) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"Set the GPIO to output Mode\n");
-		} else {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"Failed to put GPIO in Output Mode\n");
-			break;
-		}
-	}
-	break;
-
-	case BCM_LED_THREAD_STATE_CHANGE_REQ: {
-		struct bcm_user_thread_req threadReq = {0};
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-				"User made LED thread InActive");
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"GPIO Can't be set/clear in Low power Mode");
-			Status = -EACCES;
-			break;
-		}
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(threadReq))
-			return -EINVAL;
-
-		if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		/* if LED thread is running(Actively or Inactively) set it state to make inactive */
-		if (Adapter->LEDInfo.led_thread_running) {
-			if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"Activating thread req");
-				Adapter->DriverState = LED_THREAD_ACTIVE;
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
-						OSAL_DBG, DBG_LVL_ALL,
-						"DeActivating Thread req.....");
-				Adapter->DriverState = LED_THREAD_INACTIVE;
-			}
-
-			/* signal thread. */
-			wake_up(&Adapter->LEDInfo.notify_led_event);
-		}
-	}
-	break;
-
-	case IOCTL_BCM_GPIO_STATUS_REQUEST: {
-		ULONG uiBit = 0;
-		UCHAR ucRead[4];
-		struct bcm_gpio_info gpio_info = {0};
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE))
-			return -EACCES;
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(gpio_info))
-			return -EINVAL;
-
-		if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		uiBit = gpio_info.uiGpioNumber;
-
-		/* Set the gpio output register */
-		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
-					(PUINT)ucRead, sizeof(UINT));
-
-		if (bytes < 0) {
-			Status = bytes;
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"RDM Failed\n");
-			return Status;
-		} else {
-			Status = STATUS_SUCCESS;
-		}
-	}
-	break;
-
-	case IOCTL_BCM_GPIO_MULTI_REQUEST: {
-		UCHAR ucResetValue[4];
-		struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
-		struct bcm_gpio_multi_info *pgpio_multi_info = (struct bcm_gpio_multi_info *)gpio_multi_info;
-
-		memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE))
-			return -EINVAL;
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(gpio_multi_info))
-			return -EINVAL;
-
-		if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL,
-					"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
-					pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
-					Adapter->gpioBitMap);
-			Status = -EINVAL;
-			break;
-		}
-
-		/* Set the gpio output register */
-		if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
-			(pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
-			/* Set 1's in GPIO OUTPUT REGISTER */
-			*(UINT *)ucResetValue =  pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
-				pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
-				pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
-
-			if (*(UINT *) ucResetValue)
-				Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG,
-							(PUINT)ucResetValue, sizeof(ULONG));
-
-			if (Status != STATUS_SUCCESS) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
-				return Status;
-			}
-
-			/* Clear to 0's in GPIO OUTPUT REGISTER */
-			*(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
-						pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
-						(~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
-
-			if (*(UINT *) ucResetValue)
-				Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG));
-
-			if (Status != STATUS_SUCCESS) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
-				return Status;
-			}
-		}
-
-		if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
-			bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
-
-			if (bytes < 0) {
-				Status = bytes;
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"RDM to GPIO_PIN_STATE_REGISTER Failed.");
-				return Status;
-			} else {
-				Status = STATUS_SUCCESS;
-			}
-
-			pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
-								pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
-		}
-
-		Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Failed while copying Content to IOBufer for user space err:%d", Status);
-			return -EFAULT;
-		}
-	}
-	break;
-
-	case IOCTL_BCM_GPIO_MODE_REQUEST: {
-		UCHAR ucResetValue[4];
-		struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
-		struct bcm_gpio_multi_mode *pgpio_multi_mode = (struct bcm_gpio_multi_mode *)gpio_multi_mode;
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE))
-			return -EINVAL;
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
-			return -EINVAL;
-
-		if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			return -EFAULT;
-
-		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
-
-		if (bytes < 0) {
-			Status = bytes;
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read of GPIO_MODE_REGISTER failed");
-			return Status;
-		} else {
-			Status = STATUS_SUCCESS;
-		}
-
-		/* Validating the request */
-		if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-					"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
-					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap);
-			Status = -EINVAL;
-			break;
-		}
-
-		if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
-			/* write all OUT's (1's) */
-			*(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
-						pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
-
-			/* write all IN's (0's) */
-			*(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
-						pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
-
-			/* Currently implemented return the modes of all GPIO's
-			 * else needs to bit AND with  mask
-			 */
-			pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
-
-			Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(ULONG));
-			if (Status == STATUS_SUCCESS) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-						"WRM to GPIO_MODE_REGISTER Done");
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"WRM to GPIO_MODE_REGISTER Failed");
-				Status = -EFAULT;
-				break;
-			}
-		} else {
-/* if uiGPIOMask is 0 then return mode register configuration */
-			pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
-		}
-
-		Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Failed while copying Content to IOBufer for user space err:%d", Status);
-			return -EFAULT;
-		}
-	}
-	break;
+	case IOCTL_BCM_GPIO_MODE_REQUEST:
+		Status = bcm_char_ioctl_gpio_mode_request(argp, Adapter);
+		return Status;
 
 	case IOCTL_MAC_ADDR_REQ:
 	case IOCTL_LINK_REQ:
 	case IOCTL_CM_REQUEST:
 	case IOCTL_SS_INFO_REQ:
 	case IOCTL_SEND_CONTROL_MESSAGE:
-	case IOCTL_IDLE_REQ: {
-		PVOID pvBuffer = NULL;
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
-			return -EINVAL;
-
-		if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
-			return -EINVAL;
-
-		pvBuffer = memdup_user(IoBuffer.InputBuffer,
-				       IoBuffer.InputLength);
-		if (IS_ERR(pvBuffer))
-			return PTR_ERR(pvBuffer);
-
-		down(&Adapter->LowPowerModeSync);
-		Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
-							!Adapter->bPreparingForLowPowerMode,
-							(1 * HZ));
-		if (Status == -ERESTARTSYS)
-			goto cntrlEnd;
-
-		if (Adapter->bPreparingForLowPowerMode) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-					"Preparing Idle Mode is still True - Hence Rejecting control message\n");
-			Status = STATUS_FAILURE;
-			goto cntrlEnd;
-		}
-		Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
-
-cntrlEnd:
-		up(&Adapter->LowPowerModeSync);
-		kfree(pvBuffer);
-		break;
-	}
-
-	case IOCTL_BCM_BUFFER_DOWNLOAD_START: {
-		if (down_trylock(&Adapter->NVMRdmWrmLock)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
-					"IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
-			return -EACCES;
-		}
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-				"Starting the firmware download PID =0x%x!!!!\n", current->pid);
-
-		if (down_trylock(&Adapter->fw_download_sema))
-			return -EBUSY;
-
-		Adapter->bBinDownloaded = false;
-		Adapter->fw_download_process_pid = current->pid;
-		Adapter->bCfgDownloaded = false;
-		Adapter->fw_download_done = false;
-		netif_carrier_off(Adapter->dev);
-		netif_stop_queue(Adapter->dev);
-		Status = reset_card_proc(Adapter);
-		if (Status) {
-			pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
-			up(&Adapter->fw_download_sema);
-			up(&Adapter->NVMRdmWrmLock);
-			return Status;
-		}
-		mdelay(10);
-
-		up(&Adapter->NVMRdmWrmLock);
+	case IOCTL_IDLE_REQ:
+		Status = bcm_char_ioctl_misc_request(argp, Adapter);
 		return Status;
-	}
 
-	case IOCTL_BCM_BUFFER_DOWNLOAD: {
-		struct bcm_firmware_info *psFwInfo = NULL;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
-
-		if (!down_trylock(&Adapter->fw_download_sema)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Invalid way to download buffer. Use Start and then call this!!!\n");
-			up(&Adapter->fw_download_sema);
-			Status = -EINVAL;
-			return Status;
-		}
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
-			up(&Adapter->fw_download_sema);
-			return -EFAULT;
-		}
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-				"Length for FW DLD is : %lx\n", IoBuffer.InputLength);
-
-		if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) {
-			up(&Adapter->fw_download_sema);
-			return -EINVAL;
-		}
-
-		psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
-		if (!psFwInfo) {
-			up(&Adapter->fw_download_sema);
-			return -ENOMEM;
-		}
-
-		if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
-			up(&Adapter->fw_download_sema);
-			kfree(psFwInfo);
-			return -EFAULT;
-		}
-
-		if (!psFwInfo->pvMappedFirmwareAddress ||
-			(psFwInfo->u32FirmwareLength == 0)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
-					psFwInfo->u32FirmwareLength);
-			up(&Adapter->fw_download_sema);
-			kfree(psFwInfo);
-			Status = -EINVAL;
-			return Status;
-		}
-
-		Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
-
-		if (Status != STATUS_SUCCESS) {
-			if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
-			else
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,	"IOCTL: Firmware File Upload Failed\n");
-
-			/* up(&Adapter->fw_download_sema); */
-
-			if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
-				Adapter->DriverState = DRIVER_INIT;
-				Adapter->LEDInfo.bLedInitDone = false;
-				wake_up(&Adapter->LEDInfo.notify_led_event);
-			}
-		}
-
-		if (Status != STATUS_SUCCESS)
-			up(&Adapter->fw_download_sema);
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
-		kfree(psFwInfo);
+	case IOCTL_BCM_BUFFER_DOWNLOAD_START:
+		Status = bcm_char_ioctl_buffer_download_start(Adapter);
 		return Status;
-	}
 
-	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: {
-		if (!down_trylock(&Adapter->fw_download_sema)) {
-			up(&Adapter->fw_download_sema);
-			return -EINVAL;
-		}
-
-		if (down_trylock(&Adapter->NVMRdmWrmLock)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"FW download blocked as EEPROM Read/Write is in progress\n");
-			up(&Adapter->fw_download_sema);
-			return -EACCES;
-		}
-
-		Adapter->bBinDownloaded = TRUE;
-		Adapter->bCfgDownloaded = TRUE;
-		atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
-		Adapter->CurrNumRecvDescs = 0;
-		Adapter->downloadDDR = 0;
-
-		/* setting the Mips to Run */
-		Status = run_card_proc(Adapter);
-
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
-			up(&Adapter->fw_download_sema);
-			up(&Adapter->NVMRdmWrmLock);
-			return Status;
-		} else {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-					DBG_LVL_ALL, "Firm Download Over...\n");
-		}
-
-		mdelay(10);
-
-		/* Wait for MailBox Interrupt */
-		if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
-
-		timeout = 5*HZ;
-		Adapter->waiting_to_fw_download_done = false;
-		wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
-				Adapter->waiting_to_fw_download_done, timeout);
-		Adapter->fw_download_process_pid = INVALID_PID;
-		Adapter->fw_download_done = TRUE;
-		atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
-		Adapter->CurrNumRecvDescs = 0;
-		Adapter->PrevNumRecvDescs = 0;
-		atomic_set(&Adapter->cntrlpktCnt, 0);
-		Adapter->LinkUpStatus = 0;
-		Adapter->LinkStatus = 0;
-
-		if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
-			Adapter->DriverState = FW_DOWNLOAD_DONE;
-			wake_up(&Adapter->LEDInfo.notify_led_event);
-		}
-
-		if (!timeout)
-			Status = -ENODEV;
-
-		up(&Adapter->fw_download_sema);
-		up(&Adapter->NVMRdmWrmLock);
+	case IOCTL_BCM_BUFFER_DOWNLOAD:
+		Status = bcm_char_ioctl_buffer_download(argp, Adapter);
 		return Status;
-	}
+
+	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
+		Status = bcm_char_ioctl_buffer_download_stop(argp, Adapter);
+		return Status;
+
 
 	case IOCTL_BE_BUCKET_SIZE:
 		Status = 0;
@@ -986,35 +2404,13 @@
 			Status = -EFAULT;
 		break;
 
-	case IOCTL_CHIP_RESET: {
-		INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
-		if (NVMAccess) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
-			return -EACCES;
-		}
+	case IOCTL_CHIP_RESET:
+		Status = bcm_char_ioctl_chip_reset(Adapter);
+		return Status;
 
-		down(&Adapter->RxAppControlQueuelock);
-		Status = reset_card_proc(Adapter);
-		flushAllAppQ();
-		up(&Adapter->RxAppControlQueuelock);
-		up(&Adapter->NVMRdmWrmLock);
-		ResetCounters(Adapter);
-		break;
-	}
-
-	case IOCTL_QOS_THRESHOLD: {
-		USHORT uiLoopIndex;
-
-		Status = 0;
-		for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
-			if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
-					(unsigned long __user *)arg)) {
-				Status = -EFAULT;
-				break;
-			}
-		}
-		break;
-	}
+	case IOCTL_QOS_THRESHOLD:
+		Status = bcm_char_ioctl_qos_threshold(arg, Adapter);
+		return Status;
 
 	case IOCTL_DUMP_PACKET_INFO:
 		DumpPackInfo(Adapter);
@@ -1023,142 +2419,39 @@
 		break;
 
 	case IOCTL_GET_PACK_INFO:
-		if (copy_to_user(argp, &Adapter->PackInfo, sizeof(struct bcm_packet_info)*NO_OF_QUEUES))
+		if (copy_to_user(argp, &Adapter->PackInfo,
+			sizeof(struct bcm_packet_info)*NO_OF_QUEUES))
 			return -EFAULT;
 		Status = STATUS_SUCCESS;
 		break;
 
-	case IOCTL_BCM_SWITCH_TRANSFER_MODE: {
-		UINT uiData = 0;
-		if (copy_from_user(&uiData, argp, sizeof(UINT)))
-			return -EFAULT;
+	case IOCTL_BCM_SWITCH_TRANSFER_MODE:
+		Status = bcm_char_ioctl_switch_transfer_mode(argp, Adapter);
+		return Status;
 
-		if (uiData) {
-			/* Allow All Packets */
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
-				Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
-		} else {
-			/* Allow IP only Packets */
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
-			Adapter->TransferMode = IP_PACKET_ONLY_MODE;
-		}
-		Status = STATUS_SUCCESS;
-		break;
-	}
+	case IOCTL_BCM_GET_DRIVER_VERSION:
+		Status = bcm_char_ioctl_get_driver_version(argp);
+		return Status;
 
-	case IOCTL_BCM_GET_DRIVER_VERSION: {
-		ulong len;
+	case IOCTL_BCM_GET_CURRENT_STATUS:
+		Status = bcm_char_ioctl_get_current_status(argp, Adapter);
+		return Status;
 
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
+	case IOCTL_BCM_SET_MAC_TRACING:
+		Status = bcm_char_ioctl_set_mac_tracing(argp, Adapter);
+		return Status;
 
-		len = min_t(ulong, IoBuffer.OutputLength, strlen(DRV_VERSION) + 1);
+	case IOCTL_BCM_GET_DSX_INDICATION:
+		Status = bcm_char_ioctl_get_dsx_indication(argp, Adapter);
+		return Status;
 
-		if (copy_to_user(IoBuffer.OutputBuffer, DRV_VERSION, len))
-			return -EFAULT;
-		Status = STATUS_SUCCESS;
-		break;
-	}
-
-	case IOCTL_BCM_GET_CURRENT_STATUS: {
-		struct bcm_link_state link_state;
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
-			return -EFAULT;
-		}
-
-		if (IoBuffer.OutputLength != sizeof(link_state)) {
-			Status = -EINVAL;
-			break;
-		}
-
-		memset(&link_state, 0, sizeof(link_state));
-		link_state.bIdleMode = Adapter->IdleMode;
-		link_state.bShutdownMode = Adapter->bShutStatus;
-		link_state.ucLinkStatus = Adapter->LinkStatus;
-
-		if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
-			return -EFAULT;
-		}
-		Status = STATUS_SUCCESS;
-		break;
-	}
-
-	case IOCTL_BCM_SET_MAC_TRACING: {
-		UINT  tracing_flag;
-
-		/* copy ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
-			return -EFAULT;
-
-		if (tracing_flag)
-			Adapter->pTarangs->MacTracingEnabled = TRUE;
-		else
-			Adapter->pTarangs->MacTracingEnabled = false;
-		break;
-	}
-
-	case IOCTL_BCM_GET_DSX_INDICATION: {
-		ULONG ulSFId = 0;
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Mismatch req: %lx needed is =0x%zx!!!",
-					IoBuffer.OutputLength, sizeof(struct bcm_add_indication_alt));
-			return -EINVAL;
-		}
-
-		if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
-			return -EFAULT;
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId);
-		get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
-		Status = STATUS_SUCCESS;
-	}
-	break;
-
-	case IOCTL_BCM_GET_HOST_MIBS: {
-		PVOID temp_buff;
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Length Check failed %lu %zd\n",
-					IoBuffer.OutputLength, sizeof(struct bcm_host_stats_mibs));
-			return -EINVAL;
-		}
-
-		/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
-		temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
-		if (!temp_buff)
-			return STATUS_FAILURE;
-
-		Status = ProcessGetHostMibs(Adapter, temp_buff);
-		GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
-
-		if (Status != STATUS_FAILURE)
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(struct bcm_host_stats_mibs))) {
-				kfree(temp_buff);
-				return -EFAULT;
-			}
-
-		kfree(temp_buff);
-		break;
-	}
+	case IOCTL_BCM_GET_HOST_MIBS:
+		Status = bcm_char_ioctl_get_host_mibs(argp, Adapter, pTarang);
+		return Status;
 
 	case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
-		if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE == Adapter->IdleMode)) {
+		if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) &&
+			(TRUE == Adapter->IdleMode)) {
 			Adapter->usIdleModePattern = ABORT_IDLE_MODE;
 			Adapter->bWakeUpDevice = TRUE;
 			wake_up(&Adapter->process_rx_cntrlpkt);
@@ -1167,886 +2460,82 @@
 		Status = STATUS_SUCCESS;
 		break;
 
-	case IOCTL_BCM_BULK_WRM: {
-		struct bcm_bulk_wrm_buffer *pBulkBuffer;
-		UINT uiTempVar = 0;
-		PCHAR pvBuffer = NULL;
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n");
-			Status = -EACCES;
-			break;
-		}
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.InputLength < sizeof(ULONG) * 2)
-			return -EINVAL;
-
-		pvBuffer = memdup_user(IoBuffer.InputBuffer,
-				       IoBuffer.InputLength);
-		if (IS_ERR(pvBuffer))
-			return PTR_ERR(pvBuffer);
-
-		pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;
-
-		if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
-			((ULONG)pBulkBuffer->Register & 0x3)) {
-			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)pBulkBuffer->Register);
-			kfree(pvBuffer);
-			Status = -EINVAL;
-			break;
-		}
-
-		uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
-		if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) &&
-			((uiTempVar == EEPROM_REJECT_REG_1) ||
-				(uiTempVar == EEPROM_REJECT_REG_2) ||
-				(uiTempVar == EEPROM_REJECT_REG_3) ||
-				(uiTempVar == EEPROM_REJECT_REG_4)) &&
-			(cmd == IOCTL_BCM_REGISTER_WRITE)) {
-
-			kfree(pvBuffer);
-			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
-			Status = -EFAULT;
-			break;
-		}
-
-		if (pBulkBuffer->SwapEndian == false)
-			Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
-		else
-			Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
-
-		if (Status != STATUS_SUCCESS)
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
-
-		kfree(pvBuffer);
-		break;
-	}
+	case IOCTL_BCM_BULK_WRM:
+		Status = bcm_char_ioctl_bulk_wrm(argp, Adapter, cmd);
+		return Status;
 
 	case IOCTL_BCM_GET_NVM_SIZE:
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
+		Status = bcm_char_ioctl_get_nvm_size(argp, Adapter);
+		return Status;
 
-		if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
-			if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT)))
-				return -EFAULT;
-		}
-
-		Status = STATUS_SUCCESS;
-		break;
-
-	case IOCTL_BCM_CAL_INIT: {
-		UINT uiSectorSize = 0;
-		if (Adapter->eNVMType == NVM_FLASH) {
-			if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-				return -EFAULT;
-
-			if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
-				return -EFAULT;
-
-			if ((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) {
-				if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize,
-							sizeof(UINT)))
-					return -EFAULT;
-			} else {
-				if (IsFlash2x(Adapter)) {
-					if (copy_to_user(IoBuffer.OutputBuffer,	&Adapter->uiSectorSize, sizeof(UINT)))
-						return -EFAULT;
-				} else {
-					if ((TRUE == Adapter->bShutStatus) || (TRUE == Adapter->IdleMode)) {
-						BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is in Idle/Shutdown Mode\n");
-						return -EACCES;
-					}
-
-					Adapter->uiSectorSize = uiSectorSize;
-					BcmUpdateSectorSize(Adapter, Adapter->uiSectorSize);
-				}
-			}
-			Status = STATUS_SUCCESS;
-		} else {
-			Status = STATUS_FAILURE;
-		}
-	}
-	break;
+	case IOCTL_BCM_CAL_INIT:
+		Status = bcm_char_ioctl_cal_init(argp, Adapter);
+		return Status;
 
 	case IOCTL_BCM_SET_DEBUG:
-#ifdef DEBUG
-	{
-		struct bcm_user_debug_state sUserDebugState;
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(struct bcm_user_debug_state)))
-			return -EFAULT;
-
-		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
-				sUserDebugState.OnOff, sUserDebugState.Type);
-		/* sUserDebugState.Subtype <<= 1; */
-		sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
-		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype);
-
-		/* Update new 'DebugState' in the Adapter */
-		Adapter->stDebugState.type |= sUserDebugState.Type;
-		/* Subtype: A bitmap of 32 bits for Subtype per Type.
-		 * Valid indexes in 'subtype' array: 1,2,4,8
-		 * corresponding to valid Type values. Hence we can use the 'Type' field
-		 * as the index value, ignoring the array entries 0,3,5,6,7 !
-		 */
-		if (sUserDebugState.OnOff)
-			Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype;
-		else
-			Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype;
-
-		BCM_SHOW_DEBUG_BITMAP(Adapter);
-	}
-#endif
-	break;
+		Status = bcm_char_ioctl_set_debug(argp, Adapter);
+		return Status;
 
 	case IOCTL_BCM_NVM_READ:
-	case IOCTL_BCM_NVM_WRITE: {
-		struct bcm_nvm_readwrite stNVMReadWrite;
-		PUCHAR pReadData = NULL;
-		ULONG ulDSDMagicNumInUsrBuff = 0;
-		struct timeval tv0, tv1;
-		memset(&tv0, 0, sizeof(struct timeval));
-		memset(&tv1, 0, sizeof(struct timeval));
-		if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
-			return -EFAULT;
-		}
+	case IOCTL_BCM_NVM_WRITE:
+		Status = bcm_char_ioctl_nvm_rw(argp, Adapter, cmd);
+		return Status;
 
-		if (IsFlash2x(Adapter)) {
-			if ((Adapter->eActiveDSD != DSD0) &&
-				(Adapter->eActiveDSD != DSD1) &&
-				(Adapter->eActiveDSD != DSD2)) {
+	case IOCTL_BCM_FLASH2X_SECTION_READ:
+		Status = bcm_char_ioctl_flash2x_section_read(argp, Adapter);
+		return Status;
 
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked");
-				return STATUS_FAILURE;
-			}
-		}
+	case IOCTL_BCM_FLASH2X_SECTION_WRITE:
+		Status = bcm_char_ioctl_flash2x_section_write(argp, Adapter);
+		return Status;
 
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
+	case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP:
+		Status = bcm_char_ioctl_flash2x_section_bitmap(argp, Adapter);
+		return Status;
 
-		if (copy_from_user(&stNVMReadWrite,
-					(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
-					sizeof(struct bcm_nvm_readwrite)))
-			return -EFAULT;
+	case IOCTL_BCM_SET_ACTIVE_SECTION:
+		Status = bcm_char_ioctl_set_active_section(argp, Adapter);
+		return Status;
 
-		/*
-		 * Deny the access if the offset crosses the cal area limit.
-		 */
-		if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
-			return STATUS_FAILURE;
-
-		if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) {
-			/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
-			return STATUS_FAILURE;
-		}
-
-		pReadData = memdup_user(stNVMReadWrite.pBuffer,
-					stNVMReadWrite.uiNumBytes);
-		if (IS_ERR(pReadData))
-			return PTR_ERR(pReadData);
-
-		do_gettimeofday(&tv0);
-		if (IOCTL_BCM_NVM_READ == cmd) {
-			down(&Adapter->NVMRdmWrmLock);
-
-			if ((Adapter->IdleMode == TRUE) ||
-				(Adapter->bShutStatus == TRUE) ||
-				(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-				up(&Adapter->NVMRdmWrmLock);
-				kfree(pReadData);
-				return -EACCES;
-			}
-
-			Status = BeceemNVMRead(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
-			up(&Adapter->NVMRdmWrmLock);
-
-			if (Status != STATUS_SUCCESS) {
-				kfree(pReadData);
-				return Status;
-			}
-
-			if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) {
-				kfree(pReadData);
-				return -EFAULT;
-			}
-		} else {
-			down(&Adapter->NVMRdmWrmLock);
-
-			if ((Adapter->IdleMode == TRUE) ||
-				(Adapter->bShutStatus == TRUE) ||
-				(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-				up(&Adapter->NVMRdmWrmLock);
-				kfree(pReadData);
-				return -EACCES;
-			}
-
-			Adapter->bHeaderChangeAllowed = TRUE;
-			if (IsFlash2x(Adapter)) {
-				/*
-				 *			New Requirement:-
-				 *			DSD section updation will be allowed in two case:-
-				 *			1.  if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
-				 *			2.  if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
-				 *			      corrupted then user space program first modify the DSD header with valid DSD sig so
-				 *			      that this as well as further write may be worthwhile.
-				 *
-				 *			 This restriction has been put assuming that if DSD sig is corrupted, DSD
-				 *			 data won't be considered valid.
-				 */
-
-				Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD);
-				if (Status != STATUS_SUCCESS) {
-					if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize) ||
-						(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {
-
-						BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
-						up(&Adapter->NVMRdmWrmLock);
-						kfree(pReadData);
-						return Status;
-					}
-
-					ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
-					if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) {
-						BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
-						up(&Adapter->NVMRdmWrmLock);
-						kfree(pReadData);
-						return Status;
-					}
-				}
-			}
-
-			Status = BeceemNVMWrite(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
-			if (IsFlash2x(Adapter))
-				BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
-
-			Adapter->bHeaderChangeAllowed = false;
-
-			up(&Adapter->NVMRdmWrmLock);
-
-			if (Status != STATUS_SUCCESS) {
-				kfree(pReadData);
-				return Status;
-			}
-		}
-
-		do_gettimeofday(&tv1);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
-
-		kfree(pReadData);
-		return STATUS_SUCCESS;
-	}
-
-	case IOCTL_BCM_FLASH2X_SECTION_READ: {
-		struct bcm_flash2x_readwrite sFlash2xRead = {0};
-		PUCHAR pReadBuff = NULL;
-		UINT NOB = 0;
-		UINT BuffSize = 0;
-		UINT ReadBytes = 0;
-		UINT ReadOffset = 0;
-		void __user *OutPutBuff;
-
-		if (IsFlash2x(Adapter) != TRUE)	{
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
-			return -EINVAL;
-		}
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		/* Reading FLASH 2.x READ structure */
-		if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
-			return -EFAULT;
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%x", sFlash2xRead.offset);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify);
-
-		/* This was internal to driver for raw read. now it has ben exposed to user space app. */
-		if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == false)
-			return STATUS_FAILURE;
-
-		NOB = sFlash2xRead.numOfBytes;
-		if (NOB > Adapter->uiSectorSize)
-			BuffSize = Adapter->uiSectorSize;
-		else
-			BuffSize = NOB;
-
-		ReadOffset = sFlash2xRead.offset;
-		OutPutBuff = IoBuffer.OutputBuffer;
-		pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
-
-		if (pReadBuff == NULL) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure");
-			return -ENOMEM;
-		}
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			up(&Adapter->NVMRdmWrmLock);
-			kfree(pReadBuff);
-			return -EACCES;
-		}
-
-		while (NOB) {
-			if (NOB > Adapter->uiSectorSize)
-				ReadBytes = Adapter->uiSectorSize;
-			else
-				ReadBytes = NOB;
-
-			/* Reading the data from Flash 2.x */
-			Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff, sFlash2xRead.Section, ReadOffset, ReadBytes);
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Flash 2x read err with Status :%d", Status);
-				break;
-			}
-
-			BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes);
-
-			Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy to use failed with status :%d", Status);
-				up(&Adapter->NVMRdmWrmLock);
-				kfree(pReadBuff);
-				return -EFAULT;
-			}
-			NOB = NOB - ReadBytes;
-			if (NOB) {
-				ReadOffset = ReadOffset + ReadBytes;
-				OutPutBuff = OutPutBuff + ReadBytes;
-			}
-		}
-
-		up(&Adapter->NVMRdmWrmLock);
-		kfree(pReadBuff);
-	}
-	break;
-
-	case IOCTL_BCM_FLASH2X_SECTION_WRITE: {
-		struct bcm_flash2x_readwrite sFlash2xWrite = {0};
-		PUCHAR pWriteBuff;
-		void __user *InputAddr;
-		UINT NOB = 0;
-		UINT BuffSize = 0;
-		UINT WriteOffset = 0;
-		UINT WriteBytes = 0;
-
-		if (IsFlash2x(Adapter) != TRUE) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
-			return -EINVAL;
-		}
-
-		/* First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite */
-		Adapter->bAllDSDWriteAllow = false;
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		/* Reading FLASH 2.x READ structure */
-		if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_readwrite)))
-			return -EFAULT;
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%d", sFlash2xWrite.offset);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify);
-
-		if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && (sFlash2xWrite.Section != VSA2)) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Only VSA write is allowed");
-			return -EINVAL;
-		}
-
-		if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == false)
-			return STATUS_FAILURE;
-
-		InputAddr = sFlash2xWrite.pDataBuff;
-		WriteOffset = sFlash2xWrite.offset;
-		NOB = sFlash2xWrite.numOfBytes;
-
-		if (NOB > Adapter->uiSectorSize)
-			BuffSize = Adapter->uiSectorSize;
-		else
-			BuffSize = NOB;
-
-		pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
-
-		if (pWriteBuff == NULL)
-			return -ENOMEM;
-
-		/* extracting the remainder of the given offset. */
-		WriteBytes = Adapter->uiSectorSize;
-		if (WriteOffset % Adapter->uiSectorSize)
-			WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
-
-		if (NOB < WriteBytes)
-			WriteBytes = NOB;
-
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			up(&Adapter->NVMRdmWrmLock);
-			kfree(pWriteBuff);
-			return -EACCES;
-		}
-
-		BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section);
-		do {
-			Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes);
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to user failed with status :%d", Status);
-				up(&Adapter->NVMRdmWrmLock);
-				kfree(pWriteBuff);
-				return -EFAULT;
-			}
-			BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes);
-
-			/* Writing the data from Flash 2.x */
-			Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff, sFlash2xWrite.Section, WriteOffset, WriteBytes, sFlash2xWrite.bVerify);
-
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status);
-				break;
-			}
-
-			NOB = NOB - WriteBytes;
-			if (NOB) {
-				WriteOffset = WriteOffset + WriteBytes;
-				InputAddr = InputAddr + WriteBytes;
-				if (NOB > Adapter->uiSectorSize)
-					WriteBytes = Adapter->uiSectorSize;
-				else
-					WriteBytes = NOB;
-			}
-		} while (NOB > 0);
-
-		BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section);
-		up(&Adapter->NVMRdmWrmLock);
-		kfree(pWriteBuff);
-	}
-	break;
-
-	case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: {
-		struct bcm_flash2x_bitmap *psFlash2xBitMap;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
-			return -EINVAL;
-
-		psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
-		if (psFlash2xBitMap == NULL) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory is not available");
-			return -ENOMEM;
-		}
-
-		/* Reading the Flash Sectio Bit map */
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			up(&Adapter->NVMRdmWrmLock);
-			kfree(psFlash2xBitMap);
-			return -EACCES;
-		}
-
-		BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
-		up(&Adapter->NVMRdmWrmLock);
-		if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(struct bcm_flash2x_bitmap))) {
-			kfree(psFlash2xBitMap);
-			return -EFAULT;
-		}
-
-		kfree(psFlash2xBitMap);
-	}
-	break;
-
-	case IOCTL_BCM_SET_ACTIVE_SECTION: {
-		enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
-
-		if (IsFlash2x(Adapter) != TRUE) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
-			return -EINVAL;
-		}
-
-		Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			return -EFAULT;
-		}
-
-		Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-			return -EFAULT;
-		}
-
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			up(&Adapter->NVMRdmWrmLock);
-			return -EACCES;
-		}
-
-		Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal);
-		if (Status)
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Failed to make it's priority Highest. Status %d", Status);
-
-		up(&Adapter->NVMRdmWrmLock);
-	}
-	break;
-
-	case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: {
+	case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION:
 		/* Right Now we are taking care of only DSD */
 		Adapter->bAllDSDWriteAllow = false;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+			"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
 		Status = STATUS_SUCCESS;
-	}
-	break;
-
-	case IOCTL_BCM_COPY_SECTION: {
-		struct bcm_flash2x_copy_section sCopySectStrut = {0};
-		Status = STATUS_SUCCESS;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION  Called");
-
-		Adapter->bAllDSDWriteAllow = false;
-		if (IsFlash2x(Adapter) != TRUE) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
-			return -EINVAL;
-		}
-
-		Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
-			return -EFAULT;
-		}
-
-		Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(struct bcm_flash2x_copy_section));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
-			return -EFAULT;
-		}
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset);
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes);
-
-		if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exist in Flash ", sCopySectStrut.SrcSection);
-			return -EINVAL;
-		}
-
-		if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exist in Flash ", sCopySectStrut.DstSection);
-			return -EINVAL;
-		}
-
-		if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source and Destination section should be different");
-			return -EINVAL;
-		}
-
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			up(&Adapter->NVMRdmWrmLock);
-			return -EACCES;
-		}
-
-		if (sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) {
-			if (IsNonCDLessDevice(Adapter)) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is Non-CDLess hence won't have ISO !!");
-				Status = -EINVAL;
-			} else if (sCopySectStrut.numOfBytes == 0) {
-				Status = BcmCopyISO(Adapter, sCopySectStrut);
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Partial Copy of ISO section is not Allowed..");
-				Status = STATUS_FAILURE;
-			}
-			up(&Adapter->NVMRdmWrmLock);
-			return Status;
-		}
-
-		Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
-					sCopySectStrut.DstSection, sCopySectStrut.offset, sCopySectStrut.numOfBytes);
-		up(&Adapter->NVMRdmWrmLock);
-	}
-	break;
-
-	case IOCTL_BCM_GET_FLASH_CS_INFO: {
-		Status = STATUS_SUCCESS;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
-
-		Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			return -EFAULT;
-		}
-
-		if (Adapter->eNVMType != NVM_FLASH) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Connected device does not have flash");
-			Status = -EINVAL;
-			break;
-		}
-
-		if (IsFlash2x(Adapter) == TRUE) {
-			if (IoBuffer.OutputLength < sizeof(struct bcm_flash2x_cs_info))
-				return -EINVAL;
-
-			if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(struct bcm_flash2x_cs_info)))
-				return -EFAULT;
-		} else {
-			if (IoBuffer.OutputLength < sizeof(struct bcm_flash_cs_info))
-				return -EINVAL;
-
-			if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(struct bcm_flash_cs_info)))
-				return -EFAULT;
-		}
-	}
-	break;
-
-	case IOCTL_BCM_SELECT_DSD: {
-		UINT SectOfset = 0;
-		enum bcm_flash2x_section_val eFlash2xSectionVal;
-		eFlash2xSectionVal = NO_SECTION_VAL;
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SELECT_DSD Called");
-
-		if (IsFlash2x(Adapter) != TRUE) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map");
-			return -EINVAL;
-		}
-
-		Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			return -EFAULT;
-		}
-		Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-			return -EFAULT;
-		}
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read Section :%d", eFlash2xSectionVal);
-		if ((eFlash2xSectionVal != DSD0) &&
-			(eFlash2xSectionVal != DSD1) &&
-			(eFlash2xSectionVal != DSD2)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Passed section<%x> is not DSD section", eFlash2xSectionVal);
-			return STATUS_FAILURE;
-		}
-
-		SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
-		if (SectOfset == INVALID_OFFSET) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section val <%d> does not exist in Flash 2.x", eFlash2xSectionVal);
-			return -EINVAL;
-		}
-
-		Adapter->bAllDSDWriteAllow = TRUE;
-		Adapter->ulFlashCalStart = SectOfset;
-		Adapter->eActiveDSD = eFlash2xSectionVal;
-	}
-	Status = STATUS_SUCCESS;
-	break;
-
-	case IOCTL_BCM_NVM_RAW_READ: {
-		struct bcm_nvm_readwrite stNVMRead;
-		INT NOB;
-		INT BuffSize;
-		INT ReadOffset = 0;
-		UINT ReadBytes = 0;
-		PUCHAR pReadBuff;
-		void __user *OutPutBuff;
-
-		if (Adapter->eNVMType != NVM_FLASH) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "NVM TYPE is not Flash");
-			return -EINVAL;
-		}
-
-		/* Copy Ioctl Buffer structure */
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
-			return -EFAULT;
-		}
-
-		if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(struct bcm_nvm_readwrite)))
-			return -EFAULT;
-
-		NOB = stNVMRead.uiNumBytes;
-		/* In Raw-Read max Buff size : 64MB */
-
-		if (NOB > DEFAULT_BUFF_SIZE)
-			BuffSize = DEFAULT_BUFF_SIZE;
-		else
-			BuffSize = NOB;
-
-		ReadOffset = stNVMRead.uiOffset;
-		OutPutBuff = stNVMRead.pBuffer;
-
-		pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
-		if (pReadBuff == NULL) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure");
-			Status = -ENOMEM;
-			break;
-		}
-		down(&Adapter->NVMRdmWrmLock);
-
-		if ((Adapter->IdleMode == TRUE) ||
-			(Adapter->bShutStatus == TRUE) ||
-			(Adapter->bPreparingForLowPowerMode == TRUE)) {
-
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
-			kfree(pReadBuff);
-			up(&Adapter->NVMRdmWrmLock);
-			return -EACCES;
-		}
-
-		Adapter->bFlashRawRead = TRUE;
-
-		while (NOB) {
-			if (NOB > DEFAULT_BUFF_SIZE)
-				ReadBytes = DEFAULT_BUFF_SIZE;
-			else
-				ReadBytes = NOB;
-
-			/* Reading the data from Flash 2.x */
-			Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff, ReadOffset, ReadBytes);
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status);
-				break;
-			}
-
-			BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes);
-
-			Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to use failed with status :%d", Status);
-				up(&Adapter->NVMRdmWrmLock);
-				kfree(pReadBuff);
-				return -EFAULT;
-			}
-			NOB = NOB - ReadBytes;
-			if (NOB) {
-				ReadOffset = ReadOffset + ReadBytes;
-				OutPutBuff = OutPutBuff + ReadBytes;
-			}
-		}
-		Adapter->bFlashRawRead = false;
-		up(&Adapter->NVMRdmWrmLock);
-		kfree(pReadBuff);
 		break;
-	}
 
-	case IOCTL_BCM_CNTRLMSG_MASK: {
-		ULONG RxCntrlMsgBitMask = 0;
+	case IOCTL_BCM_COPY_SECTION:
+		Status = bcm_char_ioctl_copy_section(argp, Adapter);
+		return Status;
 
-		/* Copy Ioctl Buffer structure */
-		Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space");
-			return -EFAULT;
-		}
+	case IOCTL_BCM_GET_FLASH_CS_INFO:
+		Status = bcm_char_ioctl_get_flash_cs_info(argp, Adapter);
+		return Status;
 
-		if (IoBuffer.InputLength != sizeof(unsigned long)) {
-			Status = -EINVAL;
-			break;
-		}
+	case IOCTL_BCM_SELECT_DSD:
+		Status = bcm_char_ioctl_select_dsd(argp, Adapter);
+		return Status;
 
-		Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
-		if (Status) {
-			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of control bit mask failed from user space");
-			return -EFAULT;
-		}
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
-		pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask;
-	}
-	break;
+	case IOCTL_BCM_NVM_RAW_READ:
+		Status = bcm_char_ioctl_nvm_raw_read(argp, Adapter);
+		return Status;
 
-	case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: {
-		struct bcm_driver_info DevInfo;
+	case IOCTL_BCM_CNTRLMSG_MASK:
+		Status = bcm_char_ioctl_cntrlmsg_mask(argp, Adapter, pTarang);
+		return Status;
 
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
+	case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
+		Status = bcm_char_ioctl_get_device_driver_info(argp, Adapter);
+		return Status;
 
-		memset(&DevInfo, 0, sizeof(DevInfo));
-		DevInfo.MaxRDMBufferSize = BUFFER_4K;
-		DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
-		DevInfo.u32RxAlignmentCorrection = 0;
-		DevInfo.u32NVMType = Adapter->eNVMType;
-		DevInfo.u32InterfaceType = BCM_USB;
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength < sizeof(DevInfo))
-			return -EINVAL;
-
-		if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
-			return -EFAULT;
-	}
-	break;
-
-	case IOCTL_BCM_TIME_SINCE_NET_ENTRY: {
-		struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
-
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
-
-		if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
-			return -EFAULT;
-
-		if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
-			return -EINVAL;
-
-		stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
-
-		if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(struct bcm_time_elapsed)))
-			return -EFAULT;
-	}
-	break;
+	case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
+		Status = bcm_char_ioctl_time_since_net_entry(argp, Adapter);
+		return Status;
 
 	case IOCTL_CLOSE_NOTIFICATION:
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+			DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION");
 		break;
 
 	default:
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
index cc91b5e..632f81a 100644
--- a/drivers/staging/bcm/CmHost.c
+++ b/drivers/staging/bcm/CmHost.c
@@ -975,8 +975,8 @@
 				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
-				DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: "
-				"%pM", psfCSType->cCPacketClassificationRule.
+				DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM",
+				psfCSType->cCPacketClassificationRule.
 						u8EthernetSourceMACAddress);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ",
@@ -1092,18 +1092,16 @@
 				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
-				DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: "
-				"0x%*ph ", 4, psfCSType->
-						cCPacketClassificationRule.
+				DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%*ph ",
+				4, psfCSType->cCPacketClassificationRule.
 						u8ProtocolSourcePortRange);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ",
 				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
-				DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: "
-				"0x%*ph ", 4, psfCSType->
-						cCPacketClassificationRule.
+				DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%*ph ",
+				4, psfCSType->cCPacketClassificationRule.
 						u8ProtocolDestPortRange);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ",
@@ -1118,8 +1116,8 @@
 				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL,
-				DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: "
-				"%pM", psfCSType->cCPacketClassificationRule.
+				DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM",
+				psfCSType->cCPacketClassificationRule.
 						u8EthernetSourceMACAddress);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength);
@@ -1637,6 +1635,8 @@
 	struct bcm_add_indication_alt *pstAddIndication = NULL;
 	struct bcm_change_indication *pstChangeIndication = NULL;
 	struct bcm_leader *pLeader = NULL;
+	INT uiSearchRuleIndex = 0;
+	ULONG ulSFID;
 
 	/*
 	 * Otherwise the message contains a target address from where we need to
@@ -1660,7 +1660,6 @@
 	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID);
 	switch (pstAddIndication->u8Type) {
 	case DSA_REQ:
-	{
 		pLeader->PLength = sizeof(struct bcm_add_indication_alt);
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength);
@@ -1671,22 +1670,16 @@
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
 		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
 		kfree(pstAddIndication);
-	}
-	break;
+		break;
 	case DSA_RSP:
-	{
 		pLeader->PLength = sizeof(struct bcm_add_indication_alt);
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
 				pLeader->PLength);
 		*((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
 			= *pstAddIndication;
 		((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
-
-	} /* no break here..we should go down. */
+		/* FALLTHROUGH */
 	case DSA_ACK:
-	{
-		UINT uiSearchRuleIndex = 0;
-
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
 				ntohs(pstAddIndication->u16VCID));
 		uiSearchRuleIndex = SearchFreeSfid(Adapter);
@@ -1694,7 +1687,7 @@
 				uiSearchRuleIndex);
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Direction:0x%X ",
 				pstAddIndication->u8Direction);
-		if ((uiSearchRuleIndex < NO_OF_QUEUES)) {
+		if (uiSearchRuleIndex < NO_OF_QUEUES) {
 			Adapter->PackInfo[uiSearchRuleIndex].ucDirection =
 				pstAddIndication->u8Direction;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ",
@@ -1769,10 +1762,8 @@
 			kfree(pstAddIndication);
 			return false;
 		}
-	}
-	break;
+		break;
 	case DSC_REQ:
-	{
 		pLeader->PLength = sizeof(struct bcm_change_indication);
 		pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
@@ -1782,26 +1773,21 @@
 
 		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
 		kfree(pstAddIndication);
-	}
-	break;
+		break;
 	case DSC_RSP:
-	{
 		pLeader->PLength = sizeof(struct bcm_change_indication);
 		pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
 		*((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
 		((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
-	}
+		/* FALLTHROUGH */
 	case DSC_ACK:
-	{
-		UINT uiSearchRuleIndex = 0;
-
 		pstChangeIndication = (struct bcm_change_indication *)pstAddIndication;
 		uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID));
 		if (uiSearchRuleIndex > NO_OF_QUEUES-1)
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
 
-		if ((uiSearchRuleIndex < NO_OF_QUEUES)) {
+		if (uiSearchRuleIndex < NO_OF_QUEUES) {
 			Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction;
 			if (pstChangeIndication->sfActiveSet.bValid == TRUE)
 				Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE;
@@ -1849,13 +1835,8 @@
 			kfree(pstAddIndication);
 			return false;
 		}
-	}
-	break;
+		break;
 	case DSD_REQ:
-	{
-		UINT uiSearchRuleIndex;
-		ULONG ulSFID;
-
 		pLeader->PLength = sizeof(struct bcm_del_indication);
 		*((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((struct bcm_del_indication *)pstAddIndication);
 
@@ -1872,12 +1853,10 @@
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");
 		((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;
 		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
-	}
+		/* FALLTHROUGH */
 	case DSD_RSP:
-	{
 		/* Do nothing as SF has already got Deleted */
-	}
-	break;
+		break;
 	case DSD_ACK:
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
 		break;
diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c
index ed285b2..f1d7cb8 100644
--- a/drivers/staging/bcm/DDRInit.c
+++ b/drivers/staging/bcm/DDRInit.c
@@ -3,7 +3,7 @@
 
 
 #define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
-#define MIPS_CLOCK_REG 	0x0f000820
+#define MIPS_CLOCK_REG 0x0f000820
 
 /* DDR INIT-133Mhz */
 #define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12  /* index for 0x0F007000 */
@@ -818,13 +818,13 @@
 	if ((Adapter->chip_id !=  BCS220_2) &&
 		(Adapter->chip_id !=  BCS220_2BC) &&
 		(Adapter->chip_id != BCS220_3)) {
-		retval = rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+		retval = rdmalt(Adapter, (UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
 		if (retval < 0) {
 			BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 			return retval;
 		}
 		uiResetValue |= 0x44;
-		retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+		retval = wrmalt(Adapter, (UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
 		if (retval < 0) {
 			BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 			return retval;
@@ -871,7 +871,7 @@
 	case 0xbece0121:
 	case 0xbece0130:
 	case 0xbece0300:
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
 		switch (Adapter->DDRSetting) {
 		case DDR_80_MHZ:
 			psDDRSetting = asT3_DDRSetting80MHz;
@@ -933,7 +933,7 @@
 	}
 
 	value = 0;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount);
 	while (RegCount && !retval) {
 		if (uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
 			value = uiClockSetting;
@@ -990,12 +990,12 @@
 		 * we will change this when we will have internal PMU.
 		 */
 		if (Adapter->PmuMode == HYBRID_MODE_7C) {
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
@@ -1006,12 +1006,12 @@
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
@@ -1024,12 +1024,12 @@
 			}
 		} else if (Adapter->PmuMode == HYBRID_MODE_6) {
 
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
@@ -1040,12 +1040,12 @@
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
 			}
-			retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+			retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
 			if (retval < 0) {
 				BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
 				return retval;
@@ -1094,8 +1094,8 @@
 			RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
 			psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
 			break;
-			default:
-			    return -EINVAL;
+		default:
+			return -EINVAL;
 		}
 		break;
 
@@ -1215,7 +1215,7 @@
 		ul_ddr_setting_load_addr += sizeof(ULONG);
 		if (!retval) {
 			if (bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) {
-				value = (psDDRSetting->ulRegValue |(1<<8));
+				value = (psDDRSetting->ulRegValue | (1<<8));
 			if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr,
 				&value, sizeof(value))) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
index 94f3272..7c04c73 100644
--- a/drivers/staging/bcm/InterfaceInit.c
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -1,5 +1,5 @@
 #include "headers.h"
-
+#include <linux/usb/ch9.h>
 static struct usb_device_id InterfaceUsbtable[] = {
 	{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
 	{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
@@ -30,19 +30,22 @@
 	int i = 0;
 
 	/* Wake up the wait_queue... */
-	if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
+	if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running &
+			BCM_LED_THREAD_RUNNING_ACTIVELY) {
 		psIntfAdapter->psAdapter->DriverState = DRIVER_HALT;
 		wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event);
 	}
 	reset_card_proc(psIntfAdapter->psAdapter);
 
 	/*
-	 * worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms
-	 * to accertain the device is not being accessed. After this No RDM/WRM should be made.
+	 * worst case time taken by the RDM/WRM will be 5 sec. will check after
+	 * every 100 ms to accertain the device is not being accessed. After
+	 * this No RDM/WRM should be made.
 	 */
 	while (psIntfAdapter->psAdapter->DeviceAccess) {
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-			"Device is being accessed.\n");
+		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT,
+				DRV_ENTRY, DBG_LVL_ALL,
+				"Device is being accessed.\n");
 		msleep(100);
 	}
 	/* Free interrupt URB */
@@ -71,6 +74,7 @@
 {
 	u32 ulReg;
 	int bytes;
+	struct bcm_interface_adapter *interfaceAdapter;
 
 	/* Program EP2 MAX_PKT_SIZE */
 	ulReg = ntohl(EP2_MPS_REG);
@@ -80,7 +84,9 @@
 
 	ulReg = ntohl(EP2_CFG_REG);
 	BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE);
-	if (((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) {
+	interfaceAdapter =
+		(struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
+	if (interfaceAdapter->bHighSpeedDevice) {
 		ulReg = ntohl(EP2_CFG_INT);
 		BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE);
 	} else {
@@ -98,8 +104,8 @@
 	/* Program TX EP as interrupt(Alternate Setting) */
 	bytes = rdmalt(Adapter, 0x0F0110F8, &ulReg, sizeof(u32));
 	if (bytes < 0) {
-		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-			"reading of Tx EP failed\n");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
+				DBG_LVL_ALL, "reading of Tx EP failed\n");
 		return;
 	}
 	ulReg |= 0x6;
@@ -150,7 +156,8 @@
 	struct net_device *ndev;
 
 	/* Reserve one extra queue for the bit-bucket */
-	ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter), NO_OF_QUEUES+1);
+	ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter),
+			NO_OF_QUEUES + 1);
 	if (ndev == NULL) {
 		dev_err(&udev->dev, DRV_NAME ": no memory for device\n");
 		return -ENOMEM;
@@ -169,13 +176,14 @@
 
 	/*
 	 * Technically, one can start using BCM_DEBUG_PRINT after this point.
-	 * However, realize that by default the Type/Subtype bitmaps are all zero now;
-	 * so no prints will actually appear until the TestApp turns on debug paths via
-	 * the ioctl(); so practically speaking, in early init, no logging happens.
+	 * However, realize that by default the Type/Subtype bitmaps are all
+	 * zero now; so no prints will actually appear until the TestApp turns
+	 * on debug paths via the ioctl(); so practically speaking, in early
+	 * init, no logging happens.
 	 *
-	 * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT
-	 * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug
-	 * during early init.
+	 * A solution (used below): we explicitly set the bitmaps to 1 for
+	 * Type=DBG_TYPE_INITEXIT and ALL subtype's of the same. Now all bcm
+	 * debug statements get logged, enabling debug during early init.
 	 * Further, we turn this OFF once init_module() completes.
 	 */
 
@@ -191,7 +199,7 @@
 
 	/* Allocate interface adapter structure */
 	psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter),
-				GFP_KERNEL);
+			GFP_KERNEL);
 	if (psIntfAdapter == NULL) {
 		AdapterFree(psAdapter);
 		return -ENOMEM;
@@ -205,7 +213,7 @@
 	usb_set_intfdata(intf, psIntfAdapter);
 
 	BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-		"psIntfAdapter 0x%p\n", psIntfAdapter);
+			"psIntfAdapter 0x%p\n", psIntfAdapter);
 	retval = InterfaceAdapterInit(psIntfAdapter);
 	if (retval) {
 		/* If the Firmware/Cfg File is not present
@@ -213,12 +221,13 @@
 		 * download the files.
 		 */
 		if (-ENOENT == retval) {
-			BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-				"File Not Found.  Use app to download.\n");
+			BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"File Not Found.  Use app to download.\n");
 			return STATUS_SUCCESS;
 		}
-		BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-			"InterfaceAdapterInit failed.\n");
+		BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
+				DBG_LVL_ALL, "InterfaceAdapterInit failed.\n");
 		usb_set_intfdata(intf, NULL);
 		udev = interface_to_usbdev(intf);
 		usb_put_dev(udev);
@@ -228,7 +237,10 @@
 	if (psAdapter->chip_id > T3) {
 		uint32_t uiNackZeroLengthInt = 4;
 
-		retval = wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt));
+		retval =
+			wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT,
+					&uiNackZeroLengthInt,
+					sizeof(uiNackZeroLengthInt));
 		if (retval)
 			return retval;
 	}
@@ -242,9 +254,11 @@
 			intf->needs_remote_wakeup = 1;
 			usb_enable_autosuspend(udev);
 			device_init_wakeup(&intf->dev, 1);
-			INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend);
-			BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-				"Enabling USB Auto-Suspend\n");
+			INIT_WORK(&psIntfAdapter->usbSuspendWork,
+					putUsbSuspend);
+			BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"Enabling USB Auto-Suspend\n");
 #endif
 		} else {
 			intf->needs_remote_wakeup = 0;
@@ -271,7 +285,7 @@
 	if (psAdapter->bDoSuspend)
 		intf->needs_remote_wakeup = 0;
 
-	psAdapter->device_removed = TRUE ;
+	psAdapter->device_removed = TRUE;
 	usb_set_intfdata(intf, NULL);
 	InterfaceAdapterFree(psIntfAdapter);
 	usb_put_dev(udev);
@@ -285,8 +299,10 @@
 		psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
 
 		if (psIntfAdapter->asUsbTcb[i].urb == NULL) {
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
-				"Can't allocate Tx urb for index %d\n", i);
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_PRINTK, 0, 0,
+					"Can't allocate Tx urb for index %d\n",
+					i);
 			return -ENOMEM;
 		}
 	}
@@ -295,19 +311,25 @@
 		psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
 
 		if (psIntfAdapter->asUsbRcb[i].urb == NULL) {
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
-				"Can't allocate Rx urb for index %d\n", i);
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_PRINTK, 0, 0,
+					"Can't allocate Rx urb for index %d\n",
+					i);
 			return -ENOMEM;
 		}
 
-		psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
+		psIntfAdapter->asUsbRcb[i].urb->transfer_buffer =
+			kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
 
 		if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) {
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
-				"Can't allocate Rx buffer for index %d\n", i);
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_PRINTK, 0, 0,
+					"Can't allocate Rx buffer for index %d\n",
+					i);
 			return -ENOMEM;
 		}
-		psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE;
+		psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length =
+			MAX_DATA_BUFFER_SIZE;
 	}
 	return 0;
 }
@@ -322,24 +344,29 @@
 		pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n");
 		return status;
 	}
-	if (TRUE == psIntfAdapter->psAdapter->fw_download_done) {
+	if (psIntfAdapter->psAdapter->fw_download_done) {
 		if (StartInterruptUrb(psIntfAdapter)) {
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-			"Cannot send interrupt in URB\n");
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"Cannot send interrupt in URB\n");
 		}
 
 		/*
-		 * now register the cntrl interface.
-		 * after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
+		 * now register the cntrl interface.  after downloading the f/w
+		 * waiting for 5 sec to get the mailbox interrupt.
 		 */
 		psIntfAdapter->psAdapter->waiting_to_fw_download_done = false;
-		value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
-					psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ);
+		value = wait_event_timeout(
+				psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
+				psIntfAdapter->psAdapter->waiting_to_fw_download_done,
+				5 * HZ);
 
 		if (value == 0)
 			pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n");
 
-		if (register_control_device_interface(psIntfAdapter->psAdapter) < 0) {
+		if (register_control_device_interface(
+					psIntfAdapter->psAdapter) < 0) {
 			pr_err(DRV_NAME ": Register Control Device failed.\n");
 			return -EIO;
 		}
@@ -347,81 +374,6 @@
 	return 0;
 }
 
-
-static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
-{
-	return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-}
-
-static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
-{
-	return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-}
-
-static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
-}
-
-static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-}
-
-static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		USB_ENDPOINT_XFER_BULK);
-}
-
-static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		USB_ENDPOINT_XFER_CONTROL);
-}
-
-static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		USB_ENDPOINT_XFER_INT);
-}
-
-static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
-{
-	return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		USB_ENDPOINT_XFER_ISOC);
-}
-
-static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd);
-}
-
-static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd);
-}
-
-static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd);
-}
-
-static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd);
-}
-
-static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd);
-}
-
-static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
-{
-	return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
-}
-
 static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
 {
 	struct usb_host_interface *iface_desc;
@@ -429,23 +381,27 @@
 	size_t buffer_size;
 	unsigned long value;
 	int retval = 0;
-	int usedIntOutForBulkTransfer = 0 ;
+	int usedIntOutForBulkTransfer = 0;
 	bool bBcm16 = false;
 	UINT uiData = 0;
 	int bytes;
 
 	/* Store the usb dev into interface adapter */
-	psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
+	psIntfAdapter->udev =
+		usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
 
-	psIntfAdapter->bHighSpeedDevice = (psIntfAdapter->udev->speed == USB_SPEED_HIGH);
+	psIntfAdapter->bHighSpeedDevice =
+		(psIntfAdapter->udev->speed == USB_SPEED_HIGH);
 	psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
 	psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
 
 	bytes = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
-			(u32 *)&(psIntfAdapter->psAdapter->chip_id), sizeof(u32));
+			(u32 *) &(psIntfAdapter->psAdapter->chip_id),
+			sizeof(u32));
 	if (bytes < 0) {
 		retval = bytes;
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n");
+		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+				"CHIP ID Read Failed\n");
 		return retval;
 	}
 
@@ -453,81 +409,119 @@
 		psIntfAdapter->psAdapter->chip_id &= ~0xF0;
 
 	dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n",
-		 psIntfAdapter->psAdapter->chip_id);
+			psIntfAdapter->psAdapter->chip_id);
 
 	iface_desc = psIntfAdapter->interface->cur_altsetting;
 
 	if (psIntfAdapter->psAdapter->chip_id == T3B) {
-		/* T3B device will have EEPROM, check if EEPROM is proper and BCM16 can be done or not. */
+		/* T3B device will have EEPROM, check if EEPROM is proper and
+		 * BCM16 can be done or not. */
 		BeceemEEPROMBulkRead(psIntfAdapter->psAdapter, &uiData, 0x0, 4);
 		if (uiData == BECM)
 			bBcm16 = TRUE;
 
-		dev_info(&psIntfAdapter->udev->dev, "number of alternate setting %d\n",
-			 psIntfAdapter->interface->num_altsetting);
+		dev_info(&psIntfAdapter->udev->dev,
+				"number of alternate setting %d\n",
+				psIntfAdapter->interface->num_altsetting);
 
 		if (bBcm16 == TRUE) {
-			/* selecting alternate setting one as a default setting for High Speed  modem. */
+			/* selecting alternate setting one as a default setting
+			 * for High Speed  modem. */
 			if (psIntfAdapter->bHighSpeedDevice)
-				retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-				"BCM16 is applicable on this dongle\n");
-			if (retval || (psIntfAdapter->bHighSpeedDevice == false)) {
-				usedIntOutForBulkTransfer = EP2 ;
+				retval = usb_set_interface(psIntfAdapter->udev,
+						DEFAULT_SETTING_0,
+						ALTERNATE_SETTING_1);
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"BCM16 is applicable on this dongle\n");
+			if (retval || !psIntfAdapter->bHighSpeedDevice) {
+				usedIntOutForBulkTransfer = EP2;
 				endpoint = &iface_desc->endpoint[EP2].desc;
-				BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-					 "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
+				BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+						DBG_TYPE_INITEXIT, DRV_ENTRY,
+						DBG_LVL_ALL,
+						"Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
 				/*
-				 * If Modem is high speed device EP2 should be INT OUT End point
-				 * If Mode is FS then EP2 should be bulk end point
+				 * If Modem is high speed device EP2 should be
+				 * INT OUT End point
+				 *
+				 * If Mode is FS then EP2 should be bulk end
+				 * point
 				 */
-				if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == false))
-					|| ((psIntfAdapter->bHighSpeedDevice == false) && (bcm_usb_endpoint_is_bulk_out(endpoint) == false))) {
-					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-						"Configuring the EEPROM\n");
+				if ((psIntfAdapter->bHighSpeedDevice &&
+							!usb_endpoint_is_int_out(endpoint)) ||
+						(!psIntfAdapter->bHighSpeedDevice &&
+						 !usb_endpoint_is_bulk_out(endpoint))) {
+					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+							DBG_TYPE_INITEXIT,
+							DRV_ENTRY, DBG_LVL_ALL,
+							"Configuring the EEPROM\n");
 					/* change the EP2, EP4 to INT OUT end point */
-					ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
+					ConfigureEndPointTypesThroughEEPROM(
+							psIntfAdapter->psAdapter);
 
 					/*
-					 * It resets the device and if any thing gets changed
-					 *  in USB descriptor it will show fail and re-enumerate
-					 * the device
+					 * It resets the device and if any thing
+					 * gets changed in USB descriptor it
+					 * will show fail and re-enumerate the
+					 * device
 					 */
-					retval = usb_reset_device(psIntfAdapter->udev);
+					retval = usb_reset_device(
+							psIntfAdapter->udev);
 					if (retval) {
-						BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-							"reset failed.  Re-enumerating the device.\n");
-						return retval ;
+						BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+								DBG_TYPE_INITEXIT,
+								DRV_ENTRY,
+								DBG_LVL_ALL,
+								"reset failed.  Re-enumerating the device.\n");
+						return retval;
 					}
 
 				}
-				if ((psIntfAdapter->bHighSpeedDevice == false) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
+				if (!psIntfAdapter->bHighSpeedDevice &&
+				    usb_endpoint_is_bulk_out(endpoint)) {
 					/* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
 					UINT _uiData = ntohl(EP2_CFG_INT);
-					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-						"Reverting Bulk to INT as it is in Full Speed mode.\n");
-					BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE);
+					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+							DBG_TYPE_INITEXIT,
+							DRV_ENTRY, DBG_LVL_ALL,
+							"Reverting Bulk to INT as it is in Full Speed mode.\n");
+					BeceemEEPROMBulkWrite(
+							psIntfAdapter->psAdapter,
+							(PUCHAR) & _uiData,
+							0x136, 4, TRUE);
 				}
 			} else {
-				usedIntOutForBulkTransfer = EP4 ;
+				usedIntOutForBulkTransfer = EP4;
 				endpoint = &iface_desc->endpoint[EP4].desc;
-				BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-					"Choosing AltSetting as a default setting.\n");
-				if (bcm_usb_endpoint_is_int_out(endpoint) == false) {
-					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-						"Dongle does not have BCM16 Fix.\n");
+				BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+						DBG_TYPE_INITEXIT, DRV_ENTRY,
+						DBG_LVL_ALL,
+						"Choosing AltSetting as a default setting.\n");
+				if (!usb_endpoint_is_int_out(endpoint)) {
+					BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+							DBG_TYPE_INITEXIT,
+							DRV_ENTRY, DBG_LVL_ALL,
+							"Dongle does not have BCM16 Fix.\n");
 					/* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */
-					ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
+					ConfigureEndPointTypesThroughEEPROM(
+							psIntfAdapter->psAdapter);
 
 					/*
-					 * It resets the device and if any thing gets changed in
-					 *  USB descriptor it will show fail and re-enumerate the
+					 * It resets the device and if any thing
+					 * gets changed in USB descriptor it
+					 * will show fail and re-enumerate the
 					 * device
 					 */
-					retval = usb_reset_device(psIntfAdapter->udev);
+					retval = usb_reset_device(
+							psIntfAdapter->udev);
 					if (retval) {
-						BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-							"reset failed.  Re-enumerating the device.\n");
+						BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+								DBG_TYPE_INITEXIT,
+								DRV_ENTRY,
+								DBG_LVL_ALL,
+								"reset failed.  Re-enumerating the device.\n");
 						return retval;
 					}
 
@@ -541,49 +535,69 @@
 	for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) {
 		endpoint = &iface_desc->endpoint[value].desc;
 
-		if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) {
+		if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr &&
+				usb_endpoint_is_bulk_in(endpoint)) {
 			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 			psIntfAdapter->sBulkIn.bulk_in_size = buffer_size;
-			psIntfAdapter->sBulkIn.bulk_in_endpointAddr = endpoint->bEndpointAddress;
-			psIntfAdapter->sBulkIn.bulk_in_pipe =
-					usb_rcvbulkpipe(psIntfAdapter->udev,
-								psIntfAdapter->sBulkIn.bulk_in_endpointAddr);
+			psIntfAdapter->sBulkIn.bulk_in_endpointAddr =
+				endpoint->bEndpointAddress;
+			psIntfAdapter->sBulkIn.bulk_in_pipe = usb_rcvbulkpipe(
+					psIntfAdapter->udev,
+					psIntfAdapter->sBulkIn.bulk_in_endpointAddr);
 		}
 
-		if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) {
-			psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress;
-			psIntfAdapter->sBulkOut.bulk_out_pipe =
-				usb_sndbulkpipe(psIntfAdapter->udev,
+		if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
+				usb_endpoint_is_bulk_out(endpoint)) {
+			psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
+				endpoint->bEndpointAddress;
+			psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndbulkpipe(
+					psIntfAdapter->udev,
 					psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
 		}
 
-		if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) {
+		if (!psIntfAdapter->sIntrIn.int_in_endpointAddr &&
+				usb_endpoint_is_int_in(endpoint)) {
 			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 			psIntfAdapter->sIntrIn.int_in_size = buffer_size;
-			psIntfAdapter->sIntrIn.int_in_endpointAddr = endpoint->bEndpointAddress;
-			psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval;
+			psIntfAdapter->sIntrIn.int_in_endpointAddr =
+				endpoint->bEndpointAddress;
+			psIntfAdapter->sIntrIn.int_in_interval =
+				endpoint->bInterval;
 			psIntfAdapter->sIntrIn.int_in_buffer =
-						kmalloc(buffer_size, GFP_KERNEL);
+				kmalloc(buffer_size, GFP_KERNEL);
 			if (!psIntfAdapter->sIntrIn.int_in_buffer)
 				return -EINVAL;
 		}
 
-		if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) {
+		if (!psIntfAdapter->sIntrOut.int_out_endpointAddr &&
+				usb_endpoint_is_int_out(endpoint)) {
 			if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
-				(psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) {
+					(psIntfAdapter->psAdapter->chip_id == T3B) &&
+					(value == usedIntOutForBulkTransfer)) {
 				/* use first intout end point as a bulk out end point */
-				buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-				psIntfAdapter->sBulkOut.bulk_out_size = buffer_size;
-				psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress;
-				psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndintpipe(psIntfAdapter->udev,
-									psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
-				psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval;
+				buffer_size =
+					le16_to_cpu(endpoint->wMaxPacketSize);
+				psIntfAdapter->sBulkOut.bulk_out_size =
+					buffer_size;
+				psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
+					endpoint->bEndpointAddress;
+				psIntfAdapter->sBulkOut.bulk_out_pipe =
+					usb_sndintpipe(psIntfAdapter->udev,
+							psIntfAdapter->sBulkOut
+							.bulk_out_endpointAddr);
+				psIntfAdapter->sBulkOut.int_out_interval =
+					endpoint->bInterval;
 			} else if (value == EP6) {
-				buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-				psIntfAdapter->sIntrOut.int_out_size = buffer_size;
-				psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress;
-				psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval;
-				psIntfAdapter->sIntrOut.int_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+				buffer_size =
+					le16_to_cpu(endpoint->wMaxPacketSize);
+				psIntfAdapter->sIntrOut.int_out_size =
+					buffer_size;
+				psIntfAdapter->sIntrOut.int_out_endpointAddr =
+					endpoint->bEndpointAddress;
+				psIntfAdapter->sIntrOut.int_out_interval =
+					endpoint->bInterval;
+				psIntfAdapter->sIntrOut.int_out_buffer =
+					kmalloc(buffer_size, GFP_KERNEL);
 				if (!psIntfAdapter->sIntrOut.int_out_buffer)
 					return -EINVAL;
 			}
@@ -594,14 +608,14 @@
 
 	psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
 	psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
-				InterfaceFileReadbackFromChip;
+		InterfaceFileReadbackFromChip;
 	psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket;
 
 	retval = CreateInterruptUrb(psIntfAdapter);
 
 	if (retval) {
 		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
-			"Cannot create interrupt urb\n");
+				"Cannot create interrupt urb\n");
 		return retval;
 	}
 
@@ -618,17 +632,21 @@
 
 	psIntfAdapter->bSuspended = TRUE;
 
-	if (TRUE == psIntfAdapter->bPreparingForBusSuspend) {
+	if (psIntfAdapter->bPreparingForBusSuspend) {
 		psIntfAdapter->bPreparingForBusSuspend = false;
 
 		if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) {
-			psIntfAdapter->psAdapter->IdleMode = TRUE ;
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-				"Host Entered in PMU Idle Mode.\n");
+			psIntfAdapter->psAdapter->IdleMode = TRUE;
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"Host Entered in PMU Idle Mode.\n");
 		} else {
 			psIntfAdapter->psAdapter->bShutStatus = TRUE;
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
-				"Host Entered in PMU Shutdown Mode.\n");
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_INITEXIT, DRV_ENTRY,
+					DBG_LVL_ALL,
+					"Host Entered in PMU Shutdown Mode.\n");
 		}
 	}
 	psIntfAdapter->psAdapter->bPreparingForLowPowerMode = false;
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
index 7b39f4f..b9f8a7a 100644
--- a/drivers/staging/bcm/InterfaceIsr.c
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -4,108 +4,126 @@
 static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
 {
 	int		status = urb->status;
-	struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)urb->context;
-	struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter ;
+	struct bcm_interface_adapter *psIntfAdapter =
+		(struct bcm_interface_adapter *)urb->context;
+	struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
 
 	if (netif_msg_intr(Adapter))
 		pr_info(PFX "%s: interrupt status %d\n",
-			Adapter->dev->name, status);
+				Adapter->dev->name, status);
 
-	if(Adapter->device_removed == TRUE)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed.");
-		return ;
+	if (Adapter->device_removed) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL, "Device has Got Removed.");
+		return;
 	}
 
-	if(((Adapter->bPreparingForLowPowerMode == TRUE) && (Adapter->bDoSuspend == TRUE)) ||
-		psIntfAdapter->bSuspended ||
-		psIntfAdapter->bPreparingForBusSuspend)
-	{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt call back is called while suspending the device");
-			return ;
+	if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) ||
+			psIntfAdapter->bSuspended ||
+			psIntfAdapter->bPreparingForBusSuspend) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL,
+				"Interrupt call back is called while suspending the device");
+		return;
 	}
 
-	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "interrupt urb status %d", status);
 	switch (status) {
-	    /* success */
-	    case STATUS_SUCCESS:
-		if ( urb->actual_length )
-		{
+	/* success */
+	case STATUS_SUCCESS:
+		if (urb->actual_length) {
 
-			if(psIntfAdapter->ulInterruptData[1] & 0xFF)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Got USIM interrupt");
+			if (psIntfAdapter->ulInterruptData[1] & 0xFF) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+						INTF_INIT, DBG_LVL_ALL,
+						"Got USIM interrupt");
 			}
 
-			if(psIntfAdapter->ulInterruptData[1] & 0xFF00)
-			{
+			if (psIntfAdapter->ulInterruptData[1] & 0xFF00) {
 				atomic_set(&Adapter->CurrNumFreeTxDesc,
-					(psIntfAdapter->ulInterruptData[1] & 0xFF00) >> 8);
-				atomic_set (&Adapter->uiMBupdate, TRUE);
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "TX mailbox contains %d",
+					(psIntfAdapter->ulInterruptData[1] &
+					 0xFF00) >> 8);
+				atomic_set(&Adapter->uiMBupdate, TRUE);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					INTF_INIT, DBG_LVL_ALL,
+					"TX mailbox contains %d",
 					atomic_read(&Adapter->CurrNumFreeTxDesc));
 			}
-			if(psIntfAdapter->ulInterruptData[1] >> 16)
-			{
-				Adapter->CurrNumRecvDescs=
+			if (psIntfAdapter->ulInterruptData[1] >> 16) {
+				Adapter->CurrNumRecvDescs =
 					(psIntfAdapter->ulInterruptData[1]  >> 16);
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"RX mailbox contains %d",
-					Adapter->CurrNumRecvDescs);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+						INTF_INIT, DBG_LVL_ALL,
+						"RX mailbox contains %d",
+						Adapter->CurrNumRecvDescs);
 				InterfaceRx(psIntfAdapter);
 			}
-			if(Adapter->fw_download_done &&
+			if (Adapter->fw_download_done &&
 				!Adapter->downloadDDR &&
-				atomic_read(&Adapter->CurrNumFreeTxDesc))
-			{
-				psIntfAdapter->psAdapter->downloadDDR +=1;
+				atomic_read(&Adapter->CurrNumFreeTxDesc)) {
+
+				psIntfAdapter->psAdapter->downloadDDR += 1;
 				wake_up(&Adapter->tx_packet_wait_queue);
 			}
-			if(false == Adapter->waiting_to_fw_download_done)
-			{
+			if (!Adapter->waiting_to_fw_download_done) {
 				Adapter->waiting_to_fw_download_done = TRUE;
 				wake_up(&Adapter->ioctl_fw_dnld_wait_queue);
 			}
-			if(!atomic_read(&Adapter->TxPktAvail))
-			{
+			if (!atomic_read(&Adapter->TxPktAvail)) {
 				atomic_set(&Adapter->TxPktAvail, 1);
 				wake_up(&Adapter->tx_packet_wait_queue);
 			}
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Firing interrupt in URB");
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+					DBG_LVL_ALL, "Firing interrupt in URB");
 		}
 		break;
-		case -ENOENT :
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"URB has got disconnected ....");
-			return ;
-		}
-		case -EINPROGRESS:
-		{
-			//This situation may happened when URBunlink is used. for detail check usb_unlink_urb documentation.
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occurred... something very bad is going on");
-			break ;
-			//return;
-		}
-		case -EPIPE:
-		{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint  has got halted/stalled...need to clear this");
-				Adapter->bEndPointHalted = TRUE ;
-				wake_up(&Adapter->tx_packet_wait_queue);
-				urb->status = STATUS_SUCCESS ;
-				return;
-		}
-	    /* software-driven interface shutdown */
-	    case -ECONNRESET: //URB got unlinked.
-	    case -ESHUTDOWN:		// hardware gone. this is the serious problem.
-	    						//Occurs only when something happens with the host controller device
-	    case -ENODEV : //Device got removed
-		case -EINVAL : //Some thing very bad happened with the URB. No description is available.
-	    	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"interrupt urb error %d", status);
-			urb->status = STATUS_SUCCESS ;
-			break ;
-			//return;
-	    default:
-			//This is required to check what is the defaults conditions when it occurs..
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", status);
+	case -ENOENT:
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL, "URB has got disconnected....");
+		return;
+	case -EINPROGRESS:
+		/*
+		 * This situation may happened when URBunlink is used.  for
+		 * detail check usb_unlink_urb documentation.
+		 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL,
+				"Impossibe condition has occurred... something very bad is going on");
+		break;
+		/* return; */
+	case -EPIPE:
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL,
+				"Interrupt IN endPoint has got halted/stalled...need to clear this");
+		Adapter->bEndPointHalted = TRUE;
+		wake_up(&Adapter->tx_packet_wait_queue);
+		urb->status = STATUS_SUCCESS;
+		return;
+	/* software-driven interface shutdown */
+	case -ECONNRESET:	/* URB got unlinked */
+	case -ESHUTDOWN:	/* hardware gone. this is the serious problem */
+		/*
+		 * Occurs only when something happens with the
+		 * host controller device
+		 */
+	case -ENODEV: /* Device got removed */
+	case -EINVAL:
+		/*
+		 * Some thing very bad happened with the URB. No
+		 * description is available.
+		 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+				DBG_LVL_ALL, "interrupt urb error %d", status);
+		urb->status = STATUS_SUCCESS;
+		break;
+		/* return; */
+	default:
+		/*
+		 * This is required to check what is the defaults conditions
+		 * when it occurs..
+		 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
+				"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...",
+				status);
 		break;
 	}
 
@@ -117,28 +135,30 @@
 int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
 {
 	psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!psIntfAdapter->psInterruptUrb)
-	{
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot allocate interrupt urb");
+	if (!psIntfAdapter->psInterruptUrb) {
+		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS,
+				INTF_INIT, DBG_LVL_ALL,
+				"Cannot allocate interrupt urb");
 		return -ENOMEM;
 	}
 	psIntfAdapter->psInterruptUrb->transfer_buffer =
-								psIntfAdapter->ulInterruptData;
+		psIntfAdapter->ulInterruptData;
 	psIntfAdapter->psInterruptUrb->transfer_buffer_length =
-							sizeof(psIntfAdapter->ulInterruptData);
+		sizeof(psIntfAdapter->ulInterruptData);
 
 	psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev,
-						psIntfAdapter->sIntrIn.int_in_endpointAddr);
+			psIntfAdapter->sIntrIn.int_in_endpointAddr);
 
 	usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev,
-					psIntfAdapter->sIntrIn.int_in_pipe,
-					psIntfAdapter->psInterruptUrb->transfer_buffer,
-					psIntfAdapter->psInterruptUrb->transfer_buffer_length,
-					read_int_callback, psIntfAdapter,
-					psIntfAdapter->sIntrIn.int_in_interval);
+			psIntfAdapter->sIntrIn.int_in_pipe,
+			psIntfAdapter->psInterruptUrb->transfer_buffer,
+			psIntfAdapter->psInterruptUrb->transfer_buffer_length,
+			read_int_callback, psIntfAdapter,
+			psIntfAdapter->sIntrIn.int_in_interval);
 
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt Interval: %d\n",
-				psIntfAdapter->sIntrIn.int_in_interval);
+	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, INTF_INIT,
+			DBG_LVL_ALL, "Interrupt Interval: %d\n",
+			psIntfAdapter->sIntrIn.int_in_interval);
 	return 0;
 }
 
@@ -147,19 +167,20 @@
 {
 	INT status = 0;
 
-	if( false == psIntfAdapter->psAdapter->device_removed &&
-		false == psIntfAdapter->psAdapter->bEndPointHalted &&
-		false == psIntfAdapter->bSuspended &&
-		false == psIntfAdapter->bPreparingForBusSuspend &&
-		false == psIntfAdapter->psAdapter->StopAllXaction)
-	{
-		status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
-		if (status)
-		{
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot send int urb %d\n", status);
-			if(status == -EPIPE)
-			{
-				psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
+	if (!(psIntfAdapter->psAdapter->device_removed ||
+				psIntfAdapter->psAdapter->bEndPointHalted ||
+				psIntfAdapter->bSuspended ||
+				psIntfAdapter->bPreparingForBusSuspend ||
+				psIntfAdapter->psAdapter->StopAllXaction)) {
+		status =
+			usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
+		if (status) {
+			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+					DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,
+					"Cannot send inturb %d\n", status);
+			if (status == -EPIPE) {
+				psIntfAdapter->psAdapter->bEndPointHalted =
+					TRUE;
 				wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
 			}
 		}
diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c
index 0727599..4f31583 100644
--- a/drivers/staging/bcm/Qos.c
+++ b/drivers/staging/bcm/Qos.c
@@ -222,10 +222,7 @@
 
 		//Checking classifier validity
 		if (!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR)
-		{
-			bClassificationSucceed = false;
 			break;
-		}
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!");
 		if (pstClassifierRule->bIpv6Protocol)
@@ -233,51 +230,47 @@
 
 		//**************Checking IP header parameter**************************//
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address");
-		if (false == (bClassificationSucceed =
-			MatchSrcIpAddress(pstClassifierRule, iphd->saddr)))
+		if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
 			break;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched");
 
-		if (false == (bClassificationSucceed =
-			MatchDestIpAddress(pstClassifierRule, iphd->daddr)))
+		if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
 			break;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched");
 
-		if (false == (bClassificationSucceed =
-			MatchTos(pstClassifierRule, iphd->tos)))
-		{
+		if (!MatchTos(pstClassifierRule, iphd->tos)) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n");
 			break;
 		}
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched");
 
-		if (false == (bClassificationSucceed =
-			MatchProtocol(pstClassifierRule, iphd->protocol)))
+		if (!MatchProtocol(pstClassifierRule, iphd->protocol))
 			break;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched");
 
 		//if protocol is not TCP or UDP then no need of comparing source port and destination port
-		if (iphd->protocol != TCP && iphd->protocol != UDP)
+		if (iphd->protocol != TCP && iphd->protocol != UDP) {
+			bClassificationSucceed = TRUE;
 			break;
+		}
 		//******************Checking Transport Layer Header field if present *****************//
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
 			(iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
 
-		if (false == (bClassificationSucceed =
-			MatchSrcPort(pstClassifierRule,
-				ntohs((iphd->protocol == UDP) ?
-				xprt_hdr->uhdr.source : xprt_hdr->thdr.source))))
+		if (!MatchSrcPort(pstClassifierRule,
+				  ntohs((iphd->protocol == UDP) ?
+				  xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
 			break;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched");
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x",
 			(iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
 			xprt_hdr->thdr.dest);
-		if (false == (bClassificationSucceed =
-			MatchDestPort(pstClassifierRule,
-			ntohs((iphd->protocol == UDP) ?
-			xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest))))
+		if (!MatchDestPort(pstClassifierRule,
+				   ntohs((iphd->protocol == UDP) ?
+				   xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
 			break;
+		bClassificationSucceed = TRUE;
 	} while (0);
 
 	if (TRUE == bClassificationSucceed)
diff --git a/drivers/staging/bcm/Typedefs.h b/drivers/staging/bcm/Typedefs.h
index 832adcf..90b3b25 100644
--- a/drivers/staging/bcm/Typedefs.h
+++ b/drivers/staging/bcm/Typedefs.h
@@ -25,16 +25,16 @@
 typedef unsigned long ULONG;
 typedef unsigned long DWORD;
 
-typedef char* PCHAR;
-typedef short* PSHORT;
-typedef int* PINT;
-typedef long* PLONG;
-typedef void* PVOID;
+typedef char *PCHAR;
+typedef short *PSHORT;
+typedef int *PINT;
+typedef long *PLONG;
+typedef void *PVOID;
 
-typedef unsigned char* PUCHAR;
-typedef unsigned short* PUSHORT;
-typedef unsigned int* PUINT;
-typedef unsigned long* PULONG;
+typedef unsigned char *PUCHAR;
+typedef unsigned short *PUSHORT;
+typedef unsigned int *PUINT;
+typedef unsigned long *PULONG;
 typedef unsigned long long ULONG64;
 typedef unsigned long long LARGE_INTEGER;
 typedef unsigned int UINT32;
@@ -43,5 +43,5 @@
 #endif
 
 
-#endif	//__TYPEDEFS_H__
+#endif	/* __TYPEDEFS_H__ */
 
diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h
index 7fd21c6..6f3270c 100644
--- a/drivers/staging/bcm/headers.h
+++ b/drivers/staging/bcm/headers.h
@@ -34,7 +34,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/usb.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <net/ip.h>
 
 #include "Typedefs.h"
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
index f55300d..39ace55 100644
--- a/drivers/staging/bcm/hostmibs.c
+++ b/drivers/staging/bcm/hostmibs.c
@@ -27,9 +27,9 @@
 	/* Copy the classifier Table */
 	for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) {
 		if (Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE)
-			memcpy((PVOID) & pstHostMibs->
+			memcpy((PVOID) &pstHostMibs->
 			       astClassifierTable[nClassifierIndex],
-			       (PVOID) & Adapter->
+			       (PVOID) &Adapter->
 			       astClassifierTable[nClassifierIndex],
 			       sizeof(struct bcm_mibs_classifier_rule));
 	}
@@ -37,8 +37,8 @@
 	/* Copy the SF Table */
 	for (nSfIndex = 0; nSfIndex < NO_OF_QUEUES; nSfIndex++) {
 		if (Adapter->PackInfo[nSfIndex].bValid) {
-			memcpy((PVOID) & pstHostMibs->astSFtable[nSfIndex],
-			       (PVOID) & Adapter->PackInfo[nSfIndex],
+			memcpy((PVOID) &pstHostMibs->astSFtable[nSfIndex],
+			       (PVOID) &Adapter->PackInfo[nSfIndex],
 				sizeof(struct bcm_mibs_table));
 		} else {
 			/* If index in not valid,
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
index fca164f..63be3be 100644
--- a/drivers/staging/bcm/nvm.c
+++ b/drivers/staging/bcm/nvm.c
@@ -122,7 +122,7 @@
  *		OSAL_STATUS_CODE:
  */
 
-int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
+static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
 			DWORD dwAddress,
 			DWORD *pdwData,
 			DWORD dwNumWords)
@@ -2698,7 +2698,7 @@
  * On Failure -returns STATUS_FAILURE
  */
 
-int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
+static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
 {
 	int SectEndOffset = 0;
 
@@ -2980,7 +2980,7 @@
  *
  */
 
-B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
+static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
 {
 	unsigned int uiSectorNum = 0;
 	unsigned int uiWordOfSectorPermission = 0;
@@ -3374,7 +3374,7 @@
 	case DSD2:
 		if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
 			HighestPriDSD = getHighestPriDSD(Adapter);
-			if ((HighestPriDSD == eFlash2xSectVal)) {
+			if (HighestPriDSD == eFlash2xSectVal) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
 				Status = STATUS_SUCCESS;
 				break;
@@ -3402,7 +3402,7 @@
 
 				HighestPriDSD = getHighestPriDSD(Adapter);
 
-				if ((HighestPriDSD == eFlash2xSectVal)) {
+				if (HighestPriDSD == eFlash2xSectVal) {
 					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
 					Status = STATUS_SUCCESS;
 					break;
@@ -3421,7 +3421,7 @@
 				}
 
 				HighestPriDSD = getHighestPriDSD(Adapter);
-				if ((HighestPriDSD == eFlash2xSectVal)) {
+				if (HighestPriDSD == eFlash2xSectVal) {
 					Status = STATUS_SUCCESS;
 					break;
 				}
@@ -4074,7 +4074,7 @@
  *	Faillure :- Return negative error code
  */
 
-int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
+static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
 {
 	unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
 	bool bHasHeader = false;
@@ -4213,7 +4213,7 @@
 	return STATUS_SUCCESS;
 }
 
-int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
+static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
 {
 	unsigned int uiDSDsig = 0;
 	/* unsigned int sigoffsetInMap = 0;
@@ -4238,7 +4238,7 @@
 	return uiDSDsig;
 }
 
-int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
+static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
 {
 	/* unsigned int priOffsetInMap = 0 ; */
 	unsigned int uiDSDPri = STATUS_FAILURE;
@@ -4261,7 +4261,7 @@
 	return uiDSDPri;
 }
 
-enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
+static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
 {
 	int DSDHighestPri = STATUS_FAILURE;
 	int DsdPri = 0;
@@ -4293,7 +4293,7 @@
 	return  HighestPriDSD;
 }
 
-int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
+static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
 {
 	unsigned int uiISOsig = 0;
 	/* unsigned int sigoffsetInMap = 0;
@@ -4316,7 +4316,7 @@
 	return uiISOsig;
 }
 
-int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
+static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
 {
 	unsigned int ISOPri = STATUS_FAILURE;
 	if (IsSectionWritable(Adapter, iso)) {
@@ -4335,7 +4335,7 @@
 	return ISOPri;
 }
 
-enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
+static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
 {
 	int ISOHighestPri = STATUS_FAILURE;
 	int ISOPri = 0;
@@ -4359,7 +4359,7 @@
 	return HighestPriISO;
 }
 
-int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
+static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
 				PUINT pBuff,
 				enum bcm_flash2x_section_val eFlash2xSectionVal,
 				unsigned int uiOffset,
@@ -4472,7 +4472,7 @@
 	return SectionPresent;
 }
 
-int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
+static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
 {
 	int offset = STATUS_FAILURE;
 	int Status = false;
diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c
index bf532b1..ebbc509 100644
--- a/drivers/staging/ced1401/ced_ioc.c
+++ b/drivers/staging/ced1401/ced_ioc.c
@@ -38,8 +38,8 @@
 ****************************************************************************/
 static void FlushOutBuff(DEVICE_EXTENSION *pdx)
 {
-	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
-		pdx->sCurrentState);
+	dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n",
+		__func__, pdx->sCurrentState);
 	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
 		return;
 	/* Kill off any pending I/O */
@@ -59,8 +59,8 @@
 ****************************************************************************/
 static void FlushInBuff(DEVICE_EXTENSION *pdx)
 {
-	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
-		pdx->sCurrentState);
+	dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n",
+		__func__, pdx->sCurrentState);
 	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
 		return;
 	/* Kill off any pending I/O */
@@ -118,8 +118,8 @@
 
 	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	if (n > 0) {		/*  do nothing if nowt to do! */
-		dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n,
-			buffer);
+		dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n",
+			__func__, n, buffer);
 		iReturn = PutChars(pdx, buffer, n);
 	}
 
@@ -139,7 +139,7 @@
 	int iReturn;
 	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */