Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile
===================================================================
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:8 @
 # architecture-specific flags and dependencies.
 #
 
+GCOV_PROFILE	:= n
+
 LDFLAGS_bootp	:=-p --no-undefined -X \
 		 --defsym initrd_phys=$(INITRD_PHYS) \
 		 --defsym params_phys=$(PARAMS_PHYS) -T
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/compressed/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/boot/compressed/Makefile	2014-07-20 22:05:50.288065763 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/compressed/Makefile	2014-07-20 22:06:33.848347087 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:40 @
 OBJS		+= hyp-stub.o
 endif
 
+GCOV_PROFILE		:= n
+
 #
 # Architecture dependencies
 #
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/boot/dts/Makefile	2014-07-20 22:05:50.284065829 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/Makefile	2014-07-20 22:06:33.863346840 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:267 @
 	wm8750-apc8750.dtb \
 	wm8850-w70v2.dtb
 dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
+			zynq-zc702-base-trd.dtb \
+			zynq-zc702-drm-v4l2.dtb \
+			zynq-afx-nand.dtb \
+			zynq-afx-nor.dtb \
+			zynq-cc108.dtb \
+			zynq-zc770-xm010.dtb \
+			zynq-zc770-xm011.dtb \
+			zynq-zc770-xm012.dtb \
+			zynq-zc770-xm013.dtb \
 	zynq-zc706.dtb \
 	zynq-zed.dtb
 
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-afx-nand.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-afx-nand.dts	2014-07-20 22:06:33.874346658 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		serial0 = &ps7_uart_1;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x8000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x3cffff>;
+			gpio-mask-low = <0xff008002>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_smcc_0: ps7-smcc@e000e000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 11>, <&clkc 44>;
+			compatible = "xlnx,ps7-smcc-1.00.a", "xlnx,ps7-smc";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 18 4>;
+			ranges ;
+			reg = <0xe000e000 0x1000>;
+			xlnx,addr25 = <0x0>;
+			xlnx,nor-chip-sel0 = <0x0>;
+			xlnx,nor-chip-sel1 = <0x0>;
+			xlnx,sram-chip-sel0 = <0x0>;
+			xlnx,sram-chip-sel1 = <0x0>;
+			ps7_nand_0: ps7-nand@e1000000 {
+				compatible = "xlnx,ps7-nand-1.00.a";
+				reg = <0xe1000000 0x1000000>;
+				xlnx,nand-cycle-t0 = <0x4>;
+				xlnx,nand-cycle-t1 = <0x4>;
+				xlnx,nand-cycle-t2 = <0x1>;
+				xlnx,nand-cycle-t3 = <0x2>;
+				xlnx,nand-cycle-t4 = <0x2>;
+				xlnx,nand-cycle-t5 = <0x2>;
+				xlnx,nand-cycle-t6 = <0x4>;
+				xlnx,nand-width = <0x10>;
+				#address-cells = <0x1>;
+				#size-cells = <0x1>;
+
+				partition@nand-fsbl-uboot {
+					label = "nand-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@nand-linux {
+					label = "nand-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@nand-device-tree {
+					label = "nand-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@nand-rootfs {
+					label = "nand-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@nand-bitstream {
+					label = "nand-bitstream";
+					reg = <0xC00000 0x400000>;
+
+				};
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_ttc_1: ps7-ttc@f8002000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+			reg = <0xf8002000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-afx-nor.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-afx-nor.dts	2014-07-20 22:06:33.882346526 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		serial0 = &ps7_uart_1;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x8000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_smcc_0: ps7-smcc@e000e000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 11>, <&clkc 44>;
+			compatible = "xlnx,ps7-smcc-1.00.a", "xlnx,ps7-smc";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 18 4>;
+			ranges ;
+			reg = <0xe000e000 0x1000>;
+			xlnx,addr25 = <0x1>;
+			xlnx,nor-chip-sel0 = <0x1>;
+			xlnx,nor-chip-sel1 = <0x0>;
+			xlnx,sram-chip-sel0 = <0x0>;
+			xlnx,sram-chip-sel1 = <0x0>;
+			ps7_nor_0: ps7-nor@e2000000 {
+				bank-width = <1>;
+				compatible = "xlnx,ps7-nor-1.00.a", "cfi-flash";
+				reg = <0xe2000000 0x1000>;
+				xlnx,sram-cycle-t0 = <0xb>;
+				xlnx,sram-cycle-t1 = <0xb>;
+				xlnx,sram-cycle-t2 = <0x5>;
+				xlnx,sram-cycle-t3 = <0x4>;
+				xlnx,sram-cycle-t4 = <0x3>;
+				xlnx,sram-cycle-t5 = <0x3>;
+				xlnx,sram-cycle-t6 = <0x2>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				partition@nor-fsbl-uboot {
+					label = "nor-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@nor-linux {
+					label = "nor-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@nor-device-tree {
+					label = "nor-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@nor-rootfs {
+					label = "nor-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@nor-bitstream {
+					label = "nor-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_ttc_1: ps7-ttc@f8002000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+			reg = <0xf8002000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-cc108.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-cc108.dts	2014-07-20 22:06:33.891346378 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.7 EDK_P.20131013
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x20000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			enet-reset = <&ps7_gpio_0 0 0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@1 {
+					compatible = "marvell,88e1510";
+					device_type = "ethernet-phy";
+					reg = <1>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <0>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x0>;
+			xlnx,qspi-mode = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 { /* 16 MB */
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@0 {
+					label = "qspi-fsbl-uboot-bs";
+					reg = <0x0 0x400000>; /* 4MB */
+				};
+				partition@0x400000 {
+					label = "qspi-linux";
+					reg = <0x400000 0x400000>; /* 4MB */
+				};
+				partition@0x800000 {
+					label = "qspi-rootfs";
+					reg = <0x800000 0x400000>; /* 4MB */
+				};
+				partition@0xc00000 {
+					label = "qspi-devicetree";
+					reg = <0xc00000 0x100000>; /* 1MB */
+				};
+				partition@0xd00000 {
+					label = "qspi-scratch";
+					reg = <0xd00000 0x200000>; /* 2MB */
+				};
+				partition@0xf00000 {
+					label = "qspi-uboot-env";
+					reg = <0xf00000 0x100000>; /* 1MB */
+				};
+			};
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x1000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_1: ps7-sdio@e0101000 {
+			broken-cd ;
+			wp-inverted ;
+			clock-frequency = <50000000>;
+			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clkc 22>, <&clkc 33>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci", "arasan,sdhci-8.9a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 47 4>;
+			reg = <0xe0101000 0x1000>;
+			xlnx,has-cd = <0x0>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_ttc_1: ps7-ttc@f8002000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+			reg = <0xf8002000 0x1000>;
+		} ;
+		ps7_uart_0: serial@e0000000 {
+			status = "disabled";
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 23>, <&clkc 40>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 27 4>;
+			port-number = <0>;
+			reg = <0xe0000000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "peripheral";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+			usb-reset = <&ps7_gpio_0 9 0>;
+		} ;
+		ps7_usb_1: ps7-usb@e0003000 {
+			clocks = <&clkc 29>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 44 4>;
+			phy_type = "ulpi";
+			reg = <0xe0003000 0x1000>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702-base-trd.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702-base-trd.dts	2014-07-20 22:06:33.901346213 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/dts-v1/;
+
+/ {
+	model = "Xilinx Zynq ZC702";
+	compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+	interrupt-parent = <0x1>;
+	aliases {
+		spi1 = &qspi0;
+	};
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x40000000>;
+	};
+	chosen {
+		bootargs = "console=tty0 console=ttyPS0,115200 root=/dev/ram rw ip=192.168.1.10:::255.255.255.0:ZC702:eth0 earlyprintk mem=768M";
+		linux,stdout-path = "/amba@0/uart@E0001000";
+	};
+
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupts = <0 5 4>, <0 6 4>;
+		interrupt-parent = <&gic>;
+	};
+
+	amba@0 {
+		compatible = "simple-bus";
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+
+		gic: intc@f8f01000 {
+			interrupt-controller;
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			reg = <0xf8f01000 0x1000>,
+			      <0xf8f00100 0x0100>;
+		};
+
+		pl310@f8f02000 {
+			compatible = "arm,pl310-cache";
+			cache-unified;
+			cache-level = <2>;
+			reg = <0xf8f02000 0x1000>;
+			interrupts = <0 2 4>;
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+		};
+
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+
+		ps7_ocm_0: ps7-ocm@0xfffc0000 {
+			compatible = "xlnx,ps7-ocm";
+			reg = <0xfffc0000 0x40000>; /* 256k */
+		};
+
+		uart@e0001000 {
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			clocks = <&clkc 24>, <&clkc 41>;
+			clock-names = "ref_clk", "aper_clk";
+			reg = <0xe0001000 0x1000>;
+			interrupts = <0 50 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		slcr: slcr@f8000000 {
+			compatible = "xlnx,zynq-slcr";
+			reg = <0xF8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				clkc: clkc {
+					#clock-cells = <1>;
+					compatible = "xlnx,ps7-clkc";
+					ps-clk-frequency = <33333333>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
+							"cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
+							"dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+							"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+							"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
+							"dma", "usb0_aper", "usb1_aper", "gem0_aper",
+							"gem1_aper", "sdio0_aper", "sdio1_aper",
+							"spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
+							"i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
+							"gpio_aper", "lqspi_aper", "smc_aper", "swdt",
+							"dbg_trc", "dbg_apb";
+				};
+			} ;
+		};
+
+		timer@0xf8001000 {
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			clocks = <&clkc 6>;
+			reg = <0xf8001000 0x1000>;
+			interrupts = <0 10 4>,<0 11 4>,<0 12 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		timer@f8f00600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			clocks = <&clkc 4>;
+			reg = <0xf8f00600 0x20>;
+			interrupts = <1 13 0x301>;
+			interrupt-parent = <&gic>;
+		};
+
+		swdt@f8005000 {
+			device_type = "watchdog";
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			clocks = <&clkc 45>;
+			reg = <0xf8005000 0x100>;
+			interrupts = <0 9 4>;
+			interrupt-parent = <&gic>;
+			reset = <0>;
+			timeout = <10>;
+		};
+
+		scuwdt@f8f00620 {
+			device_type = "watchdog";
+			compatible = "arm,mpcore_wdt";
+			clocks = <&clkc 4>;
+			reg = <0xf8f00620 0x20>;
+			clock-frequency = <333333333>;
+			reset = <1>;
+		};
+
+		eth@e000b000 {
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			clocks = <&clkc 13>, <&clkc 30>;
+			clock-names = "ref_clk", "aper_clk";
+			reg = <0xe000b000 0x1000>;
+			interrupts = <0 22 4>;
+			interrupt-parent = <&gic>;
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			xlnx,ptp-enet-clock = <111111111>;
+			xlnx,slcr-div0-1000Mbps = <8>;
+			xlnx,slcr-div0-100Mbps = <8>;
+			xlnx,slcr-div0-10Mbps = <8>;
+			xlnx,slcr-div1-1000Mbps = <1>;
+			xlnx,slcr-div1-100Mbps = <5>;
+			xlnx,slcr-div1-10Mbps = <50>;
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "marvell,88e1116r";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				};
+			};
+		};
+
+		i2c0: i2c@e0004000 {
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			clocks = <&clkc 38>;
+			reg = <0xE0004000 0x1000>;
+			interrupts = <0 25 4>;
+			interrupt-parent = <&gic>;
+			bus-id = <0>;
+			input-clk = <111111111>;
+			i2c-clk = <100000>;
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2cswitch@74 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x74>;
+
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+					osc@5d {
+						compatible = "si570";
+						reg = <0x5d>;
+						factory-fout = <156250000>;
+						initial-fout = <148500000>;
+					};
+				};
+
+				i2c@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+					hdmio@39 {
+						compatible = "adv7511";
+						reg = <0x39>;
+						interrupts = <0 54 4>;
+						interrupt-parent = <&gic>;
+						dma-request = <&logicvc0>;
+						edid-addr = <0x50>;
+						video-input {
+							input-id = <1>;
+							input-style = <3>;
+							input-color-depth = <8>;
+							bit-justification = <1>;
+							hsync-polarity = <0>;
+							vsync-polarity = <0>;
+							clock-delay = <3>;
+						};
+						video-output {
+							hdmi-mode = <0>;
+							output-format = <0>;
+							output-color-space = <0>;
+							up-conversion = <0>;
+							csc-enable = <1>;
+							csc-scaling-factor = <2>;
+							csc-coefficients {
+								a1 = <0x0B37>;
+								a2 = <0x0800>;
+								a3 = <0x0000>;
+								a4 = <0x1A86>;
+								b1 = <0x1A49>;
+								b2 = <0x0800>;
+								b3 = <0x1D3F>;
+								b4 = <0x0422>;
+								c1 = <0x0000>;
+								c2 = <0x0800>;
+								c3 = <0x0E2D>;
+								c4 = <0x1914>;
+							};
+						};
+					};
+				};
+
+				i2c@2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+					eeprom@54 {
+						compatible = "at,24c08";
+						reg = <0x54>;
+					};
+				};
+
+				i2c@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+					gpio@21 {
+						compatible = "ti,tca6416";
+						reg = <0x21>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				i2c@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+					rtc@54 {
+						compatible = "nxp,pcf8563";
+						reg = <0x51>;
+					};
+				};
+
+				i2c@5{
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+					eeprom@50 {
+						compatible = "at,24c02";
+						reg = <0x50>;
+					};
+				};
+
+				i2c@6{
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+					eeprom@50 {
+						compatible = "at,24c02";
+						reg = <0x50>;
+					};
+				};
+
+				i2c@7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+					hwmon@52 {
+						compatible = "pmbus,ucd9248";
+						reg = <52>;
+					};
+					hwmon@53 {
+						compatible = "pmbus,ucd9248";
+						reg = <53>;
+					};
+					hwmon@54 {
+						compatible = "pmbus,ucd9248";
+						reg = <54>;
+					};
+				};
+			};
+		};
+
+		i2c1: i2c@e0005000 {
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			clocks = <&clkc 39>;
+			reg = <0xE0005000 0x1000>;
+			interrupts = <0 48 4>;
+			interrupt-parent = <&gic>;
+			bus-id = <1>;
+			input-clk = <111111111>;
+			i2c-clk = <100000>;
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2cswitch@70 {
+				compatible = "nxp,pca9546";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x70>;
+
+				i2c_adv7611: i2c@2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				i2c@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+					ioexp: gpio@20 {
+						compatible = "nxp,pca9534";
+						reg = <0x20>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+			};
+		};
+
+		sdhci@e0100000 {
+			compatible = "xlnx,ps7-sdhci-1.00.a";
+			clocks = <&clkc 21>, <&clkc 32>;
+			clock-names = "ref_clk", "aper_clk";
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			interrupts = <0 24 4>;
+			interrupt-parent = <&gic>;
+			clock-frequency = <33333000>;
+		};
+
+		usb@e0002000 {
+			compatible = "xlnx,ps7-usb-1.00.a";
+			clocks = <&clkc 28>;
+			reg = <0xe0002000 0x1000>;
+			interrupts = <0 21 4>;
+			interrupt-parent = <&gic>;
+			dr_mode = "host";
+			phy_type = "ulpi";
+		};
+
+		gpio@e000a000 {
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			clocks = <&clkc 42>;
+			reg = <0xe000a000 0x1000>;
+			interrupts = <0 20 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		qspi0: spi@e000d000 {
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			clocks = <&clkc 10>, <&clkc 43>;
+			clock-names = "ref_clk", "aper_clk";
+			reg = <0xE000D000 0x1000>;
+			interrupts = <0 19 4>;
+			interrupt-parent = <&gic>;
+			speed-hz = <200000000>;
+			num-chip-select = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			is-dual = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
+		};
+
+		devcfg@f8007000 {
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			reg = <0xf8007000 0x100>;
+			interrupts = <0 8 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		xadc@f8007100 {
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			clocks = <&clkc 12>;
+			reg = <0xf8007100 0x20>;
+			interrupts = <0 7 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			arm,primecell-periphid = <0x41330>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			clocks = <&clkc 27>;
+			interrupt-parent = <&gic>;
+			interrupts = <0 13 4 0 14 4 0 15 4 0 16 4 0 17 4 0 40 4 0 41 4 0 42 4 0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		};
+
+		axi_sobel_0: axi-sobel@0x400D0000 {
+			compatible = "generic-uio";
+			reg = <0x400D0000 0x10000>;
+			interrupts = <0 55 4>;
+			interrupt-parent = <&gic>;
+		};
+
+		yuv2rgb_0: v-ycrcb2rgb@0x40050000 {
+			compatible = "generic-uio";
+			reg = <0x40050000 0x10000>;
+		};
+
+		tpg_0: v-tpg@40080000 {
+			compatible = "generic-uio";
+			reg = <0x40080000 0x10000>;
+		};
+
+		cresample_0: v-cresample@40040000 {
+			compatible = "generic-uio";
+			reg = <0x40040000 0x10000>;
+		};
+
+		vtc_0: v-tc@40070000 {
+			compatible = "generic-uio";
+			reg = <0x40070000 0x10000>;
+		};
+
+		perf_mon_hp0_hp2: axi-perf-mon@400f0000 {
+			compatible = "generic-uio";
+			reg = <0x400f0000 0x10000>;
+		};
+
+		axi_vdma_0: axivdma@0x40090000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,axi-vdma";
+			ranges = <0x40090000 0x40090000 0x10000>;
+			reg = <0x40090000 0x10000>;
+			xlnx,flush-fsync = <0x1>;
+			xlnx,include-sg = <0x0>;
+			xlnx,num-fstores = <0x3>;
+			xlnx,family = "zynq-770";
+			dma-channel@0x40090000 {
+				compatible = "xlnx,axi-vdma-s2mm-channel";
+				interrupt-parent = <&gic>;
+				interrupts = <0 58 4>;
+				xlnx,datawidth = <0x08>;
+				xlnx,genlock-mode = <0x1>;
+				xlnx,include-dre = <0x1>;
+				xlnx,device-id = <0x0>;
+			};
+		};
+
+		axi_vdma_1: axivdma@0x400B0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,axi-vdma";
+			ranges = <0x400B0000 0x400B0000 0x10000>;
+			reg = <0x400B0000 0x10000>;
+			xlnx,flush-fsync = <0x1>;
+			xlnx,include-sg = <0x0>;
+			xlnx,num-fstores = <0x3>;
+			xlnx,family = "zynq-770";
+			dma-s2mmchannel@0x400B0000 {
+				compatible = "xlnx,axi-vdma-s2mm-channel";
+				interrupt-parent = <&gic>;
+				interrupts = <0 57 4>;
+				xlnx,datawidth = <0x08>;
+				xlnx,genlock-mode = <0x1>;
+				xlnx,include-dre = <0x1>;
+				xlnx,device-id = <0x1>;
+			};
+			dma-mm2schannel@0x400B0000 {
+				compatible = "xlnx,axi-vdma-mm2s-channel";
+				interrupt-parent = <&gic>;
+				interrupts = <0 56 4>;
+				xlnx,datawidth = <0x08>;
+				xlnx,genlock-mode = <0x1>;
+				xlnx,include-dre = <0x1>;
+				xlnx,device-id = <0x1>;
+			};
+		};
+
+		logicvc0: logicvc@40030000 {
+			compatible = "xylon,logicvc-3.00.a";
+			reg = <0x40030000 0x6000>;
+			interrupt-parent = <&gic>;
+			interrupts = <0 59 4>;
+
+			xlnx,display-interface = <0>;
+			xlnx,display-color-space = <1>;
+			xlnx,ip-license-type = <0>;
+			xlnx,ip-major-revision = <3>;
+			xlnx,ip-minor-revision = <0>;
+			xlnx,ip-patch-level = <0>;
+			xlnx,num-of-layers = <3>;
+			xlnx,layer-0-type = <0>;
+			xlnx,layer-0-alpha-mode = <0>;
+			xlnx,layer-0-data-width = <16>;
+			xlnx,layer-0-offset = <0>;
+			xlnx,layer-1-type = <0>;
+			xlnx,layer-1-alpha-mode = <0>;
+			xlnx,layer-1-data-width = <24>;
+			xlnx,layer-1-offset = <1620>;
+			xlnx,layer-2-type = <0>;
+			xlnx,layer-2-alpha-mode = <0>;
+			xlnx,layer-2-data-width = <24>;
+			xlnx,layer-2-offset = <6480>;
+			xlnx,layer-3-type = <0>;
+			xlnx,layer-3-alpha-mode = <0>;
+			xlnx,layer-3-data-width = <24>;
+			xlnx,layer-3-offset = <9720>;
+			xlnx,layer-4-type = <0>;
+			xlnx,layer-4-alpha-mode = <0>;
+			xlnx,layer-4-data-width = <24>;
+			xlnx,layer-4-offset = <12960>;
+			xlnx,buffer-0-offset = <1080>;
+			xlnx,buffer-1-offset = <1080>;
+			xlnx,buffer-2-offset = <1080>;
+			xlnx,buffer-3-offset = <1080>;
+			xlnx,buffer-4-offset = <1080>;
+			xlnx,little-endian = <1>;
+			xlnx,readable-regs = <1>;
+			xlnx,row-stride = <2048>;
+			xlnx,use-background = <1>;
+			xlnx,use-size-position = <1>;
+			xlnx,vmem-baseaddr = <0x30000000>;
+			xlnx,vmem-highaddr = <0x3FFFFFFF>;
+
+			//0-EXT; 1-ZynqPS; 2-logiCLK; 3-SI570
+			pixel-clock-source = <3>;
+			pixel-data-invert = <0>;
+			pixel-clock-active-high = <1>;
+			pixel-component-format = "ARGB";
+			pixel-component-layer = <0>,<1>,<2>;
+			active-layer = <0>;
+			videomode = "1920x1080";
+			edid {
+				preffered-videomode = <1>;
+				display-data = <0>;
+			};
+		};
+
+		xylon-video-params {
+			800x480_TM050RBH01 {
+				name = "800x480_TM050RBH01";
+				refresh = <60>;
+				xres = <800>;
+				yres = <480>;
+				pixclock-khz = <30000>;
+				left-margin = <40>;
+				right-margin = <40>;
+				upper-margin = <29>;
+				lower-margin = <13>;
+				hsync-len = <48>;
+				vsync-len = <3>;
+				sync = <0>;
+				vmode = <0>;
+			};
+			1280x720 {
+				name = "1280x720";
+				refresh = <60>;
+				xres = <1280>;
+				yres = <720>;
+				pixclock-khz = <74250>;
+				left-margin = <220>;
+				right-margin = <110>;
+				upper-margin = <20>;
+				lower-margin = <5>;
+				hsync-len = <40>;
+				vsync-len = <5>;
+				sync = <0>;
+				vmode = <0>;
+			};
+			1680x1050 {
+				name = "1680x1050";
+				refresh = <60>;
+				xres = <1680>;
+				yres = <1050>;
+				pixclock-khz = <119000>;
+				left-margin = <80>;
+				right-margin = <48>;
+				upper-margin = <21>;
+				lower-margin = <3>;
+				hsync-len = <32>;
+				vsync-len = <6>;
+				sync = <0>;
+				vmode = <0>;
+			};
+			1920x1080 {
+				name = "1920x1080";
+				refresh = <60>;
+				xres = <1920>;
+				yres = <1080>;
+				pixclock-khz = <148500>;
+				left-margin = <148>;
+				right-margin = <88>;
+				upper-margin = <36>;
+				lower-margin = <4>;
+				hsync-len = <44>;
+				vsync-len = <5>;
+				sync = <0>;
+				vmode = <0>;
+			};
+		};
+	};
+};
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702-drm-v4l2.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702-drm-v4l2.dts	2014-07-20 22:06:33.915345982 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		i2c0 = &ps7_i2c_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_0: ps7-can@e0008000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 19>, <&clkc 36>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 28 4>;
+			reg = <0xe0008000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			arm,primecell-periphid = <0x41330>;
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,enet-reset = "MIO 11";
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "marvell,88e1116r";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x5600>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_0: ps7-i2c@e0004000 {
+			bus-id = <0>;
+			clocks = <&clkc 38>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 25 4>;
+			reg = <0xe0004000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			xlnx,i2c-reset = "MIO 13";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2cswitch@74 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x74>;
+
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+					si570: si570@5d {
+						compatible = "si570";
+						reg = <0x5d>;
+						factory-fout = <156250000>;
+						initial-fout = <148500000>;
+					};
+				};
+
+				i2c_adv7511: i2c@1 {
+					#size-cells = <0>;
+					#address-cells = <1>;
+					reg = <1>;
+
+					adv7511: adv7511@39 {
+						compatible = "adi,adv7511";
+						reg = <0x39>;
+						adi,input-style = <0x02>;
+						adi,input-id = <0x01>;
+						adi,input-color-depth = <0x3>;
+						adi,sync-pulse = <0x03>;
+						adi,bit-justification = <0x01>;
+						adi,up-conversion = <0x00>;
+						adi,timing-generation-sequence = <0x00>;
+						adi,vsync-polarity = <0x02>;
+						adi,hsync-polarity = <0x02>;
+						adi,tdms-clock-inversion;
+						adi,clock-delay = <0x00>;
+					};
+				};
+
+				i2c@2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+					eeprom@54 {
+						compatible = "at,24c08";
+						reg = <0x54>;
+					};
+				};
+
+				i2c@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+					gpio@21 {
+						compatible = "ti,tca6416";
+						reg = <0x21>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				i2c@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+					rtc@54 {
+						compatible = "nxp,pcf8563";
+						reg = <0x51>;
+					};
+				};
+
+				i2c@7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+					hwmon@52 {
+						compatible = "pmbus,ucd9248";
+						reg = <52>;
+					};
+					hwmon@53 {
+						compatible = "pmbus,ucd9248";
+						reg = <53>;
+					};
+					hwmon@54 {
+						compatible = "pmbus,ucd9248";
+						reg = <54>;
+					};
+				};
+			};
+
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <0>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
+
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x1000000>;
+		} ;
+		ps7_ram_0: ps7-ram@0 {
+			compatible = "xlnx,ps7-ram-1.00.a", "xlnx,ps7-ocm";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xfffc0000 0x40000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_0: ps7-sdio@e0100000 {
+			clock-frequency = <50000000>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 21>, <&clkc 32>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 24 4>;
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x1>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+			xlnx,usb-reset = "MIO 7";
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+
+		axi_vdma_0: axivdma@40000000 {
+			compatible = "xlnx,axi-vdma";
+			reg = <0x40000000 0x10000>;
+
+			xlnx,flush-fsync = <1>;
+			xlnx,num-fstores = <1>;
+			xlnx,family = "zynq-770";
+
+			#dma-cells = <1>;
+			dma-mm2schannel@40000000 {
+				compatible = "xlnx,axi-vdma-mm2s-channel";
+				interrupt-parent = <&ps7_scugic_0>;
+				interrupts = <0 58 0x4>;
+				xlnx,datawidth = <0x40>;
+				xlnx,device-id = <0>;
+			};
+		};
+
+		axi_vdma_1: axivdma@40060000 {
+			compatible = "xlnx,axi-vdma";
+			reg = <0x40060000 0x10000>;
+
+			xlnx,flush-fsync = <1>;
+			xlnx,num-fstores = <1>;
+			xlnx,family = "zynq-770";
+
+			#dma-cells = <1>;
+			dma-mm2schannel@40060000 {
+				compatible = "xlnx,axi-vdma-mm2s-channel";
+				interrupt-parent = <&ps7_scugic_0>;
+				interrupts = <0 57 0x4>;
+				xlnx,datawidth = <0x40>;
+				xlnx,device-id = <0>;
+			};
+			dma-s2mmchannel@40060000 {
+				compatible = "xlnx,axi-vdma-s2mm-channel";
+				interrupt-parent = <&ps7_scugic_0>;
+				interrupts = <0 56 4>;
+				xlnx,datawidth = <0x40>;
+				xlnx,include-dre;
+				xlnx,device-id = <1>;
+			};
+		};
+
+		axi_vdma_2: axivdma@400a0000 {
+			compatible = "xlnx,axi-vdma";
+			reg = <0x400a0000 0x10000>;
+
+			xlnx,flush-fsync = <1>;
+			xlnx,num-fstores = <1>;
+			xlnx,family = "zynq-770";
+
+			#dma-cells = <1>;
+			dma-mm2schannel@400a0000 {
+				compatible = "xlnx,axi-vdma-mm2s-channel";
+				interrupt-parent = <&ps7_scugic_0>;
+				interrupts = <0 35 0x4>;
+				xlnx,datawidth = <0x40>;
+				xlnx,device-id = <0>;
+			};
+		};
+
+		vtc_0: v-tc@40010000 {
+			compatible = "xlnx,v-tc-6.0";
+			reg = <0x40010000 0x10000>;
+			interrupts = <0 54 4>;
+			interrupt-parent = <&ps7_scugic_0>;
+		};
+
+		cresample_0: v-cresample@40020000 {
+			compatible = "xlnx,v-cresample-4.0";
+			reg = <0x40020000 0x10000>;
+			xlnx,input-format = "yuv444";
+			xlnx,output-format = "yuv422";
+		};
+
+		rgb2ycrcb_0: v-rgb2ycrcb@40030000 {
+			compatible = "xlnx,v-rgb2ycrcb-7.0";
+			reg = <0x40030000 0x10000>;
+		};
+
+		osd_0: v-osd@40040000 {
+			compatible = "xlnx,v-osd-6.0";
+			reg = <0x40040000 0x10000>;
+			xlnx,num-layers = <3>;
+			xlnx,screen-width = <1920>;
+		};
+
+		xilinx_drm {
+			compatible = "xlnx,drm";
+			osd = <&osd_0>;
+			vtc = <&vtc_0>;
+			encoder-slave = <&adv7511>;
+			clocks = <&si570>;
+			planes {
+				plane0 {
+					dmas = <&axi_vdma_0 0>;
+					dma-names = "vdma";
+					rgb2yuv = <&rgb2ycrcb_0>;
+					cresample = <&cresample_0>;
+				};
+				plane1 {
+					dmas = <&axi_vdma_1 0>;
+					dma-names = "vdma";
+				};
+				plane2 {
+					dmas = <&axi_vdma_2 0>;
+					dma-names = "vdma";
+				};
+			};
+		};
+
+		axi_tpg_0: axi_tpg@40050000 {
+			compatible = "xlnx,axi-tpg";
+			reg = <0x40050000 0x10000>;
+
+			xlnx,axi-video-format = "yuv422";
+			xlnx,axi-video-width = <8>;
+
+			port {
+				tpg0_out: endpoint {
+					remote-endpoint = <&vcap0_in>;
+				};
+			};
+		};
+
+		axi_video_cap {
+			compatible = "xlnx,axi-video";
+			dmas = <&axi_vdma_1 1>;
+			dma-names = "vdma-s2mm";
+
+			vdma-s2mm {
+				port {
+					vcap0_in: endpoint {
+						remote-endpoint = <&tpg0_out>;
+					};
+				};
+			};
+		};
+
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702.dts
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/boot/dts/zynq-zc702.dts	2014-07-20 22:05:50.283065845 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc702.dts	2014-07-20 22:06:33.926345800 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
 /*
- *  Copyright (C) 2011 Xilinx
- *  Copyright (C) 2012 National Instruments Corp.
+ * Device Tree Generator version: 1.1
  *
- * 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.
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
  *
- * 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.
  */
-/dts-v1/;
-/include/ "zynq-7000.dtsi"
 
+/dts-v1/;
 / {
-	model = "Zynq ZC702 Development Board";
-	compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
-
-	memory {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		i2c0 = &ps7_i2c_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
 		device_type = "memory";
 		reg = <0x0 0x40000000>;
-	};
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_0: ps7-can@e0008000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 19>, <&clkc 36>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 28 4>;
+			reg = <0xe0008000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			enet-reset = <&ps7_gpio_0 11 0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "marvell,88e1116r";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x5600>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_0: ps7-i2c@e0004000 {
+			bus-id = <0>;
+			clocks = <&clkc 38>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			i2c-reset = <&ps7_gpio_0 13 0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 25 4>;
+			reg = <0xe0004000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2cswitch@74 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x74>;
 
-	chosen {
-		bootargs = "console=ttyPS0,115200 earlyprintk";
-	};
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+					si570: clock-generator@5d {
+						#clock-cells = <0>;
+						compatible = "silabs,si570";
+						temperature-stability = <50>;
+						reg = <0x5d>;
+						factory-fout = <156250000>;
+						clock-frequency = <148500000>;
+					};
+				};
+
+				i2c@2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+					eeprom@54 {
+						compatible = "at,24c08";
+						reg = <0x54>;
+					};
+				};
+
+				i2c@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+					gpio@21 {
+						compatible = "ti,tca6416";
+						reg = <0x21>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				i2c@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+					rtc@54 {
+						compatible = "nxp,pcf8563";
+						reg = <0x51>;
+					};
+				};
+
+				i2c@7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+					hwmon@52 {
+						compatible = "pmbus,ucd9248";
+						reg = <52>;
+					};
+					hwmon@53 {
+						compatible = "pmbus,ucd9248";
+						reg = <53>;
+					};
+					hwmon@54 {
+						compatible = "pmbus,ucd9248";
+						reg = <54>;
+					};
+				};
+			};
 
-};
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <0>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
 
-&uart1 {
-	status = "okay";
-};
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x1000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_0: ps7-sdio@e0100000 {
+			clock-frequency = <50000000>;
+			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clkc 21>, <&clkc 32>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci", "arasan,sdhci-8.9a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 24 4>;
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x1>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+			usb-reset = <&ps7_gpio_0 7 0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc706.dts
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/boot/dts/zynq-zc706.dts	2014-07-20 22:05:50.285065813 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc706.dts	2014-07-20 22:06:33.939345586 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
 /*
- *  Copyright (C) 2011 Xilinx
- *  Copyright (C) 2012 National Instruments Corp.
- *  Copyright (C) 2013 Xilinx
+ * Device Tree Generator version: 1.1
  *
- * 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.
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
  *
- * 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.
  */
-/dts-v1/;
-/include/ "zynq-7000.dtsi"
 
+/dts-v1/;
 / {
-	model = "Zynq ZC706 Development Board";
-	compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
-
-	memory {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		i2c0 = &ps7_i2c_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
 		device_type = "memory";
-		reg = <0 0x40000000>;
-	};
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			enet-reset = <&ps7_gpio_0 47 0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "marvell,88e1116r";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_0: ps7-i2c@e0004000 {
+			bus-id = <0>;
+			clocks = <&clkc 38>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			i2c-reset = <&ps7_gpio_0 46 0>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 25 4>;
+			reg = <0xe0004000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2cswitch@74 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x74>;
 
-	chosen {
-		bootargs = "console=ttyPS0,115200 earlyprintk";
-	};
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+					si570: clock-generator@5d {
+						#clock-cells = <0>;
+						compatible = "silabs,si570";
+						temperature-stability = <50>;
+						reg = <0x5d>;
+						factory-fout = <156250000>;
+						clock-frequency = <148500000>;
+					};
+				};
+
+				i2c@2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+					eeprom@54 {
+						compatible = "at,24c08";
+						reg = <0x54>;
+					};
+				};
+
+				i2c@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+					gpio@21 {
+						compatible = "ti,tca6416";
+						reg = <0x21>;
+						gpio-controller;
+						#gpio-cells = <2>;
+					};
+				};
+
+				i2c@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+					rtc@51 {
+						compatible = "nxp,pcf8563";
+						reg = <0x51>;
+					};
+				};
+
+
+				i2c@7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+					ucd90120@65 {
+						compatible = "pmbus,ucd90120";
+						reg = <0x65>;
+					};
+				};
+			};
 
-};
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <1>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
 
-&uart1 {
-	status = "okay";
-};
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x2000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_0: ps7-sdio@e0100000 {
+			clock-frequency = <50000000>;
+			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clkc 21>, <&clkc 32>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci", "arasan,sdhci-8.9a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 24 4>;
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x1>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_ttc_1: ps7-ttc@f8002000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+			reg = <0xf8002000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+			usb-reset = <&ps7_gpio_0 7 0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm010.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm010.dts	2014-07-20 22:06:33.950345405 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		i2c0 = &ps7_i2c_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_spi_1;
+		spi1 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_0: ps7-can@e0008000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 19>, <&clkc 36>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 28 4>;
+			reg = <0xe0008000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "marvell,88e1116r";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x200>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_0: ps7-i2c@e0004000 {
+			bus-id = <0>;
+			clocks = <&clkc 38>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 25 4>;
+			reg = <0xe0004000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			m24c02_eeprom@52 {
+				compatible = "at,24c02";
+				reg = <0x52>;
+			};
+
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <0>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
+
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x1000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_0: ps7-sdio@e0100000 {
+			clock-frequency = <50000000>;
+			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clkc 21>, <&clkc 32>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci", "arasan,sdhci-8.9a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 24 4>;
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x1>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_spi_1: ps7-spi@e0007000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 26>, <&clkc 35>;
+			compatible = "xlnx,ps7-spi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 49 4>;
+			num-chip-select = <4>;
+			reg = <0xe0007000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "sst25wf080";
+				reg = <1>;
+				spi-max-frequency = <1000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@test {
+					label = "spi-flash";
+					reg = <0x0 0x100000>;
+				};
+			};
+
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+			usb-reset = <&ps7_gpio_0 7 0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm011.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm011.dts	2014-07-20 22:06:33.961345223 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		i2c0 = &ps7_i2c_1;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_spi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_0: ps7-can@e0008000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 19>, <&clkc 36>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 28 4>;
+			reg = <0xe0008000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0xfc>;
+			gpio-mask-low = <0xff8002>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_1: ps7-i2c@e0005000 {
+			bus-id = <0>;
+			clocks = <&clkc 39>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 48 4>;
+			reg = <0xe0005000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			m24c02_eeprom@52 {
+				compatible = "at,24c02";
+				reg = <0x52>;
+			};
+
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_smcc_0: ps7-smcc@e000e000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 11>, <&clkc 44>;
+			compatible = "xlnx,ps7-smcc-1.00.a", "xlnx,ps7-smc";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 18 4>;
+			ranges ;
+			reg = <0xe000e000 0x1000>;
+			xlnx,addr25 = <0x0>;
+			xlnx,nor-chip-sel0 = <0x0>;
+			xlnx,nor-chip-sel1 = <0x0>;
+			xlnx,sram-chip-sel0 = <0x0>;
+			xlnx,sram-chip-sel1 = <0x0>;
+			ps7_nand_0: ps7-nand@e1000000 {
+				compatible = "xlnx,ps7-nand-1.00.a";
+				reg = <0xe1000000 0x1000000>;
+				xlnx,nand-cycle-t0 = <0x4>;
+				xlnx,nand-cycle-t1 = <0x4>;
+				xlnx,nand-cycle-t2 = <0x1>;
+				xlnx,nand-cycle-t3 = <0x2>;
+				xlnx,nand-cycle-t4 = <0x2>;
+				xlnx,nand-cycle-t5 = <0x2>;
+				xlnx,nand-cycle-t6 = <0x4>;
+				xlnx,nand-width = <0x8>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				partition@nand-fsbl-uboot {
+					label = "nand-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@nand-linux {
+					label = "nand-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@nand-device-tree {
+					label = "nand-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@nand-rootfs {
+					label = "nand-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@nand-bitstream {
+					label = "nand-bitstream";
+					reg = <0xC00000 0x400000>;
+
+				};
+
+			} ;
+		} ;
+		ps7_spi_0: ps7-spi@e0006000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 25>, <&clkc 34>;
+			compatible = "xlnx,ps7-spi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 26 4>;
+			num-chip-select = <4>;
+			reg = <0xe0006000 0x1000>;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_1: ps7-usb@e0003000 {
+			clocks = <&clkc 29>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 44 4>;
+			phy_type = "ulpi";
+			reg = <0xe0003000 0x1000>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm012.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm012.dts	2014-07-20 22:06:33.969345091 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		i2c0 = &ps7_i2c_0;
+		i2c1 = &ps7_i2c_1;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_spi_1;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_1: ps7-can@e0009000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 20>, <&clkc 37>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 51 4>;
+			reg = <0xe0009000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0x0>;
+			gpio-mask-low = <0x4004>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_0: ps7-i2c@e0004000 {
+			bus-id = <0>;
+			clocks = <&clkc 38>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 25 4>;
+			reg = <0xe0004000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			m24c02_eeprom@52 {
+				compatible = "at,24c02";
+				reg = <0x52>;
+			};
+
+		} ;
+		ps7_i2c_1: ps7-i2c@e0005000 {
+			bus-id = <1>;
+			clocks = <&clkc 39>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 48 4>;
+			reg = <0xe0005000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			m24c02_eeprom@52 {
+				compatible = "at,24c02";
+				reg = <0x52>;
+			};
+
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_smcc_0: ps7-smcc@e000e000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 11>, <&clkc 44>;
+			compatible = "xlnx,ps7-smcc-1.00.a", "xlnx,ps7-smc";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 18 4>;
+			ranges ;
+			reg = <0xe000e000 0x1000>;
+			xlnx,addr25 = <0x1>;
+			xlnx,nor-chip-sel0 = <0x1>;
+			xlnx,nor-chip-sel1 = <0x0>;
+			xlnx,sram-chip-sel0 = <0x0>;
+			xlnx,sram-chip-sel1 = <0x0>;
+			ps7_nor_0: ps7-nor@e2000000 {
+				bank-width = <1>;
+				compatible = "xlnx,ps7-nor-1.00.a", "cfi-flash";
+				reg = <0xe2000000 0x1000>;
+				xlnx,sram-cycle-t0 = <0xb>;
+				xlnx,sram-cycle-t1 = <0xb>;
+				xlnx,sram-cycle-t2 = <0x4>;
+				xlnx,sram-cycle-t3 = <0x4>;
+				xlnx,sram-cycle-t4 = <0x3>;
+				xlnx,sram-cycle-t5 = <0x3>;
+				xlnx,sram-cycle-t6 = <0x2>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				partition@nor-fsbl-uboot {
+					label = "nor-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@nor-linux {
+					label = "nor-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@nor-device-tree {
+					label = "nor-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@nor-rootfs {
+					label = "nor-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@nor-bitstream {
+					label = "nor-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			} ;
+		} ;
+		ps7_spi_1: ps7-spi@e0007000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 26>, <&clkc 35>;
+			compatible = "xlnx,ps7-spi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 49 4>;
+			num-chip-select = <4>;
+			reg = <0xe0007000 0x1000>;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_ttc_1: ps7-ttc@f8002000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
+			reg = <0xf8002000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm013.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zc770-xm013.dts	2014-07-20 22:06:33.978344943 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
+ *
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynq-7000";
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_1;
+		i2c0 = &ps7_i2c_1;
+		serial0 = &ps7_uart_0;
+		spi0 = &ps7_spi_0;
+		spi1 = &ps7_qspi_0;
+	} ;
+	chosen {
+		bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0000000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_can_1: ps7-can@e0009000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 20>, <&clkc 37>;
+			compatible = "xlnx,ps7-can-1.00.a", "xlnx,ps7-can";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 51 4>;
+			reg = <0xe0009000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_1: ps7-ethernet@e000c000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 14>, <&clkc 31>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 45 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000c000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@7 {
+					compatible = "vitesse,vsc8211";
+					device_type = "ethernet-phy";
+					reg = <7>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0xdc000>;
+			gpio-mask-low = <0xfc00080>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_i2c_1: ps7-i2c@e0005000 {
+			bus-id = <0>;
+			clocks = <&clkc 39>;
+			compatible = "xlnx,ps7-i2c-1.00.a";
+			i2c-clk = <400000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 48 4>;
+			reg = <0xe0005000 0x1000>;
+			xlnx,has-interrupt = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			si570: clock-generator@55 {
+				#clock-cells = <0>;
+				compatible = "silabs,si570";
+				temperature-stability = <50>;
+				reg = <0x55>;
+				factory-fout = <156250000>;
+				clock-frequency = <148500000>;
+			};
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <1>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
+
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x2000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_spi_0: ps7-spi@e0006000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 25>, <&clkc 34>;
+			compatible = "xlnx,ps7-spi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 26 4>;
+			num-chip-select = <4>;
+			reg = <0xe0006000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			eeprom: at25@0 {
+				at25,byte-len = <8192>;
+				at25,addr-mode = <2>;
+				at25,page-size = <32>;
+
+				compatible = "atmel,at25";
+				reg = <2>;
+				spi-max-frequency = <1000000>;
+			};
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_0: serial@e0000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 23>, <&clkc 40>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 27 4>;
+			port-number = <0>;
+			reg = <0xe0000000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_wdt_0: ps7-wdt@f8005000 {
+			clocks = <&clkc 45>;
+			compatible = "xlnx,ps7-wdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 9 1>;
+			reg = <0xf8005000 0x1000>;
+			reset = <0>;
+			timeout = <10>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zed.dts
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/boot/dts/zynq-zed.dts	2014-07-20 22:05:50.287065779 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/boot/dts/zynq-zed.dts	2014-07-20 22:06:33.988344778 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
 /*
- *  Copyright (C) 2011 Xilinx
- *  Copyright (C) 2012 National Instruments Corp.
- *  Copyright (C) 2013 Xilinx
+ * Device Tree Generator version: 1.1
  *
- * 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.
+ * (C) Copyright 2007-2013 Xilinx, Inc.
+ * (C) Copyright 2007-2013 Michal Simek
+ * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 14.5 EDK_P.58f
  *
- * 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.
  */
-/dts-v1/;
-/include/ "zynq-7000.dtsi"
 
+/dts-v1/;
 / {
-	model = "Zynq Zed Development Board";
+	#address-cells = <1>;
+	#size-cells = <1>;
 	compatible = "xlnx,zynq-7000";
-
-	memory {
-		device_type = "memory";
-		reg = <0 0x20000000>;
-	};
-
+	model = "Xilinx Zynq";
+	aliases {
+		ethernet0 = &ps7_ethernet_0;
+		serial0 = &ps7_uart_1;
+		spi0 = &ps7_qspi_0;
+	} ;
 	chosen {
-		bootargs = "console=ttyPS0,115200 earlyprintk";
-	};
-
-};
+		bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rootwait rw earlyprintk";
+		linux,stdout-path = "/amba@0/serial@e0001000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ps7_cortexa9_0: cpu@0 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x0>;
+		} ;
+		ps7_cortexa9_1: cpu@1 {
+			bus-handle = <&ps7_axi_interconnect_0>;
+			compatible = "arm,cortex-a9";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x8000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x8000>;
+			interrupt-handle = <&ps7_scugic_0>;
+			reg = <0x1>;
+		} ;
+	} ;
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 5 4>, <0 6 4>;
+		reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>;
+		reg-names = "cpu0", "cpu1";
+	} ;
+	ps7_ddr_0: memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x20000000>;
+	} ;
+	ps7_axi_interconnect_0: amba@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
+		ranges ;
+		ps7_afi_0: ps7-afi@f8008000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8008000 0x1000>;
+		} ;
+		ps7_afi_1: ps7-afi@f8009000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf8009000 0x1000>;
+		} ;
+		ps7_afi_2: ps7-afi@f800a000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800a000 0x1000>;
+		} ;
+		ps7_afi_3: ps7-afi@f800b000 {
+			compatible = "xlnx,ps7-afi-1.00.a";
+			reg = <0xf800b000 0x1000>;
+		} ;
+		ps7_ddrc_0: ps7-ddrc@f8006000 {
+			compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+			reg = <0xf8006000 0x1000>;
+			xlnx,has-ecc = <0x0>;
+		} ;
+		ps7_dev_cfg_0: ps7-dev-cfg@f8007000 {
+			clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
+			clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
+			compatible = "xlnx,ps7-dev-cfg-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 8 4>;
+			reg = <0xf8007000 0x100>;
+		} ;
+		ps7_dma_s: ps7-dma@f8003000 {
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <4>;
+			clock-names = "apb_pclk";
+			clocks = <&clkc 27>;
+			compatible = "xlnx,ps7-dma-1.00.a", "arm,primecell", "arm,pl330";
+			interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+				"dma4", "dma5", "dma6", "dma7";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
+			reg = <0xf8003000 0x1000>;
+		} ;
+		ps7_ethernet_0: ps7-ethernet@e000b000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 13>, <&clkc 30>;
+			compatible = "xlnx,ps7-ethernet-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 22 4>;
+			local-mac-address = [00 0a 35 00 00 00];
+			phy-handle = <&phy0>;
+			phy-mode = "rgmii-id";
+			reg = <0xe000b000 0x1000>;
+			xlnx,eth-mode = <0x1>;
+			xlnx,has-mdio = <0x1>;
+			xlnx,ptp-enet-clock = <111111115>;
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				phy0: phy@0 {
+					compatible = "marvell,88e1510";
+					device_type = "ethernet-phy";
+					reg = <0>;
+				} ;
+			} ;
+		} ;
+		ps7_gpio_0: ps7-gpio@e000a000 {
+			#gpio-cells = <2>;
+			clocks = <&clkc 42>;
+			compatible = "xlnx,ps7-gpio-1.00.a";
+			emio-gpio-width = <64>;
+			gpio-controller ;
+			gpio-mask-high = <0xc0000>;
+			gpio-mask-low = <0xfe81>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 20 4>;
+			reg = <0xe000a000 0x1000>;
+		} ;
+		ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 {
+			compatible = "xlnx,ps7-iop-bus-config-1.00.a";
+			reg = <0xe0200000 0x1000>;
+		} ;
+		ps7_ocmc_0: ps7-ocmc@f800c000 {
+			compatible = "xlnx,ps7-ocmc-1.00.a", "xlnx,zynq-ocm-1.0";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 3 4>;
+			reg = <0xf800c000 0x1000>;
+		} ;
+		ps7_pl310_0: ps7-pl310@f8f02000 {
+			arm,data-latency = <3 2 2>;
+			arm,tag-latency = <2 2 2>;
+			cache-level = <2>;
+			cache-unified ;
+			compatible = "xlnx,ps7-pl310-1.00.a", "arm,pl310-cache";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 2 4>;
+			reg = <0xf8f02000 0x1000>;
+		} ;
+		ps7_qspi_0: ps7-qspi@e000d000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 19 4>;
+			is-dual = <0>;
+			num-chip-select = <1>;
+			reg = <0xe000d000 0x1000>;
+			xlnx,fb-clk = <0x1>;
+			xlnx,qspi-mode = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash@0 {
+				compatible = "n25q128";
+				reg = <0x0>;
+				spi-max-frequency = <50000000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				partition@qspi-fsbl-uboot {
+					label = "qspi-fsbl-uboot";
+					reg = <0x0 0x100000>;
+				};
+				partition@qspi-linux {
+					label = "qspi-linux";
+					reg = <0x100000 0x500000>;
+				};
+				partition@qspi-device-tree {
+					label = "qspi-device-tree";
+					reg = <0x600000 0x20000>;
+				};
+				partition@qspi-rootfs {
+					label = "qspi-rootfs";
+					reg = <0x620000 0x5E0000>;
+				};
+				partition@qspi-bitstream {
+					label = "qspi-bitstream";
+					reg = <0xC00000 0x400000>;
+				};
+			};
 
-&uart1 {
-	status = "okay";
-};
+		} ;
+		ps7_qspi_linear_0: ps7-qspi-linear@fc000000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 10>, <&clkc 43>;
+			compatible = "xlnx,ps7-qspi-linear-1.00.a";
+			reg = <0xfc000000 0x1000000>;
+		} ;
+		ps7_scugic_0: ps7-scugic@f8f01000 {
+			#address-cells = <2>;
+			#interrupt-cells = <3>;
+			#size-cells = <1>;
+			compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic";
+			interrupt-controller ;
+			num_cpus = <2>;
+			num_interrupts = <96>;
+			reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>;
+		} ;
+		ps7_scutimer_0: ps7-scutimer@f8f00600 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scutimer-1.00.a", "arm,cortex-a9-twd-timer";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 13 0x301>;
+			reg = <0xf8f00600 0x20>;
+		} ;
+		ps7_scuwdt_0: ps7-scuwdt@f8f00620 {
+			clocks = <&clkc 4>;
+			compatible = "xlnx,ps7-scuwdt-1.00.a";
+			device_type = "watchdog";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <1 14 0x301>;
+			reg = <0xf8f00620 0xe0>;
+		} ;
+		ps7_sd_0: ps7-sdio@e0100000 {
+			clock-frequency = <50000000>;
+			clock-names = "clk_xin", "clk_ahb";
+			clocks = <&clkc 21>, <&clkc 32>;
+			compatible = "xlnx,ps7-sdio-1.00.a", "generic-sdhci", "arasan,sdhci-8.9a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 24 4>;
+			reg = <0xe0100000 0x1000>;
+			xlnx,has-cd = <0x1>;
+			xlnx,has-power = <0x0>;
+			xlnx,has-wp = <0x1>;
+		} ;
+		ps7_slcr_0: ps7-slcr@f8000000 {
+			compatible = "xlnx,ps7-slcr-1.00.a", "xlnx,zynq-slcr";
+			reg = <0xf8000000 0x1000>;
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clkc: clkc {
+					#clock-cells = <1>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x",
+						"cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci",
+						"lqspi", "smc", "pcap", "gem0", "gem1",
+						"fclk0", "fclk1", "fclk2", "fclk3", "can0",
+						"can1", "sdio0", "sdio1", "uart0", "uart1",
+						"spi0", "spi1", "dma", "usb0_aper", "usb1_aper",
+						"gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper",
+						"spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+						"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper",
+						"swdt", "dbg_trc", "dbg_apb";
+					compatible = "xlnx,ps7-clkc";
+					fclk-enable = <0xf>;
+					ps-clk-frequency = <33333333>;
+				} ;
+			} ;
+		} ;
+		ps7_ttc_0: ps7-ttc@f8001000 {
+			clocks = <&clkc 6>;
+			compatible = "xlnx,ps7-ttc-1.00.a", "cdns,ttc";
+			interrupt-names = "ttc0", "ttc1", "ttc2";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+			reg = <0xf8001000 0x1000>;
+		} ;
+		ps7_uart_1: serial@e0001000 {
+			clock-names = "ref_clk", "aper_clk";
+			clocks = <&clkc 24>, <&clkc 41>;
+			compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 50 4>;
+			port-number = <0>;
+			reg = <0xe0001000 0x1000>;
+			xlnx,has-modem = <0x0>;
+		} ;
+		ps7_usb_0: ps7-usb@e0002000 {
+			clocks = <&clkc 28>;
+			compatible = "xlnx,ps7-usb-1.00.a";
+			dr_mode = "host";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 21 4>;
+			phy_type = "ulpi";
+			reg = <0xe0002000 0x1000>;
+		} ;
+		ps7_xadc: ps7-xadc@f8007100 {
+			clocks = <&clkc 12>;
+			compatible = "xlnx,ps7-xadc-1.00.a";
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 7 4>;
+			reg = <0xf8007100 0x20>;
+		} ;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_apf_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_apf_defconfig	2014-07-20 22:06:34.025344167 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.12.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="arm-xilinx-linux-gnueabi-"
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION="-xilinx-trd"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GENERIC_SCHED_CLOCK=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+
+#
+# Multiple platform selection
+#
+
+#
+# CPU Core family selection
+#
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MULTI_V6_V7=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_BCM is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_KEYSTONE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_SOC_OMAP5 is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_SOC_AM43XX is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_STI is not set
+# CONFIG_ARCH_SHMOBILE_MULTI is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_SIRF is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_ARCH_VEXPRESS=y
+
+#
+# Versatile Express platform type
+#
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
+CONFIG_PLAT_VERSATILE_CLCD=y
+CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
+# CONFIG_ARCH_VIRT is not set
+# CONFIG_ARCH_WM8850 is not set
+CONFIG_ARCH_ZYNQ=y
+
+#
+# Xilinx Specific Options
+#
+CONFIG_XILINX_L1_PREFETCH=y
+CONFIG_XILINX_L2_PREFETCH=y
+CONFIG_XILINX_AXIPCIE=y
+CONFIG_PLAT_VERSATILE=y
+CONFIG_ARM_TIMER_SP804=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_ARM_ERRATA_773022 is not set
+CONFIG_ICST=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+
+#
+# PCI host controller drivers
+#
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=1024
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_100=y
+# CONFIG_HZ_200 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_500 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_ZBUD is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_AUTO_ZRELADDR=y
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_ZYNQ_CPUFREQ=y
+
+#
+# CPU Idle
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_KERNEL_MODE_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_CLK=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ARM_CPU_SUSPEND is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=m
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+CONFIG_DMA_CMA=y
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=256
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+
+#
+# Bus devices
+#
+# CONFIG_ARM_CCI is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_ZYNQ=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_ARM_CHARLCD is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+CONFIG_SI570=y
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_MPT3SAS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_VIRTIO is not set
+# CONFIG_SCSI_CHELSIO_FCOE is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+CONFIG_NET_VENDOR_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_NET_CADENCE=y
+# CONFIG_ARM_AT91_ETHER is not set
+# CONFIG_MACB is not set
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R8169=y
+# CONFIG_SH_ETH is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NET_VENDOR_XILINX=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_XILINX_AXI_EMAC=y
+CONFIG_XILINX_PS_EMAC=y
+# CONFIG_XILINX_PS_EMAC_HWTSTAMP is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_ST_ASC is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_XILINX_DEVCFG=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_VERSATILE is not set
+CONFIG_I2C_ZYNQ=y
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_FSL_DSPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+CONFIG_SPI_ZYNQ_QSPI=y
+# CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED is not set
+CONFIG_SPI_ZYNQ=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# LPC GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_SMB347 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_HTU21 is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_XADCPS=y
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+CONFIG_ZYNQ_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_XILINX_WATCHDOG is not set
+# CONFIG_MEN_A21_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_V4L2=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+# CONFIG_MEDIA_USB_SUPPORT is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+# CONFIG_VIDEO_CAFE_CCIC is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_XILINX is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+
+#
+# Encoders, decoders, sensors and other helper chips
+#
+
+#
+# Audio decoders, processors and mixers
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_UDA1342 is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+# CONFIG_VIDEO_SONY_BTF_MPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_ADV7183 is not set
+CONFIG_VIDEO_ADV7604=y
+# CONFIG_VIDEO_ADV7842 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_ML86V7667 is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
+# CONFIG_VIDEO_TW2804 is not set
+# CONFIG_VIDEO_TW9903 is not set
+# CONFIG_VIDEO_TW9906 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+# CONFIG_VIDEO_ADV7393 is not set
+CONFIG_VIDEO_ADV7511=y
+# CONFIG_VIDEO_AD9389B is not set
+# CONFIG_VIDEO_AK881X is not set
+# CONFIG_VIDEO_THS8200 is not set
+
+#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_OV7640 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_OV9650 is not set
+# CONFIG_VIDEO_VS6624 is not set
+# CONFIG_VIDEO_MT9M032 is not set
+# CONFIG_VIDEO_MT9P031 is not set
+# CONFIG_VIDEO_MT9T001 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_MT9V032 is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_VIDEO_M5MOLS is not set
+# CONFIG_VIDEO_S5K6AA is not set
+# CONFIG_VIDEO_S5K4ECGX is not set
+# CONFIG_VIDEO_SMIAPP is not set
+# CONFIG_VIDEO_S5C73M3 is not set
+
+#
+# Flash devices
+#
+# CONFIG_VIDEO_ADP1653 is not set
+# CONFIG_VIDEO_AS3645A is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# Miscelaneous helper chips
+#
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_M52790 is not set
+
+#
+# Sensors used on soc_camera driver
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_AU8522_V4L is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_TEGRA_HOST1X is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_XILINX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+CONFIG_FB_XYLON=y
+# CONFIG_FB_XYLON_PLATFORM is not set
+CONFIG_FB_XYLON_OF=y
+CONFIG_FB_XYLON_PIXCLK=y
+# CONFIG_FB_XYLON_PIXCLK_ZYNQ_PS is not set
+# CONFIG_FB_XYLON_PIXCLK_LOGICLK is not set
+CONFIG_FB_XYLON_PIXCLK_SI570=y
+CONFIG_FB_XYLON_MISC=y
+CONFIG_FB_XYLON_MISC_ADV7511=y
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+# CONFIG_SOUND is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_XUSBPS_DR_OF=y
+CONFIG_USB_EHCI_XUSBPS=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_AM335X_PHY_USB is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+# CONFIG_USB_ZYNQ_PHY is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+CONFIG_USB_GADGET_XUSBPS=y
+CONFIG_XUSBPS_ERRATA_DT654401=y
+CONFIG_USB_XUSBPS=y
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_GADGET_XILINX is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_SS_LB=m
+# CONFIG_USB_CONFIGFS is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_ZYNQ=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_RTC_DRV_MOXART is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_XILINX_DMA_ENGINES=y
+CONFIG_XILINX_AXIDMA=y
+# CONFIG_XILINX_DMATEST is not set
+CONFIG_XILINX_AXIVDMA=y
+# CONFIG_XILINX_VDMATEST is not set
+CONFIG_XILINX_AXICDMA=y
+# CONFIG_XILINX_CDMATEST is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_PL330_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_CIF is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_MF624 is not set
+# CONFIG_UIO_XILINX_APM is not set
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=m
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+CONFIG_STAGING=y
+# CONFIG_ET131X is not set
+# CONFIG_USBIP_CORE is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTLLIB is not set
+# CONFIG_R8712U is not set
+# CONFIG_R8188EU is not set
+# CONFIG_RTS5139 is not set
+# CONFIG_TRANZPORT is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_DX_SEP is not set
+# CONFIG_ZSMALLOC is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_CRYSTALHD is not set
+# CONFIG_FB_XGI is not set
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_BCM_WIMAX is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
+# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_USB_WPAN_HCD is not set
+# CONFIG_WIMAX_GDM72XX is not set
+# CONFIG_LTE_GDM724X is not set
+CONFIG_NET_VENDOR_SILICOM=y
+# CONFIG_SBYPASS is not set
+# CONFIG_BPCTL is not set
+# CONFIG_CED1401 is not set
+# CONFIG_DGRP is not set
+# CONFIG_USB_DWC2 is not set
+# CONFIG_LUSTRE_FS is not set
+# CONFIG_XILLYBUS is not set
+# CONFIG_DGNC is not set
+# CONFIG_DGAP is not set
+CONFIG_XILINX_VIDEO_IP=y
+CONFIG_XILINX_VDMA_WRAPPER=y
+CONFIG_XILINX_APF=y
+CONFIG_XILINX_DMA_APF=y
+# CONFIG_PMODS is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_COMMON_CLK_VERSATILE=y
+# CONFIG_COMMON_CLK_SI5351 is not set
+# CONFIG_COMMON_CLK_SI570 is not set
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CADENCE_TTC_TIMER=y
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_OF_IOMMU=y
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=m
+# CONFIG_STE_MODEM_RPROC is not set
+CONFIG_ZYNQ_REMOTEPROC=m
+CONFIG_MB_REMOTEPROC=m
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=m
+# CONFIG_RPMSG_SERVER_SAMPLE is not set
+# CONFIG_RPMSG_OMX is not set
+# CONFIG_RPMSG_FREERTOS_STAT is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+CONFIG_MEMORY=y
+CONFIG_ZYNQ_SMC=y
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ZYNQ_UART0 is not set
+CONFIG_DEBUG_ZYNQ_UART1=y
+# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
+# CONFIG_DEBUG_LL_UART_8250 is not set
+# CONFIG_DEBUG_LL_UART_PL01X is not set
+CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_UART_8250 is not set
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_EARLY_PRINTK=y
+# CONFIG_OC_ETM is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_VIRTUALIZATION=y
Index: linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_base_trd_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_base_trd_defconfig	2014-07-20 22:06:34.056343656 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.12.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION="-xilinx-trd"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GENERIC_SCHED_CLOCK=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+
+#
+# Multiple platform selection
+#
+
+#
+# CPU Core family selection
+#
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MULTI_V6_V7=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_BCM is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_KEYSTONE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_SOC_OMAP5 is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_SOC_AM43XX is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_STI is not set
+# CONFIG_ARCH_SHMOBILE_MULTI is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_SIRF is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_ARCH_VEXPRESS=y
+
+#
+# Versatile Express platform type
+#
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
+CONFIG_PLAT_VERSATILE_CLCD=y
+CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
+# CONFIG_ARCH_VIRT is not set
+# CONFIG_ARCH_WM8850 is not set
+CONFIG_ARCH_ZYNQ=y
+
+#
+# Xilinx Specific Options
+#
+CONFIG_XILINX_L1_PREFETCH=y
+CONFIG_XILINX_L2_PREFETCH=y
+CONFIG_XILINX_AXIPCIE=y
+CONFIG_PLAT_VERSATILE=y
+CONFIG_ARM_TIMER_SP804=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_ARM_ERRATA_773022 is not set
+CONFIG_ICST=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+
+#
+# PCI host controller drivers
+#
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=1024
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_100=y
+# CONFIG_HZ_200 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_500 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_ZBUD is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_AUTO_ZRELADDR=y
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_ZYNQ_CPUFREQ=y
+
+#
+# CPU Idle
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_KERNEL_MODE_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_CLK=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ARM_CPU_SUSPEND is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=m
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_DMA_CMA is not set
+
+#
+# Bus devices
+#
+# CONFIG_ARM_CCI is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_ZYNQ=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_ARM_CHARLCD is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+CONFIG_SI570=y
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_MPT3SAS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_VIRTIO is not set
+# CONFIG_SCSI_CHELSIO_FCOE is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+CONFIG_NET_VENDOR_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_NET_CADENCE=y
+# CONFIG_ARM_AT91_ETHER is not set
+# CONFIG_MACB is not set
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R8169=y
+# CONFIG_SH_ETH is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NET_VENDOR_XILINX=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_XILINX_AXI_EMAC=y
+CONFIG_XILINX_PS_EMAC=y
+# CONFIG_XILINX_PS_EMAC_HWTSTAMP is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_ST_ASC is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_XILINX_DEVCFG=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_VERSATILE is not set
+CONFIG_I2C_ZYNQ=y
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_FSL_DSPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+CONFIG_SPI_ZYNQ_QSPI=y
+# CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED is not set
+CONFIG_SPI_ZYNQ=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# LPC GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_SMB347 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_HTU21 is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_XADCPS=y
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+CONFIG_ZYNQ_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_XILINX_WATCHDOG is not set
+# CONFIG_MEN_A21_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_V4L2=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+# CONFIG_MEDIA_USB_SUPPORT is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+# CONFIG_VIDEO_CAFE_CCIC is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_XILINX is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+
+#
+# Encoders, decoders, sensors and other helper chips
+#
+
+#
+# Audio decoders, processors and mixers
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_UDA1342 is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+# CONFIG_VIDEO_SONY_BTF_MPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_ADV7183 is not set
+CONFIG_VIDEO_ADV7604=y
+# CONFIG_VIDEO_ADV7842 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_ML86V7667 is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
+# CONFIG_VIDEO_TW2804 is not set
+# CONFIG_VIDEO_TW9903 is not set
+# CONFIG_VIDEO_TW9906 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+# CONFIG_VIDEO_ADV7393 is not set
+CONFIG_VIDEO_ADV7511=y
+# CONFIG_VIDEO_AD9389B is not set
+# CONFIG_VIDEO_AK881X is not set
+# CONFIG_VIDEO_THS8200 is not set
+
+#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_OV7640 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_OV9650 is not set
+# CONFIG_VIDEO_VS6624 is not set
+# CONFIG_VIDEO_MT9M032 is not set
+# CONFIG_VIDEO_MT9P031 is not set
+# CONFIG_VIDEO_MT9T001 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_MT9V032 is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_VIDEO_M5MOLS is not set
+# CONFIG_VIDEO_S5K6AA is not set
+# CONFIG_VIDEO_S5K4ECGX is not set
+# CONFIG_VIDEO_SMIAPP is not set
+# CONFIG_VIDEO_S5C73M3 is not set
+
+#
+# Flash devices
+#
+# CONFIG_VIDEO_ADP1653 is not set
+# CONFIG_VIDEO_AS3645A is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# Miscelaneous helper chips
+#
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_M52790 is not set
+
+#
+# Sensors used on soc_camera driver
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_AU8522_V4L is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_TEGRA_HOST1X is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_XILINX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+CONFIG_FB_XYLON=y
+# CONFIG_FB_XYLON_PLATFORM is not set
+CONFIG_FB_XYLON_OF=y
+CONFIG_FB_XYLON_PIXCLK=y
+# CONFIG_FB_XYLON_PIXCLK_ZYNQ_PS is not set
+# CONFIG_FB_XYLON_PIXCLK_LOGICLK is not set
+CONFIG_FB_XYLON_PIXCLK_SI570=y
+CONFIG_FB_XYLON_MISC=y
+CONFIG_FB_XYLON_MISC_ADV7511=y
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+# CONFIG_SOUND is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_XUSBPS_DR_OF=y
+CONFIG_USB_EHCI_XUSBPS=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_AM335X_PHY_USB is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+# CONFIG_USB_ZYNQ_PHY is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+CONFIG_USB_GADGET_XUSBPS=y
+CONFIG_XUSBPS_ERRATA_DT654401=y
+CONFIG_USB_XUSBPS=y
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_GADGET_XILINX is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_SS_LB=m
+# CONFIG_USB_CONFIGFS is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_ZYNQ=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_RTC_DRV_MOXART is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_XILINX_DMA_ENGINES=y
+CONFIG_XILINX_AXIDMA=y
+# CONFIG_XILINX_DMATEST is not set
+CONFIG_XILINX_AXIVDMA=y
+# CONFIG_XILINX_VDMATEST is not set
+CONFIG_XILINX_AXICDMA=y
+# CONFIG_XILINX_CDMATEST is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_PL330_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_CIF is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_MF624 is not set
+# CONFIG_UIO_XILINX_APM is not set
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=m
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+CONFIG_STAGING=y
+# CONFIG_ET131X is not set
+# CONFIG_USBIP_CORE is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTLLIB is not set
+# CONFIG_R8712U is not set
+# CONFIG_R8188EU is not set
+# CONFIG_RTS5139 is not set
+# CONFIG_TRANZPORT is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_DX_SEP is not set
+# CONFIG_ZSMALLOC is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_CRYSTALHD is not set
+# CONFIG_FB_XGI is not set
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_BCM_WIMAX is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
+# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_USB_WPAN_HCD is not set
+# CONFIG_WIMAX_GDM72XX is not set
+# CONFIG_LTE_GDM724X is not set
+CONFIG_NET_VENDOR_SILICOM=y
+# CONFIG_SBYPASS is not set
+# CONFIG_BPCTL is not set
+# CONFIG_CED1401 is not set
+# CONFIG_DGRP is not set
+# CONFIG_USB_DWC2 is not set
+# CONFIG_LUSTRE_FS is not set
+# CONFIG_XILLYBUS is not set
+# CONFIG_DGNC is not set
+# CONFIG_DGAP is not set
+CONFIG_XILINX_VIDEO_IP=y
+CONFIG_XILINX_VDMA_WRAPPER=y
+# CONFIG_XILINX_APF is not set
+# CONFIG_PMODS is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_COMMON_CLK_VERSATILE=y
+# CONFIG_COMMON_CLK_SI5351 is not set
+# CONFIG_COMMON_CLK_SI570 is not set
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CADENCE_TTC_TIMER=y
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_OF_IOMMU=y
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=m
+# CONFIG_STE_MODEM_RPROC is not set
+CONFIG_ZYNQ_REMOTEPROC=m
+CONFIG_MB_REMOTEPROC=m
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=m
+# CONFIG_RPMSG_SERVER_SAMPLE is not set
+# CONFIG_RPMSG_OMX is not set
+# CONFIG_RPMSG_FREERTOS_STAT is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+CONFIG_MEMORY=y
+CONFIG_ZYNQ_SMC=y
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ZYNQ_UART0 is not set
+CONFIG_DEBUG_ZYNQ_UART1=y
+# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
+# CONFIG_DEBUG_LL_UART_8250 is not set
+# CONFIG_DEBUG_LL_UART_PL01X is not set
+CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_UART_8250 is not set
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_EARLY_PRINTK=y
+# CONFIG_OC_ETM is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_VIRTUALIZATION=y
Index: linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_defconfig	2014-07-20 22:06:34.086343161 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.12.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION="-xilinx"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GENERIC_SCHED_CLOCK=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+
+#
+# Multiple platform selection
+#
+
+#
+# CPU Core family selection
+#
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MULTI_V6_V7=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_BCM is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_KEYSTONE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_SOC_OMAP5 is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_SOC_AM43XX is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_STI is not set
+# CONFIG_ARCH_SHMOBILE_MULTI is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_SIRF is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_ARCH_VEXPRESS=y
+
+#
+# Versatile Express platform type
+#
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
+CONFIG_PLAT_VERSATILE_CLCD=y
+CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
+# CONFIG_ARCH_VIRT is not set
+# CONFIG_ARCH_WM8850 is not set
+CONFIG_ARCH_ZYNQ=y
+
+#
+# Xilinx Specific Options
+#
+CONFIG_XILINX_L1_PREFETCH=y
+CONFIG_XILINX_L2_PREFETCH=y
+CONFIG_XILINX_AXIPCIE=y
+CONFIG_PLAT_VERSATILE=y
+CONFIG_ARM_TIMER_SP804=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_ARM_ERRATA_773022 is not set
+CONFIG_ICST=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+
+#
+# PCI host controller drivers
+#
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=1024
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_100=y
+# CONFIG_HZ_200 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_500 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_ZBUD is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_AUTO_ZRELADDR=y
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_ZYNQ_CPUFREQ=y
+
+#
+# CPU Idle
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_KERNEL_MODE_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_CLK=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=m
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_DMA_CMA is not set
+
+#
+# Bus devices
+#
+# CONFIG_ARM_CCI is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_ZYNQ=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_ARM_CHARLCD is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_SI570 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+CONFIG_SRAM=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_MPT3SAS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_VIRTIO is not set
+# CONFIG_SCSI_CHELSIO_FCOE is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+CONFIG_NET_VENDOR_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_NET_CADENCE=y
+# CONFIG_ARM_AT91_ETHER is not set
+CONFIG_MACB=y
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R8169=y
+# CONFIG_SH_ETH is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NET_VENDOR_XILINX=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_XILINX_AXI_EMAC=y
+CONFIG_XILINX_PS_EMAC=y
+# CONFIG_XILINX_PS_EMAC_HWTSTAMP is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_ST_ASC is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_XILINX_DEVCFG=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_VERSATILE is not set
+CONFIG_I2C_ZYNQ=y
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_FSL_DSPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XCOMM is not set
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_ZYNQ_QSPI=y
+# CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED is not set
+CONFIG_SPI_ZYNQ=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# LPC GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_SMB347 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_HTU21 is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_XADCPS=y
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+CONFIG_ZYNQ_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+CONFIG_XILINX_WATCHDOG=y
+# CONFIG_MEN_A21_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CAMERA_SUPPORT is not set
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+# CONFIG_MEDIA_USB_SUPPORT is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_TEGRA_HOST1X is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_XILINX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+CONFIG_FB_XYLON=y
+# CONFIG_FB_XYLON_PLATFORM is not set
+CONFIG_FB_XYLON_OF=y
+# CONFIG_FB_XYLON_PIXCLK is not set
+# CONFIG_FB_XYLON_MISC is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+# CONFIG_SOUND is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_XUSBPS_DR_OF=y
+CONFIG_USB_EHCI_XUSBPS=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_AM335X_PHY_USB is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+# CONFIG_USB_ZYNQ_PHY is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+CONFIG_USB_GADGET_XUSBPS=y
+CONFIG_XUSBPS_ERRATA_DT654401=y
+CONFIG_USB_XUSBPS=y
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+CONFIG_USB_GADGET_XILINX=y
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_SS_LB=m
+# CONFIG_USB_CONFIGFS is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_ZYNQ=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_RTC_DRV_MOXART is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_XILINX_DMA_ENGINES=y
+CONFIG_XILINX_AXIDMA=y
+# CONFIG_XILINX_DMATEST is not set
+CONFIG_XILINX_AXIVDMA=y
+# CONFIG_XILINX_VDMATEST is not set
+CONFIG_XILINX_AXICDMA=y
+# CONFIG_XILINX_CDMATEST is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_PL330_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_CIF is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_MF624 is not set
+CONFIG_UIO_XILINX_APM=y
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=m
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_COMMON_CLK_VERSATILE=y
+# CONFIG_COMMON_CLK_SI5351 is not set
+CONFIG_COMMON_CLK_SI570=y
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CADENCE_TTC_TIMER=y
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_OF_IOMMU=y
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=m
+# CONFIG_STE_MODEM_RPROC is not set
+CONFIG_ZYNQ_REMOTEPROC=m
+CONFIG_MB_REMOTEPROC=m
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=m
+# CONFIG_RPMSG_SERVER_SAMPLE is not set
+# CONFIG_RPMSG_OMX is not set
+# CONFIG_RPMSG_FREERTOS_STAT is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+CONFIG_MEMORY=y
+CONFIG_ZYNQ_SMC=y
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ZYNQ_UART0 is not set
+CONFIG_DEBUG_ZYNQ_UART1=y
+# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
+# CONFIG_DEBUG_LL_UART_8250 is not set
+# CONFIG_DEBUG_LL_UART_PL01X is not set
+CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_UART_8250 is not set
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_EARLY_PRINTK=y
+# CONFIG_OC_ETM is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_VIRTUALIZATION=y
Index: linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_drm_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/configs/xilinx_zynq_drm_defconfig	2014-07-20 22:06:34.116342666 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.12.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION="-xilinx-drm"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GENERIC_SCHED_CLOCK=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+
+#
+# Multiple platform selection
+#
+
+#
+# CPU Core family selection
+#
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MULTI_V6_V7=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_BCM is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_KEYSTONE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_SOC_OMAP5 is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_SOC_AM43XX is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_STI is not set
+# CONFIG_ARCH_SHMOBILE_MULTI is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_SIRF is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_ARCH_VEXPRESS=y
+
+#
+# Versatile Express platform type
+#
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
+CONFIG_PLAT_VERSATILE_CLCD=y
+CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
+# CONFIG_ARCH_VIRT is not set
+# CONFIG_ARCH_WM8850 is not set
+CONFIG_ARCH_ZYNQ=y
+
+#
+# Xilinx Specific Options
+#
+CONFIG_XILINX_L1_PREFETCH=y
+CONFIG_XILINX_L2_PREFETCH=y
+CONFIG_XILINX_AXIPCIE=y
+CONFIG_PLAT_VERSATILE=y
+CONFIG_ARM_TIMER_SP804=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_ARM_ERRATA_773022 is not set
+CONFIG_ICST=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+
+#
+# PCI host controller drivers
+#
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=1024
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_100=y
+# CONFIG_HZ_200 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_500 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_ZBUD is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw initrd=0x00800000,16M earlyprintk mtdparts=physmap-flash.0:512K(nor-fsbl),512K(nor-u-boot),5M(nor-linux),9M(nor-user),1M(nor-scratch),-(nor-rootfs)"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_AUTO_ZRELADDR=y
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_ZYNQ_CPUFREQ=y
+
+#
+# CPU Idle
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_KERNEL_MODE_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_CLK=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=m
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_CMA=y
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=128
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+
+#
+# Bus devices
+#
+# CONFIG_ARM_CCI is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_ZYNQ=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_ARM_CHARLCD is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_SI570 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+CONFIG_SRAM=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_MPT3SAS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_VIRTIO is not set
+# CONFIG_SCSI_CHELSIO_FCOE is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+CONFIG_NET_VENDOR_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_NET_CADENCE=y
+# CONFIG_ARM_AT91_ETHER is not set
+CONFIG_MACB=y
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R8169=y
+# CONFIG_SH_ETH is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NET_VENDOR_XILINX=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_XILINX_AXI_EMAC=y
+CONFIG_XILINX_PS_EMAC=y
+# CONFIG_XILINX_PS_EMAC_HWTSTAMP is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_ST_ASC is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_XILINX_DEVCFG=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_VERSATILE is not set
+CONFIG_I2C_ZYNQ=y
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_FSL_DSPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XCOMM is not set
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_ZYNQ_QSPI=y
+# CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED is not set
+CONFIG_SPI_ZYNQ=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# LPC GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_SMB347 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_HTU21 is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_XADCPS=y
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+CONFIG_ZYNQ_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+CONFIG_XILINX_WATCHDOG=y
+# CONFIG_MEN_A21_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_V4L2=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_DMA_CONTIG=y
+# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+# CONFIG_MEDIA_USB_SUPPORT is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+# CONFIG_VIDEO_CAFE_CCIC is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_VIDEO_XILINX=y
+CONFIG_VIDEO_XILINX_REMAPPER=y
+CONFIG_VIDEO_XILINX_TPG=y
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+
+#
+# Audio decoders, processors and mixers
+#
+
+#
+# RDS decoders
+#
+
+#
+# Video decoders
+#
+
+#
+# Video and audio decoders
+#
+
+#
+# Video encoders
+#
+
+#
+# Camera sensor devices
+#
+
+#
+# Flash devices
+#
+
+#
+# Video improvement chips
+#
+
+#
+# Miscelaneous helper chips
+#
+
+#
+# Sensors used on soc_camera driver
+#
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_DRM=y
+CONFIG_DRM_KMS_HELPER=y
+# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
+CONFIG_DRM_GEM_CMA_HELPER=y
+CONFIG_DRM_KMS_CMA_HELPER=y
+
+#
+# I2C encoder or helper chips
+#
+# CONFIG_DRM_I2C_CH7006 is not set
+# CONFIG_DRM_I2C_SIL164 is not set
+# CONFIG_DRM_I2C_NXP_TDA998X is not set
+CONFIG_DRM_ENCODER_ADV7511=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_NOUVEAU is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
+# CONFIG_DRM_EXYNOS is not set
+# CONFIG_DRM_VMWGFX is not set
+# CONFIG_DRM_UDL is not set
+# CONFIG_DRM_AST is not set
+# CONFIG_DRM_MGAG200 is not set
+# CONFIG_DRM_CIRRUS_QEMU is not set
+# CONFIG_DRM_RCAR_DU is not set
+# CONFIG_DRM_SHMOBILE is not set
+# CONFIG_DRM_TILCDC is not set
+# CONFIG_DRM_QXL is not set
+CONFIG_DRM_XILINX=y
+# CONFIG_TEGRA_HOST1X is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_HDMI=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_XILINX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+CONFIG_FB_XYLON=y
+# CONFIG_FB_XYLON_PLATFORM is not set
+CONFIG_FB_XYLON_OF=y
+# CONFIG_FB_XYLON_PIXCLK is not set
+# CONFIG_FB_XYLON_MISC is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_COMPRESS_OFFLOAD=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
+# CONFIG_SND_CTXFI is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LOLA is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+# CONFIG_SND_USB_HIFACE is not set
+CONFIG_SND_SOC=y
+# CONFIG_SND_ATMEL_SOC is not set
+# CONFIG_SND_DESIGNWARE_I2S is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_XUSBPS_DR_OF=y
+CONFIG_USB_EHCI_XUSBPS=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_AM335X_PHY_USB is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+# CONFIG_USB_ZYNQ_PHY is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+CONFIG_USB_GADGET_XUSBPS=y
+CONFIG_XUSBPS_ERRATA_DT654401=y
+CONFIG_USB_XUSBPS=y
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+CONFIG_USB_GADGET_XILINX=y
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_SS_LB=m
+# CONFIG_USB_CONFIGFS is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_ZYNQ=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_RTC_DRV_MOXART is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_XILINX_DMA_ENGINES=y
+CONFIG_XILINX_AXIDMA=y
+# CONFIG_XILINX_DMATEST is not set
+CONFIG_XILINX_AXIVDMA=y
+# CONFIG_XILINX_VDMATEST is not set
+CONFIG_XILINX_AXICDMA=y
+# CONFIG_XILINX_CDMATEST is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_PL330_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_CIF is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_MF624 is not set
+CONFIG_UIO_XILINX_APM=y
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=m
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_COMMON_CLK_VERSATILE=y
+# CONFIG_COMMON_CLK_SI5351 is not set
+CONFIG_COMMON_CLK_SI570=y
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CADENCE_TTC_TIMER=y
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_OF_IOMMU=y
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=m
+# CONFIG_STE_MODEM_RPROC is not set
+CONFIG_ZYNQ_REMOTEPROC=m
+CONFIG_MB_REMOTEPROC=m
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=m
+# CONFIG_RPMSG_SERVER_SAMPLE is not set
+# CONFIG_RPMSG_OMX is not set
+# CONFIG_RPMSG_FREERTOS_STAT is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+CONFIG_MEMORY=y
+CONFIG_ZYNQ_SMC=y
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ZYNQ_UART0 is not set
+CONFIG_DEBUG_ZYNQ_UART1=y
+# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
+# CONFIG_DEBUG_LL_UART_8250 is not set
+# CONFIG_DEBUG_LL_UART_PL01X is not set
+CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_UART_8250 is not set
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_EARLY_PRINTK=y
+# CONFIG_OC_ETM is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_VIRTUALIZATION=y
Index: linux-3.12.24-rt38-xilinx/arch/arm/include/asm/elf.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/include/asm/elf.h	2014-07-20 22:05:50.291065713 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/include/asm/elf.h	2014-07-20 22:06:34.131342419 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:53 @
 #define R_ARM_ABS32		2
 #define R_ARM_CALL		28
 #define R_ARM_JUMP24		29
+#define R_ARM_TARGET1		38
 #define R_ARM_V4BX		40
 #define R_ARM_PREL31		42
 #define R_ARM_MOVW_ABS_NC	43
Index: linux-3.12.24-rt38-xilinx/arch/arm/include/asm/hardirq.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/include/asm/hardirq.h	2014-07-20 22:05:50.292065697 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/include/asm/hardirq.h	2014-07-20 22:06:34.141342254 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:8 @
 #include <linux/threads.h>
 #include <asm/irq.h>
 
-#define NR_IPI	6
+#define NR_IPI	16
 
 typedef struct {
 	unsigned int __softirq_pending;
Index: linux-3.12.24-rt38-xilinx/arch/arm/include/asm/setup.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/include/asm/setup.h	2014-07-20 22:05:50.290065730 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/include/asm/setup.h	2014-07-20 22:06:34.155342023 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:52 @
 #define bank_phys_end(bank)	((bank)->start + (bank)->size)
 #define bank_phys_size(bank)	(bank)->size
 
-extern int arm_add_memory(phys_addr_t start, phys_addr_t size);
+extern int arm_add_memory(u64 start, u64 size);
 extern void early_print(const char *str, ...);
 extern void dump_machine_table(void);
 
Index: linux-3.12.24-rt38-xilinx/arch/arm/include/asm/smp.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/include/asm/smp.h	2014-07-20 22:05:50.293065680 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/include/asm/smp.h	2014-07-20 22:06:34.167341825 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:120 @
  */
 extern void smp_set_ops(struct smp_operations *);
 
+extern int set_ipi_handler(int ipinr, void *handler, char *desc);
+extern void clear_ipi_handler(int ipinr);
+
 #endif /* ifndef __ASM_ARM_SMP_H */
Index: linux-3.12.24-rt38-xilinx/arch/arm/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/Kconfig	2014-07-20 22:05:50.276065961 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/Kconfig	2014-07-20 22:06:34.186341512 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:7 @
 	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-	select ARCH_HAVE_CUSTOM_GPIO_H
+	select ARCH_HAVE_CUSTOM_GPIO_H if (!ARCH_ZYNQ)
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select BUILDTIME_EXTABLE_SORT if MMU
 	select CLONE_BACKWARDS
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1604 @
 # selected platforms.
 config ARCH_NR_GPIO
 	int
-	default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
+	default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
 	default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || SOC_DRA7XX
 	default 392 if ARCH_U8500
 	default 352 if ARCH_VT8500
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2100 @
 
 config KEXEC
 	bool "Kexec system call (EXPERIMENTAL)"
-	depends on (!SMP || PM_SLEEP_SMP)
+	depends on PM_SLEEP_SMP
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
Index: linux-3.12.24-rt38-xilinx/arch/arm/kernel/machine_kexec.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/kernel/machine_kexec.c	2014-07-20 22:05:50.281065878 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/kernel/machine_kexec.c	2014-07-20 22:06:34.201341264 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:5 @
  * machine_kexec.c - handle transition of Linux booting another kernel
  */
 
+#include <linux/cpu.h>
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/delay.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:120 @
 	unsigned long msecs;
 
 	local_irq_disable();
+	disable_nonboot_cpus();
 
 	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
 	smp_call_function(machine_crash_nonpanic_core, NULL, false);
Index: linux-3.12.24-rt38-xilinx/arch/arm/kernel/module.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/kernel/module.c	2014-07-20 22:05:50.280065895 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/kernel/module.c	2014-07-20 22:06:34.212341083 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:92 @
 			break;
 
 		case R_ARM_ABS32:
+		case R_ARM_TARGET1:
 			*(u32 *)loc += sym->st_value;
 			break;
 
Index: linux-3.12.24-rt38-xilinx/arch/arm/kernel/process.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/kernel/process.c	2014-07-20 22:05:50.278065928 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/kernel/process.c	2014-07-20 22:06:34.223340901 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:191 @
 void machine_shutdown(void)
 {
 	disable_nonboot_cpus();
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
 }
 
 /*
Index: linux-3.12.24-rt38-xilinx/arch/arm/kernel/setup.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/kernel/setup.c	2014-07-20 22:05:50.279065912 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/kernel/setup.c	2014-07-20 22:06:34.237340670 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:622 @
 		/* can't use cpu_relax() here as it may require MMU setup */;
 }
 
-int __init arm_add_memory(phys_addr_t start, phys_addr_t size)
+int __init arm_add_memory(u64 start, u64 size)
 {
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 	u64 aligned_start;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:694 @
 static int __init early_mem(char *p)
 {
 	static int usermem __initdata = 0;
-	phys_addr_t size;
-	phys_addr_t start;
+	u64 size;
+	u64 start;
 	char *endp;
 
 	/*
Index: linux-3.12.24-rt38-xilinx/arch/arm/kernel/smp.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/kernel/smp.c	2014-07-20 22:05:50.282065862 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/kernel/smp.c	2014-07-20 22:06:34.250340456 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:451 @
 	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
 }
 
-static const char *ipi_types[NR_IPI] = {
-#define S(x,s)	[x] = s
-	S(IPI_WAKEUP, "CPU wakeup interrupts"),
-	S(IPI_TIMER, "Timer broadcast interrupts"),
-	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
-	S(IPI_CALL_FUNC, "Function call interrupts"),
-	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
-	S(IPI_CPU_STOP, "CPU stop interrupts"),
+struct ipi {
+	const char *desc;
+	void (*handler)(void);
+};
+
+static void ipi_cpu_stop(void);
+
+static struct ipi ipi_types[NR_IPI] = {
+#define S(x, s, f)	[x].desc = s, [x].handler = f
+	S(IPI_WAKEUP, "CPU wakeup interrupts", NULL),
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+	S(IPI_TIMER, "Timer broadcast interrupts", tick_receive_broadcast),
+#endif
+	S(IPI_RESCHEDULE, "Rescheduling interrupts", scheduler_ipi),
+	S(IPI_CALL_FUNC, "Function call interrupts",
+					generic_smp_call_function_interrupt),
+	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts",
+				generic_smp_call_function_single_interrupt),
+	S(IPI_CPU_STOP, "CPU stop interrupts", ipi_cpu_stop),
 };
 
 void show_ipi_list(struct seq_file *p, int prec)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:477 @
 	unsigned int cpu, i;
 
 	for (i = 0; i < NR_IPI; i++) {
-		seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
-
-		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ",
-				   __get_irq_stat(cpu, ipi_irqs[i]));
-
-		seq_printf(p, " %s\n", ipi_types[i]);
+		if (ipi_types[i].handler) {
+			seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
+			for_each_present_cpu(cpu)
+				seq_printf(p, "%10u ",
+					__get_irq_stat(cpu, ipi_irqs[i]));
+			seq_printf(p, " %s\n", ipi_types[i].desc);
+		}
 	}
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:510 @
 /*
  * ipi_cpu_stop - handle IPI from smp_send_stop()
  */
-static void ipi_cpu_stop(unsigned int cpu)
+static void ipi_cpu_stop(void)
 {
+	unsigned int cpu = smp_processor_id();
+
 	if (system_state == SYSTEM_BOOTING ||
 	    system_state == SYSTEM_RUNNING) {
 		raw_spin_lock(&stop_lock);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:544 @
 	unsigned int cpu = smp_processor_id();
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
-	if (ipinr < NR_IPI)
+	if (ipi_types[ipinr].handler) {
 		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
-
-	switch (ipinr) {
-	case IPI_WAKEUP:
-		break;
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-	case IPI_TIMER:
 		irq_enter();
-		tick_receive_broadcast();
+		(*ipi_types[ipinr].handler)();
 		irq_exit();
-		break;
-#endif
+	} else
+		pr_debug("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 
-	case IPI_RESCHEDULE:
-		scheduler_ipi();
-		break;
+	set_irq_regs(old_regs);
+}
 
-	case IPI_CALL_FUNC:
-		irq_enter();
-		generic_smp_call_function_interrupt();
-		irq_exit();
-		break;
+/*
+ * set_ipi_handler:
+ * Interface provided for a kernel module to specify an IPI handler function.
+ */
+int set_ipi_handler(int ipinr, void *handler, char *desc)
+{
+	unsigned int cpu = smp_processor_id();
 
-	case IPI_CALL_FUNC_SINGLE:
-		irq_enter();
-		generic_smp_call_function_single_interrupt();
-		irq_exit();
-		break;
+	if (ipi_types[ipinr].handler) {
+		pr_crit("CPU%u: IPI handler 0x%x already registered to %pf\n",
+					cpu, ipinr, ipi_types[ipinr].handler);
+		return -1;
+	}
 
-	case IPI_CPU_STOP:
-		irq_enter();
-		ipi_cpu_stop(cpu);
-		irq_exit();
-		break;
+	ipi_types[ipinr].handler = handler;
+	ipi_types[ipinr].desc = desc;
 
-	default:
-		printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
-		       cpu, ipinr);
-		break;
-	}
-	set_irq_regs(old_regs);
+	return 0;
+}
+EXPORT_SYMBOL(set_ipi_handler);
+
+/*
+ * clear_ipi_handler:
+ * Interface provided for a kernel module to clear an IPI handler function.
+ */
+void clear_ipi_handler(int ipinr)
+{
+	ipi_types[ipinr].handler = NULL;
+	ipi_types[ipinr].desc = NULL;
 }
+EXPORT_SYMBOL(clear_ipi_handler);
 
 void smp_send_reschedule(int cpu)
 {
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/common.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/common.c	2014-07-20 22:05:50.272066027 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/common.c	2014-07-20 22:06:34.265340209 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:19 @
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/cpu.h>
 #include <linux/cpumask.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/clk/zynq.h>
+#include <linux/opp.h>
 #include <linux/clocksource.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
+#include <linux/memblock.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:47 @
 
 void __iomem *zynq_scu_base;
 
-static struct of_device_id zynq_of_bus_ids[] __initdata = {
-	{ .compatible = "simple-bus", },
-	{}
+/**
+ * zynq_memory_init() - Initialize special memory
+ *
+ * We need to stop things allocating the low memory as DMA can't work in
+ * the 1st 512K of memory.  Using reserve vs remove is not totally clear yet.
+ */
+static void __init zynq_memory_init(void)
+{
+	/*
+	 * Reserve the 0-0x4000 addresses (before page tables and kernel)
+	 * which can't be used for DMA
+	 */
+	if (!__pa(PAGE_OFFSET))
+		memblock_reserve(0, 0x4000);
+}
+
+#ifdef CONFIG_CPU_FREQ
+#define CPUFREQ_MIN_FREQ_HZ	200000000
+static unsigned int freq_divs[] __initdata = {
+	2, 3
 };
 
+static long __init xilinx_calc_opp_freq(struct clk *clk, long rate)
+{
+	long rate_nearest = clk_round_rate_nearest(clk, rate);
+	long rate_round = clk_round_rate(clk, rate_nearest / 1000 * 1000);
+
+	if (rate_round != rate_nearest)
+		rate_nearest += 1000;
+
+	return rate_nearest;
+}
+
 /**
- * zynq_init_machine - System specific initialization, intended to be
- *		       called from board specific initialization.
+ * zynq_opp_init() - Register OPPs
+ *
+ * Registering frequency/voltage operating points for voltage and frequency
+ * scaling. Currently we only support frequency scaling.
  */
-static void __init zynq_init_machine(void)
+static int __init zynq_opp_init(void)
+{
+	long freq;
+	unsigned int i;
+	struct device *dev = get_cpu_device(0);
+	int ret = 0;
+	struct clk *cpuclk = clk_get(NULL, "cpufreq_clk");
+
+	if (!dev) {
+		pr_warn("%s: no cpu device. DVFS not available.", __func__);
+		return -ENODEV;
+	}
+
+	if (IS_ERR(cpuclk)) {
+		pr_warn("%s: CPU clock not found. DVFS not available.",
+				__func__);
+		return PTR_ERR(cpuclk);
+	}
+
+	/* frequency/voltage operating points. For now use f only */
+	freq = clk_get_rate(cpuclk);
+	ret |= opp_add(dev, xilinx_calc_opp_freq(cpuclk, freq), 0);
+	for (i = 0; i < ARRAY_SIZE(freq_divs); i++) {
+		long tmp = xilinx_calc_opp_freq(cpuclk, freq / freq_divs[i]);
+		if (tmp >= CPUFREQ_MIN_FREQ_HZ)
+			ret |= opp_add(dev, tmp, 0);
+	}
+	freq = xilinx_calc_opp_freq(cpuclk, CPUFREQ_MIN_FREQ_HZ);
+	if (freq >= CPUFREQ_MIN_FREQ_HZ && IS_ERR(opp_find_freq_exact(dev, freq,
+				1)))
+		ret |= opp_add(dev, freq, 0);
+
+	if (ret)
+		pr_warn("%s: Error adding OPPs.", __func__);
+
+	return ret;
+}
+device_initcall(zynq_opp_init);
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+static int __init zynq_l2c_init(void)
+{
+	/* 64KB way size, 8-way associativity, parity disabled,
+	 * prefetching option */
+#ifndef	CONFIG_XILINX_L2_PREFETCH
+	return l2x0_of_init(0x02060000, 0xF0F0FFFF);
+#else
+	return l2x0_of_init(0x72060000, 0xF0F0FFFF);
+#endif
+}
+early_initcall(zynq_l2c_init);
+#endif
+
+
+#ifdef CONFIG_XILINX_L1_PREFETCH
+static void __init zynq_data_prefetch_enable(void *info)
 {
 	/*
-	 * 64KB way size, 8-way associativity, parity disabled
+	 * Enable prefetching in aux control register. L2 prefetch must
+	 * only be enabled if the slave supports it (PL310 does)
 	 */
-	l2x0_of_init(0x02060000, 0xF0F0FFFF);
+	asm volatile ("mrc   p15, 0, r1, c1, c0, 1\n"
+		      "orr   r1, r1, #6\n"
+		      "mcr   p15, 0, r1, c1, c0, 1\n"
+		      : : : "r1");
+}
+#endif
+
+static void __init zynq_init_late(void)
+{
+	zynq_pm_late_init();
 
-	of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL);
+#ifdef CONFIG_XILINX_L1_PREFETCH
+	on_each_cpu(zynq_data_prefetch_enable, NULL, 0);
+#endif
+}
+
+/**
+ * zynq_init_machine - System specific initialization, intended to be
+ *		       called from board specific initialization.
+ */
+static void __init zynq_init_machine(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static void __init zynq_timer_init(void)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:206 @
 	zynq_scu_map_io();
 }
 
+static void __init zynq_irq_init(void)
+{
+	gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;
+	irqchip_init();
+}
+
 static void zynq_system_reset(enum reboot_mode mode, const char *cmd)
 {
 	zynq_slcr_system_reset();
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:225 @
 DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
 	.smp		= smp_ops(zynq_smp_ops),
 	.map_io		= zynq_map_io,
+	.init_irq	= zynq_irq_init,
 	.init_machine	= zynq_init_machine,
+	.init_late	= zynq_init_late,
 	.init_time	= zynq_timer_init,
 	.dt_compat	= zynq_dt_match,
+	.reserve	= zynq_memory_init,
 	.restart	= zynq_system_reset,
 MACHINE_END
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/common.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/common.h	2014-07-20 22:05:50.267066110 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/common.h	2014-07-20 22:06:34.274340060 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:24 @
 extern void zynq_slcr_system_reset(void);
 extern void zynq_slcr_cpu_stop(int cpu);
 extern void zynq_slcr_cpu_start(int cpu);
+extern u32 zynq_slcr_get_ocm_config(void);
 
 #ifdef CONFIG_SMP
+extern void zynq_secondary_startup(void);
 extern void secondary_startup(void);
 extern char zynq_secondary_trampoline;
 extern char zynq_secondary_trampoline_jump;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:36 @
 extern struct smp_operations zynq_smp_ops __initdata;
 #endif
 
+extern void zynq_slcr_write(u32 val, u32 offset);
+extern u32 zynq_slcr_read(u32 offset);
+
+extern void zynq_slcr_init_preload_fpga(void);
+extern void zynq_slcr_init_postload_fpga(void);
+
 extern void __iomem *zynq_slcr_base;
 extern void __iomem *zynq_scu_base;
 
 /* Hotplug */
 extern void zynq_platform_cpu_die(unsigned int cpu);
 
+#ifdef CONFIG_SUSPEND
+int zynq_pm_late_init(void);
+#else
+static inline int zynq_pm_late_init(void)
+{
+	return 0;
+}
+#endif
+
+extern unsigned int zynq_sys_suspend_sz;
+int zynq_sys_suspend(void __iomem *ddrc_base, void __iomem *slcr_base);
+
 #endif
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/headsmp.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/headsmp.S	2014-07-20 22:05:50.275065977 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/headsmp.S	2014-07-20 22:06:34.284339895 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:21 @
 	.word	/* cpu 1 */
 .globl zynq_secondary_trampoline_end
 zynq_secondary_trampoline_end:
-
 ENDPROC(zynq_secondary_trampoline)
+
+ENTRY(zynq_secondary_startup)
+	bl	v7_invalidate_l1
+	b	secondary_startup
+ENDPROC(zynq_secondary_startup)
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/Kconfig	2014-07-20 22:05:50.273066011 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/Kconfig	2014-07-20 22:06:34.295339714 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:5 @
 	bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
 	select ARM_AMBA
 	select ARM_GIC
-	select COMMON_CLK
-	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
 	select ICST
 	select MIGHT_HAVE_CACHE_L2X0
-	select USE_OF
 	select HAVE_SMP
-	select SPARSE_IRQ
+	select CACHE_L2X0
+	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
+	select MIGHT_HAVE_PCI
 	select CADENCE_TTC_TIMER
+	select GENERIC_ALLOCATOR
 	help
 	  Support for Xilinx Zynq ARM Cortex A9 Platform
+
+if ARCH_ZYNQ
+
+menu "Xilinx Specific Options"
+
+config XILINX_L1_PREFETCH
+	bool "L1 Cache Prefetch"
+	default y
+	help
+	  This option turns on L1 cache prefetching to get the best performance
+	  in many cases. This may not always be the best performance depending on
+	  the usage. There are some cases where this may cause issues when booting.
+
+config XILINX_L2_PREFETCH
+	bool "L2 Cache Prefetch"
+	default y
+	help
+	  This option turns on L2 cache prefetching to get the best performance
+	  in many cases. This may not always be the best performance depending on
+	  the usage.
+
+config XILINX_AXIPCIE
+	bool "Xilinx AXI PCIe host bridge support"
+	select PCI
+	select ARCH_SUPPORTS_MSI
+	help
+	  Say 'Y' here if you want kernel to support the Xilinx AXI PCIe
+	  Host Bridge. This supports Message Signal Interrupts (MSI), if you
+	  want to use this feature select CONFIG_PCI_MSI from 'Bus Support ->'.
+
+endmenu
+
+endif
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/Makefile	2014-07-20 22:05:50.270066060 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/Makefile	2014-07-20 22:06:34.304339565 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:6 @
 #
 
 # Common support
-obj-y				:= common.o slcr.o
+obj-y				:= common.o slcr.o zynq_ocm.o
+
+obj-$(CONFIG_PCI_MSI)           += xaxipcie-msi.o
 CFLAGS_REMOVE_hotplug.o		=-march=armv6k
 CFLAGS_hotplug.o 		=-Wa,-march=armv7-a -mcpu=cortex-a9
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 obj-$(CONFIG_SMP)		+= headsmp.o platsmp.o
+obj-$(CONFIG_SUSPEND)		+= pm.o suspend.o
+obj-$(CONFIG_XILINX_AXIPCIE)    += xaxipcie.o
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/Makefile.boot
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/Makefile.boot	2014-07-20 22:05:50.269066076 +0200
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
-   zreladdr-y	+= 0x00008000
-params_phys-y	:= 0x00000100
-initrd_phys-y	:= 0x00800000
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/platsmp.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/platsmp.c	2014-07-20 22:05:50.268066093 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/platsmp.c	2014-07-20 22:06:34.333339087 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:42 @
 	u32 trampoline_code_size = &zynq_secondary_trampoline_end -
 						&zynq_secondary_trampoline;
 
-	if (cpu > ncores) {
+	if (cpu >= ncores) {
 		pr_warn("CPU No. is not available in the system\n");
 		return -1;
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:98 @
 static int zynq_boot_secondary(unsigned int cpu,
 						struct task_struct *idle)
 {
-	return zynq_cpun_start(virt_to_phys(secondary_startup), cpu);
+	return zynq_cpun_start(virt_to_phys(zynq_secondary_startup), cpu);
 }
 
 /*
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:117 @
 
 static void __init zynq_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
 	scu_enable(zynq_scu_base);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int zynq_cpu_kill(unsigned cpu)
+{
+	zynq_slcr_cpu_stop(cpu);
+	return 1;
+}
+#endif
+
 struct smp_operations zynq_smp_ops __initdata = {
 	.smp_init_cpus		= zynq_smp_init_cpus,
 	.smp_prepare_cpus	= zynq_smp_prepare_cpus,
 	.smp_boot_secondary	= zynq_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_die		= zynq_platform_cpu_die,
+	.cpu_kill		= zynq_cpu_kill,
 #endif
 };
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/pm.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/pm.c	2014-07-20 22:06:34.343338922 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Suspend support for Zynq
+ *
+ *  Copyright (C) 2012 Xilinx
+ *
+ *  Soren Brinkmann <soren.brinkmann@xilinx.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk/zynq.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
+#include <asm/suspend.h>
+#include "common.h"
+
+#define DDRC_CTRL_REG1_OFFS		0x60
+#define DDRC_DRAM_PARAM_REG3_OFFS	0x20
+#define SCU_CTRL			0
+
+#define DDRC_CLOCKSTOP_MASK	BIT(23)
+#define DDRC_SELFREFRESH_MASK	BIT(12)
+#define SCU_STBY_EN_MASK	BIT(5)
+
+static void __iomem *ddrc_base;
+static void __iomem *ocm_base;
+
+static int zynq_pm_prepare_late(void)
+{
+	return zynq_clk_suspend_early();
+}
+
+static void zynq_pm_wake(void)
+{
+	zynq_clk_resume_late();
+}
+
+static int zynq_pm_suspend(unsigned long arg)
+{
+	u32 reg;
+	int (*zynq_suspend_ptr)(void __iomem *, void __iomem *);
+	int do_ddrpll_bypass = 1;
+
+	/* Enable DDR self-refresh and clock stop */
+	if (ddrc_base) {
+		reg = readl(ddrc_base + DDRC_CTRL_REG1_OFFS);
+		reg |= DDRC_SELFREFRESH_MASK;
+		writel(reg, ddrc_base + DDRC_CTRL_REG1_OFFS);
+
+		reg = readl(ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+		reg |= DDRC_CLOCKSTOP_MASK;
+		writel(reg, ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+	} else {
+		do_ddrpll_bypass = 0;
+	}
+
+	/* SCU standby mode */
+	if (zynq_scu_base) {
+		reg = readl(zynq_scu_base + SCU_CTRL);
+		reg |= SCU_STBY_EN_MASK;
+		writel(reg, zynq_scu_base + SCU_CTRL);
+	}
+
+	/* Topswitch clock stop disable */
+	zynq_clk_topswitch_disable();
+
+	/* A9 clock gating */
+	asm volatile ("mrc  p15, 0, r12, c15, c0, 0\n"
+		      "orr  r12, r12, #1\n"
+		      "mcr  p15, 0, r12, c15, c0, 0\n"
+		      : /* no outputs */
+		      : /* no inputs */
+		      : "r12");
+
+	if (ocm_base) {
+		/*
+		 * Copy code to suspend system into OCM. The suspend code
+		 * needs to run from OCM as DRAM may no longer be available
+		 * when the PLL is stopped.
+		 */
+		memcpy((__force void *)ocm_base, &zynq_sys_suspend,
+			zynq_sys_suspend_sz);
+		flush_icache_range((unsigned long)ocm_base,
+			(unsigned long)(ocm_base) + zynq_sys_suspend_sz);
+		zynq_suspend_ptr = (__force void *)ocm_base;
+	} else {
+		do_ddrpll_bypass = 0;
+	}
+
+	/* Transfer to suspend code in OCM */
+	if (do_ddrpll_bypass) {
+		/*
+		 * Going this way will turn off DDR related clocks and the DDR
+		 * PLL. I.e. We might brake sub systems relying on any of this
+		 * clocks. And even worse: If there are any other masters in the
+		 * system (e.g. in the PL) accessing DDR they are screwed.
+		 */
+		flush_cache_all();
+		if (zynq_suspend_ptr(ddrc_base, zynq_slcr_base))
+			pr_warn("DDR self refresh failed.\n");
+	} else {
+		WARN_ONCE(1, "DRAM self-refresh not available\n");
+		cpu_do_idle();
+	}
+
+	/* Topswitch clock stop enable */
+	zynq_clk_topswitch_enable();
+
+	/* SCU standby mode */
+	if (zynq_scu_base) {
+		reg = readl(zynq_scu_base + SCU_CTRL);
+		reg &= ~SCU_STBY_EN_MASK;
+		writel(reg, zynq_scu_base + SCU_CTRL);
+	}
+
+	/* A9 clock gating */
+	asm volatile ("mrc  p15, 0, r12, c15, c0, 0\n"
+		      "bic  r12, r12, #1\n"
+		      "mcr  p15, 0, r12, c15, c0, 0\n"
+		      : /* no outputs */
+		      : /* no inputs */
+		      : "r12");
+
+	/* Disable DDR self-refresh and clock stop */
+	if (ddrc_base) {
+		reg = readl(ddrc_base + DDRC_CTRL_REG1_OFFS);
+		reg &= ~DDRC_SELFREFRESH_MASK;
+		writel(reg, ddrc_base + DDRC_CTRL_REG1_OFFS);
+
+		reg = readl(ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+		reg &= ~DDRC_CLOCKSTOP_MASK;
+		writel(reg, ddrc_base + DDRC_DRAM_PARAM_REG3_OFFS);
+	}
+
+	return 0;
+}
+
+static int zynq_pm_enter(suspend_state_t suspend_state)
+{
+	switch (suspend_state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		outer_disable();
+		cpu_suspend(0, zynq_pm_suspend);
+		outer_resume();
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct platform_suspend_ops zynq_pm_ops = {
+	.prepare_late	= zynq_pm_prepare_late,
+	.enter		= zynq_pm_enter,
+	.wake		= zynq_pm_wake,
+	.valid		= suspend_valid_only_mem,
+};
+
+/**
+ * zynq_pm_ioremap() - Create IO mappings
+ * @comp	DT compatible string
+ * Returns a pointer to the mapped memory or NULL.
+ *
+ * Remap the memory region for a compatible DT node.
+ */
+static void __iomem *zynq_pm_ioremap(const char *comp)
+{
+	struct device_node *np;
+	void __iomem *base = NULL;
+
+	np = of_find_compatible_node(NULL, NULL, comp);
+	if (np) {
+		base = of_iomap(np, 0);
+		of_node_put(np);
+	} else {
+		pr_warn("%s: no compatible node found for '%s'\n", __func__,
+				comp);
+	}
+
+	return base;
+}
+
+/**
+ * zynq_pm_remap_ocm() - Remap OCM
+ * Returns a pointer to the mapped memory or NULL.
+ *
+ * Remap the OCM.
+ */
+static void __iomem *zynq_pm_remap_ocm(void)
+{
+	struct device_node *np;
+	const char *comp = "xlnx,zynq-ocm-1.0";
+	void __iomem *base = NULL;
+
+	np = of_find_compatible_node(NULL, NULL, comp);
+	if (np) {
+		struct device *dev;
+		unsigned long pool_addr;
+		unsigned long pool_addr_virt;
+		struct gen_pool *pool;
+
+		of_node_put(np);
+
+		dev = &(of_find_device_by_node(np)->dev);
+
+		/* Get OCM pool from device tree or platform data */
+		pool = dev_get_gen_pool(dev);
+		if (!pool) {
+			pr_warn("%s: OCM pool is not available\n", __func__);
+			return NULL;
+		}
+
+		pool_addr_virt = gen_pool_alloc(pool, zynq_sys_suspend_sz);
+		if (!pool_addr_virt) {
+			pr_warn("%s: Can't get OCM poll\n", __func__);
+			return NULL;
+		}
+		pool_addr = gen_pool_virt_to_phys(pool, pool_addr_virt);
+		if (!pool_addr) {
+			pr_warn("%s: Can't get physical address of OCM pool\n",
+				__func__);
+			return NULL;
+		}
+		base = __arm_ioremap(pool_addr, zynq_sys_suspend_sz, MT_MEMORY);
+		if (!base) {
+			pr_warn("%s: IOremap OCM pool failed\n", __func__);
+			return NULL;
+		}
+		pr_debug("%s: Remap OCM %s from %lx to %lx\n", __func__, comp,
+			 pool_addr_virt, (unsigned long)base);
+	} else {
+		pr_warn("%s: no compatible node found for '%s'\n", __func__,
+				comp);
+	}
+
+	return base;
+}
+
+int __init zynq_pm_late_init(void)
+{
+	ddrc_base = zynq_pm_ioremap("xlnx,ps7-ddrc");
+	if (!ddrc_base)
+		pr_warn("%s: Unable to map DDRC IO memory.\n", __func__);
+
+	/*
+	 * FIXME: should be done by an ocm driver which then provides allocators
+	 */
+	ocm_base = zynq_pm_remap_ocm();
+	if (!ocm_base)
+		pr_warn("%s: Unable to map OCM.\n", __func__);
+
+	suspend_set_ops(&zynq_pm_ops);
+
+	return 0;
+}
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/slcr.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mach-zynq/slcr.c	2014-07-20 22:05:50.274065994 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/slcr.c	2014-07-20 22:06:34.351338790 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:18 @
  */
 
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/clk/zynq.h>
 #include "common.h"
 
 /* register offsets */
 #define SLCR_UNLOCK_OFFSET		0x8   /* SCLR unlock register */
+
 #define SLCR_PS_RST_CTRL_OFFSET		0x200 /* PS Software Reset Control */
+#define SLCR_FPGA_RST_CTRL_OFFSET	0x240 /* FPGA Software Reset Control */
 #define SLCR_A9_CPU_RST_CTRL_OFFSET	0x244 /* CPU Software Reset Control */
 #define SLCR_REBOOT_STATUS_OFFSET	0x258 /* PS Reboot Status */
+#define SLCR_LVL_SHFTR_EN_OFFSET	0x900 /* Level Shifters Enable */
+#define SLCR_OCM_CFG_OFFSET		0x910 /* OCM Address Mapping */
 
 #define SLCR_UNLOCK_MAGIC		0xDF0D
 #define SLCR_A9_CPU_CLKSTOP		0x10
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:64 @
 }
 
 /**
+ * zynq_slcr_write - Write to a register in SLCR block
+ *
+ * @val:	Value to write to the register
+ * @offset:	Register offset in SLCR block
+ */
+void zynq_slcr_write(u32 val, u32 offset)
+{
+	writel(val, zynq_slcr_base + offset);
+}
+EXPORT_SYMBOL(zynq_slcr_write);
+
+/**
+ * zynq_slcr_read - Read a register in SLCR block
+ *
+ * @offset:	Register offset in SLCR block
+ *
+ * return:	Value read from the SLCR register
+ */
+u32 zynq_slcr_read(u32 offset)
+{
+	return readl(zynq_slcr_base + offset);
+}
+EXPORT_SYMBOL(zynq_slcr_read);
+
+/**
+ * zynq_slcr_get_ocm_config - Get SLCR OCM config
+ *
+ * return:	OCM config bits
+ */
+u32 zynq_slcr_get_ocm_config(void)
+{
+	return zynq_slcr_read(SLCR_OCM_CFG_OFFSET);
+}
+
+/**
+ * zynq_slcr_init_preload_fpga - Disable communication from the PL to PS.
+ */
+void zynq_slcr_init_preload_fpga(void)
+{
+
+	/* Assert FPGA top level output resets */
+	zynq_slcr_write(0xF, SLCR_FPGA_RST_CTRL_OFFSET);
+
+	/* Disable level shifters */
+	zynq_slcr_write(0, SLCR_LVL_SHFTR_EN_OFFSET);
+
+	/* Enable output level shifters */
+	zynq_slcr_write(0xA, SLCR_LVL_SHFTR_EN_OFFSET);
+}
+EXPORT_SYMBOL(zynq_slcr_init_preload_fpga);
+
+/**
+ * zynq_slcr_init_postload_fpga - Re-enable communication from the PL to PS.
+ */
+void zynq_slcr_init_postload_fpga(void)
+{
+
+	/* Enable level shifters */
+	zynq_slcr_write(0xf, SLCR_LVL_SHFTR_EN_OFFSET);
+
+	/* Deassert AXI interface resets */
+	zynq_slcr_write(0, SLCR_FPGA_RST_CTRL_OFFSET);
+}
+EXPORT_SYMBOL(zynq_slcr_init_postload_fpga);
+
+/**
  * zynq_slcr_cpu_start - Start cpu
  * @cpu:	cpu number
  */
 void zynq_slcr_cpu_start(int cpu)
 {
 	u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+
 	reg &= ~(SLCR_A9_CPU_RST << cpu);
 	writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
 	reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu);
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/suspend.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/suspend.S	2014-07-20 22:06:34.360338641 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Suspend support for Zynq
+ *
+ *  Copyright (C) 2012 Xilinx
+ *
+ *  Soren Brinkmann <soren.brinkmann@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <linux/linkage.h>
+
+#define DDRPLL_CTRL_OFFS	0x104
+#define PLLSTATUS_OFFS		0x10c
+#define DDR_CLK_CTRL_OFFS	0x124
+#define DCI_CLK_CTRL_OFFS	0x128
+#define DDR_CMD_STA_OFFS	0x618
+#define MODE_STS_OFFS		0x54
+
+#define PLL_RESET_MASK		1
+#define PLL_PWRDWN_MASK		(1 << 1)
+#define PLL_BYPASS_MASK		(1 << 4)
+#define DCICLK_ENABLE_MASK	1
+#define DDRCLK_ENABLE_MASK	3
+#define DDR_LOCK_MASK		(1 << 1)
+#define DDR_STATUS_MASK		7
+
+#define DDR_OPMODE_SR		3
+#define MAXTRIES		100
+
+	.text
+
+/**
+ * zynq_sys_suspend - Enter suspend
+ * @ddrc_base:	Base address of the DDRC
+ * @slcr_base:	Base address of the SLCR
+ * Returns -1 if DRAM subsystem is not gated off, 0 otherwise.
+ *
+ * This function is moved into OCM and finishes the suspend operation. I.e. DDR
+ * related clocks are gated off and the DDR PLL is bypassed.
+ */
+ENTRY(zynq_sys_suspend)
+	dsb
+	/* Check DDRC is in self-refresh mode */
+	ldr	r2, [r0, #MODE_STS_OFFS]
+	and	r2, #DDR_STATUS_MASK
+	cmp	r2, #DDR_OPMODE_SR
+	movweq	r3, #0xff00
+	bne	suspend
+
+	mov	r3, #0
+	/* Wait for command queue empty */
+1:	cmp	r3, #MAXTRIES
+	movweq	r3, #0xff00
+	beq	suspend
+	ldr	r2, [r1, #DDR_CMD_STA_OFFS]
+	cmp	r2, #0
+	addne	r3, #1
+	bne	1b
+
+	dsb
+
+	/* Stop DDR clocks */
+	ldr	r2, [r1, #DDR_CLK_CTRL_OFFS]
+	bic	r2, #DDRCLK_ENABLE_MASK
+	str	r2, [r1, #DDR_CLK_CTRL_OFFS]
+
+	dmb
+
+	ldr	r2, [r1, #DCI_CLK_CTRL_OFFS]
+	bic	r2, #DCICLK_ENABLE_MASK
+	str	r2, [r1, #DCI_CLK_CTRL_OFFS]
+
+	dmb
+
+	/* Bypass and powerdown DDR PLL */
+	ldr	r2, [r1, #DDRPLL_CTRL_OFFS]
+	orr	r2, #PLL_BYPASS_MASK
+	str	r2, [r1, #DDRPLL_CTRL_OFFS]
+	orr	r2, #(PLL_PWRDWN_MASK | PLL_RESET_MASK)
+	str	r2, [r1, #DDRPLL_CTRL_OFFS]
+
+suspend:
+	wfi
+	dsb
+	cmp	r3, #0xff00
+	moveq	r0, #-1
+	beq	exit
+
+	/* Power up DDR PLL */
+	ldr	r2, [r1, #DDRPLL_CTRL_OFFS]
+	bic	r2, #(PLL_PWRDWN_MASK | PLL_RESET_MASK)
+	str	r2, [r1, #DDRPLL_CTRL_OFFS]
+	/* wait for lock */
+1:	ldr	r2, [r1, #PLLSTATUS_OFFS]
+	and	r2, #DDR_LOCK_MASK
+	cmp	r2, #0
+	beq	1b
+
+	dsb
+
+	/* Disable PLL bypass */
+	ldr	r2, [r1, #DDRPLL_CTRL_OFFS]
+	bic	r2, #PLL_BYPASS_MASK
+	str	r2, [r1, #DDRPLL_CTRL_OFFS]
+
+	dmb
+
+	/* Start DDR clocks */
+	ldr	r2, [r1, #DCI_CLK_CTRL_OFFS]
+	orr	r2, #DCICLK_ENABLE_MASK
+	str	r2, [r1, #DCI_CLK_CTRL_OFFS]
+
+	dmb
+
+	ldr	r2, [r1, #DDR_CLK_CTRL_OFFS]
+	orr	r2, #DDRCLK_ENABLE_MASK
+	str	r2, [r1, #DDR_CLK_CTRL_OFFS]
+
+	dsb
+
+	mov	r0, #0
+exit:	bx	lr
+
+ENTRY(zynq_sys_suspend_sz)
+	.word	. - zynq_sys_suspend
+
+	ENDPROC(zynq_sys_suspend)
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/xaxipcie.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/xaxipcie.c	2014-07-20 22:06:34.374338411 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI PCIe IP hardware initialation, setup and
+ * configuration spaces access file.
+ *
+ * Copyright (c) 2012 Xilinx, Inc.
+ *
+ * This program has adopted some work from PCI/PCIE support for AMCC
+ * PowerPC boards written by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * 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/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/sizes.h>
+#include <linux/irqdomain.h>
+#include <linux/pci.h>
+#include <asm/mach/pci.h>
+
+/* Register definitions */
+#define PCIE_CFG_CMD			0x00000004
+#define PCIE_CFG_CLS			0x00000008
+#define PCIE_CFG_HDR			0x0000000C
+#define PCIE_CFG_AD1			0x00000010
+#define PCIE_CFG_AD2			0x00000014
+#define PCIE_CFG_BUS			0x00000018
+#define PCIE_CFG_IO			0x0000001C
+#define PCIE_CFG_MEM			0x00000020
+#define PCIE_CFG_PREF_MEM		0x00000024
+#define PCIE_CFG_PREF_BASE_UPPER	0x00000028
+#define PCIE_CFG_PREF_LIMIT_UPPER	0x0000002c
+#define PCIE_CFG_IO_UPPER		0x00000030
+
+#define XAXIPCIE_REG_VSECC		0x00000128
+#define XAXIPCIE_REG_VSECH		0x0000012c
+#define XAXIPCIE_REG_BIR		0x00000130
+#define XAXIPCIE_REG_BSCR		0x00000134
+#define XAXIPCIE_REG_IDR		0x00000138
+#define XAXIPCIE_REG_IMR		0x0000013c
+#define XAXIPCIE_REG_BLR		0x00000140
+#define XAXIPCIE_REG_PSCR		0x00000144
+#define XAXIPCIE_REG_RPSC		0x00000148
+#define XAXIPCIE_REG_MSIBASE1		0x0000014c
+#define XAXIPCIE_REG_MSIBASE2		0x00000150
+#define XAXIPCIE_REG_RPEFR		0x00000154
+#define XAXIPCIE_REG_RPIFR1		0x00000158
+#define XAXIPCIE_REG_RPIFR2		0x0000015c
+#define XAXIPCIE_REG_VSECC2		0x00000200
+#define XAXIPCIE_REG_VSECH2		0x00000204
+
+/* Interrupt register defines */
+#define XAXIPCIE_INTR_LINK_DOWN		(1 << 0)
+#define XAXIPCIE_INTR_ECRC_ERR		(1 << 1)
+#define XAXIPCIE_INTR_STR_ERR		(1 << 2)
+#define XAXIPCIE_INTR_HOT_RESET		(1 << 3)
+#define XAXIPCIE_INTR_CFG_COMPL		(7 << 5)
+#define XAXIPCIE_INTR_CFG_TIMEOUT	(1 << 8)
+#define XAXIPCIE_INTR_CORRECTABLE	(1 << 9)
+#define XAXIPCIE_INTR_NONFATAL		(1 << 10)
+#define XAXIPCIE_INTR_FATAL		(1 << 11)
+#define XAXIPCIE_INTR_INTX		(1 << 16)
+#define XAXIPCIE_INTR_MSI		(1 << 17)
+#define XAXIPCIE_INTR_SLV_UNSUPP	(1 << 20)
+#define XAXIPCIE_INTR_SLV_UNEXP		(1 << 21)
+#define XAXIPCIE_INTR_SLV_COMPL		(1 << 22)
+#define XAXIPCIE_INTR_SLV_ERRP		(1 << 23)
+#define XAXIPCIE_INTR_SLV_CMPABT	(1 << 24)
+#define XAXIPCIE_INTR_SLV_ILLBUR	(1 << 25)
+#define XAXIPCIE_INTR_MST_DECERR	(1 << 26)
+#define XAXIPCIE_INTR_MST_SLVERR	(1 << 27)
+#define XAXIPCIE_INTR_MST_ERRP		(1 << 28)
+
+#define BUS_LOC_SHIFT			20
+#define DEV_LOC_SHIFT			12
+#define PRIMARY_BUS			1
+#define PORT_REG_SIZE			0x1000
+#define PORT_HEADER_SIZE		0x128
+
+#define XAXIPCIE_LOCAL_CNFG_BASE	0x00000000
+#define XAXIPCIE_REG_BASE		0x00000128
+#define XAXIPCIE_REG_PSCR_LNKUP		0x00000800
+#define XAXIPCIE_REG_IMR_MASKALL	0x1FF30FED
+#define XAXIPCIE_REG_IDR_MASKALL	0xFFFFFFFF
+#define XAXIPCIE_REG_RPSC_BEN		0x00000001
+#define BUS_MASTER_ENABLE		0x00000004
+
+#define XAXIPCIE_ACCESS8	1
+#define XAXIPCIE_ACCESS16	2
+
+#define XAXIPCIE_MEM_SPACE	2
+#define XAXIPCIE_MEM_SPACE64	3
+
+/* Config structure for PCIe */
+struct xaxi_pcie_of_config {
+	u32 num_instances;
+	u32 device_id;
+	u32 device_type;
+	u32 ecam_base;
+	u32 ecam_high;
+	u32 baseaddr;
+	u32 highaddr;
+	u32 bars_num;
+	u32 irq_num;
+	u32 reg_base;
+	u32 reg_len;
+	u32 pcie2axibar_0;
+	u32 pcie2axibar_1;
+	const __be32 *ranges;
+	int range_len;
+	u32 address_cells;
+};
+
+/* PCIe Root Port Structure */
+struct xaxi_pcie_port {
+	struct device_node *node;
+	u32 reg_base;
+	u32 reg_len;
+	u32 ecam_base;
+	u32 ecam_high;
+	u32 baseaddr;
+	u32 highaddr;
+	u32 header_addr;
+	u8 index;
+	u8 type;
+	u8 link_up;
+	u8 bars_num;
+	u32 irq_num;
+	const __be32 *ranges;
+	int range_len;
+	u32 pna;
+	u8 __iomem *base_addr_remap;
+	u8 __iomem *header_remap;
+	u8 __iomem *ecam_remap;
+	u32 pcie2axibar_0;
+	u32 pcie2axibar_1;
+	u32 root_bus_nr;
+	u32 first_busno;
+	u32 last_busno;
+	resource_size_t isa_mem_phys;
+	resource_size_t isa_mem_size;
+	resource_size_t pci_mem_offset;
+	struct resource io_resource;
+	struct resource mem_resources[3];
+	char mem_space_name[16];
+};
+
+static struct xaxi_pcie_port *xaxi_pcie_ports;
+static int xaxi_pcie_port_cnt;
+static int last_bus_on_record;
+
+/* ISA Memory physical address */
+static resource_size_t isa_mem_base;
+
+#ifdef CONFIG_PCI_MSI
+static int xaxipcie_msi_irq_base;
+
+int xaxipcie_alloc_msi_irqdescs(struct device_node *node,
+				unsigned long msg_addr);
+#endif
+
+/* Macros */
+#define is_link_up(base_address)	\
+	((readl(base_address + XAXIPCIE_REG_PSCR) &	\
+	XAXIPCIE_REG_PSCR_LNKUP) ? 1 : 0)
+
+#define bridge_enable(base_address)	\
+	writel((readl(base_address + XAXIPCIE_REG_RPSC) |	\
+		XAXIPCIE_REG_RPSC_BEN), \
+		(base_address + XAXIPCIE_REG_RPSC))
+
+/**
+ * xaxi_pcie_verify_config
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: device/function
+ *
+ * @return: Error / no error
+ *
+ * @note: Make sure we can handle this configuration call on our
+ *        device.
+ */
+static int xaxi_pcie_verify_config(struct xaxi_pcie_port *port,
+				struct pci_bus *bus,
+				unsigned int devfn)
+{
+	static int message;
+
+	/* Endpoint can not generate upstream(remote) config cycles */
+	if ((!port->type) && bus->number != port->first_busno)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Check we are within the mapped range */
+	if (bus->number > port->last_busno) {
+		if (!message) {
+			pr_warn("Warning! Probing bus %u out of range !\n",
+				bus->number);
+			message++;
+		}
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/* The other side of the RC has only one device as well */
+	if (bus->number == (port->first_busno + 1) &&
+		PCI_SLOT(devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Check if we have a link */
+	if (!port->link_up)
+		port->link_up = is_link_up(port->base_addr_remap);
+
+	if ((bus->number != port->first_busno) && !port->link_up)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return 0;
+}
+
+/**
+ * xaxi_pcie_get_config_base
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ * @where: Offset from base
+ *
+ * @return: Base address of the configuration space needed to be
+ *          accessed.
+ *
+ * @note: Get the base address of the configuration space for this
+ *        pcie device.
+ */
+static void __iomem *xaxi_pcie_get_config_base(
+				struct xaxi_pcie_port *port,
+				struct pci_bus *bus,
+				unsigned int devfn, int where)
+{
+	int relbus;
+
+	relbus = ((bus->number << BUS_LOC_SHIFT) | (devfn << DEV_LOC_SHIFT));
+
+	return port->header_remap + relbus + where;
+}
+
+/**
+ * xaxi_pcie_read_config - Read config reg.
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: A pointer to value read
+ *
+ * @return: Error / no error
+ *
+ *
+ * @note: Read byte/word/dword from pcie device config reg.
+ */
+static int xaxi_pcie_read_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where,
+				int size,
+				u32 *val)
+{
+	struct pci_sys_data *sys = bus->sysdata;
+	struct xaxi_pcie_port *port = sys->private_data;
+	void __iomem *addr;
+
+	if (xaxi_pcie_verify_config(port, bus, devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr = xaxi_pcie_get_config_base(port, bus, devfn, where);
+
+	if ((bus->number == 0) && devfn > 0) {
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	switch (size) {
+	case XAXIPCIE_ACCESS8:
+		*val = readb(addr);
+		break;
+	case XAXIPCIE_ACCESS16:
+		*val = readw(addr);
+		break;
+	default:
+		*val = readl(addr);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/**
+ * xaxi_pcie_write_config - Write config reg.
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: Value to be written to device
+ *
+ * @return: Error / no error
+ *
+ *
+ * @note: Write byte/word/dword to pcie device config reg.
+ */
+static int xaxi_pcie_write_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where,
+				int size,
+				u32 val)
+{
+	struct pci_sys_data *sys = bus->sysdata;
+	struct xaxi_pcie_port *port = sys->private_data;
+	void __iomem *addr;
+
+	if (xaxi_pcie_verify_config(port, bus, devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr = xaxi_pcie_get_config_base(port, bus, devfn, where);
+
+	if ((bus->number == 0) && devfn > 0)
+		return PCIBIOS_SUCCESSFUL;
+
+	switch (size) {
+	case XAXIPCIE_ACCESS8:
+		writeb(val, addr);
+		break;
+	case XAXIPCIE_ACCESS16:
+		writew(val, addr);
+		break;
+	default:
+		writel(val, addr);
+		break;
+	}
+
+	wmb();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/**
+ * xaxi_pcie_set_bridge_resource - Setup base & limit registers of config space.
+ * @port: Pointer to a root port
+ *
+ * @return: None
+ *
+ * @note: None
+ */
+static void xaxi_pcie_set_bridge_resource(struct xaxi_pcie_port *port)
+{
+	const __be32 *ranges = port->ranges;
+	int rlen = port->range_len;
+	int np = port->pna + 5;
+	u32 pci_space;
+	unsigned long long pci_addr, size;
+	u32 val = 0;
+
+	while ((rlen -= np * 4) >= 0) {
+		pci_space = be32_to_cpup(ranges);
+		pci_addr = of_read_number(ranges + 1, 2);
+		size = of_read_number(ranges + port->pna + 3, 2);
+
+		pr_info("%s:pci_space: 0x%08x pci_addr:0x%016llx size: 0x%016llx\n",
+			__func__, pci_space, pci_addr, size);
+
+		ranges += np;
+
+		switch ((pci_space >> 24) & 0x3) {
+		case XAXIPCIE_MEM_SPACE:	/* PCI Memory space */
+			pr_info("%s:Setting resource in Memory Space\n",
+								__func__);
+			writel(port->pcie2axibar_0,
+					port->header_remap +
+						PCIE_CFG_AD1);
+			writel(port->pcie2axibar_1,
+					port->header_remap +
+						PCIE_CFG_AD2);
+			break;
+		case XAXIPCIE_MEM_SPACE64:	/* PCI 64 bits Memory space */
+			pr_info("%s:Setting resource in Prefetchable Memory Space\n",
+				__func__);
+
+			val = ((pci_addr >> 16) & 0xfff0) |
+					((pci_addr + size - 1) & 0xfff00000);
+
+			writel(val, port->header_remap +
+						PCIE_CFG_PREF_MEM);
+
+			val = ((pci_addr >> 32) & 0xffffffff);
+			writel(val, port->header_remap +
+						PCIE_CFG_PREF_BASE_UPPER);
+
+			val = (((pci_addr + size - 1) >> 32) & 0xffffffff);
+			writel(val, port->header_remap +
+						PCIE_CFG_PREF_LIMIT_UPPER);
+			break;
+		}
+	}
+}
+
+static int xaxi_pcie_hookup_resources(struct xaxi_pcie_port *port,
+					struct pci_sys_data *sys)
+{
+	struct resource *res;
+	int i;
+
+	/* Hookup Memory resources */
+	for (i = 0; i < 3; ++i) {
+		res = &port->mem_resources[i];
+		snprintf(port->mem_space_name, sizeof(port->mem_space_name),
+			"PCIe %d MEM", port->index);
+		port->mem_space_name[sizeof(port->mem_space_name) - 1] = 0;
+		res->name = port->mem_space_name;
+
+		if (!res->flags) {
+			if (i > 0)
+				continue;
+			/* Workaround for lack of MEM resource only on 32-bit */
+			res->start = port->pci_mem_offset;
+			res->end = (resource_size_t)-1LL;
+			res->flags = IORESOURCE_MEM;
+		}
+		if (request_resource(&iomem_resource, res))
+			panic("Request PCIe%d Memory resource failed\n",
+					port->index);
+		pci_add_resource_offset(&sys->resources,
+				res, port->pci_mem_offset);
+
+		pr_info("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
+			i, (unsigned long long)res->start,
+			(unsigned long long)res->end,
+			(unsigned long)res->flags);
+	}
+
+	return 0;
+}
+
+static void xaxi_pcie_process_bridge_OF_ranges(struct xaxi_pcie_port *port,
+					int primary)
+{
+	/* The address cells of PCIe node */
+	int pna = port->pna;
+	int np = pna + 5;
+	int memno = 0, isa_hole = -1;
+	u32 pci_space;
+	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+	unsigned long long isa_mb = 0;
+	struct resource *res;
+	const __be32 *ranges = port->ranges;
+	int rlen = port->range_len;
+	struct device_node *node = port->node;
+
+	pr_info("PCI host bridge %s %s ranges:\n",
+		node->full_name, primary ? "(primary)" : "");
+
+	/* Parse it */
+	pr_debug("Parsing ranges property...\n");
+	while ((rlen -= np * 4) >= 0) {
+		/* Read next ranges element */
+		pci_space = be32_to_cpup(ranges);
+		pci_addr = of_read_number(ranges + 1, 2);
+		cpu_addr = of_translate_address(node, ranges + 3);
+		size = of_read_number(ranges + pna + 3, 2);
+
+		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx\n",
+				pci_space, pci_addr);
+		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n", cpu_addr, size);
+
+		ranges += np;
+
+		/* If we failed translation or got a zero-sized region
+		 * (some FW try to feed us with non sensical zero sized regions
+		 * such as power3 which look like some kind of attempt
+		 * at exposing the VGA memory hole)
+		 */
+		if (cpu_addr == OF_BAD_ADDR || size == 0)
+			continue;
+
+		/* Now consume following elements while they are contiguous */
+		for (; rlen >= np * sizeof(u32);
+			ranges += np, rlen -= np * 4) {
+			if (be32_to_cpup(ranges) != pci_space)
+				break;
+			pci_next = of_read_number(ranges + 1, 2);
+			cpu_next = of_translate_address(node, ranges + 3);
+			if (pci_next != pci_addr + size ||
+				cpu_next != cpu_addr + size)
+				break;
+			size += of_read_number(ranges + pna + 3, 2);
+		}
+
+		/* Act based on address space type */
+		res = NULL;
+		switch ((pci_space >> 24) & 0x3) {
+		case XAXIPCIE_MEM_SPACE:	/* PCI Memory space */
+		case XAXIPCIE_MEM_SPACE64:	/* PCI 64 bits Memory space */
+			pr_info("MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+				cpu_addr, cpu_addr + size - 1, pci_addr,
+				(pci_space & 0x40000000) ? "Prefetch" : "");
+
+			/* We support only 3 memory ranges */
+			if (memno >= 3) {
+				pr_info("\\--> Skipped (too many) !\n");
+				continue;
+			}
+			/* Handles ISA memory hole space here */
+			if (pci_addr == 0) {
+				isa_mb = cpu_addr;
+				isa_hole = memno;
+				if (primary || isa_mem_base == 0)
+					isa_mem_base = cpu_addr;
+				port->isa_mem_phys = cpu_addr;
+				port->isa_mem_size = size;
+			}
+
+			/* We get the PCI/Mem offset from the first range or
+			 * the, current one if the offset came from an ISA
+			 * hole. If they don't match, bugger.
+			 */
+			if (memno == 0 ||
+				(isa_hole >= 0 && pci_addr != 0 &&
+					port->pci_mem_offset == isa_mb))
+				port->pci_mem_offset = cpu_addr - pci_addr;
+			else if (pci_addr != 0 &&
+				port->pci_mem_offset != cpu_addr - pci_addr) {
+				pr_info("\\--> Skipped (offset mismatch) !\n");
+				continue;
+			}
+
+			/* Build resource */
+			res = &port->mem_resources[memno++];
+			res->flags = IORESOURCE_MEM;
+			if (pci_space & 0x40000000)
+				res->flags |= IORESOURCE_PREFETCH;
+			res->start = cpu_addr;
+			break;
+		}
+		if (res != NULL) {
+			res->name = node->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+	}
+
+	/* If there's an ISA hole and the pci_mem_offset is -not- matching
+	 * the ISA hole offset, then we need to remove the ISA hole from
+	 * the resource list for that brige
+	 */
+	if (isa_hole >= 0 && port->pci_mem_offset != isa_mb) {
+		unsigned int next = isa_hole + 1;
+		pr_info("Removing ISA hole at 0x%016llx\n", isa_mb);
+		if (next < memno)
+			memmove(&port->mem_resources[isa_hole],
+				&port->mem_resources[next],
+				sizeof(struct resource) * (memno - next));
+		port->mem_resources[--memno].flags = 0;
+	}
+}
+
+static struct pci_ops xaxi_pcie_ops = {
+	.read  = xaxi_pcie_read_config,
+	.write = xaxi_pcie_write_config,
+};
+
+static int xaxi_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	u32 val;
+	struct xaxi_pcie_port *port = &xaxi_pcie_ports[nr];
+
+	sys->private_data = port;
+
+	/* Get bus range */
+	port->first_busno = last_bus_on_record;
+
+	val = readl(port->base_addr_remap + XAXIPCIE_REG_PSCR);
+	val = readl(port->header_remap + XAXIPCIE_REG_BIR);
+	val = (val >> 16) & 0x7;
+	port->last_busno = (((port->reg_base - port->reg_len - 1) >> 20)
+						& 0xFF) & val;
+
+	/* Write primary, secondary and subordinate bus numbers */
+	val = port->first_busno;
+	val |= ((port->first_busno + 1) << 8);
+	val |= (port->last_busno << 16);
+
+	writel(val, (port->header_remap + PCIE_CFG_BUS));
+	last_bus_on_record = port->last_busno + 1;
+
+	xaxi_pcie_set_bridge_resource(port);
+
+	/* Parse outbound mapping resources */
+	xaxi_pcie_process_bridge_OF_ranges(port, PRIMARY_BUS);
+	xaxi_pcie_hookup_resources(port, sys);
+
+	return 1;
+}
+
+static struct pci_bus __init *xaxi_pcie_scan_bus(int nr,
+				struct pci_sys_data *sys)
+{
+	struct xaxi_pcie_port *port;
+
+	if (nr >= xaxi_pcie_port_cnt)
+		return NULL;
+
+	port = &xaxi_pcie_ports[nr];
+	port->root_bus_nr = sys->busnr;
+
+	return pci_scan_root_bus(NULL, sys->busnr, &xaxi_pcie_ops, sys,
+			&sys->resources);
+}
+
+static int xaxi_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pci_sys_data *sys = dev->sysdata;
+	struct xaxi_pcie_port *port = sys->private_data;
+
+	return port->irq_num;
+}
+
+/* Interrupt handler */
+static irqreturn_t xaxi_pcie_intr_handler(int irq, void *data)
+{
+	struct xaxi_pcie_port *port = (struct xaxi_pcie_port *)data;
+	u32 val = 0, mask = 0;
+	u32 status;
+	u32 msi_addr = 0;
+	u32 msi_data = 0;
+
+	/* Read interrupt decode and mask registers */
+	val = readl(port->header_remap + XAXIPCIE_REG_IDR);
+	mask = readl(port->header_remap + XAXIPCIE_REG_IMR);
+
+	status = val & mask;
+	if (!status)
+		return IRQ_NONE;
+
+	if (status & XAXIPCIE_INTR_LINK_DOWN)
+		pr_err("Link Down\n");
+
+	if (status & XAXIPCIE_INTR_ECRC_ERR)
+		pr_warn("ECRC failed\n");
+
+	if (status & XAXIPCIE_INTR_STR_ERR)
+		pr_warn("Streaming error\n");
+
+	if (status & XAXIPCIE_INTR_HOT_RESET)
+		pr_info("Hot reset\n");
+
+	if (status & XAXIPCIE_INTR_CFG_TIMEOUT)
+		pr_warn("ECAM access timeout\n");
+
+	if (status & XAXIPCIE_INTR_CORRECTABLE) {
+		pr_warn("Correctable error message\n");
+		val = readl(port->header_remap +
+				XAXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			writel(0xFFFFFFFF,
+				port->base_addr_remap +
+				XAXIPCIE_REG_RPEFR);
+			pr_debug("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & XAXIPCIE_INTR_NONFATAL) {
+		pr_warn("Non fatal error message\n");
+		val = readl((port->header_remap) +
+				XAXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			writel(0xFFFFFFFF,
+				port->base_addr_remap +
+				XAXIPCIE_REG_RPEFR);
+			pr_debug("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & XAXIPCIE_INTR_FATAL) {
+		pr_warn("Fatal error message\n");
+		val = readl(port->header_remap +
+				XAXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			writel(0xFFFFFFFF,
+				port->base_addr_remap +
+				XAXIPCIE_REG_RPEFR);
+			pr_debug("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & XAXIPCIE_INTR_INTX) {
+		/* INTx interrupt received */
+		val = readl(port->header_remap + XAXIPCIE_REG_RPIFR1);
+
+		/* Check whether interrupt valid */
+		if (!(val & (1 << 31))) {
+			pr_warn("RP Intr FIFO1 read error\n");
+			return IRQ_HANDLED;
+		}
+
+		/* Check MSI or INTX */
+		if (!(val & (1 << 30))) {
+			if (val & (1 << 29))
+				pr_debug("INTx assert\n");
+			else
+				pr_debug("INTx deassert\n");
+		}
+
+		/* Clear interrupt FIFO register 1 */
+		writel(0xFFFFFFFF,
+			port->base_addr_remap + XAXIPCIE_REG_RPIFR1);
+	}
+
+	if (status & XAXIPCIE_INTR_MSI) {
+		/* MSI Interrupt */
+		val = readl(port->header_remap + XAXIPCIE_REG_RPIFR1);
+
+		if (!(val & (1 << 31))) {
+			pr_warn("RP Intr FIFO1 read error\n");
+			return IRQ_HANDLED;
+		}
+
+		if (val & (1 << 30)) {
+			msi_addr = (val >> 16) & 0x7FF;
+			msi_data = readl(port->header_remap +
+					XAXIPCIE_REG_RPIFR2) & 0xFFFF;
+			pr_debug("%s: msi_addr %08x msi_data %08x\n",
+					__func__, msi_addr, msi_data);
+		}
+
+		/* Clear interrupt FIFO register 1 */
+		writel(0xFFFFFFFF,
+			port->base_addr_remap + XAXIPCIE_REG_RPIFR1);
+#ifdef CONFIG_PCI_MSI
+		/* Handle MSI Interrupt */
+		if (msi_data >= xaxipcie_msi_irq_base)
+			generic_handle_irq(msi_data);
+#endif
+	}
+
+	if (status & XAXIPCIE_INTR_SLV_UNSUPP)
+		pr_warn("Slave unsupported request\n");
+
+	if (status & XAXIPCIE_INTR_SLV_UNEXP)
+		pr_warn("Slave unexpected completion\n");
+
+	if (status & XAXIPCIE_INTR_SLV_COMPL)
+		pr_warn("Slave completion timeout\n");
+
+	if (status & XAXIPCIE_INTR_SLV_ERRP)
+		pr_warn("Slave Error Poison\n");
+
+	if (status & XAXIPCIE_INTR_SLV_CMPABT)
+		pr_warn("Slave Completer Abort\n");
+
+	if (status & XAXIPCIE_INTR_SLV_ILLBUR)
+		pr_warn("Slave Illegal Burst\n");
+
+	if (status & XAXIPCIE_INTR_MST_DECERR)
+		pr_warn("Master decode error\n");
+
+	if (status & XAXIPCIE_INTR_MST_SLVERR)
+		pr_warn("Master slave error\n");
+
+	if (status & XAXIPCIE_INTR_MST_ERRP)
+		pr_warn("Master error poison\n");
+
+	/* Clear the Interrupt Decode register */
+	writel(status, port->base_addr_remap + XAXIPCIE_REG_IDR);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xaxi_pcie_init_port - Initialize hardware
+ * @port: A pointer to a pcie port that needs to be initialized
+ *
+ * @return: Error / no error
+ *
+ * @note: None
+ */
+static int xaxi_pcie_init_port(struct xaxi_pcie_port *port)
+{
+	void __iomem *base_addr_remap = NULL;
+	int err = 0;
+#ifdef CONFIG_PCI_MSI
+	unsigned long xaxipcie_msg_addr;
+#endif
+
+	base_addr_remap = ioremap(port->reg_base, port->reg_len);
+	if (!base_addr_remap)
+		return -ENOMEM;
+
+	port->base_addr_remap = base_addr_remap;
+
+	/* make sure it is root port before touching header */
+	if (port->type) {
+		port->header_remap = base_addr_remap;
+		writel(BUS_MASTER_ENABLE,
+			port->base_addr_remap + PCIE_CFG_CMD);
+	}
+
+#ifdef CONFIG_PCI_MSI
+	xaxipcie_msg_addr = port->reg_base & ~0xFFF;	/* 4KB aligned */
+	writel(0x0, port->base_addr_remap +
+				XAXIPCIE_REG_MSIBASE1);
+
+	writel(xaxipcie_msg_addr, port->base_addr_remap +
+				XAXIPCIE_REG_MSIBASE2);
+
+	xaxipcie_msi_irq_base = xaxipcie_alloc_msi_irqdescs(port->node,
+					xaxipcie_msg_addr);
+	if (xaxipcie_msi_irq_base < 0) {
+		pr_err("%s: Couldn't allocate MSI IRQ numbers\n",
+					 __func__);
+		return -ENODEV;
+	}
+#endif
+
+	port->link_up = is_link_up(port->base_addr_remap);
+	if (!port->link_up)
+		pr_info("%s: LINK IS DOWN\n", __func__);
+	else
+		pr_info("%s: LINK IS UP\n", __func__);
+
+	/* Disable all interrupts*/
+	writel(~XAXIPCIE_REG_IDR_MASKALL,
+		port->base_addr_remap + XAXIPCIE_REG_IMR);
+
+	/* Clear pending interrupts*/
+	writel(readl(port->base_addr_remap + XAXIPCIE_REG_IDR) &
+			XAXIPCIE_REG_IMR_MASKALL,
+			port->base_addr_remap + XAXIPCIE_REG_IDR);
+
+	/* Enable all interrupts*/
+	writel(XAXIPCIE_REG_IMR_MASKALL,
+			port->base_addr_remap + XAXIPCIE_REG_IMR);
+
+	/*
+	 * Bridge enable must be done after enumeration,
+	 * but there is no callback defined
+	 */
+	bridge_enable(port->base_addr_remap);
+
+	/* Register Interrupt Handler */
+	err = request_irq(port->irq_num, xaxi_pcie_intr_handler,
+					IRQF_SHARED, "zynqpcie", port);
+	if (err) {
+		pr_err("%s: Could not allocate interrupt\n", __func__);
+		return err;
+	}
+
+	return 0;
+}
+
+static struct xaxi_pcie_port *
+xaxi_pcie_instantiate_port_info(struct xaxi_pcie_of_config *config,
+					struct device_node *node)
+{
+	struct xaxi_pcie_port *port;
+	int port_num;
+
+	port_num = config->device_id;
+	port = &xaxi_pcie_ports[port_num];
+	port->node = of_node_get(node);
+	port->index = port_num;
+	port->type = config->device_type;
+	port->reg_base = config->reg_base;
+	port->reg_len = config->reg_len;
+	port->bars_num  = config->bars_num;
+	port->irq_num   = config->irq_num;
+	port->header_addr = port->reg_base + XAXIPCIE_LOCAL_CNFG_BASE;
+	port->pcie2axibar_0 = config->pcie2axibar_0;
+	port->pcie2axibar_1 = config->pcie2axibar_1;
+	port->ranges = config->ranges;
+	port->range_len = config->range_len;
+	port->pna = config->address_cells;
+
+	return port;
+}
+
+/**
+ * xaxi_get_pcie_of_config - Read info from device tree
+ * @node: A pointer to device node to read from
+ * @info: A pointer to xilinx_pcie_node struct to write device tree
+ *	info into to.
+ *
+ * @return: Error / no error
+ *
+ * @note: Read related info from device tree
+ */
+static int xaxi_pcie_get_of_config(struct device_node *node,
+		struct xaxi_pcie_of_config *info)
+{
+	const __be32 *value;
+	int rlen;
+
+	info->num_instances = 1;
+
+	value = of_get_property(node, "xlnx,device-num", &rlen);
+
+	info->device_id = 0;
+
+	value = of_get_property(node, "xlnx,include-rc", &rlen);
+	if (value)
+		info->device_type = be32_to_cpup(value);
+	else
+		return -ENODEV;
+
+	value = of_get_property(node, "reg", &rlen);
+	if (value) {
+		info->reg_base =
+			be32_to_cpup(value);
+		info->reg_len =
+			be32_to_cpup(value + 1);
+	} else
+		return -ENODEV;
+
+	value = of_get_property(node, "xlnx,pciebar-num", &rlen);
+	if (value)
+		info->bars_num = be32_to_cpup(value);
+	else
+		return -ENODEV;
+
+	info->irq_num = irq_of_parse_and_map(node, 0);
+
+	/* Get address translation parameters */
+	value = of_get_property(node, "xlnx,pciebar2axibar-0", &rlen);
+	if (value) {
+		info->pcie2axibar_0 =
+			be32_to_cpup(value);
+	} else
+		return -ENODEV;
+
+	value = of_get_property(node, "xlnx,pciebar2axibar-1", &rlen);
+	if (value) {
+		info->pcie2axibar_1 =
+			be32_to_cpup(value);
+	} else
+		return -ENODEV;
+
+	/* The address cells of PCIe node */
+	info->address_cells = of_n_addr_cells(node);
+
+	/* Get ranges property */
+	value = of_get_property(node, "ranges", &rlen);
+	if (value) {
+		info->ranges = value;
+		info->range_len = rlen;
+	} else
+		return -ENODEV;
+
+	return 0;
+}
+
+static int __init xaxi_pcie_of_probe(struct device_node *node)
+{
+	int err = 0;
+	struct xaxi_pcie_of_config config;
+	struct xaxi_pcie_port *port;
+
+	err = xaxi_pcie_get_of_config(node, &config);
+	if (err) {
+		pr_err("%s: Invalid Configuration\n", __func__);
+		return err;
+	}
+
+	if (!xaxi_pcie_port_cnt) {
+		xaxi_pcie_port_cnt = config.num_instances;
+
+		if (xaxi_pcie_port_cnt) {
+			xaxi_pcie_ports = (struct xaxi_pcie_port *)
+				kzalloc(xaxi_pcie_port_cnt *
+				sizeof(struct xaxi_pcie_port), GFP_KERNEL);
+
+			if (!xaxi_pcie_ports) {
+				pr_err("%s: Memory allocation failed\n",
+					__func__);
+				return -ENOMEM;
+			}
+		} else /* not suppose to be here
+			* when we don't have pcie ports */
+			return -ENODEV;
+	}
+
+	port = xaxi_pcie_instantiate_port_info(&config, node);
+	err = xaxi_pcie_init_port(port);
+	if (err) {
+		pr_err("%s: Port Initalization failed\n", __func__);
+		return err;
+	}
+
+	return err;
+}
+
+static struct of_device_id xaxi_pcie_match[] = {
+	{ .compatible = "xlnx,axi-pcie-1.05.a" ,},
+	{}
+};
+
+static struct hw_pci xaxi_pcie_hw __initdata = {
+	.nr_controllers = 1,
+	.setup          = xaxi_pcie_setup,
+	.scan           = xaxi_pcie_scan_bus,
+	.map_irq        = xaxi_pcie_map_irq,
+};
+
+static int __init xaxi_pcie_init(void)
+{
+	int err;
+	int init = 0;
+	struct device_node *node;
+
+	for_each_matching_node(node, xaxi_pcie_match) {
+		err = xaxi_pcie_of_probe(node);
+		if (err) {
+			pr_err("%s: Root Port Probe failed\n", __func__);
+
+			return err;
+		}
+		pr_info("AXI PCIe Root Port Probe Successful\n");
+		init++;
+	}
+
+	if (init)
+		pci_common_init(&xaxi_pcie_hw);
+
+	return 0;
+}
+
+subsys_initcall(xaxi_pcie_init);
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/xaxipcie-msi.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/xaxipcie-msi.c	2014-07-20 22:06:34.382338279 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PCIe IP hardware MSI initialisation
+ *
+ * Copyright (c) 2012 Xilinx, Inc.
+ *
+ * This program has adopted some work from PCI/PCIE support for AMCC
+ * PowerPC boards written by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * 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/msi.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+
+#define XILINX_NUM_MSI_IRQS	128
+
+static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS);
+
+static unsigned long xaxipcie_msg_addr;
+static struct irq_domain *xaxipcie_irq_domain;
+static int xaxipcie_msi_irq_base;
+
+/* Dynamic irq allocate and deallocation */
+
+/**
+ * create_irq- Dynamic irq allocate
+ * void
+ *
+ * @return: Interrupt number allocated/ error
+ *
+ * @note: None
+ */
+int create_irq(void)
+{
+	int irq, pos;
+again:
+	pos = find_first_zero_bit(msi_irq_in_use, XILINX_NUM_MSI_IRQS);
+
+	irq = irq_find_mapping(xaxipcie_irq_domain, pos);
+
+	/* test_and_set_bit operates on 32-bits at a time */
+	if (test_and_set_bit(pos, msi_irq_in_use))
+		goto again;
+
+	dynamic_irq_init(irq);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return irq;
+}
+
+/**
+ * destroy_irq- Dynamic irq de-allocate
+ * @irq: Interrupt number to de-allocate
+ *
+ * @return: None
+ *
+ * @note: None
+ */
+void destroy_irq(unsigned int irq)
+{
+	int pos = irq - xaxipcie_msi_irq_base;
+
+	dynamic_irq_cleanup(irq);
+
+	clear_bit(pos, msi_irq_in_use);
+}
+
+/**
+ * arch_teardown_msi_irq-Teardown the Interrupt
+ * @irq: Interrupt number to teardown
+ *
+ * @return: None
+ *
+ * @note: This function  is called when pci_disable_msi is called
+ */
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	destroy_irq(irq);
+}
+
+/**
+ * xilinx_msi_nop-No operation handler
+ * @irq: Interrupt number
+ *
+ * @return: None
+ *
+ * @note: None
+ */
+static void xilinx_msi_nop(struct irq_data *d)
+{
+	return;
+}
+
+static struct irq_chip xilinx_msi_chip = {
+		.name = "PCIe-MSI",
+		.irq_ack = xilinx_msi_nop,
+		.irq_enable = unmask_msi_irq,
+		.irq_disable = mask_msi_irq,
+		.irq_mask = mask_msi_irq,
+		.irq_unmask = unmask_msi_irq,
+};
+
+/**
+ * arch_setup_msi_irq-Setup MSI interrupt
+ * @pdev: Pointer to current pci device structure
+ * @desc: Pointer to MSI description structure
+ *
+ * @return: Error/ no-error
+ *
+ * @note: This function  is called when pci_enable_msi is called
+ */
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+	int irq = create_irq();
+	struct msi_msg msg;
+
+	if (irq < 0)
+		return irq;
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_hi = 0x00000000;
+	msg.address_lo = xaxipcie_msg_addr;
+	msg.data = irq;
+
+	pr_debug("irq %d addr_hi %08x low %08x data %08x\n",
+			irq, msg.address_hi, msg.address_lo, msg.data);
+
+	write_msi_msg(irq, &msg);
+
+	irq_set_chip_and_handler(irq, &xilinx_msi_chip, handle_simple_irq);
+
+	return 0;
+}
+
+
+/**
+ * xaxipcie_alloc_msi_irqdescs - allocate msi irq descs
+ * @node: Pointer to device node structure
+ * @msg_addr: PCIe MSI message address
+ *
+ * @return: Allocated MSI IRQ Base/ error
+ *
+ * @note: This function is called when xaxipcie_init_port() is called
+ */
+int xaxipcie_alloc_msi_irqdescs(struct device_node *node,
+					unsigned long msg_addr)
+{
+	/* Store the PCIe MSI message address */
+	xaxipcie_msg_addr = msg_addr;
+
+	/* Allocate MSI IRQ descriptors */
+	xaxipcie_msi_irq_base = irq_alloc_descs(-1, 0,
+					XILINX_NUM_MSI_IRQS, 0);
+
+	if (xaxipcie_msi_irq_base < 0)
+		return -ENODEV;
+
+	/* Register IRQ domain */
+	xaxipcie_irq_domain = irq_domain_add_legacy(node,
+				XILINX_NUM_MSI_IRQS,
+				xaxipcie_msi_irq_base,
+				0, &irq_domain_simple_ops, NULL);
+
+	if (!xaxipcie_irq_domain)
+		return -ENOMEM;
+
+	return xaxipcie_msi_irq_base;
+}
+EXPORT_SYMBOL(xaxipcie_alloc_msi_irqdescs);
Index: linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/zynq_ocm.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/arm/mach-zynq/zynq_ocm.c	2014-07-20 22:06:34.390338147 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Copyright (C) 2013 Xilinx
+ *
+ * Based on "Generic on-chip SRAM allocation driver"
+ *
+ * Copyright (C) 2012 Philipp Zabel, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/genalloc.h>
+
+#include "common.h"
+
+#define ZYNQ_OCM_HIGHADDR	0xfffc0000
+#define ZYNQ_OCM_LOWADDR	0x0
+#define ZYNQ_OCM_BLOCK_SIZE	0x10000
+#define ZYNQ_OCM_BLOCKS		4
+#define ZYNQ_OCM_GRANULARITY	32
+
+#define ZYNQ_OCM_PARITY_CTRL	0x0
+#define ZYNQ_OCM_PARITY_ENABLE	0x1e
+
+#define ZYNQ_OCM_PARITY_ERRADDRESS	0x4
+
+#define ZYNQ_OCM_IRQ_STS		0x8
+#define ZYNQ_OCM_IRQ_STS_ERR_MASK	0x7
+
+struct zynq_ocm_dev {
+	void __iomem *base;
+	int irq;
+	struct gen_pool *pool;
+	struct resource res[ZYNQ_OCM_BLOCKS];
+};
+
+/**
+ * zynq_ocm_irq_handler - Interrupt service routine of the OCM controller
+ * @irq:        IRQ number
+ * @data:     Pointer to the zynq_ocm_dev structure
+ *
+ * returns:     IRQ_HANDLED always
+ */
+static irqreturn_t zynq_ocm_irq_handler(int irq, void *data)
+{
+	u32 sts;
+	u32 err_addr;
+	struct zynq_ocm_dev *zynq_ocm = data;
+
+	/* check status */
+	sts = readl(zynq_ocm->base + ZYNQ_OCM_IRQ_STS);
+	if (sts & ZYNQ_OCM_IRQ_STS_ERR_MASK) {
+		/* check error address */
+		err_addr = readl(zynq_ocm->base + ZYNQ_OCM_PARITY_ERRADDRESS);
+		pr_err("%s: OCM err intr generated at 0x%04x (stat: 0x%08x).",
+		       __func__, err_addr, sts & ZYNQ_OCM_IRQ_STS_ERR_MASK);
+	}
+	pr_warn("%s: Interrupt generated by OCM, but no error is found.",
+		__func__);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * zynq_ocm_probe - Probe method for the OCM driver
+ * @pdev:       Pointer to the platform_device structure
+ *
+ * This function initializes the driver data structures and the hardware.
+ *
+ * returns:     0 on success and error value on failure
+ */
+static int zynq_ocm_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct zynq_ocm_dev *zynq_ocm;
+	u32 i, ocm_config, curr;
+	struct resource *res;
+
+	ocm_config = zynq_slcr_get_ocm_config();
+
+	zynq_ocm = devm_kzalloc(&pdev->dev, sizeof(*zynq_ocm), GFP_KERNEL);
+	if (!zynq_ocm)
+		return -ENOMEM;
+
+	zynq_ocm->pool = devm_gen_pool_create(&pdev->dev,
+					      ilog2(ZYNQ_OCM_GRANULARITY), -1);
+	if (!zynq_ocm->pool)
+		return -ENOMEM;
+
+	curr = 0; /* For storing current struct resource for OCM */
+	for (i = 0; i < ZYNQ_OCM_BLOCKS; i++) {
+		u32 base, start, end;
+
+		/* Setup base address for 64kB OCM block */
+		if (ocm_config & BIT(i))
+			base = ZYNQ_OCM_HIGHADDR;
+		else
+			base = ZYNQ_OCM_LOWADDR;
+
+		/* Calculate start and end block addresses */
+		start = i * ZYNQ_OCM_BLOCK_SIZE + base;
+		end = start + (ZYNQ_OCM_BLOCK_SIZE - 1);
+
+		/* Concatenate OCM blocks together to get bigger pool */
+		if (i > 0 && start == (zynq_ocm->res[curr - 1].end + 1)) {
+			zynq_ocm->res[curr - 1].end = end;
+		} else {
+#ifdef CONFIG_SMP
+			/*
+			 * OCM block if placed at 0x0 has special meaning
+			 * for SMP because jump trampoline is added there.
+			 * Ensure that this address won't be allocated.
+			 */
+			if (!base) {
+				u32 trampoline_code_size =
+					&zynq_secondary_trampoline_end -
+					&zynq_secondary_trampoline;
+				dev_dbg(&pdev->dev,
+					"Allocate reset vector table %dB\n",
+					trampoline_code_size);
+				/* postpone start offset */
+				start += trampoline_code_size;
+			}
+#endif
+			/* First resource is always initialized */
+			zynq_ocm->res[curr].start = start;
+			zynq_ocm->res[curr].end = end;
+			zynq_ocm->res[curr].flags = IORESOURCE_MEM;
+			curr++; /* Increment curr value */
+		}
+		dev_dbg(&pdev->dev, "OCM block %d, start %x, end %x\n",
+			i, start, end);
+	}
+
+	/*
+	 * Separate pool allocation from OCM block detection to ensure
+	 * the biggest possible pool.
+	 */
+	for (i = 0; i < ZYNQ_OCM_BLOCKS; i++) {
+		unsigned long size;
+		void __iomem *virt_base;
+
+		/* Skip all zero size resources */
+		if (zynq_ocm->res[i].end == 0)
+			break;
+		dev_dbg(&pdev->dev, "OCM resources %d, start %x, end %x\n",
+			i, zynq_ocm->res[i].start, zynq_ocm->res[i].end);
+		size = resource_size(&zynq_ocm->res[i]);
+		virt_base = devm_ioremap_resource(&pdev->dev,
+						  &zynq_ocm->res[i]);
+		if (IS_ERR(virt_base))
+			return PTR_ERR(virt_base);
+
+		ret = gen_pool_add_virt(zynq_ocm->pool,
+					(unsigned long)virt_base,
+					zynq_ocm->res[i].start, size, -1);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Gen pool failed\n");
+			return ret;
+		}
+		dev_info(&pdev->dev, "ZYNQ OCM pool: %ld KiB @ 0x%p\n",
+			 size / 1024, virt_base);
+	}
+
+	/* Get OCM config space */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	zynq_ocm->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(zynq_ocm->base))
+		return PTR_ERR(zynq_ocm->base);
+
+	/* Allocate OCM parity IRQ */
+	zynq_ocm->irq = platform_get_irq(pdev, 0);
+	if (zynq_ocm->irq < 0) {
+		dev_err(&pdev->dev, "irq resource not found\n");
+		return zynq_ocm->irq;
+	}
+	ret = devm_request_irq(&pdev->dev, zynq_ocm->irq, zynq_ocm_irq_handler,
+			       0, pdev->name, zynq_ocm);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "request_irq failed\n");
+		return ret;
+	}
+
+	/* Enable parity errors */
+	writel(ZYNQ_OCM_PARITY_ENABLE, zynq_ocm->base + ZYNQ_OCM_PARITY_CTRL);
+
+	platform_set_drvdata(pdev, zynq_ocm);
+
+	return 0;
+}
+
+/**
+ * zynq_ocm_remove - Remove method for the OCM driver
+ * @pdev:       Pointer to the platform_device structure
+ *
+ * This function is called if a device is physically removed from the system or
+ * if the driver module is being unloaded. It frees all resources allocated to
+ * the device.
+ *
+ * returns:     0 on success and error value on failure
+ */
+static int zynq_ocm_remove(struct platform_device *pdev)
+{
+	struct zynq_ocm_dev *zynq_ocm = platform_get_drvdata(pdev);
+
+	if (gen_pool_avail(zynq_ocm->pool) < gen_pool_size(zynq_ocm->pool))
+		dev_dbg(&pdev->dev, "removed while SRAM allocated\n");
+
+	return 0;
+}
+
+static struct of_device_id zynq_ocm_dt_ids[] = {
+	{ .compatible = "xlnx,zynq-ocm-1.0" },
+	{ /* end of table */ }
+};
+
+static struct platform_driver zynq_ocm_driver = {
+	.driver = {
+		.name = "zynq_ocm",
+		.of_match_table = zynq_ocm_dt_ids,
+	},
+	.probe = zynq_ocm_probe,
+	.remove = zynq_ocm_remove,
+};
+
+static int __init zynq_ocm_init(void)
+{
+	return platform_driver_register(&zynq_ocm_driver);
+}
+
+arch_initcall(zynq_ocm_init);
Index: linux-3.12.24-rt38-xilinx/arch/arm/mm/mmu.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/arm/mm/mmu.c	2014-07-20 22:05:50.277065944 +0200
+++ linux-3.12.24-rt38-xilinx/arch/arm/mm/mmu.c	2014-07-20 22:06:34.408337850 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:574 @
 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
 		break;
 	}
-	printk("Memory policy: ECC %sabled, Data cache %s\n",
-		ecc_mask ? "en" : "dis", cp->policy);
+	pr_info("Memory policy: %sData cache %s\n",
+		ecc_mask ? "ECC enabled, " : "", cp->policy);
 
 	for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
 		struct mem_type *t = &mem_types[i];
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/boot/dts/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/boot/dts/Makefile	2014-07-20 22:05:50.320065235 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/boot/dts/Makefile	2014-07-20 22:06:34.427337536 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
 #
-# arch/microblaze/boot/Makefile
-#
 
 obj-y += linked_dtb.o
 
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/include/asm/io.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/include/asm/io.h	2014-07-20 22:05:50.323065185 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/include/asm/io.h	2014-07-20 22:06:34.445337239 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:345 @
 #define iowrite32_rep(p, src, count) \
 	outsl((unsigned long) (p), (src), (count))
 
+#define readb_relaxed	readb
+#define readw_relaxed	readw
+#define readl_relaxed	readl
+
+#define writeb_relaxed	writeb
+#define writew_relaxed	writew
+#define writel_relaxed	writel
+
 #endif /* _ASM_MICROBLAZE_IO_H */
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/include/asm/irq.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/include/asm/irq.h	2014-07-20 22:05:50.322065202 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/include/asm/irq.h	2014-07-20 22:06:34.455337075 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:12 @
 #ifndef _ASM_MICROBLAZE_IRQ_H
 #define _ASM_MICROBLAZE_IRQ_H
 
-#define NR_IRQS		(32 + 1)
+/*
+ * Linux IRQ# is currently offset by one to map to the hardware
+ * irq number. So hardware IRQ0 maps to Linux irq 1.
+ */
+#define NO_IRQ_OFFSET	1
+#define IRQ_OFFSET	NO_IRQ_OFFSET
+/* AXI PCIe MSI support */
+#if defined(CONFIG_XILINX_AXIPCIE) && defined(CONFIG_PCI_MSI)
+#define IRQ_XILINX_MSI_0	128
+#define XILINX_NUM_MSI_IRQS	32
+#define NR_IRQS		(32 + IRQ_XILINX_MSI_0 + IRQ_OFFSET)
+#else
+#define NR_IRQS		(32 + IRQ_OFFSET)
+#endif
+
 #include <asm-generic/irq.h>
 
 struct pt_regs;
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/Kconfig	2014-07-20 22:05:50.312065367 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/Kconfig	2014-07-20 22:06:34.466336893 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:32 @
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS3
 	select CLKSRC_OF
+	select BUILDTIME_EXTABLE_SORT
 
 config SWAP
 	def_bool n
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:86 @
 	bool "MMU support"
 	default n
 
-config NO_MMU
-	bool
-	depends on !MMU
-	default y
-
 comment "Boot options"
 
 config CMDLINE_BOOL
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:249 @
 
 endchoice
 
-config KERNEL_PAD
-	hex "Kernel PAD for unpacking" if ADVANCED_OPTIONS
-	default "0x80000" if MMU
-
 endmenu
 
 source "mm/Kconfig"
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:274 @
 	bool "Xilinx PCI host bridge support"
 	depends on PCI
 
+config XILINX_AXIPCIE
+	bool "Xilinx AXI PCIe host bridge support"
+	depends on PCI
+	select ARCH_SUPPORTS_MSI
+
 source "drivers/pci/Kconfig"
 
 endmenu
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/cpu/cpuinfo.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/cpu/cpuinfo.c	2014-07-20 22:05:50.316065301 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/cpu/cpuinfo.c	2014-07-20 22:06:34.483336613 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:42 @
 	{"8.30.a", 0x17},
 	{"8.40.a", 0x18},
 	{"8.40.b", 0x19},
+	{"8.50.a", 0x1a},
 	{"9.0", 0x1b},
 	{"9.1", 0x1d},
 	{NULL, 0},
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/head.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/head.S	2014-07-20 22:05:50.319065251 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/head.S	2014-07-20 22:06:34.494336431 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:67 @
 #endif
 
 	mts	rmsr, r0
+/* Disable stack protection from bootloader */
+	mts	rslr, r0
+	addi	r8, r0, 0xFFFFFFF
+	mts	rshr, r8
 /*
  * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
  * if the msrclr instruction is not enabled. We use this to detect
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:183 @
 	/* start to do TLB calculation */
 	addik	r12, r0, _end
 	rsub	r12, r3, r12
-	addik	r12, r12, CONFIG_KERNEL_PAD /* that's the pad */
+	addik	r12, r12, CONFIG_LOWMEM_SIZE >> PTE_SHIFT /* that's the pad */
 
 	or r9, r0, r0 /* TLB0 = 0 */
 	or r10, r0, r0 /* TLB1 = 0 */
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/hw_exception_handler.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/hw_exception_handler.S	2014-07-20 22:05:50.318065268 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/hw_exception_handler.S	2014-07-20 22:06:34.634334122 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:150 @
 		or	r3, r0, NUM_TO_REG (regnum);
 
 	/* Shift right instruction depending on available configuration */
-	#if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
-	#define BSRLI(rD, rA, imm)	\
-		bsrli rD, rA, imm
-	#else
-	#define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
+	#if CONFIG_XILINX_MICROBLAZE0_USE_BARREL == 0
 	/* Only the used shift constants defined here - add more if needed */
 	#define BSRLI2(rD, rA)				\
 		srl rD, rA;		/* << 1 */	\
 		srl rD, rD;		/* << 2 */
+	#define BSRLI4(rD, rA)		\
+		BSRLI2(rD, rA);		\
+		BSRLI2(rD, rD)
 	#define BSRLI10(rD, rA)				\
 		srl rD, rA;		/* << 1 */	\
 		srl rD, rD;		/* << 2 */	\
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:172 @
 	#define BSRLI20(rD, rA)		\
 		BSRLI10(rD, rA);	\
 		BSRLI10(rD, rD)
+
+	.macro	bsrli, rD, rA, IMM
+	.if (\IMM) == 2
+		BSRLI2(\rD, \rA)
+	.elseif (\IMM) == 10
+		BSRLI10(\rD, \rA)
+	.elseif (\IMM) == 12
+		BSRLI2(\rD, \rA)
+		BSRLI10(\rD, \rD)
+	.elseif (\IMM) == 14
+		BSRLI4(\rD, \rA)
+		BSRLI10(\rD, \rD)
+	.elseif (\IMM) == 20
+		BSRLI20(\rD, \rA)
+	.elseif (\IMM) == 24
+		BSRLI4(\rD, \rA)
+		BSRLI20(\rD, \rD)
+	.elseif (\IMM) == 28
+		BSRLI4(\rD, \rA)
+		BSRLI4(\rD, \rD)
+		BSRLI20(\rD, \rD)
+	.else
+	.error "BSRLI shift macros \IMM"
+	.endif
+	.endm
 	#endif
+
 #endif /* CONFIG_MMU */
 
 .extern other_exception_handler /* Defined in exception.c */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:221 @
  *      -                            W   S   REG   EXC
  *
  *
- * STACK FRAME STRUCTURE (for NO_MMU)
- * ---------------------------------
+ * STACK FRAME STRUCTURE (for CONFIG_MMU=n)
+ * ----------------------------------------
  *
  *      +-------------+         + 0
  *      |     MSR     |
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:632 @
 	ex4:
 		tophys(r4,r4)
 		/* Create L1 (pgdir/pmd) address */
-		BSRLI(r5,r3, PGDIR_SHIFT - 2)
+		bsrli	r5, r3, PGDIR_SHIFT - 2
 		andi	r5, r5, PAGE_SIZE - 4
 /* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
 		or	r4, r4, r5
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:641 @
 		beqi	r5, ex2			/* Bail if no table */
 
 		tophys(r5,r5)
-		BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+		bsrli	r6, r3, PTE_SHIFT /* Compute PTE address */
 		andi	r6, r6, PAGE_SIZE - 4
 		or	r5, r5, r6
 		lwi	r4, r5, 0		/* Get Linux PTE */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:733 @
 	ex6:
 		tophys(r4,r4)
 		/* Create L1 (pgdir/pmd) address */
-		BSRLI(r5,r3, PGDIR_SHIFT - 2)
+		bsrli	r5, r3, PGDIR_SHIFT - 2
 		andi	r5, r5, PAGE_SIZE - 4
 /* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
 		or	r4, r4, r5
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:742 @
 		beqi	r5, ex7			/* Bail if no table */
 
 		tophys(r5,r5)
-		BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+		bsrli	r6, r3, PTE_SHIFT /* Compute PTE address */
 		andi	r6, r6, PAGE_SIZE - 4
 		or	r5, r5, r6
 		lwi	r4, r5, 0		/* Get Linux PTE */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:804 @
 	ex9:
 		tophys(r4,r4)
 		/* Create L1 (pgdir/pmd) address */
-		BSRLI(r5,r3, PGDIR_SHIFT - 2)
+		bsrli	r5, r3, PGDIR_SHIFT - 2
 		andi	r5, r5, PAGE_SIZE - 4
 /* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
 		or	r4, r4, r5
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:813 @
 		beqi	r5, ex10		/* Bail if no table */
 
 		tophys(r5,r5)
-		BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+		bsrli	r6, r3, PTE_SHIFT /* Compute PTE address */
 		andi	r6, r6, PAGE_SIZE - 4
 		or	r5, r5, r6
 		lwi	r4, r5, 0		/* Get Linux PTE */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:950 @
 .ent _unaligned_data_exception
 _unaligned_data_exception:
 	andi	r8, r3, 0x3E0;	/* Mask and extract the register operand */
-	BSRLI(r8,r8,2);		/* r8 >> 2 = register operand * 8 */
+	bsrli   r8, r8, 2;		/* r8 >> 2 = register operand * 8 */
 	andi	r6, r3, 0x400;	/* Extract ESR[S] */
 	bneid	r6, ex_sw_vm;
 	andi	r6, r3, 0x800;	/* Extract ESR[W] - delay slot */
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/setup.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/setup.c	2014-07-20 22:05:50.314065334 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/setup.c	2014-07-20 22:06:34.645333941 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:177 @
 #else
 	if (!msr) {
 		pr_info("!!!Your kernel not setup MSR instruction but ");
-		pr_cont"CPU have it %x\n", msr);
+		pr_cont("CPU have it %x\n", msr);
 	}
 #endif
 
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/syscall_table.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/syscall_table.S	2014-07-20 22:05:50.317065284 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/syscall_table.S	2014-07-20 22:06:34.656333759 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:195 @
 	.long sys_ni_syscall		/* reserved for streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap_pgoff		/* mmap2 */
+	.long sys_mmap2
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64		/* 195 */
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/sys_microblaze.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/sys_microblaze.c	2014-07-20 22:05:50.313065351 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/sys_microblaze.c	2014-07-20 22:06:34.665333611 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:36 @
 #include <linux/slab.h>
 #include <asm/syscalls.h>
 
-asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, off_t pgoff)
+SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+		unsigned long, prot, unsigned long, flags, unsigned long, fd,
+		off_t, pgoff)
 {
 	if (pgoff & ~PAGE_MASK)
 		return -EINVAL;
 
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
 }
+
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
+		unsigned long, prot, unsigned long, flags, unsigned long, fd,
+		unsigned long, pgoff)
+{
+	if (pgoff & (~PAGE_MASK >> 12))
+		return -EINVAL;
+
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
+}
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/timer.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/kernel/timer.c	2014-07-20 22:05:50.315065317 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/kernel/timer.c	2014-07-20 22:06:34.676333429 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:151 @
 
 static struct irqaction timer_irqaction = {
 	.handler = timer_interrupt,
-	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.flags = IRQF_TIMER,
 	.name = "timer",
 	.dev_id = &clockevent_xilinx_timer,
 };
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/pci/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/pci/Makefile	2014-07-20 22:05:50.310065400 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/pci/Makefile	2014-07-20 22:06:34.689333215 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:7 @
 
 obj-$(CONFIG_PCI)		+= pci-common.o indirect_pci.o iomap.o
 obj-$(CONFIG_PCI_XILINX)	+= xilinx_pci.o
+obj-$(CONFIG_XILINX_AXIPCIE)	+= xilinx_axipcie.o
+obj-$(CONFIG_PCI_MSI)		+= msi.o
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/pci/msi.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/pci/msi.c	2014-07-20 22:06:34.697333083 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PCIe IP hardware MSI initialisation
+ *
+ * Copyright (c) 2010-2011 Xilinx, Inc.
+ *
+ * This program has adopted some work from PCI/PCIE support for AMCC
+ * PowerPC boards written by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * 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/pci.h>
+#include <linux/msi.h>
+#include <asm/irq.h>
+#include "xilinx_axipcie.h"
+
+static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS);
+
+/*
+ * Dynamic irq allocate and deallocation
+ */
+
+/**
+* create_irq- Dynamic irq allocate
+* void
+*
+* @return: Interrupt number allocated/ error
+*
+* @note: None
+*/
+int create_irq(void)
+{
+	int irq, pos;
+again:
+	pos = find_first_zero_bit(msi_irq_in_use, XILINX_NUM_MSI_IRQS);
+
+	irq = IRQ_XILINX_MSI_0 + pos;
+	if (irq > NR_IRQS)
+		return -ENOSPC;
+
+	/* test_and_set_bit operates on 32-bits at a time */
+	if (test_and_set_bit(pos, msi_irq_in_use))
+		goto again;
+
+	dynamic_irq_init(irq);
+
+	return irq;
+}
+
+/**
+* destroy_irq- Dynamic irq de-allocate
+* @irq: Interrupt number to de-allocate
+*
+* @return: None
+*
+* @note: None
+*/
+void destroy_irq(unsigned int irq)
+{
+	int pos = irq - IRQ_XILINX_MSI_0;
+
+	dynamic_irq_cleanup(irq);
+
+	clear_bit(pos, msi_irq_in_use);
+}
+
+/**
+* arch_teardown_msi_irq-Teardown the Interrupt
+* @irq: Interrupt number to teardown
+*
+* @return: None
+*
+* @note: This function  is called when pci_disable_msi is called
+*/
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	destroy_irq(irq);
+}
+
+/**
+* xilinx_msi_nop-No operation handler
+* @irq: Interrupt number
+*
+* @return: None
+*
+* @note: None
+*/
+static void xilinx_msi_nop(struct irq_data *d)
+{
+	return;
+}
+
+static struct irq_chip xilinx_msi_chip = {
+		.name = "PCI-MSI",
+		.irq_ack = xilinx_msi_nop,
+		.irq_enable = unmask_msi_irq,
+		.irq_disable = mask_msi_irq,
+		.irq_mask = mask_msi_irq,
+		.irq_unmask = unmask_msi_irq,
+};
+
+/**
+* arch_setup_msi_irq-Setup MSI interrupt
+* @pdev: Pointer to current pci device structure
+* @desc: Pointer to MSI description structure
+*
+* @return: Error/ no-error
+*
+* @note: This function  is called when pci_enable_msi is called
+*/
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+	int irq = create_irq();
+	struct msi_msg msg;
+
+	if (irq < 0)
+		return irq;
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_hi = 0x00000000;
+	msg.address_lo = msg_addr;
+	msg.data = irq;
+
+	DBG("irq %d addr_hi %08x low %08x data %08x\n",
+			irq, msg.address_hi, msg.address_lo, msg.data);
+
+	write_msi_msg(irq, &msg);
+
+	irq_set_chip_and_handler(irq, &xilinx_msi_chip, handle_simple_irq);
+
+	return 0;
+}
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/pci/pci-common.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/microblaze/pci/pci-common.c	2014-07-20 22:05:50.311065383 +0200
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/pci/pci-common.c	2014-07-20 22:06:34.712332835 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:190 @
 	return device_create_file(&pdev->dev, &dev_attr_devspec);
 }
 
-void pcibios_set_master(struct pci_dev *dev)
+void __weak pcibios_set_master(struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
 }
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/pci/xilinx_axipcie.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/pci/xilinx_axipcie.c	2014-07-20 22:06:34.726332604 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI PCIe IP hardware initialation, setup and
+ * configuration spaces access file.
+ *
+ * Copyright (c) 2010-2011 Xilinx, Inc.
+ *
+ * This program has adopted some work from PCI/PCIE support for AMCC
+ * PowerPC boards written by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/compiler.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/pci-bridge.h>
+#include <linux/interrupt.h>
+#include "xilinx_axipcie.h"
+
+static struct xilinx_axipcie_port *xilinx_axipcie_ports;
+static unsigned int xilinx_axipcie_port_count;
+
+static const struct of_device_id xilinx_axipcie_match[] = {
+	{ .compatible = "xlnx,axi-pcie-1.05.a" ,},
+	{}
+};
+
+static int last_bus_on_record;
+
+#ifdef CONFIG_PCI_MSI
+unsigned long msg_addr;
+#endif
+
+/* Macros */
+#define is_link_up(base_address)	\
+	((in_le32(((u8 *)base_address) + AXIPCIE_REG_PSCR) &	\
+	AXIPCIE_REG_PSCR_LNKUP) ? 1 : 0)
+
+#define bridge_enable(base_address)	\
+	out_le32((((u8 *)base_address) + AXIPCIE_REG_RPSC),	\
+		(in_le32(((u8 *)base_address) + AXIPCIE_REG_RPSC) |	\
+		AXIPCIE_REG_RPSC_BEN))
+
+/**
+ * xilinx_get_axipcie_ip_config_info - Read info from device tree
+ * @dev: A pointer to device node to read from
+ * @ip_config_info: A pointer to xilinx_pcie_node struct to write device tree
+ *			info into to.
+ *
+ * @return: Error / no error
+ *
+ * @note: Read related info from device tree
+ */
+int xilinx_get_axipcie_ip_config_info(struct device_node *dev,
+		struct xilinx_axipcie_node *ip_config_info)
+{
+	u32 *ip_setup_parameter;
+	u32 rlen;
+
+	ip_config_info->number_of_instances = 1;
+
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+						"xlnx,device-num", &rlen);
+	ip_config_info->device_id = 0;
+
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+						"xlnx,include-rc", &rlen);
+
+	if (ip_setup_parameter)
+		ip_config_info->device_type = be32_to_cpup(ip_setup_parameter);
+	else
+		return -ENODEV;
+
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+						"reg", &rlen);
+
+	if (ip_setup_parameter) {
+		ip_config_info->reg_base =
+					be32_to_cpup(ip_setup_parameter);
+		ip_config_info->reg_len =
+					be32_to_cpup(ip_setup_parameter + 1);
+	} else
+		return -ENODEV;
+
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+						"xlnx,pciebar-num", &rlen);
+
+	if (ip_setup_parameter)
+		ip_config_info->bars_num = be32_to_cpup(ip_setup_parameter);
+	else
+		return -ENODEV;
+
+	ip_config_info->irq_num = irq_of_parse_and_map(dev, 0);
+
+	/* Get address translation parameters */
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+					"xlnx,pciebar2axibar-0", &rlen);
+
+	if (ip_setup_parameter)
+		ip_config_info->pcie2axibar_0 =
+					be32_to_cpup(ip_setup_parameter);
+	else
+		return -ENODEV;
+
+	ip_setup_parameter = (u32 *) of_get_property(dev,
+					"xlnx,pciebar2axibar-1", &rlen);
+
+	if (ip_setup_parameter)
+		ip_config_info->pcie2axibar_1 =
+					be32_to_cpup(ip_setup_parameter);
+	else
+		ip_config_info->pcie2axibar_1 = 0x0;
+
+	return 0;
+}
+
+/**
+ * fixup_xilinx_axipcie_bridge
+ * @dev: A pointer to device pcie device struct
+ *
+ * @return: None
+ *
+ * @note: A fix up routine to be called by kernel during enumeration
+ */
+static void fixup_xilinx_axipcie_bridge(struct pci_dev *dev)
+{
+	struct pci_controller *hose;
+	int i;
+
+	if (dev->devfn != 0 || dev->bus->self != NULL)
+		return;
+
+	hose = pci_bus_to_host(dev->bus);
+	if (hose == NULL)
+		return;
+
+	if (!of_match_node(xilinx_axipcie_match, hose->dn))
+		return;
+
+	/* Hide the PCI host BARs from the kernel as their content doesn't
+	 * fit well in the resource management
+	 */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		dev->resource[i].start = dev->resource[i].end = 0;
+		dev->resource[i].flags = 0;
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_xilinx_axipcie_bridge);
+
+/**
+ * xilinx_init_axipcie_port - Initialize hardware
+ * @port: A pointer to a pcie port that needs to be initialized
+ *
+ * @return: Error / no error
+ *
+ * @note: None
+ */
+static int xilinx_init_axipcie_port(struct xilinx_axipcie_port *port)
+{
+	void __iomem *base_addr_remap = NULL;
+
+	/* base_addr_remap = ioremap(port->reg_base, PORT_REG_SIZE); */
+	base_addr_remap = ioremap(port->reg_base, port->reg_len);
+	if (!base_addr_remap)
+		return -ENOMEM;
+
+	port->base_addr_remap = base_addr_remap;
+
+	/* make sure it is root port before touching header */
+	if (port->type) {
+
+		port->header_remap = base_addr_remap;
+		out_le32((((u8 *)port->base_addr_remap) + PCIE_CFG_CMD),
+							BUS_MASTER_ENABLE);
+	}
+
+#ifdef CONFIG_PCI_MSI
+	msg_addr = port->reg_base & ~0xFFF;	/* 4KB aligned */
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_MSIBASE1),
+							0x00000000);
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_MSIBASE2),
+							msg_addr);
+#endif
+
+	port->link = is_link_up(port->base_addr_remap);
+	if (!port->link)
+		pr_info("LINK IS DOWN\n");
+	else
+		pr_info("LINK IS UP\n");
+
+	/* Disable all interrupts*/
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_IMR),
+					~AXIPCIE_REG_IDR_MASKALL);
+	/* Clear pending interrupts*/
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_IDR),
+		in_le32(((u8 *)port->base_addr_remap) + AXIPCIE_REG_IDR) &
+					AXIPCIE_REG_IMR_MASKALL);
+	/* Enable all interrupts*/
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_IMR),
+					AXIPCIE_REG_IMR_MASKALL);
+
+	/* Bridge enable must be done after enumeration,
+		but there is no callback defined */
+	bridge_enable(port->base_addr_remap);
+
+	return 0;
+}
+
+/**
+ * xilinx_axipcie_verify_config
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: device/function
+ *
+ * @return: Error / no error
+ *
+ * @note: Make sure we can handle this configuration call on our
+ *        device.
+ */
+static int xilinx_axipcie_verify_config(struct xilinx_axipcie_port *port,
+				struct pci_bus *bus,
+				unsigned int devfn)
+{
+	static int message;
+
+	/* Endpoint can not generate upstream(remote) config cycles */
+	if ((!port->type) && bus->number != port->hose->first_busno)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Check we are within the mapped range */
+	if (bus->number > port->hose->last_busno) {
+		if (!message) {
+			printk(KERN_WARNING "Warning! Probing bus %u"
+			       " out of range !\n", bus->number);
+			message++;
+		}
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/* The other side of the RC has only one device as well */
+	if (bus->number == (port->hose->first_busno + 1) &&
+	    PCI_SLOT(devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Check if we have a link */
+	if (!port->link)
+		port->link = is_link_up(port->base_addr_remap);
+
+	if ((bus->number != port->hose->first_busno) && !port->link)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return 0;
+}
+
+/**
+ * xilinx_axipcie_get_config_base
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ *
+ * @return: Base address of the configuration space needed to be
+ *          accessed.
+ *
+ * @note: Get the base address of the configuration space for this
+ *        pcie device.
+ */
+static void __iomem *xilinx_axipcie_get_config_base(
+					struct xilinx_axipcie_port *port,
+					struct pci_bus *bus,
+					unsigned int devfn)
+{
+	int relbus;
+
+	relbus = ((bus->number << BUS_LOC_SHIFT) | (devfn << DEV_LOC_SHIFT));
+
+	if (relbus == 0)
+		return (void __iomem *)port->header_remap;
+
+	return (void __iomem *)port->hose->cfg_data + relbus;
+}
+
+/**
+ * xilinx_axipcie_read_config - Read config reg.
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ * @offset: Offset from base
+ * @len: Byte/word/dword
+ * @val: A pointer to value read
+ *
+ * @return: Error / no error
+ *
+ *
+ * @note: Read byte/word/dword from pcie device config reg.
+ */
+static int xilinx_axipcie_read_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int offset,
+				int len,
+				u32 *val)
+{
+	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+	struct xilinx_axipcie_port *port =
+				&xilinx_axipcie_ports[hose->indirect_type];
+	void __iomem *addr;
+
+	if (xilinx_axipcie_verify_config(port, bus, devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr = xilinx_axipcie_get_config_base(port, bus, devfn);
+
+	if ((bus->number == 0) && devfn > 0) {
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	switch (len) {
+	case 1:
+		*val = in_8((u8 *)(addr + offset));
+		break;
+	case 2:
+		*val = in_le16((u16 *)(addr + offset));
+		break;
+	default:
+		*val = in_le32((u32 *)(addr + offset));
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/**
+ * xilinx_axipcie_write_config - Write config reg.
+ * @port: A pointer to a pcie port that needs to be handled
+ * @bus: Bus structure of current bus
+ * @devfun: Device/function
+ * @offset: Offset from base
+ * @len: Byte/word/dword
+ * @val: Value to be written to device
+ *
+ * @return: Error / no error
+ *
+ *
+ * @note: Write byte/word/dword to pcie device config reg.
+ */
+static int xilinx_axipcie_write_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int offset,
+				int len,
+				u32 val)
+{
+	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+	struct xilinx_axipcie_port *port =
+				&xilinx_axipcie_ports[hose->indirect_type];
+	void __iomem  *addr;
+
+	if (xilinx_axipcie_verify_config(port, bus, devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr = xilinx_axipcie_get_config_base(port, bus, devfn);
+
+	if ((bus->number == 0) && devfn > 0)
+		return PCIBIOS_SUCCESSFUL;
+
+	switch (len) {
+	case 1:
+		out_8((u8 *)(addr + offset), val);
+		break;
+	case 2:
+		out_le16((u16 *)(addr + offset), val);
+		break;
+	default:
+		out_le32((u32 *)(addr + offset), val);
+		break;
+	}
+
+	wmb();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops xlnx_pcie_pci_ops = {
+	.read  = xilinx_axipcie_read_config,
+	.write = xilinx_axipcie_write_config,
+};
+
+/**
+ * xilinx_set_bridge_resource - Setup base & limit registers of config space.
+ * @port: Pointer to a root port
+ *
+ * @return: None
+ *
+ * @note: None
+ */
+void xilinx_set_bridge_resource(struct xilinx_axipcie_port *port)
+{
+	const u32 *ranges;
+	int rlen;
+	/* The address cells of PCIe parent node */
+	int pna = of_n_addr_cells(port->node);
+	int np = pna + 5;
+	u32 pci_space;
+	unsigned long long pci_addr, size;
+	struct device_node *dev;
+	u32 val = 0;
+
+	dev = port->node;
+
+	/* Get ranges property */
+	ranges = of_get_property(dev, "ranges", &rlen);
+	if (ranges == NULL) {
+		printk(KERN_DEBUG "%s:Didnot get any ranges property\n",
+								__func__);
+		return;
+	}
+
+	while ((rlen -= np * 4) >= 0) {
+		pci_space = be32_to_cpup(ranges);
+		pci_addr = of_read_number(ranges + 1, 2);
+		size = of_read_number(ranges + pna + 3, 2);
+
+		printk(KERN_INFO "%s:pci_space: 0x%08x pci_addr:0x%016llx size:"
+			"0x%016llx\n", __func__, pci_space, pci_addr, size);
+
+		ranges += np;
+
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* PCI IO space */
+			printk(KERN_INFO "%s:Setting resource in IO Space\n",
+								__func__);
+
+			val = ((pci_addr >> 8) & 0x000000F0) |
+					((pci_addr + size - 1) & 0x0000F000);
+
+			out_le32((((u8 *)port->header_remap) + PCIE_CFG_IO),
+									val);
+
+			val = ((pci_addr >> 16) & 0x0000FFFF) |
+					((pci_addr + size - 1) & 0xFFFF0000);
+
+			out_le32((((u8 *)port->header_remap) +
+						PCIE_CFG_IO_UPPER), val);
+
+			break;
+		case 2:		/* PCI Memory space */
+			printk(KERN_INFO "%s:Setting resource in Memory Space\n",
+								__func__);
+			val = ((pci_addr >> 16) & 0xfff0) |
+					((pci_addr + size - 1) & 0xfff00000);
+
+			/* out_le32((((u8 *)port->header_remap) + PCIE_CFG_MEM),
+								val); */
+
+			break;
+		case 3:		/* PCI 64 bits Memory space */
+			printk(KERN_INFO "%s:Setting resource in Prefetchable"
+					" Memory Space\n", __func__);
+
+			val = ((pci_addr >> 16) & 0xfff0) |
+					((pci_addr + size - 1) & 0xfff00000);
+
+			out_le32((((u8 *)port->header_remap) +
+						PCIE_CFG_PREF_MEM), val);
+
+			val = ((pci_addr >> 32) & 0xffffffff);
+			out_le32((((u8 *)port->header_remap) +
+					PCIE_CFG_PREF_BASE_UPPER), val);
+
+			val = (((pci_addr + size - 1) >> 32) & 0xffffffff);
+			out_le32((((u8 *)port->header_remap) +
+					PCIE_CFG_PREF_LIMIT_UPPER), val);
+
+			break;
+		}
+	}
+
+	/* EP initiated memory access */
+	out_le32((((u8 *)port->header_remap) + PCIE_CFG_AD1),
+						port->pcie2axibar_0);
+	out_le32((((u8 *)port->header_remap) + PCIE_CFG_AD2),
+						port->pcie2axibar_1);
+}
+
+/**
+ * xilinx_setup_axipcie_root_port - Setup root port
+ * @port: Pointer to a root port
+ *
+ * @return: Error / no error
+ *
+ * @note: This is a root port so set it up accordingly
+ */
+static int __init xilinx_setup_axipcie_root_port(
+					struct xilinx_axipcie_port *port)
+{
+	struct pci_controller *hose = NULL;
+	u32 val = 0;
+
+	/* Allocate the host controller data structure */
+	hose = pcibios_alloc_controller(port->node);
+	if (!hose) {
+		iounmap(port->base_addr_remap);
+		iounmap(port->header_remap);
+		return -ENOMEM;
+	}
+
+	hose->indirect_type = port->index;
+
+	/* Get bus range */
+	hose->first_busno = last_bus_on_record;
+
+	val = in_le32(((u8 *)port->header_remap) + AXIPCIE_REG_BIR);
+	val = (val >> 16) & 0x7;
+	hose->last_busno = (((port->reg_base - port->reg_len - 1) >> 20)
+							& 0xFF) & val;
+
+	/* Write primary, secondary and subordinate bus numbers */
+	val = hose->first_busno;
+	val |= ((hose->first_busno + 1) << 8);
+	val |= (hose->last_busno << 16);
+
+	out_le32((((u8 *)port->header_remap) + PCIE_CFG_BUS), val);
+	last_bus_on_record = hose->last_busno + 1;
+
+	port->ecam_remap = port->header_remap;
+
+	/* Setup config space */
+	hose->cfg_addr = port->header_remap;
+	hose->cfg_data = port->ecam_remap;
+	hose->ops = &xlnx_pcie_pci_ops;
+	port->hose = hose;
+
+	xilinx_set_bridge_resource(port);
+	/* Parse outbound mapping resources */
+	pci_process_bridge_OF_ranges(hose, port->node, PRIMARY_BUS);
+
+	return 0;
+}
+
+/**
+ * Interrupt handler
+ */
+static irqreturn_t xilinx_axipcie_intr_handler(int irq, void *data)
+{
+	struct xilinx_axipcie_port *port = (struct xilinx_axipcie_port *)data;
+	u32 val = 0, mask = 0;
+	u32 status;
+	u32 msi_addr = 0;
+	u32 msi_data = 0;
+
+	/* Read interrupt decode and mask registers */
+	val = in_le32(((u8 *)port->header_remap) + AXIPCIE_REG_IDR);
+	mask = in_le32(((u8 *)port->header_remap) + AXIPCIE_REG_IMR);
+
+	status = val & mask;
+	if (!status)
+		return IRQ_NONE;
+
+	if (status & AXIPCIE_INTR_LINK_DOWN)
+		printk(KERN_ERR "Link Down\n");
+
+	if (status & AXIPCIE_INTR_ECRC_ERR)
+		printk(KERN_WARNING "ECRC failed\n");
+
+	if (status & AXIPCIE_INTR_STR_ERR)
+		printk(KERN_WARNING "Streaming error\n");
+
+	if (status & AXIPCIE_INTR_HOT_RESET)
+		printk(KERN_INFO "Hot reset\n");
+
+	if (status & AXIPCIE_INTR_CFG_TIMEOUT)
+		printk(KERN_WARNING "ECAM access timeout\n");
+
+	if (status & AXIPCIE_INTR_CORRECTABLE) {
+		printk(KERN_WARNING "Correctable error message\n");
+		val = in_le32(((u8 *)port->header_remap) +
+				AXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			out_le32((((u8 *)port->base_addr_remap) +
+				AXIPCIE_REG_RPEFR), 0xFFFFFFFF);
+			DBG("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & AXIPCIE_INTR_NONFATAL) {
+		printk(KERN_WARNING "Non fatal error message\n");
+		val = in_le32(((u8 *)port->header_remap) +
+				AXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			out_le32((((u8 *)port->base_addr_remap) +
+				AXIPCIE_REG_RPEFR), 0xFFFFFFFF);
+			DBG("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & AXIPCIE_INTR_FATAL) {
+		printk(KERN_WARNING "Fatal error message\n");
+		val = in_le32(((u8 *)port->header_remap) +
+				AXIPCIE_REG_RPEFR);
+		if (val & (1 << 18)) {
+			out_le32((((u8 *)port->base_addr_remap) +
+				AXIPCIE_REG_RPEFR), 0xFFFFFFFF);
+			DBG("Requester ID %d\n", (val & 0xffff));
+		}
+	}
+
+	if (status & AXIPCIE_INTR_INTX) {
+		/* INTx interrupt received */
+		val = in_le32(((u8 *)port->header_remap) + AXIPCIE_REG_RPIFR1);
+
+		/* Check whether interrupt valid */
+		if (!(val & (1 << 31))) {
+			printk(KERN_WARNING "RP Intr FIFO1 read error\n");
+			return IRQ_HANDLED;
+		}
+
+		/* Check MSI or INTX */
+		if (!(val & (1 << 30))) {
+			if (val & (1 << 29))
+				DBG("INTx assert\n");
+			else
+				DBG("INTx deassert\n");
+		}
+
+		/* Clear interrupt FIFO register 1 */
+		out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_RPIFR1),
+								0xFFFFFFFF);
+	}
+
+	if (status & AXIPCIE_INTR_MSI) {
+		/* MSI Interrupt */
+		val = in_le32(((u8 *)port->header_remap) + AXIPCIE_REG_RPIFR1);
+
+		if (!(val & (1 << 31))) {
+			printk(KERN_WARNING "RP Intr FIFO1 read error\n");
+			return IRQ_HANDLED;
+		}
+
+		if (val & (1 << 30)) {
+			msi_addr = (val >> 16) & 0x7FF;
+			msi_data = in_le32(((u8 *)port->header_remap) +
+						AXIPCIE_REG_RPIFR2) & 0xFFFF;
+			DBG("%s: msi_addr %08x msi_data %08x\n",
+					__func__, msi_addr, msi_data);
+		}
+
+		/* Clear interrupt FIFO register 1 */
+		out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_RPIFR1),
+								0xFFFFFFFF);
+#ifdef CONFIG_PCI_MSI
+		/* Handle MSI Interrupt */
+		if (msi_data >= IRQ_XILINX_MSI_0)
+			generic_handle_irq(msi_data);
+#endif
+	}
+
+	if (status & AXIPCIE_INTR_SLV_UNSUPP)
+		printk(KERN_WARNING "Slave unsupported request\n");
+
+	if (status & AXIPCIE_INTR_SLV_UNEXP)
+		printk(KERN_WARNING "Slave unexpected completion\n");
+
+	if (status & AXIPCIE_INTR_SLV_COMPL)
+		printk(KERN_WARNING "Slave completion timeout\n");
+
+	if (status & AXIPCIE_INTR_SLV_ERRP)
+		printk(KERN_WARNING "Slave Error Poison\n");
+
+	if (status & AXIPCIE_INTR_SLV_CMPABT)
+		printk(KERN_WARNING "Slave Completer Abort\n");
+
+	if (status & AXIPCIE_INTR_SLV_ILLBUR)
+		printk(KERN_WARNING "Slave Illegal Burst\n");
+
+	if (status & AXIPCIE_INTR_MST_DECERR)
+		printk(KERN_WARNING "Master decode error\n");
+
+	if (status & AXIPCIE_INTR_MST_SLVERR)
+		printk(KERN_WARNING "Master slave error\n");
+
+	if (status & AXIPCIE_INTR_MST_ERRP)
+		printk(KERN_WARNING "Master error poison\n");
+
+	/* Clear the Interrupt Decode register */
+	out_le32((((u8 *)port->base_addr_remap) + AXIPCIE_REG_IDR), status);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xilinx_probe_axipcie_node
+ * @np: Pointer to device node to be probed
+ *
+ * @return: Error / no error
+ *
+ * @note: Find out how this pcie node is configured
+ */
+static int __init xilinx_probe_axipcie_node(struct device_node *np)
+{
+	struct xilinx_axipcie_port *port;
+	struct xilinx_axipcie_node ip_setup_info;
+	int portno;
+	int error;
+	int ret;
+
+	printk(KERN_INFO "Probing Xilinx PCI Express root complex device\n");
+
+	error = xilinx_get_axipcie_ip_config_info(np , &ip_setup_info);
+
+	if (error) {
+		printk(KERN_INFO "Error while getting pcie config info\n");
+		return error;
+	}
+
+	if (!xilinx_axipcie_port_count) {
+		xilinx_axipcie_port_count = ip_setup_info.number_of_instances;
+
+		if (xilinx_axipcie_port_count) {
+
+			xilinx_axipcie_ports =
+					kzalloc(xilinx_axipcie_port_count *
+			sizeof(struct xilinx_axipcie_port), GFP_KERNEL);
+
+			if (!xilinx_axipcie_ports) {
+				printk(KERN_INFO "Memory allocation failed\n");
+				return -ENOMEM;
+			}
+		} else /* not suppose to be here
+			* when we don't have pcie ports */
+			return -ENODEV;
+	}
+
+	/* Initialize this port vital info. struct */
+	portno = ip_setup_info.device_id;
+
+	port = &xilinx_axipcie_ports[portno];
+	port->node = of_node_get(np);
+	port->index = portno;
+	port->type = ip_setup_info.device_type;
+	port->reg_base = ip_setup_info.reg_base;
+	port->reg_len = ip_setup_info.reg_len;
+	port->bars_num  = ip_setup_info.bars_num;
+	port->irq_num	= ip_setup_info.irq_num;
+	port->header_addr = port->reg_base + AXIPCIE_LOCAL_CNFG_BASE;
+	port->pcie2axibar_0 = ip_setup_info.pcie2axibar_0;
+	port->pcie2axibar_1 = ip_setup_info.pcie2axibar_1;
+
+	irq_set_chip_data(port->irq_num, port);
+
+	/* initialize hardware */
+	error = xilinx_init_axipcie_port(port);
+	if (error) {
+		printk(KERN_INFO "Error while initialize pcie port\n");
+		return error;
+	}
+
+	/* Register interrupt handler */
+	ret = request_irq(port->irq_num, xilinx_axipcie_intr_handler,
+						IRQF_SHARED, "xaxipcie", port);
+	if (ret) {
+		printk(KERN_ERR "%s: Could not allocate interrupt\n", __func__);
+		return ret;
+	}
+
+	/* Setup hose data structure */
+	if (port->type) {
+		error = xilinx_setup_axipcie_root_port(port);
+		if (error) {
+			printk(KERN_INFO "Error while initialize "
+							"pcie root port\n");
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * pcibios_set_master - Architecture specific function
+ * @dev: A pointer to device pcie device struct
+ *
+ * @return: Error / no error
+ * @note: Enables Bridge Enable bit during the rescan process
+ */
+void pcibios_set_master(struct pci_dev *dev)
+{
+	struct pci_controller *hose =
+			(struct pci_controller *) dev->bus->sysdata;
+	struct xilinx_axipcie_port *port =
+			&xilinx_axipcie_ports[hose->indirect_type];
+
+	if (port->link)
+		bridge_enable(port->base_addr_remap);
+}
+
+/**
+ * xilinx_find_axipcie_nodes - Entry function
+ * void
+ *
+ * @return: Error / no error
+ * @note: Find pcie nodes in device tree
+ */
+static int __init xilinx_find_axipcie_nodes(void)
+{
+	struct device_node *np;
+	const struct of_device_id *matches = xilinx_axipcie_match;
+	int error = 0;
+
+	printk(KERN_INFO "Initialising Xilinx PCI Express root"
+						" complex device\n");
+	for_each_matching_node(np, matches) {
+		error = xilinx_probe_axipcie_node(np);
+		if (error)
+			return error;
+	}
+	return 0;
+}
+
+arch_initcall(xilinx_find_axipcie_nodes);
Index: linux-3.12.24-rt38-xilinx/arch/microblaze/pci/xilinx_axipcie.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/microblaze/pci/xilinx_axipcie.h	2014-07-20 22:06:34.734332472 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Header file for Xilinx AXI PCIe IP driver.
+ *
+ * Copyright (c) 2010-2011 Xilinx, Inc.
+ *
+ * This program has adopted some work from PCI/PCIE support for AMCC
+ * PowerPC boards written by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef XILINX_AXIPCIE_H_
+#define XILINX_AXIPCIE_H_
+
+/* Register definitions */
+#define PCIE_CFG_CMD			0x00000004
+#define PCIE_CFG_CLS			0x00000008
+#define PCIE_CFG_HDR			0x0000000C
+#define PCIE_CFG_AD1			0x00000010
+#define PCIE_CFG_AD2			0x00000014
+#define PCIE_CFG_BUS			0x00000018
+#define PCIE_CFG_IO			0x0000001C
+#define PCIE_CFG_MEM			0x00000020
+#define PCIE_CFG_PREF_MEM		0x00000024
+#define PCIE_CFG_PREF_BASE_UPPER	0x00000028
+#define PCIE_CFG_PREF_LIMIT_UPPER	0x0000002c
+#define PCIE_CFG_IO_UPPER		0x00000030
+
+#define AXIPCIE_REG_VSECC		0x00000128
+#define AXIPCIE_REG_VSECH		0x0000012c
+#define AXIPCIE_REG_BIR			0x00000130
+#define AXIPCIE_REG_BSCR		0x00000134
+#define AXIPCIE_REG_IDR			0x00000138
+#define AXIPCIE_REG_IMR			0x0000013c
+#define AXIPCIE_REG_BLR			0x00000140
+#define AXIPCIE_REG_PSCR		0x00000144
+#define AXIPCIE_REG_RPSC		0x00000148
+#define AXIPCIE_REG_MSIBASE1		0x0000014c
+#define AXIPCIE_REG_MSIBASE2		0x00000150
+#define AXIPCIE_REG_RPEFR		0x00000154
+#define AXIPCIE_REG_RPIFR1		0x00000158
+#define AXIPCIE_REG_RPIFR2		0x0000015c
+#define AXIPCIE_REG_VSECC2		0x00000200
+#define AXIPCIE_REG_VSECH2		0x00000204
+
+/* Interrupt register defines */
+#define AXIPCIE_INTR_LINK_DOWN		(1 << 0)
+#define AXIPCIE_INTR_ECRC_ERR		(1 << 1)
+#define AXIPCIE_INTR_STR_ERR		(1 << 2)
+#define AXIPCIE_INTR_HOT_RESET		(1 << 3)
+#define AXIPCIE_INTR_CFG_COMPL		(7 << 5)
+#define AXIPCIE_INTR_CFG_TIMEOUT	(1 << 8)
+#define AXIPCIE_INTR_CORRECTABLE	(1 << 9)
+#define AXIPCIE_INTR_NONFATAL		(1 << 10)
+#define AXIPCIE_INTR_FATAL		(1 << 11)
+#define AXIPCIE_INTR_INTX		(1 << 16)
+#define AXIPCIE_INTR_MSI		(1 << 17)
+#define AXIPCIE_INTR_SLV_UNSUPP		(1 << 20)
+#define AXIPCIE_INTR_SLV_UNEXP		(1 << 21)
+#define AXIPCIE_INTR_SLV_COMPL		(1 << 22)
+#define AXIPCIE_INTR_SLV_ERRP		(1 << 23)
+#define AXIPCIE_INTR_SLV_CMPABT		(1 << 24)
+#define AXIPCIE_INTR_SLV_ILLBUR		(1 << 25)
+#define AXIPCIE_INTR_MST_DECERR		(1 << 26)
+#define AXIPCIE_INTR_MST_SLVERR		(1 << 27)
+#define AXIPCIE_INTR_MST_ERRP		(1 << 28)
+
+#define BUS_LOC_SHIFT			20
+#define DEV_LOC_SHIFT			12
+#define PRIMARY_BUS			1
+#define PORT_REG_SIZE			0x1000
+#define PORT_HEADER_SIZE		0x128
+
+#define AXIPCIE_LOCAL_CNFG_BASE		0x00000000
+#define AXIPCIE_REG_BASE		0x00000128
+#define AXIPCIE_REG_PSCR_LNKUP		0x00000800
+#define AXIPCIE_REG_IMR_MASKALL		0x1FF30FED
+#define AXIPCIE_REG_IDR_MASKALL		0xFFFFFFFF
+#define AXIPCIE_REG_RPSC_BEN		0x00000001
+#define BUS_MASTER_ENABLE		0x00000004
+
+/* debug */
+//#define XILINX_AXIPCIE_DEBUG
+#ifdef XILINX_AXIPCIE_DEBUG
+#define DBG(x...) ((void)printk(x))
+#else
+#define DBG(x...)	\
+	do {		\
+	} while(0)
+#endif
+
+/* Xilinx CR# 657412 */
+/* Byte swapping */
+#define xpcie_out_be32(a, v) __raw_writel(__cpu_to_be32(v), (a))
+#define xpcie_out_be16(a, v) __raw_writew(__cpu_to_be16(v), (a))
+
+#define xpcie_in_be32(a) __be32_to_cpu(__raw_readl(a))
+#define xpcie_in_be16(a) __be16_to_cpu(__raw_readw(a))
+
+#ifdef CONFIG_PCI_MSI
+extern unsigned long msg_addr;
+#endif
+
+struct xilinx_axipcie_node {
+	u32 number_of_instances;
+	u32 device_id;
+	u32 device_type;
+	u32 ecam_base;
+	u32 ecam_high;
+	u32 baseaddr;
+	u32 highaddr;
+	u32 bars_num;
+	u32 irq_num;
+	u32 reg_base;
+	u32 reg_len;
+	u32 pcie2axibar_0;
+	u32 pcie2axibar_1;
+};
+
+struct xilinx_axipcie_port {
+	struct pci_controller	*hose;
+	struct device_node	*node;
+	u32			reg_base;
+	u32			reg_len;
+	u32			ecam_base;
+	u32			ecam_high;
+	u32			baseaddr;
+	u32			highaddr;
+	u32			header_addr;
+	u8			index;
+	u8			type;
+	u8			link;
+	u8			bars_num;
+	u32			irq_num;
+	unsigned int __iomem	*base_addr_remap;
+	unsigned int __iomem	*header_remap;
+	unsigned int __iomem	*ecam_remap;
+	u32 pcie2axibar_0;
+	u32 pcie2axibar_1;
+};
+
+#endif /* XILINX_AXIPCIE_H_ */
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/dts/virtex405-ml405.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/dts/virtex405-ml405.dts	2014-07-20 22:06:34.749332225 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * This file supports the Xilinx ML405 board with the 405 processor.
+ * A reference design for the FPGA is provided at http://git.xilinx.com.
+ *
+ * (C) Copyright 2008 Xilinx, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,virtex";
+	model = "testing";
+	DDR_SDRAM: memory@0 {
+		device_type = "memory";
+		reg = < 0 0x8000000 >;
+	} ;
+	chosen {
+		bootargs = "console=ttyS0 ip=on root=/dev/ram";
+		linux,stdout-path = "/plb@0/serial@83e00000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#cpus = <1>;
+
+		#size-cells = <0>;
+		ppc405_0: cpu@0 {
+			clock-frequency = <0x11e1a300>;
+			compatible = "PowerPC,405", "ibm,ppc405";
+			d-cache-line-size = <0x20>;
+			d-cache-size = <0x4000>;
+			device_type = "cpu";
+			i-cache-line-size = <0x20>;
+			i-cache-size = <0x4000>;
+			model = "PowerPC,405";
+			reg = <0>;
+			timebase-frequency = <0x11e1a300>;
+			xlnx,apu-control = <0xde00>;
+			xlnx,apu-udi-1 = <0xa18983>;
+			xlnx,apu-udi-2 = <0xa38983>;
+			xlnx,apu-udi-3 = <0xa589c3>;
+			xlnx,apu-udi-4 = <0xa789c3>;
+			xlnx,apu-udi-5 = <0xa98c03>;
+			xlnx,apu-udi-6 = <0xab8c03>;
+			xlnx,apu-udi-7 = <0xad8c43>;
+			xlnx,apu-udi-8 = <0xaf8c43>;
+			xlnx,deterministic-mult = <0>;
+			xlnx,disable-operand-forwarding = <1>;
+			xlnx,fastest-plb-clock = "DPLB0";
+			xlnx,generate-plb-timespecs = <1>;
+			xlnx,mmu-enable = <1>;
+			xlnx,pvr-high = <0>;
+			xlnx,pvr-low = <0>;
+		} ;
+	} ;
+	plb: plb@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,plb-v46-1.02.a", "simple-bus";
+		ranges ;
+		IIC_EEPROM: i2c@81600000 {
+			compatible = "xlnx,xps-iic-2.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 4 2 >;
+			reg = < 0x81600000 0x10000 >;
+			xlnx,clk-freq = <0x5f5e100>;
+			xlnx,family = "virtex4";
+			xlnx,gpo-width = <1>;
+			xlnx,iic-freq = <0x186a0>;
+			xlnx,scl-inertial-delay = <0>;
+			xlnx,sda-inertial-delay = <0>;
+			xlnx,ten-bit-adr = <0>;
+		} ;
+		LEDs_4Bit: gpio@81400000 {
+			compatible = "xlnx,xps-gpio-1.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 5 2 >;
+			reg = < 0x81400000 0x10000 >;
+			xlnx,all-inputs = <0>;
+			xlnx,all-inputs-2 = <0>;
+			xlnx,dout-default = <0>;
+			xlnx,dout-default-2 = <0>;
+			xlnx,family = "virtex4";
+			xlnx,gpio-width = <4>;
+			xlnx,interrupt-present = <1>;
+			xlnx,is-bidir = <1>;
+			xlnx,is-bidir-2 = <1>;
+			xlnx,is-dual = <0>;
+			xlnx,tri-default = <0xffffffff>;
+			xlnx,tri-default-2 = <0xffffffff>;
+		} ;
+		RS232_Uart: serial@83e00000 {
+			compatible = "ns16550";
+			device_type = "serial";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 6 2 >;
+			reg = < 0x83e00000 0x10000 >;
+			reg-offset = <0x1003>;
+			reg-shift = <2>;
+			clock-frequency = <0x05f5e100>;
+			xlnx,family = "virtex4";
+			xlnx,has-external-rclk = <0>;
+			xlnx,has-external-xin = <0>;
+			xlnx,is-a-16550 = <1>;
+		} ;
+		SysACE_CompactFlash: sysace@83600000 {
+			compatible = "xlnx,xps-sysace-1.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 3 2 >;
+			reg = < 0x83600000 0x10000 >;
+			xlnx,family = "virtex4";
+			xlnx,mem-width = <0x10>;
+		} ;
+		TriMode_MAC_GMII: xps-ll-temac@81c00000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,compound";
+			ethernet@81c00000 {
+				compatible = "xlnx,xps-ll-temac-1.01.a";
+				device_type = "network";
+				interrupt-parent = <&xps_intc_0>;
+				interrupts = < 2 2 >;
+				llink-connected = <&PIM2>;
+				local-mac-address = [ 02 00 00 00 00 01 ];
+				reg = < 0x81c00000 0x40 >;
+				xlnx,bus2core-clk-ratio = <1>;
+				xlnx,phy-type = <1>;
+				xlnx,phyaddr = <1>;
+				xlnx,rxcsum = <0>;
+				xlnx,rxfifo = <0x1000>;
+				xlnx,temac-type = <1>;
+				xlnx,txcsum = <0>;
+				xlnx,txfifo = <0x1000>;
+			} ;
+		} ;
+		mpmc@0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,mpmc-4.00.a";
+			PIM2: sdma@84600100 {
+				compatible = "xlnx,ll-dma-1.00.a";
+				interrupt-parent = <&xps_intc_0>;
+				interrupts = < 1 2 0 2 >;
+				reg = < 0x84600100 0x80 >;
+			} ;
+		} ;
+		xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffffe000 {
+			compatible = "xlnx,xps-bram-if-cntlr-1.00.a";
+			reg = < 0xffffe000 0x2000 >;
+			xlnx,family = "virtex4";
+		} ;
+		xps_intc_0: interrupt-controller@81800000 {
+			#interrupt-cells = <2>;
+			compatible = "xlnx,xps-intc-1.00.a";
+			interrupt-controller ;
+			reg = < 0x81800000 0x10000 >;
+			xlnx,num-intr-inputs = <7>;
+		} ;
+	} ;
+	ppc405_0_dplb1: plb@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,plb-v46-1.02.a", "simple-bus";
+		ranges ;
+	} ;
+}  ;
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/dts/virtex440-avnet-v5fx30t.dts
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/dts/virtex440-avnet-v5fx30t.dts	2014-07-20 22:06:34.758332077 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*

+ * Device Tree Generator version: 1.1

+ *

+ * This file supports the Avnet V5FX30T board with the 440 processor.
+ * A reference design for the FPGA is provided at the avnet web site.
+ *
+ * (C) Copyright 2009 Xilinx, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.

+ */

+

+/dts-v1/;

+/ {

+	#address-cells = <1>;

+	#size-cells = <1>;

+	compatible = "xlnx,virtex440", "xlnx,virtex";

+	dcr-parent = <&ppc440_0>;

+	model = "testing";

+	DDR2_SDRAM_16Mx32: memory@0 {

+		device_type = "memory";

+		reg = < 0x0 0x4000000 >;

+	} ;

+	chosen {

+		bootargs = "console=ttyS0 root=/dev/ram";
+		linux,stdout-path = "/plb@0/serial@83e00000";

+	} ;

+	cpus {

+		#address-cells = <1>;

+		#cpus = <0x1>;

+		#size-cells = <0>;

+		ppc440_0: cpu@0 {

+			#address-cells = <1>;

+			#size-cells = <1>;

+			clock-frequency = <400000000>;

+			compatible = "PowerPC,440", "ibm,ppc440";

+			d-cache-line-size = <0x20>;

+			d-cache-size = <0x8000>;

+			dcr-access-method = "native";

+			dcr-controller ;

+			device_type = "cpu";

+			i-cache-line-size = <0x20>;

+			i-cache-size = <0x8000>;

+			model = "PowerPC,440";

+			reg = <0>;

+			timebase-frequency = <400000000>;

+			xlnx,apu-control = <0x2000>;

+			xlnx,apu-udi-0 = <0x0>;

+			xlnx,apu-udi-1 = <0x0>;

+			xlnx,apu-udi-10 = <0x0>;

+			xlnx,apu-udi-11 = <0x0>;

+			xlnx,apu-udi-12 = <0x0>;

+			xlnx,apu-udi-13 = <0x0>;

+			xlnx,apu-udi-14 = <0x0>;

+			xlnx,apu-udi-15 = <0x0>;

+			xlnx,apu-udi-2 = <0x0>;

+			xlnx,apu-udi-3 = <0x0>;

+			xlnx,apu-udi-4 = <0x0>;

+			xlnx,apu-udi-5 = <0x0>;

+			xlnx,apu-udi-6 = <0x0>;

+			xlnx,apu-udi-7 = <0x0>;

+			xlnx,apu-udi-8 = <0x0>;

+			xlnx,apu-udi-9 = <0x0>;

+			xlnx,dcr-autolock-enable = <0x1>;

+			xlnx,dcu-rd-ld-cache-plb-prio = <0x0>;

+			xlnx,dcu-rd-noncache-plb-prio = <0x0>;

+			xlnx,dcu-rd-touch-plb-prio = <0x0>;

+			xlnx,dcu-rd-urgent-plb-prio = <0x0>;

+			xlnx,dcu-wr-flush-plb-prio = <0x0>;

+			xlnx,dcu-wr-store-plb-prio = <0x0>;

+			xlnx,dcu-wr-urgent-plb-prio = <0x0>;

+			xlnx,dma0-control = <0x0>;

+			xlnx,dma0-plb-prio = <0x0>;

+			xlnx,dma0-rxchannelctrl = <0x1010000>;

+			xlnx,dma0-rxirqtimer = <0x3ff>;

+			xlnx,dma0-txchannelctrl = <0x1010000>;

+			xlnx,dma0-txirqtimer = <0x3ff>;

+			xlnx,dma1-control = <0x0>;

+			xlnx,dma1-plb-prio = <0x0>;

+			xlnx,dma1-rxchannelctrl = <0x1010000>;

+			xlnx,dma1-rxirqtimer = <0x3ff>;

+			xlnx,dma1-txchannelctrl = <0x1010000>;

+			xlnx,dma1-txirqtimer = <0x3ff>;

+			xlnx,dma2-control = <0x0>;

+			xlnx,dma2-plb-prio = <0x0>;

+			xlnx,dma2-rxchannelctrl = <0x1010000>;

+			xlnx,dma2-rxirqtimer = <0x3ff>;

+			xlnx,dma2-txchannelctrl = <0x1010000>;

+			xlnx,dma2-txirqtimer = <0x3ff>;

+			xlnx,dma3-control = <0x0>;

+			xlnx,dma3-plb-prio = <0x0>;

+			xlnx,dma3-rxchannelctrl = <0x1010000>;

+			xlnx,dma3-rxirqtimer = <0x3ff>;

+			xlnx,dma3-txchannelctrl = <0x1010000>;

+			xlnx,dma3-txirqtimer = <0x3ff>;

+			xlnx,endian-reset = <0x0>;

+			xlnx,generate-plb-timespecs = <0x1>;

+			xlnx,icu-rd-fetch-plb-prio = <0x0>;

+			xlnx,icu-rd-spec-plb-prio = <0x0>;

+			xlnx,icu-rd-touch-plb-prio = <0x0>;

+			xlnx,interconnect-imask = <0xffffffff>;

+			xlnx,mplb-allow-lock-xfer = <0x1>;

+			xlnx,mplb-arb-mode = <0x0>;

+			xlnx,mplb-awidth = <0x20>;

+			xlnx,mplb-counter = <0x500>;

+			xlnx,mplb-dwidth = <0x80>;

+			xlnx,mplb-max-burst = <0x8>;

+			xlnx,mplb-native-dwidth = <0x80>;

+			xlnx,mplb-p2p = <0x0>;

+			xlnx,mplb-prio-dcur = <0x2>;

+			xlnx,mplb-prio-dcuw = <0x3>;

+			xlnx,mplb-prio-icu = <0x4>;

+			xlnx,mplb-prio-splb0 = <0x1>;

+			xlnx,mplb-prio-splb1 = <0x0>;

+			xlnx,mplb-read-pipe-enable = <0x1>;

+			xlnx,mplb-sync-tattribute = <0x0>;

+			xlnx,mplb-wdog-enable = <0x1>;

+			xlnx,mplb-write-pipe-enable = <0x1>;

+			xlnx,mplb-write-post-enable = <0x1>;

+			xlnx,num-dma = <0x1>;

+			xlnx,pir = <0xf>;

+			xlnx,ppc440mc-addr-base = <0x0>;

+			xlnx,ppc440mc-addr-high = <0x3ffffff>;

+			xlnx,ppc440mc-arb-mode = <0x0>;

+			xlnx,ppc440mc-bank-conflict-mask = <0x300000>;

+			xlnx,ppc440mc-control = <0xf850008f>;

+			xlnx,ppc440mc-max-burst = <0x8>;

+			xlnx,ppc440mc-prio-dcur = <0x2>;

+			xlnx,ppc440mc-prio-dcuw = <0x3>;

+			xlnx,ppc440mc-prio-icu = <0x4>;

+			xlnx,ppc440mc-prio-splb0 = <0x1>;

+			xlnx,ppc440mc-prio-splb1 = <0x0>;

+			xlnx,ppc440mc-row-conflict-mask = <0xfff80>;

+			xlnx,ppcdm-asyncmode = <0x0>;

+			xlnx,ppcds-asyncmode = <0x0>;

+			xlnx,user-reset = <0x0>;

+			DMA0: sdma@80 {

+				compatible = "xlnx,ll-dma-1.00.a";

+				dcr-reg = < 0x80 0x11 >;

+				interrupt-parent = <&xps_intc_0>;

+				interrupts = < 7 2 8 2 >;

+			} ;

+		} ;

+	} ;

+	plb_v46_0: plb@0 {

+		#address-cells = <1>;

+		#size-cells = <1>;

+		compatible = "xlnx,plb-v46-1.03.a", "simple-bus";

+		ranges ;

+		DIP_Switches_8Bit: gpio@81420000 {

+			compatible = "xlnx,xps-gpio-1.00.a";

+			interrupt-parent = <&xps_intc_0>;

+			interrupts = < 5 2 >;

+			reg = < 0x81420000 0x10000 >;

+			xlnx,all-inputs = <0x1>;

+			xlnx,all-inputs-2 = <0x0>;

+			xlnx,dout-default = <0x0>;

+			xlnx,dout-default-2 = <0x0>;

+			xlnx,family = "virtex5";

+			xlnx,gpio-width = <0x8>;

+			xlnx,interrupt-present = <0x1>;

+			xlnx,is-bidir = <0x0>;

+			xlnx,is-bidir-2 = <0x1>;

+			xlnx,is-dual = <0x0>;

+			xlnx,tri-default = <0xffffffff>;

+			xlnx,tri-default-2 = <0xffffffff>;

+		} ;

+		FLASH_8Mx16: flash@86000000 {

+			bank-width = <2>;

+			compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";

+			reg = < 0x86000000 0x2000000 >;

+			xlnx,family = "virtex5";

+			xlnx,include-datawidth-matching-0 = <0x1>;

+			xlnx,include-datawidth-matching-1 = <0x0>;

+			xlnx,include-datawidth-matching-2 = <0x0>;

+			xlnx,include-datawidth-matching-3 = <0x0>;

+			xlnx,include-negedge-ioregs = <0x0>;

+			xlnx,include-plb-ipif = <0x1>;

+			xlnx,include-wrbuf = <0x1>;

+			xlnx,max-mem-width = <0x10>;

+			xlnx,mch-native-dwidth = <0x20>;

+			xlnx,mch-plb-clk-period-ps = <0x2710>;

+			xlnx,mch-splb-awidth = <0x20>;

+			xlnx,mch0-accessbuf-depth = <0x10>;

+			xlnx,mch0-protocol = <0x0>;

+			xlnx,mch0-rddatabuf-depth = <0x10>;

+			xlnx,mch1-accessbuf-depth = <0x10>;

+			xlnx,mch1-protocol = <0x0>;

+			xlnx,mch1-rddatabuf-depth = <0x10>;

+			xlnx,mch2-accessbuf-depth = <0x10>;

+			xlnx,mch2-protocol = <0x0>;

+			xlnx,mch2-rddatabuf-depth = <0x10>;

+			xlnx,mch3-accessbuf-depth = <0x10>;

+			xlnx,mch3-protocol = <0x0>;

+			xlnx,mch3-rddatabuf-depth = <0x10>;

+			xlnx,mem0-width = <0x10>;

+			xlnx,mem1-width = <0x20>;

+			xlnx,mem2-width = <0x20>;

+			xlnx,mem3-width = <0x20>;

+			xlnx,num-banks-mem = <0x1>;

+			xlnx,num-channels = <0x2>;

+			xlnx,priority-mode = <0x0>;

+			xlnx,synch-mem-0 = <0x0>;

+			xlnx,synch-mem-1 = <0x0>;

+			xlnx,synch-mem-2 = <0x0>;

+			xlnx,synch-mem-3 = <0x0>;

+			xlnx,synch-pipedelay-0 = <0x2>;

+			xlnx,synch-pipedelay-1 = <0x2>;

+			xlnx,synch-pipedelay-2 = <0x2>;

+			xlnx,synch-pipedelay-3 = <0x2>;

+			xlnx,tavdv-ps-mem-0 = <0x1d4c0>;

+			xlnx,tavdv-ps-mem-1 = <0x3a98>;

+			xlnx,tavdv-ps-mem-2 = <0x3a98>;

+			xlnx,tavdv-ps-mem-3 = <0x3a98>;

+			xlnx,tcedv-ps-mem-0 = <0x1d4c0>;

+			xlnx,tcedv-ps-mem-1 = <0x3a98>;

+			xlnx,tcedv-ps-mem-2 = <0x3a98>;

+			xlnx,tcedv-ps-mem-3 = <0x3a98>;

+			xlnx,thzce-ps-mem-0 = <0x88b8>;

+			xlnx,thzce-ps-mem-1 = <0x1b58>;

+			xlnx,thzce-ps-mem-2 = <0x1b58>;

+			xlnx,thzce-ps-mem-3 = <0x1b58>;

+			xlnx,thzoe-ps-mem-0 = <0x1b58>;

+			xlnx,thzoe-ps-mem-1 = <0x1b58>;

+			xlnx,thzoe-ps-mem-2 = <0x1b58>;

+			xlnx,thzoe-ps-mem-3 = <0x1b58>;

+			xlnx,tlzwe-ps-mem-0 = <0x88b8>;

+			xlnx,tlzwe-ps-mem-1 = <0x0>;

+			xlnx,tlzwe-ps-mem-2 = <0x0>;

+			xlnx,tlzwe-ps-mem-3 = <0x0>;

+			xlnx,twc-ps-mem-0 = <0x1d4c0>;

+			xlnx,twc-ps-mem-1 = <0x3a98>;

+			xlnx,twc-ps-mem-2 = <0x3a98>;

+			xlnx,twc-ps-mem-3 = <0x3a98>;

+			xlnx,twp-ps-mem-0 = <0x1d4c0>;

+			xlnx,twp-ps-mem-1 = <0x2ee0>;

+			xlnx,twp-ps-mem-2 = <0x2ee0>;

+			xlnx,twp-ps-mem-3 = <0x2ee0>;

+			xlnx,xcl0-linesize = <0x4>;

+			xlnx,xcl0-writexfer = <0x1>;

+			xlnx,xcl1-linesize = <0x4>;

+			xlnx,xcl1-writexfer = <0x1>;

+			xlnx,xcl2-linesize = <0x4>;

+			xlnx,xcl2-writexfer = <0x1>;

+			xlnx,xcl3-linesize = <0x4>;

+			xlnx,xcl3-writexfer = <0x1>;

+		} ;

+		Hard_Ethernet_MAC: xps-ll-temac@81c00000 {

+			#address-cells = <1>;

+			#size-cells = <1>;

+			compatible = "xlnx,compound";

+			ethernet@81c00000 {

+				compatible = "xlnx,xps-ll-temac-1.01.b";

+				device_type = "network";

+				interrupt-parent = <&xps_intc_0>;

+				interrupts = < 3 2 >;

+				llink-connected = <&DMA0>;

+				local-mac-address = [ 02 00 00 00 00 00 ];

+				reg = < 0x81c00000 0x40 >;

+				xlnx,bus2core-clk-ratio = <0x1>;

+				xlnx,phy-type = <0x1>;

+				xlnx,phyaddr = <0x1>;

+				xlnx,rxcsum = <0x1>;

+				xlnx,rxfifo = <0x1000>;

+				xlnx,temac-type = <0x0>;

+				xlnx,txcsum = <0x1>;

+				xlnx,txfifo = <0x1000>;

+			} ;

+		} ;

+		LEDs_8Bit: gpio@81400000 {

+			compatible = "xlnx,xps-gpio-1.00.a";

+			reg = < 0x81400000 0x10000 >;

+			xlnx,all-inputs = <0x0>;

+			xlnx,all-inputs-2 = <0x0>;

+			xlnx,dout-default = <0x0>;

+			xlnx,dout-default-2 = <0x0>;

+			xlnx,family = "virtex5";

+			xlnx,gpio-width = <0x8>;

+			xlnx,interrupt-present = <0x0>;

+			xlnx,is-bidir = <0x0>;

+			xlnx,is-bidir-2 = <0x1>;

+			xlnx,is-dual = <0x0>;

+			xlnx,tri-default = <0xffffffff>;

+			xlnx,tri-default-2 = <0xffffffff>;

+		} ;

+		Push_Buttons_3Bit: gpio@81440000 {

+			compatible = "xlnx,xps-gpio-1.00.a";

+			interrupt-parent = <&xps_intc_0>;

+			interrupts = < 4 2 >;

+			reg = < 0x81440000 0x10000 >;

+			xlnx,all-inputs = <0x1>;

+			xlnx,all-inputs-2 = <0x0>;

+			xlnx,dout-default = <0x0>;

+			xlnx,dout-default-2 = <0x0>;

+			xlnx,family = "virtex5";

+			xlnx,gpio-width = <0x3>;

+			xlnx,interrupt-present = <0x1>;

+			xlnx,is-bidir = <0x0>;

+			xlnx,is-bidir-2 = <0x1>;

+			xlnx,is-dual = <0x0>;

+			xlnx,tri-default = <0xffffffff>;

+			xlnx,tri-default-2 = <0xffffffff>;

+		} ;

+		RS232: serial@83e00000 {

+			clock-frequency = <100000000>;

+			compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";

+			current-speed = <9600>;

+			device_type = "serial";

+			interrupt-parent = <&xps_intc_0>;

+			interrupts = < 6 2 >;

+			reg = < 0x83e00000 0x10000 >;

+			reg-offset = <0x1003>;

+			reg-shift = <2>;

+			xlnx,family = "virtex5";

+			xlnx,has-external-rclk = <0x0>;

+			xlnx,has-external-xin = <0x0>;

+			xlnx,is-a-16550 = <0x1>;

+		} ;

+		xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffff0000 {

+			compatible = "xlnx,xps-bram-if-cntlr-1.00.a";

+			reg = < 0xffff0000 0x10000 >;

+			xlnx,family = "virtex5";

+		} ;

+		xps_intc_0: interrupt-controller@81800000 {

+			#interrupt-cells = <0x2>;

+			compatible = "xlnx,xps-intc-1.00.a";

+			interrupt-controller ;

+			reg = < 0x81800000 0x10000 >;

+			xlnx,num-intr-inputs = <0x9>;

+		} ;

+		xps_timebase_wdt_1: xps-timebase-wdt@83a00000 {

+			compatible = "xlnx,xps-timebase-wdt-1.00.b";

+			interrupt-parent = <&xps_intc_0>;

+			interrupts = < 1 0 0 2 >;

+			reg = < 0x83a00000 0x10000 >;

+			xlnx,family = "virtex5";

+			xlnx,wdt-enable-once = <0x0>;

+			xlnx,wdt-interval = <0x1e>;

+		} ;

+		xps_timer_1: timer@83c00000 {

+			compatible = "xlnx,xps-timer-1.00.a";

+			interrupt-parent = <&xps_intc_0>;

+			interrupts = < 2 2 >;

+			reg = < 0x83c00000 0x10000 >;

+			xlnx,count-width = <0x20>;

+			xlnx,family = "virtex5";

+			xlnx,gen0-assert = <0x1>;

+			xlnx,gen1-assert = <0x1>;

+			xlnx,one-timer-only = <0x1>;

+			xlnx,trig0-assert = <0x1>;

+			xlnx,trig1-assert = <0x1>;

+		} ;

+	} ;

+}  ;

Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/.gitignore
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/boot/.gitignore	2014-07-20 22:05:50.307065450 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/.gitignore	2014-07-20 22:06:34.766331945 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:31 @
 zImage.miboot
 zImage.pmac
 zImage.pseries
+zImage.virtex
 zconf.h
 zlib.h
 zutil.h
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/kernel_fdt.its
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/kernel_fdt.its	2014-07-20 22:06:34.773331829 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Simple U-boot uImage source file containing a single kernel and FDT blob
+ */
+/ {
+	description = "PetaLinux PPC uImage with single Linux kernel and FDT blob";
+	#address-cells = <1>;
+
+	images {
+		kernel@1 {
+			description = "PetaLinux kernel";
+			data = /incbin/("./vmlinux.bin.gz");
+			type = "kernel";
+			arch = "ppc";
+			os = "linux";
+			compression = "gzip";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@1 {
+				algo = "crc32";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+		fdt@1 {
+			description = "Flattened Device Tree blob";
+			data = /incbin/("./target.dtb");
+			type = "flat_dt";
+			arch = "ppc";
+			compression = "none";
+/*
+			hash@1 {
+				algo = "crc32";
+			};
+			hash@2 {
+				algo = "sha1";
+			};
+*/
+		};
+	};
+
+	configurations {
+		default = "conf@1";
+		conf@1 {
+			description = "Boot Linux kernel with FDT blob";
+			kernel = "kernel@1";
+			fdt = "fdt@1";
+		};
+	};
+};
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/boot/Makefile	2014-07-20 22:05:50.306065466 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/Makefile	2014-07-20 22:06:34.783331664 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:340 @
 
 $(obj)/uImage.%: vmlinux $(obj)/%.dtb $(wrapperbits)
 	$(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb)
+	$(call if_changed,wrap,uboot-fit,,$(obj)/$*.dtb)
 
 $(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits)
 	$(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz)
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/simpleboot.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/boot/simpleboot.c	2014-07-20 22:05:50.305065482 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/simpleboot.c	2014-07-20 22:06:34.794331483 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:34 @
 	const u32 *na, *ns, *reg, *timebase;
 	u64 memsize64;
 	int node, size, i;
+	void *the_dtb = _dtb_start;
+
+	/* See if we were passed a DTB in the regs.  If so, use that instead */
+	if (fdt_check_header((void *)r3) == 0)
+		the_dtb = (void *)r3;
 
 	/* Make sure FDT blob is sane */
-	if (fdt_check_header(_dtb_start) != 0)
+	if (fdt_check_header(the_dtb) != 0)
 		fatal("Invalid device tree blob\n");
 
 	/* Find the #address-cells and #size-cells properties */
-	node = fdt_path_offset(_dtb_start, "/");
+	node = fdt_path_offset(the_dtb, "/");
 	if (node < 0)
 		fatal("Cannot find root node\n");
-	na = fdt_getprop(_dtb_start, node, "#address-cells", &size);
+	na = fdt_getprop(the_dtb, node, "#address-cells", &size);
 	if (!na || (size != 4))
 		fatal("Cannot find #address-cells property");
-	ns = fdt_getprop(_dtb_start, node, "#size-cells", &size);
+	ns = fdt_getprop(the_dtb, node, "#size-cells", &size);
 	if (!ns || (size != 4))
 		fatal("Cannot find #size-cells property");
 
 	/* Find the memory range */
-	node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
+	node = fdt_node_offset_by_prop_value(the_dtb, -1, "device_type",
 					     "memory", sizeof("memory"));
 	if (node < 0)
 		fatal("Cannot find memory node\n");
-	reg = fdt_getprop(_dtb_start, node, "reg", &size);
+	reg = fdt_getprop(the_dtb, node, "reg", &size);
 	if (size < (*na+*ns) * sizeof(u32))
 		fatal("cannot get memory range\n");
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:77 @
 		memsize64 = 0xffffffff;
 
 	/* finally, setup the timebase */
-	node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
+	node = fdt_node_offset_by_prop_value(the_dtb, -1, "device_type",
 					     "cpu", sizeof("cpu"));
 	if (!node)
 		fatal("Cannot find cpu node\n");
-	timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
+	timebase = fdt_getprop(the_dtb, node, "timebase-frequency", &size);
 	if (timebase && (size == 4))
 		timebase_period_ns = 1000000000 / *timebase;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:89 @
 	simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);
 
 	/* prepare the device tree and find the console */
-	fdt_init(_dtb_start);
+	fdt_init(the_dtb);
 
 	if (platform_specific_init)
 		platform_specific_init();
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/boot/wrapper
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/boot/wrapper	2014-07-20 22:05:50.308065433 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/boot/wrapper	2014-07-20 22:06:34.805331301 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:146 @
 tmp=$tmpdir/zImage.$$.o
 ksection=.kernel:vmlinux.strip
 isection=.kernel:initrd
-link_address='0x400000'
 make_space=y
 
+# default auto-calculate link_address to make room for the kernel
+# round up kernel image size to nearest megabyte
+link_address=`${CROSS}size -x ${kernel} | grep ${kernel} | awk '{printf("0x%08x", and($4 + 0x0fffff, 0xfffe0000))}'`
+
 case "$platform" in
 pseries)
     platformo="$object/of.o $object/epapr.o"
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:170 @
     link_address='0x500000'
     pie=
     ;;
-miboot|uboot*)
+miboot|uboot|uboot-fit)
     # miboot and U-boot want just the bare bits, not an ELF binary
     ext=bin
     objflags="-O binary"
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:345 @
     fi
     exit 0
     ;;
+uboot-fit)
+    pwd
+    rm -f "$ofile"
+    #[ "$vmz" != vmlinux.bin.gz ] && mv "$vmz" "vmlinux.bin.gz"
+    mv "$dtb" "target.dtb"
+    cp arch/powerpc/boot/kernel_fdt.its .
+    mkimage -f kernel_fdt.its "$ofile"
+    #rm kernet_fdt.its
+    exit 0
+    ;;
 esac
 
 addsec() {
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/configs/40x/virtex4_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/configs/40x/virtex4_defconfig	2014-07-20 22:06:34.831330872 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated make config: don't edit
+# Linux/powerpc 2.6.37-rc4 Kernel Configuration
+# Tue Dec 14 10:53:11 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_32 is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_32BIT=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_PPC_DCR_NATIVE=y
+CONFIG_PPC_DCR_MMIO=y
+CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HAVE_GENERIC_HARDIRQS is not set
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_ISS4xx is not set
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_XILINX_VIRTEX=y
+# CONFIG_ACADIA is not set
+# CONFIG_EP405 is not set
+# CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
+# CONFIG_KILAUEA is not set
+# CONFIG_MAKALU is not set
+# CONFIG_WALNUT is not set
+CONFIG_XILINX_VIRTEX_GENERIC_BOARD=y
+# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_XILINX_VIRTEX_II_PRO=y
+CONFIG_XILINX_VIRTEX_4_FX=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM405_ERR51=y
+CONFIG_KVM_GUEST=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_MPIC_U3_HT_IRQS is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+# CONFIG_XILINX_PCI is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PPC_4K_PAGES=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS="simpleImage.virtex405-ml405 simpleImage.initrd.virtex405-ml405"
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+# CONFIG_COMPRESSED_DEVICE_TREE is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_OF_SPI=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_XILINX_SYSACE=y
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+CONFIG_XILINX_DRIVERS=y
+CONFIG_NEED_XILINX_LLDMA=y
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM63XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMAC is not set
+# CONFIG_ATL2 is not set
+CONFIG_XILINX_EMACLITE=y
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_XILINX_TEMAC is not set
+# CONFIG_ATL1E is not set
+CONFIG_XILINX_LLTEMAC=y
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII is not set
+CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_GMII=y
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_MII is not set
+# CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_STMMAC_ETH is not set
+# CONFIG_PCH_GBE is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_XILINXPS2 is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_XILINX_HWICAP=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_XILINX_IIC=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_IBM_IIC is not set
+# CONFIG_I2C_INTEL_MID is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_PPC4xx is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+CONFIG_SPI_XILINX=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+CONFIG_GPIO_XILINX=y
+# CONFIG_GPIO_SCH is not set
+# CONFIG_GPIO_VX855 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_CS5535 is not set
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_PCH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC35892 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13XXX is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_STUB_POULSBO is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+CONFIG_FB_XILINX=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_XILINX_EDK=y
+# CONFIG_XILINX_LLDMA_USE_DCR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_DEPRECATED=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+CONFIG_BKL=y
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_DETECTOR_RUNNABLE=y
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/configs/44x/avnet_v5fx30t_defconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/configs/44x/avnet_v5fx30t_defconfig	2014-07-20 22:06:34.852330526 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc5
+# Thu Mar 12 19:42:21 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+CONFIG_PPC_DCR_MMIO=y
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_YOSEMITE is not set
+CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
+# CONFIG_PPC44x_SIMPLE is not set
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_XILINX_VIRTEX_5_FXT=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_XILINX_VIRTEX=y
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS="simpleImage.virtex440-avnet-v5fx30t simpleImage.initrd.virtex440-avnet-v5fx30t"
+CONFIG_SECCOMP=y
+# CONFIG_COMPRESSED_DEVICE_TREE is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PHYSMAP_OF is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+# CONFIG_XILINX_SYSACE_OLD is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_XILINX_DRIVERS=y
+CONFIG_NEED_XILINX_LLDMA=y
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_XILINX_EMAC is not set
+# CONFIG_XILINX_EMACLITE is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_XILINX_TEMAC is not set
+# CONFIG_ATL1E is not set
+CONFIG_XILINX_LLTEMAC=y
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII is not set
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_GMII is not set
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_MII is not set
+CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII=y
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_XILINXPS2 is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_XILINX_HWICAP=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_IBM_IIC is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+CONFIG_FB_XILINX=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+CONFIG_XILINX_EDK=y
+CONFIG_XILINX_LLDMA_USE_DCR=y
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/configs/44x/virtex5_defconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/configs/44x/virtex5_defconfig	2014-07-20 22:05:50.294065664 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/configs/44x/virtex5_defconfig	2014-07-20 22:06:34.873330180 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated make config: don't edit
+# Linux/powerpc 2.6.37-rc4 Kernel Configuration
+# Wed Dec 15 13:45:41 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_32 is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
 CONFIG_44x=y
+# CONFIG_E200 is not set
+# CONFIG_PPC_FPU is not set
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_32BIT=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_PPC_DCR_NATIVE=y
+CONFIG_PPC_DCR_MMIO=y
+CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=4
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=2
+CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
 CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HAVE_GENERIC_HARDIRQS is not set
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_47x is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_BLUESTONE is not set
 # CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
+# CONFIG_YOSEMITE is not set
+# CONFIG_ISS4xx is not set
+# CONFIG_ICON is not set
 CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
+# CONFIG_XILINX_ML510 is not set
+# CONFIG_PPC44x_SIMPLE is not set
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_XILINX_VIRTEX=y
+CONFIG_XILINX_VIRTEX_5_FXT=y
+CONFIG_KVM_GUEST=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_MPIC_U3_HT_IRQS is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+# CONFIG_XILINX_PCI is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_STDBINUTILS=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+# CONFIG_COMPRESSED_DEVICE_TREE is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
+
+#
+# Networking options
+#
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 # CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
 CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
 CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
 CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
 CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
 CONFIG_PROC_DEVICETREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_OF_SPI=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 CONFIG_XILINX_SYSACE=y
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+CONFIG_XILINX_DRIVERS=y
+CONFIG_NEED_XILINX_LLDMA=y
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
 CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM63XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMAC is not set
+# CONFIG_ATL2 is not set
+CONFIG_XILINX_EMACLITE=y
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_XILINX_TEMAC is not set
+# CONFIG_ATL1E is not set
+CONFIG_XILINX_LLTEMAC=y
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII is not set
+CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_GMII=y
+# CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_MII is not set
+# CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_STMMAC_ETH is not set
+# CONFIG_PCH_GBE is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_XILINXPS2 is not set
 CONFIG_SERIO_XILINX_XPS_PS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+# CONFIG_SERIAL_MFD_HSU is not set
 CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
 CONFIG_XILINX_HWICAP=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_XILINX_IIC=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_IBM_IIC is not set
+# CONFIG_I2C_INTEL_MID is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_PPC4xx is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+CONFIG_SPI_XILINX=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
 CONFIG_GPIO_XILINX=y
+# CONFIG_GPIO_SCH is not set
+# CONFIG_GPIO_VX855 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_CS5535 is not set
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_PCH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC35892 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13XXX is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_STUB_POULSBO is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
 CONFIG_FB_XILINX=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_XILINX_EDK=y
+CONFIG_XILINX_LLDMA_USE_DCR=y
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
 CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
 CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
 CONFIG_NLS_ASCII=m
 CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
 CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+CONFIG_BKL=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/entry_32.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/kernel/entry_32.S	2014-07-20 22:05:50.304065499 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/entry_32.S	2014-07-20 22:06:34.892329866 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:702 @
 	andc	r11,r11,r0
 	MTMSRD(r11)
 	isync
+#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+	mfspr   r5,SPRN_CCR0
+	andis.  r5,r5, ~(1<<6)@l
+	andi.	r5,r5, ~(1<<5)@l
+	mtspr   SPRN_CCR0,r5
+	isync
+#endif
 1:	stw	r11,_MSR(r1)
 	mfcr	r10
 	stw	r10,_CCR(r1)
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/fpu.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/kernel/fpu.S	2014-07-20 22:05:50.303065516 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/fpu.S	2014-07-20 22:06:34.903329685 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:127 @
  * enable the FPU for the current task and return to the task.
  */
 _GLOBAL(load_up_fpu)
+#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+	li	r3,0
+	lis	r5,excep_state@h
+	ori	r5,r5,excep_state@l
+	stw	r3,0(r5)
+
+	mfspr   r5,SPRN_CCR0
+	/* set CCR0[9] to disable the load miss queue inside the ppc440 */
+	oris    r5,r5, (1<<6)
+	/* set CCR0[26] to ... */
+	ori	r5,r5, (1<<5)
+	mtspr   SPRN_CCR0,r5
+	isync
+#endif
+
 	mfmsr	r5
 	ori	r5,r5,MSR_FP
 #ifdef CONFIG_VSX
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:209 @
  * Enables the FPU for use in the kernel on return.
  */
 _GLOBAL(giveup_fpu)
+#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+	mfspr   r5,SPRN_CCR0
+	/* set CCR0[9] to disable the load miss queue inside the ppc440 */
+	oris    r5,r5, (1<<6)
+	/* set CCR0[26] to ... */
+	ori	r5,r5, (1<<5)
+	mtspr   SPRN_CCR0,r5
+	isync
+#endif
+
 	mfmsr	r5
 	ori	r5,r5,MSR_FP
 #ifdef CONFIG_VSX
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/head_44x.S
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/kernel/head_44x.S	2014-07-20 22:05:50.302065532 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/head_44x.S	2014-07-20 22:06:34.918329437 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:99 @
 	bl	init_cpu_state
 
 	/*
+	 * The following code is needed to make GDB work with soft breakpoints.
+	 * This patch was provided by Brian Hill.
+	 */
+	lis     r2,DBCR0_IDM@h
+	mtspr   SPRN_DBCR0,r2
+	isync
+
+	/* clear any residual debug events */
+	li      r2,-1
+	mtspr   SPRN_DBSR,r2
+
+	/*
 	 * This is where the main kernel code starts.
 	 */
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:947 @
 	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
 	tlbwe	r5,r0,PPC44x_TLB_ATTRIB	/* Load the attrib/access fields */
 
+
 	/* Force context change */
+#ifdef CONFIG_XILINX_VIRTEX_5_FXT
+	/* We can not use the content of the MSR register when we are using XMD
+	 * to connect to a ml5xx board as XMD changes the contents of the MSR
+	 * register. We load the default value instead.
+	 *
+	 * EDK 10.1 fixes this issue so this should be removed once the automated
+	 * testing is updated to 10.1 tools.
+	 */
+        lis     r0,MSR_KERNEL@h
+        ori     r0,r0,MSR_KERNEL@l
+#else
 	mfmsr	r0
+#endif
 	mtspr	SPRN_SRR1, r0
 	lis	r0,3f@h
 	ori	r0,r0,3f@l
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/traps.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/kernel/traps.c	2014-07-20 22:05:50.301065548 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/kernel/traps.c	2014-07-20 22:06:34.936329140 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:83 @
 EXPORT_SYMBOL(__debugger_fault_handler);
 #endif
 
+#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+u8 excep_state = 0;
+#endif
+
 /* Transactional Memory trap debug */
 #ifdef TM_DEBUG_SW
 #define TM_DEBUG(x...) printk(KERN_INFO x)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1181 @
 	if (!emulate_math(regs))
 		goto bail;
 
+#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+	if (reason & REASON_ILLEGAL) {
+		if (excep_state < 1) {
+			excep_state++;
+			return;
+		}
+		/* should never get here */
+		BUG();
+	}
+#endif
+
 	/* Try to emulate it if we should. */
 	if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
 		switch (emulate_instruction(regs)) {
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/40x.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/40x.h	2014-07-20 22:06:34.950328910 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3 @
+#ifndef __POWERPC_PLATFORMS_40X_40X_H
+#define __POWERPC_PLATFORMS_40X_40X_H
+
+extern void ppc40x_reset_system(char *cmd);
+
+#endif /* __POWERPC_PLATFORMS_44X_44X_H */
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/platforms/40x/Makefile	2014-07-20 22:05:50.300065565 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/Makefile	2014-07-20 22:06:34.958328778 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
 obj-$(CONFIG_WALNUT)				+= walnut.o
-obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)	+= virtex.o
+obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)	+= virtex.o misc_40x.o
 obj-$(CONFIG_EP405)				+= ep405.o
 obj-$(CONFIG_PPC40x_SIMPLE)		+= ppc40x_simple.o
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/misc_40x.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/misc_40x.S	2014-07-20 22:06:34.966328646 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * This file contains miscellaneous low-level functions for PPC 44x.
+ *    Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+
+	.text
+
+/*
+ * void ppc40x_reset_system(char *cmd)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(ppc40x_reset_system)
+	mfspr	r13,SPRN_DBCR0
+	oris	r13,r13,DBCR0_RST_SYSTEM@h
+	mtspr	SPRN_DBCR0,r13
+	blr
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/virtex.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/platforms/40x/virtex.c	2014-07-20 22:05:50.299065581 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/40x/virtex.c	2014-07-20 22:06:34.974328514 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:21 @
 #include <asm/ppc4xx.h>
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
+	{ .compatible = "simple-bus", },
 	{ .compatible = "xlnx,plb-v46-1.00.a", },
+	{ .compatible = "xlnx,plb-v46-1.02.a", },
 	{ .compatible = "xlnx,plb-v34-1.01.a", },
 	{ .compatible = "xlnx,plb-v34-1.02.a", },
 	{ .compatible = "xlnx,opb-v20-1.10.c", },
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/44x/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/platforms/44x/Kconfig	2014-07-20 22:05:50.296065631 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/44x/Kconfig	2014-07-20 22:06:34.989328266 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:254 @
 	help
 	  Enable gpiolib support for ppc440 based boards
 
+config XILINX_PPC_FPU
+	depends on XILINX_VIRTEX_5_FXT
+	bool "Enable Xilinx Soft FPU"
+	select PPC_FPU
+	default n
+	help
+	  This option enables the Xilinx Soft FPU attached to the APU
+	  interface of the PPC440 (requires DP_FULL FPU pcore).
+
 config PPC4xx_OCM
 	bool "PPC4xx On Chip Memory (OCM) support"
 	depends on 4xx
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/platforms/Kconfig	2014-07-20 22:05:50.297065614 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/platforms/Kconfig	2014-07-20 22:06:35.000328085 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:335 @
 config CPM
 	bool
 
+config XILINX_VIRTEX
+	bool
+	select PPC_DCR_MMIO
+	select PPC_DCR_NATIVE
+	help
+	  Support for Xilinx Virtex platforms.
+
 config OF_RTC
 	bool
 	help
Index: linux-3.12.24-rt38-xilinx/arch/powerpc/sysdev/xilinx_pci.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/arch/powerpc/sysdev/xilinx_pci.c	2014-07-20 22:05:50.295065648 +0200
+++ linux-3.12.24-rt38-xilinx/arch/powerpc/sysdev/xilinx_pci.c	2014-07-20 22:06:35.014327854 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:118 @
 	/* Set the max latency timer to 255 */
 	early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
 
-	/* Set the max bus number to 255 */
+	/* Set the max bus number to 255, and bus/subbus no's to 0 */
 	pci_reg = of_iomap(pci_node, 0);
-	out_8(pci_reg + XPLB_PCI_BUS, 0xff);
+	out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff);
 	iounmap(pci_reg);
 
 	/* Nothing past the root bridge is working right now.  By default
Index: linux-3.12.24-rt38-xilinx/config
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/config	2014-07-20 22:06:35.046327326 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.12.14 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION="-xilinx"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_CPU_IDLERUNTIME=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_RCU_BOOST=y
+CONFIG_RCU_BOOST_PRIO=1
+CONFIG_RCU_BOOST_DELAY=500
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_IKPATCHSET is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GENERIC_SCHED_CLOCK=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLUB=y
+CONFIG_SLUB_CPU_PARTIAL=y
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_AIX_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+# CONFIG_CMDLINE_PARTITION is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+
+#
+# Multiple platform selection
+#
+
+#
+# CPU Core family selection
+#
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MULTI_V6_V7=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_BCM is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_KEYSTONE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+# CONFIG_SOC_OMAP5 is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_SOC_AM43XX is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_STI is not set
+# CONFIG_ARCH_SHMOBILE_MULTI is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_SIRF is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_ARCH_VEXPRESS=y
+
+#
+# Versatile Express platform type
+#
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
+CONFIG_PLAT_VERSATILE_CLCD=y
+CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
+# CONFIG_ARCH_VIRT is not set
+# CONFIG_ARCH_WM8850 is not set
+CONFIG_ARCH_ZYNQ=y
+
+#
+# Xilinx Specific Options
+#
+CONFIG_XILINX_L1_PREFETCH=y
+CONFIG_XILINX_L2_PREFETCH=y
+CONFIG_XILINX_AXIPCIE=y
+CONFIG_PLAT_VERSATILE=y
+CONFIG_ARM_TIMER_SP804=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+# CONFIG_ARM_ERRATA_773022 is not set
+CONFIG_ICST=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+
+#
+# PCI host controller drivers
+#
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=1024
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_RT_BASE=y
+CONFIG_HAVE_PREEMPT_LAZY=y
+CONFIG_PREEMPT_LAZY=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT__LL is not set
+# CONFIG_PREEMPT_RTB is not set
+CONFIG_PREEMPT_RT_FULL=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_100=y
+# CONFIG_HZ_200 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_500 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_ZBUD is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/mmcblk0p2 rw earlyprintk"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_AUTO_ZRELADDR=y
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_ZYNQ_CPUFREQ=y
+
+#
+# CPU Idle
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_KERNEL_MODE_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+# CONFIG_SUSPEND is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ARM_CPU_SUSPEND is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=y
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_GRE is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_DMA_CMA is not set
+
+#
+# Bus devices
+#
+# CONFIG_ARM_CCI is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_ZYNQ=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+CONFIG_HWLAT_DETECTOR=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_ARM_CHARLCD is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_SI570 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+CONFIG_SRAM=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_MPT3SAS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_VIRTIO is not set
+# CONFIG_SCSI_CHELSIO_FCOE is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_HAVE_PATA_PLATFORM=y
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+CONFIG_NET_VENDOR_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_NET_CADENCE=y
+# CONFIG_ARM_AT91_ETHER is not set
+CONFIG_MACB=y
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R8169=y
+# CONFIG_SH_ETH is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NET_VENDOR_XILINX=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_XILINX_AXI_EMAC=y
+CONFIG_XILINX_PS_EMAC=y
+# CONFIG_XILINX_PS_EMAC_HWTSTAMP is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=y
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_ST_ASC is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_XILINX_DEVCFG=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_VERSATILE is not set
+CONFIG_I2C_ZYNQ=y
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_FSL_DSPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XCOMM is not set
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_ZYNQ_QSPI=y
+# CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED is not set
+CONFIG_SPI_ZYNQ=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_PL061 is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+CONFIG_GPIO_XILINX=y
+CONFIG_GPIO_ZYNQ=y
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# LPC GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_SMB347 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_HTU21 is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_XADCPS=y
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+CONFIG_ZYNQ_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+CONFIG_XILINX_WATCHDOG=y
+# CONFIG_MEN_A21_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CAMERA_SUPPORT is not set
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+# CONFIG_MEDIA_USB_SUPPORT is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_DRM is not set
+# CONFIG_TEGRA_HOST1X is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_XILINX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+CONFIG_FB_XYLON=y
+# CONFIG_FB_XYLON_PLATFORM is not set
+CONFIG_FB_XYLON_OF=y
+# CONFIG_FB_XYLON_PIXCLK is not set
+# CONFIG_FB_XYLON_MISC is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+# CONFIG_SOUND is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_XUSBPS_DR_OF=y
+CONFIG_USB_EHCI_XUSBPS=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_AM335X_PHY_USB is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+CONFIG_USB_GADGET_XUSBPS=y
+CONFIG_XUSBPS_ERRATA_DT654401=y
+CONFIG_USB_XUSBPS=y
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+CONFIG_USB_GADGET_XILINX=y
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=y
+CONFIG_USB_U_ETHER=y
+CONFIG_USB_U_RNDIS=y
+CONFIG_USB_F_ECM=y
+CONFIG_USB_F_SUBSET=y
+CONFIG_USB_F_RNDIS=y
+# CONFIG_USB_CONFIGFS is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_ZYNQ=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_RTC_DRV_MOXART is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_XILINX_DMA_ENGINES=y
+CONFIG_XILINX_AXIDMA=y
+# CONFIG_XILINX_DMATEST is not set
+CONFIG_XILINX_AXIVDMA=y
+# CONFIG_XILINX_VDMATEST is not set
+CONFIG_XILINX_AXICDMA=y
+# CONFIG_XILINX_CDMATEST is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_PL330_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_CIF is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_MF624 is not set
+CONFIG_UIO_XILINX_APM=y
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=y
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_COMMON_CLK_VERSATILE=y
+# CONFIG_COMMON_CLK_SI5351 is not set
+CONFIG_COMMON_CLK_SI570=y
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CADENCE_TTC_TIMER=y
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_OF_IOMMU=y
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=y
+# CONFIG_STE_MODEM_RPROC is not set
+CONFIG_ZYNQ_REMOTEPROC=y
+CONFIG_MB_REMOTEPROC=y
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=y
+# CONFIG_RPMSG_SERVER_SAMPLE is not set
+# CONFIG_RPMSG_OMX is not set
+# CONFIG_RPMSG_FREERTOS_STAT is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+CONFIG_MEMORY=y
+CONFIG_ZYNQ_SMC=y
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_PREEMPT=y
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_TRACE_CLOCK=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_INTERRUPT_OFF_HIST=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_PREEMPT_OFF_HIST=y
+CONFIG_SCHED_TRACER=y
+CONFIG_WAKEUP_LATENCY_HIST=y
+CONFIG_MISSED_TIMER_OFFSETS_HIST=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_TRACER_SNAPSHOT=y
+CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_PROBE_EVENTS is not set
+CONFIG_DYNAMIC_FTRACE=y
+# CONFIG_FUNCTION_PROFILER is not set
+CONFIG_FTRACE_MCOUNT_RECORD=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_RING_BUFFER_STARTUP_TEST is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_OLD_MCOUNT=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ZYNQ_UART0 is not set
+CONFIG_DEBUG_ZYNQ_UART1=y
+# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
+# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_SEMIHOSTING is not set
+# CONFIG_DEBUG_LL_UART_8250 is not set
+# CONFIG_DEBUG_LL_UART_PL01X is not set
+CONFIG_DEBUG_LL_INCLUDE="debug/zynq.S"
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_UART_8250 is not set
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_EARLY_PRINTK=y
+# CONFIG_OC_ETM is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_VIRTUALIZATION=y
Index: linux-3.12.24-rt38-xilinx/debian/changelog
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/debian/changelog	2014-07-20 22:06:35.055327178 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2 @
+linux-image-zedboard-3.12.14-rt23 (3.12.14-rt23-2) unstable; urgency=low
+
+  * Custom built Linux kernel.
+
+ -- Anonymous <root@slartibartfast.linutronix>  Wed, 04 Jun 2014 08:42:05 +0200
Index: linux-3.12.24-rt38-xilinx/debian/control
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/debian/control	2014-07-20 22:06:35.060327095 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Source: linux-image-zedboard-3.12.14-rt23
+Section: kernel
+Priority: optional
+Maintainer: Anonymous <root@slartibartfast.linutronix>
+Standards-Version: 3.8.4
+Homepage: http://www.kernel.org/
+
+Package: linux-image-zedboard-3.12.14-rt23
+Provides: linux-image, linux-image-2.6, linux-modules-3.12.14-rt23
+Suggests: linux-firmware-image-zedboard-3.12.14-rt23
+Architecture: any
+Description: Linux kernel, version 3.12.14-rt23
+ This package contains the Linux kernel, modules and corresponding other
+ files, version: 3.12.14-rt23.
+
+Package: linux-headers-zedboard-3.12.14-rt23
+Provides: linux-headers, linux-headers-2.6
+Architecture: any
+Description: Linux kernel headers for 3.12.14-rt23 on amd64
+ This package provides kernel header files for 3.12.14-rt23 on amd64
+ .
+ This is useful for people who need to build external modules
+
+Package: linux-libc-dev
+Section: devel
+Provides: linux-kernel-headers
+Architecture: any
+Description: Linux support headers for userspace development
+ This package provides userspaces headers from the Linux kernel.  These headers
+ are used by the installed headers for GNU glibc and other system libraries.
Index: linux-3.12.24-rt38-xilinx/debian/copyright
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/debian/copyright	2014-07-20 22:06:35.066326996 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+This is a packacked upstream version of the Linux kernel.
+
+The sources may be found at most Linux ftp sites, including:
+ftp://ftp.kernel.org/pub/linux/kernel
+
+Copyright: 1991 - 2009 Linus Torvalds and others.
+
+The git repository for mainline kernel development is at:
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; version 2 dated June, 1991.
+
+On Debian GNU/Linux systems, the complete text of the GNU General Public
+License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
Index: linux-3.12.24-rt38-xilinx/debian/source/format
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/debian/source/format	2014-07-20 22:06:35.075326848 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+3.0 (git)
Index: linux-3.12.24-rt38-xilinx/debian/source/options
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/debian/source/options	2014-07-20 22:06:35.080326765 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+git-ref=HEAD
+git-depth=3
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/arm/zynq/xlnx,zynq-ocm.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/arm/zynq/xlnx,zynq-ocm.txt	2014-07-20 22:06:35.096326501 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device tree bindings for Zynq's OCM
+
+The OCM is divided to 4 64kB segments which can be separately configured
+to low or high location. Location is controlled via SLCR.
+
+Required properties:
+ compatible: Compatibility string. Must be "xlnx,zynq-ocm-1.0".
+ reg: Specify the base and size of the OCM registers in the memory map.
+      E.g.: reg = <0xf800c000 0x1000>;
+
+Example:
+ps7_ram_0: ps7-ram@f800c000 {
+	compatible = "xlnx,zynq-ocm-1.0";
+	reg = <0xf800c000 0x1000>;
+	interrupt-parent = <&ps7_scugic_0>;
+	interrupts = <0 3 4>;
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/arm/zynq/xlnx,zynq-smc.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/arm/zynq/xlnx,zynq-smc.txt	2014-07-20 22:06:35.102326402 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device tree bindings for Zynq's SMC (PL353)
+
+The SMC supports NAND, NOR and SRAM memory. The SMC driver handles generic
+tasks, while children drivers handle memory type specifics.
+
+Required properties:
+ compatible: Compatibility string. Must be "xlnx,ps7-smc".
+ reg: Specify the base and size of the SMC registers in the memory map.
+      E.g.: reg = <0xe000e000 0x1000>;
+ #address-cells: Address cells, must be 1.
+ #size-cells: Size cells. Must be 1.
+ ranges
+
+Child nodes:
+ For NAND the "xlnx,ps7-nand" and for NOR the "cfi-flash" drivers are supported
+ as child nodes.
+
+Example:
+	ps7_smc_0: ps7-smc@e000e000 {
+		compatible = "xlnx,ps7-smc";
+		reg = <0xe000e000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		ps7_nand_0: ps7-nand@e1000000 {
+			compatible = "xlnx,ps7-nand-1.00.a";
+			(...)
+		};
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/clock/silabs,si570.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/clock/silabs,si570.txt	2014-07-20 22:06:35.113326221 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Binding for Silicon Labs 570, 571, 598 and 599 programmable
+I2C clock generators.
+
+Reference
+This binding uses the common clock binding[1]. Details about the devices can be
+found in the data sheets[2][3].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Si570/571 Data Sheet
+    http://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf
+[3] Si598/599 Data Sheet
+    http://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf
+
+Required properties:
+ - compatible: Shall be one of "silabs,si570", "silabs,si571",
+			       "silabs,si598", "silabs,si599"
+ - reg: I2C device address.
+ - #clock-cells: From common clock bindings: Shall be 0.
+ - factory-fout: Factory set default frequency. This frequency is part specific.
+		 The correct frequency for the part used has to be provided in
+		 order to generate the correct output frequencies. For more
+		 details, please refer to the data sheet.
+ - temperature-stability: Temperature stability of the device in PPM. Should be
+			  one of: 7, 20, 50 or 100.
+
+Optional properties:
+ - clock-output-names: From common clock bindings. Recommended to be "si570".
+ - clock-frequency: Output frequency to generate. This defines the output
+		    frequency set during boot. It can be reprogrammed during
+		    runtime through the common clock framework.
+
+Example:
+	si570: clock-generator@5d {
+		#clock-cells = <0>;
+		compatible = "silabs,si570";
+		temperature-stability = <50>;
+		reg = <0x5d>;
+		factory-fout = <156250000>;
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/clock/zynq-7000.txt
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/Documentation/devicetree/bindings/clock/zynq-7000.txt	2014-07-20 22:05:50.329065087 +0200
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/clock/zynq-7000.txt	2014-07-20 22:06:35.121326089 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:25 @
 Optional properties:
  - clocks : as described in the clock bindings
  - clock-names : as described in the clock bindings
+ - fclk-enable : Bit mask to enable FCLKs in cases no proper CCF compatible
+		 driver is available. Bit [0..3] correspond to FCLK0..FCLK3. The
+		 corresponding FCLK will only be enabled if it is actually
+		 running at boot time.
 
 Clock inputs:
 The following strings are optional parameters to the 'clock-names' property in
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-cdma.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-cdma.txt	2014-07-20 22:06:35.135325858 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx AXI CDMA engine, it does transfers between memory and memory
+
+Required properties:
+- compatible: Should be "xlnx,axi-cdma"
+- reg: Should contain CDMA registers location and length.
+- interrupts: Should contain channel CDMA interrupts.
+
+Example:
+++++++++
+
+axi_cdma_0: axicdma@40030000 {
+	compatible = "xlnx,axi-cdma";
+	reg = < 0x40030000 0x10000 >;
+	dma-channel@40030000 {
+		interrupts = < 0 59 4 >;
+	} ;
+} ;
+
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt	2014-07-20 22:06:35.141325759 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx AXI DMA engine, it does transfers between memory and device. It can be
+configured to have one channel or two channels. If configured as two
+channels, one is to transmit to device and another is to receive from
+device.
+
+Required properties:
+- compatible: Should be "xlnx,axi-dma"
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain per channel DMA interrupts.
+- compatible (child node): It should be either "xlnx,axi-dma-mm2s-channel" or
+	"xlnx,axi-dma-s2mm-channel". It depends on the hardware design and it
+	can also have both channels.
+
+Example:
+++++++++
+
+axi_dma_0: axidma@40400000 {
+	compatible = "xlnx,axi-dma";
+	reg = < 0x40400000 0x10000 >;
+	dma-channel@40400000 {
+		compatible = "xlnx,axi-dma-mm2s-channel";
+		interrupts = < 0 59 4 >;
+	} ;
+	dma-channel@40030030 {
+		compatible = "xlnx,axi-dma-s2mm-channel";
+		interrupts = < 0 58 4 >;
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-vdma.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/axi-vdma.txt	2014-07-20 22:06:35.147325660 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx AXI VDMA engine, it does transfers between memory and video devices.
+It can be configured to have one channel or two channels. If configured
+as two channels, one is to transmit to the video device and another is
+to receive from the video device.
+
+Required properties:
+- compatible: Should be "xlnx,axi-vdma"
+- #dma-cells: Should be <1>, see "dmas" property below
+- reg: Should contain VDMA registers location and length.
+- interrupts: Should contain per channel VDMA interrupts.
+- compatible (child node): It should be either "xlnx,axi-vdma-mm2s-channel" or
+	"xlnx,axi-vdma-s2mm-channel". It depends on the hardware design and it
+	can also have both channels.
+- xlnx,device-id: Should contain device number in each channel. It should be
+	{0,1,2...so on} to the number of VDMA devices configured in hardware.
+- xlnx,num-fstores: Should be the number of framebuffers as configured in h/w.
+- xlnx,data-width: Should contain the stream data width, takes {32,64...so on}.
+- xlnx,flush-fsync: (Optional) Tells whether which channel to Flush on Fsync.
+	It takes following values:
+	{1}, flush both channels
+	{2}, flush mm2s channel
+	{3}, flush s2mm channel
+- xlnx,include-sg: (Optional) Tells whether configured for Scatter-mode in
+	the hardware.
+- xlnx,include-dre: (Optional) Tells whether hardware is configured for Data
+	Realignment Engine.
+- xlnx,genlock-mode: (Optional) Tells whether Genlock synchornisation is
+	enabled/disabled in hardware.
+
+Example:
+++++++++
+
+axi_vdma_0: axivdma@40030000 {
+	compatible = "xlnx,axi-vdma";
+	#dma_cells = <1>;
+	reg = < 0x40030000 0x10000 >;
+	xlnx,flush-fsync = <0x1>;
+	dma-channel@40030000 {
+		compatible = "xlnx,axi-vdma-mm2s-channel";
+		interrupts = < 0 54 4 >;
+		xlnx,num-fstores = <0x8>;
+		xlnx,device-id = <0x0>;
+		xlnx,datawidth = <0x40>;
+	} ;
+	dma-channel@40030030 {
+		compatible = "xlnx,axi-vdma-s2mm-channel";
+		interrupts = < 0 53 4 >;
+		xlnx,num-fstores = <0x8>;
+		xlnx,device-id = <0x0>;
+		xlnx,datawidth = <0x40>;
+	} ;
+} ;
+
+
+* Xilinx Video DMA client
+
+Required properties:
+- dmas: a list of <[Video DMA device phandle] [Channel ID]> pairs,
+	where Channel ID is '0' for write/tx and '1' for read/rx
+	channel.
+- dma-names: a list of DMA channel names, one per "dmas" entry
+
+VDMA Test Client Example:
++++++++++++++++++++++++++
+
+vdmatest_0: vdmatest@0 {
+	compatible ="xlnx,axi-vdma-test";
+	dmas = <&axi_vdma_0 0
+		&axi_vdma_0 1>;
+	dma-names = "vdma0", "vdma1";
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/vdmatest.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/dma/xilinx/vdmatest.txt	2014-07-20 22:06:35.153325561 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+* Xilinx Video DMA Test client
+
+Required properties:
+- compatible: Should be "xlnx,axi-vdma-test"
+- dmas: a list of <[Video DMA device phandle] [Channel ID]> pairs,
+	where Channel ID is '0' for write/tx and '1' for read/rx
+	channel.
+- dma-names: a list of DMA channel names, one per "dmas" entry
+- xlnx,num-fstores: Should be the number of framebuffers as configured in
+	VDMA device node.
+
+Example:
+++++++++
+
+vdmatest_0: vdmatest@0 {
+	compatible ="xlnx,axi-vdma-test";
+	dmas = <&axi_vdma_0 0
+		&axi_vdma_0 1>;
+	dma-names = "vdma0", "vdma1";
+	xlnx,num-fstores = <0x8>;
+} ;
+
+
+Xilinx Video DMA Device Node Example
+++++++++++++++++++++++++++++++++++++
+axi_vdma_0: axivdma@44A40000 {
+	compatible = "xlnx,axi-vdma";
+	...
+	dma-channel@44A40000 {
+		...
+		xlnx,num-fstores = <0x8>;
+		...
+	} ;
+	dma-channel@44A40030 {
+		...
+		xlnx,num-fstores = <0x8>;
+		...
+	} ;
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/cresample.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/cresample.txt	2014-07-20 22:06:35.165325363 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device-Tree bindings for Xilinx Chroma Resampler(CRESAMPLE)
+
+Xilinx CRESAMPLE provides the chroma resampling of YUV formats.
+
+Required properties:
+ - compatible: value should be "xlnx,v-cresample-3.01.a"
+ - reg: base address and size of the CRESAMPLE IP
+ - xlnx,input-format, xlnx,output-format: the input/output video formats of
+   CRESAMPLE. The value should be one of following format strings.
+
+	yuv422
+	yuv444
+	yuv420
+
+Example:
+
+	v_cresample_0: v-cresample@40020000 {
+		compatible = "xlnx,v-cresample-3.01.a";
+		reg = <0x40020000 0x10000>;
+		xlnx,input-format = "yuv444";
+		xlnx,output-format = "yuv422";
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/osd.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/osd.txt	2014-07-20 22:06:35.171325264 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device-Tree bindings for Xilinx Video On Screen Display(OSD)
+
+Xilinx OSD provides the multiplane support. Some properties can be configured
+in IP synthesis.
+
+Required properties:
+ - compatible: value should be "xlnx,v-osd-5.01.a"
+ - reg: base address and size of the OSD IP
+ - xlnx,num-layers: the number of layers(up to 8) supported by OSD
+ - xlnx,screen-width: the maximum size(up to 4096) of screen pixel width by OSD
+
+Example:
+
+	v_osd_0: v-osd@40040000 {
+		compatible = "xlnx,v-osd-5.01.a";
+		reg = <0x40040000 0x10000>;
+		xlnx,num-layers = <2>;
+		xlnx,screen-width = <1920>;
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/rgb2ycrcb.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/rgb2ycrcb.txt	2014-07-20 22:06:35.177325165 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device-Tree bindings for Xilinx RGB to YCrCb convertor(RGB2YCRCB)
+
+Xilinx RGB2YCRCB converts the pixel format from RGB to YCrCb
+
+Required properties:
+ - compatible: value should be "xlnx,v-rgb2ycrcb-6.01.a"
+ - reg: base address and size of the RGB2YCRCB IP
+
+Example:
+
+	v_rgb2ycrcb_0: v-rgb2ycrcb@40030000 {
+		compatible = "xlnx,v-rgb2ycrcb-6.01.a";
+		reg = <0x40030000 0x10000>;
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/vtc.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/vtc.txt	2014-07-20 22:06:35.183325066 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device-Tree bindings for Xilinx Video Timing Controller(VTC)
+
+Xilinx VTC provides the timings for Video IPs.
+
+Required properties:
+ - compatible: value should be "xlnx,v-tc-5.01.a"
+ - reg: base address and size of the VTC IP
+ - interrupts: the interrupt number
+ - interrupts-parent: the phandle for interrupt controller
+
+Example:
+
+	v_tc_0: v-tc@40010000 {
+		compatible = "xlnx,v-tc-5.01.a";
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 54 4>;
+		reg = <0x40010000 0x10000>;
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/xilinx_drm.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/drm/xilinx/xilinx_drm.txt	2014-07-20 22:06:35.190324951 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device-Tree bindings for Xilinx DRM
+
+Xilinx DRM supports the display pipelines with Xilinx soft IPs on FPGA and
+IPs on Xilinx boards.
+
+The example hardware pipeline is depicted below
+(*IPs in parentheses() are optional. IPs in brackets[] don't require drivers).
+vdma-[remap]-(rgb2yuv)-(cresample)-(osd)-(rgb2yuv)-(cresample)-[axi2vid]-adv7511
+(vdma-[remap]-(rgb2yuv)-(cresample)-|)                             |
+                                                         si570 -> vtc
+
+Required properties:
+ - compatible: value should be "xlnx,drm".
+ - osd: the phandle for on screen display IP if used in the hardware design
+ - rgb2yuv: the phandle for rgb2ycrcb IP if used in the hardware design
+ - cresample: the phandle for chroma resampler IP if used in the hardware design
+ - vtc: the phandle for video timing controller IP
+ - encoder-slave: the phandle for the encoder slave.
+ - clocks: the phandle for the pixel clock
+ - planes: the subnode for resources for each plane
+
+Required plane properties:
+ - dmas: the phandle list of DMA specifiers
+ - dma-names: the indentifier strings for DMAs
+ - rgb2yuv: the phandle for rgb2ycrcb IP if used for plane
+ - cresample: the phandle for chroma resampler IP if used for plane
+
+The pipeline can be configured as following examples or more.
+ - Example 1:
+vdma - [remap] - rgb2yuv - cresample - [axi2vid] - adv7511
+                                                      |
+                                             si570 - vtc
+	xilinx_drm {
+		compatible = "xlnx,drm";
+		vtc = <&v_tc_0>;
+		encoder-slave = <&adv7511>;
+		clocks = <&si570>;
+		planes {
+			plane0 {
+				dma = <&axi_vdma_0>;
+				dma-names = "vdma";
+				rgb2yuv = <&v_rgb2ycrcb_0>;
+				cresample = <&v_cresample_0>;
+			};
+		};
+	};
+
+ - Example 2:
+vdma - [remap] --------- osd - cresample - [axi2vid] - adv7511
+vdma - [remap] - rgb2yuv -|                               |
+                                                 si570 - vtc
+
+	xilinx_drm {
+		compatible = "xlnx,drm";
+		osd = <&v_osd_0>;
+		cresample = <&v_cresample_0>;
+		vtc = <&v_tc_0>;
+		encoder-slave = <&adv7511>;
+		clocks = <&si570>;
+		planes {
+			plane0 {
+				dma = <&axi_vdma_0>;
+				dma-names = "vdma";
+			};
+			plane1 {
+				dma = <&axi_vdma_1>;
+				dma-names = "vdma";
+				rgb2yuv = <&v_rgb2ycrcb_0>;
+			};
+		};
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/edac/zynq_edac.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/edac/zynq_edac.txt	2014-07-20 22:06:35.200324786 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Zynq EDAC driver, it does reports the DDR ECC single bit errors that are
+corrected and double bit ecc errors that are detected by the DDR ECC controller.
+ECC support for DDR is available in half-bus width(16 bit) configuration only.
+
+Required properties:
+- compatible: Should be "xlnx,ps7-ddrc" or "xlnx,ps7-ddrc-1.00.a"
+- reg: Should contain DDR controller registers location and length.
+
+Example:
+++++++++
+
+ps7_ddrc_0: ps7-ddrc@f8006000 {
+	compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc";
+	reg = <0xf8006000 0x1000>;
+};
+
+Zynq EDAC driver detects the DDR ECC enable state by reading the appropriate
+control register.
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt	2014-07-20 22:05:50.330065070 +0200
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt	2014-07-20 22:06:35.234324225 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:12 @
 - compatible : Should be "xlnx,xps-gpio-1.00.a"
 - reg : Address and length of the register set for the device
 - #gpio-cells : Should be two. The first cell is the pin number and the
-  second cell is used to specify optional parameters (currently unused).
+  second cell is used to specify channel offset:
+		0 - first channel
+		8 - second channel
 - gpio-controller : Marks the device node as a GPIO controller.
 
 Optional properties:
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/video.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/video.txt	2014-07-20 22:06:35.248323994 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+DT bindings for Xilinx video IP cores
+-------------------------------------
+
+Xilinx video IP cores process video streams by acting as video sinks and/or
+sources. They are connected by links through their input and output ports,
+creating a video pipeline.
+
+Each video IP core is represented by an AMBA bus child node in the device
+tree using bindings documented in this directory. Connections between the IP
+cores are represented as defined in ../video-interfaces.txt.
+
+Common properties
+-----------------
+
+The following properties are common to all Xilinx video IP cores.
+
+- xlnx,axi-video-format: This property represents a video format transmitted
+  on an AXI bus between video IP cores. How the format relates to the IP core
+  is decribed in the IP core bindings documentation. The following formats are
+  supported.
+
+	rbg
+	xrgb
+	yuv422
+
+- xlnx,axi-video-width: This property qualifies the video format with the
+  sample width expressed as a number of bits per pixel component. All components
+  must use the same width.
+
+The following table lists the supported formats and widths combinations, along
+with the corresponding media bus pixel code.
+
+----------------+-------+-------------------------------------------------------
+Format		| Width	| Media bus code
+----------------+-------+-------------------------------------------------------
+rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
+xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
+yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
+----------------+-------+-------------------------------------------------------
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/xlnx,axi-remapper.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/xlnx,axi-remapper.txt	2014-07-20 22:06:35.254323895 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx Video Remapper
+---------------------
+
+The IP core remaps input pixel components to produce an output pixel with
+less, more or the same number of components as the input pixel.
+
+Required properties:
+
+- compatible: Must be "xlnx,axi-remapper".
+
+- xlnx,axi-video-width: Video pixel component width, as defined in video.txt.
+
+- #xlnx,axi-s-components: Number of components per pixel at the input port
+  (between 1 and 4 inclusive).
+
+- #xlnx,axi-m-components: Number of components per pixel at the output port
+  (between 1 and 4 inclusive).
+
+- xlnx,axi-component-maps: Remapping configuration represented as an array of
+  integers. The array contains one entry per output component, in the low to
+  high order. Each entry corresponds to the zero-based position of the
+  corresponding input component, or the value 4 to drive a constant value on
+  the output component. For example, to remap RGB to BGR use <2 1 0>, and to
+  remap RBG to xRGB use <1 0 2 4>.
+
+- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt.
+  The remapper as an input port (0) and and output port (1).
+
+Example: RBG to xRGB remapper
+
+	axi_remapper_0: axi_remapper {
+		compatible = "xlnx,axi-remapper";
+
+		xlnx,axi-video-width = <8>;
+
+		#xlnx,axi-s-components = <3>;
+		#xlnx,axi-m-components = <4>;
+		xlnx,axi-component-maps = <1 0 2 4>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				remap0_in: endpoint {
+					remote-endpoint = <&tpg0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				remap0_out: endpoint {
+					remote-endpoint = <&sobel0_in>;
+				};
+			};
+		};
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/xlnx,axi-tpg.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/media/xilinx/xlnx,axi-tpg.txt	2014-07-20 22:06:35.260323796 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx Video Test Pattern Generator (TPG)
+-----------------------------------------
+
+Required properties:
+
+- compatible: Must be "xlnx,axi-tpg".
+
+- reg: Physical base address and length of the registers set for the device.
+
+- xlnx,axi-video-format, xlnx,axi-video-width: Video format and width, as
+  defined in video.txt.
+
+- port: Video port, using the DT bindings defined in ../video-interfaces.txt.
+  The TPG has a single output port numbered 0.
+
+Example:
+
+	axi_tpg_0: axi_tpg@40050000 {
+		compatible = "xlnx,axi-tpg";
+		reg = <0x40050000 0x10000>;
+
+		xlnx,axi-video-format = "yuv422";
+		xlnx,axi-video-width = <8>;
+
+		port {
+			tpg0_out: endpoint {
+				remote-endpoint = <&remap0_in>;
+			};
+		};
+	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/misc/xilinx-axitrafgen.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/misc/xilinx-axitrafgen.txt	2014-07-20 22:06:35.270323631 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+* Xilinx AXI Traffic generator IP
+
+Required properties:
+- compatible: "xlnx,axi-traffic-gen"
+- interrupts: Should contain AXI Traffic Generator interrupts.
+- interrupt-parent: Must be core interrupt controller.
+- reg: Should contain AXI Traffic Generator registers location and length.
+- interrupt-names: Should contain both the intr names of device - error
+		   and completion.
+- xlnx,device-id: Device instance Id.
+
+Example:
+++++++++
+axi_traffic_gen_1: axi-traffic-gen@76000000 {
+	compatible = "xlnx,axi-traffic-gen-1.0", "xlnx,axi-traffic-gen";
+	interrupts = <0 2 2 2>;
+	interrupt-parent = <&axi_intc_1>;
+	interrupt-names = "err-out", "irq-out";
+	reg = <0x76000000 0x800000>;
+	xlnx,device-id = <0x0>;
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt	2014-07-20 22:06:35.281323450 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Device Tree Bindings for the Arasan SDHCI Controller
+
+  The bindings follow the mmc[1], clock[2] and interrupt[3] bindings. Only
+  deviations are documented here.
+
+  [1] Documentation/devicetree/bindings/mmc/mmc.txt
+  [2] Documentation/devicetree/bindings/clock/clock-bindings.txt
+  [3] Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Required Properties:
+  - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a'
+  - reg: From mmc bindings: Register location and length.
+  - clocks: From clock bindings: Handles to clock inputs.
+  - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb"
+  - interrupts: Interrupt specifier
+  - interrupt-parent: Phandle for the interrupt controller that services
+		      interrupts for this device.
+
+Example:
+	sdhci@e0100000 {
+		compatible = "arasan,sdhci-8.9a";
+		reg = <0xe0100000 0x1000>;
+		clock-names = "clk_xin", "clk_ahb";
+		clocks = <&clkc 21>, <&clkc 32>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 24 4>;
+	} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/net/can/xilinx_can.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/net/can/xilinx_can.txt	2014-07-20 22:06:35.300323136 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
+---------------------------------------------------------
+
+Required properties:
+- compatible		: Should be "xlnx,ps7-can" for Zynq CAN controllers and
+			  "xlnx,axi-can-1.00.a" for Axi CAN controllers.
+- reg			: Physical base address and size of the Axi CAN/Zynq
+			  CANPS registers map.
+- interrupts		: Property with a value describing the interrupt
+			  number.
+- interrupt-parent	: Must be core interrupt controller
+- clock-names		: List of input clock names - "ref_clk", "aper_clk"
+			  (See clock bindings for details).
+- clocks		: Clock phandles (see clock bindings for details).
+
+
+Example:
+
+For Zynq CANPS Dts file:
+	ps7_can_0: ps7-can@e0008000 {
+			compatible = "xlnx,ps7-can";
+			clocks = <&clkc 19>, <&clkc 36>;
+			clock-names = "ref_clk", "aper_clk";
+			reg = <0xe0008000 0x1000>;
+			interrupts = <0 28 4>;
+			interrupt-parent = <&gic>;
+		};
+For Axi CAN Dts file:
+	axi_can_0: axi-can@40000000 {
+			compatible = "xlnx,axi-can-1.00.a";
+			clocks = <&clkc 0>;
+			clock-names = "ref_clk" ;
+			reg = <0x40000000 0x10000>;
+			interrupt-parent = <&ps7_scugic_0>;
+			interrupts = <0 59 1>;
+		};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/pci/xilinx-axipcie.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/pci/xilinx-axipcie.txt	2014-07-20 22:06:35.311322955 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+* Xilinx AXI PCIe Root Port Bridge
+
+Required properties:
+	compatible: Should be "xlnx,axi-pcie-1.05.a"
+	reg: Should contain AXI PCIe registers location and length.
+	interrupts: Should contain AXI PCIe interrupts.
+	ranges: These are the parameters for each PCIe bar implemented within the IP
+	The ranges property is <<child address> <parent address> <size>>.
+	The parent address #address-cells is taken from the parent node.
+	xlnx, include-rc: Root Port (=1) or End Point(=0)
+	xlnx,axibar2pciebar-0: Translates address from AXI to PCIe
+	xlnx,pciebar2axibar-0: Translates address from PCIe to AXI
+
+Example:
+++++++++
+
+	ps7_axi_interconnect_0: axi@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		pci_express: axi-pcie@50000000 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			compatible = "xlnx,axi-pcie-1.05.a";
+			interrupts = < 0 52 4 >;
+			ranges = < 0x02000000 0 0x60000000 0x60000000 0 0x10000000 >;
+			reg = < 0x50000000 0x10000000 >;
+			xlnx,include-rc = <0x1>;
+			xlnx,axibar2pciebar-0 = <0x60000000>;
+			xlnx,pciebar2axibar-0 = <0x0>;
+		};
+ 	};
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/remoteproc/mb_remoteproc.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/remoteproc/mb_remoteproc.txt	2014-07-20 22:06:35.321322790 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Xilinx ARM-Microblaze remoteproc driver
+
+This driver requires specific Zynq hardware design where Microblaze is added
+to the programmable logic.
+Microblaze is connected with PS block via axi bus connected to PS HP port
+to ensure access to PS DDR.
+Communication channels are done via soft GPIO IP connected to PS block
+and to Microblaze. There are also 2 gpio control signals reset and debug
+which are used for reseting Microblaze.
+
+Required properties:
+- compatible : Should be "xlnx,mb_remoteproc"
+- reg : Address and length of the ddr address space
+- bram: Phandle to bram controller which can access Microblaze BRAM
+- bram-firmware : Microblaze BRAM bootloader name
+- firmware : Default firmware name which can be override by
+	     "firmware" module parameter
+- reset : Gpio phandle which reset Microblaze remoteproc
+- debug : Gpio phandle which setup Microblaze to debug state
+- ipino : Gpio phandle for Microblaze to ARM communication
+- vring0 : Gpio phandle for ARM to Microblaze communication vring 0
+- vring1 : Gpio phandle for ARM to Microblaze communication vring 1
+
+Microblaze SoC can be also connected to the PS block via a axi bus.
+That's why there is the option to allocate interrupts for Microblaze use only.
+The driver will allocate interrupts to itself and Microblaze sw has to ensure
+that interrupts are properly enabled and handled by Microblaze interrupt
+controller.
+
+Optional properties:
+ - interrupts : Interrupt mapping for remoteproc
+ - interrupt-parent : Phandle for the interrupt controller
+
+Example:
+test_mb: mb_remoteproc-test@800000 {
+	compatible = "xlnx,mb_remoteproc";
+	reg = < 0x8000000 0x8000000 >;
+	bram = <&axi_bram_ctrl_0>;
+	bram-firmware = "mb.bin";
+	firmware = "image.elf";
+	reset = <&zynq_gpio_reset 1 0>;
+	debug = <&zynq_gpio_reset 0 0>;
+	ipino = <&zynq_gpio_vring 0 0>;
+	vring0 = <&zynq_gpio_vring 1 0>;
+	vring1 = <&zynq_gpio_vring 2 0>;
+} ;
Index: linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/xilinx.txt
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/Documentation/devicetree/bindings/xilinx.txt	2014-07-20 22:05:50.332065037 +0200
+++ linux-3.12.24-rt38-xilinx/Documentation/devicetree/bindings/xilinx.txt	2014-07-20 22:06:35.330322642 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:256 @
 
       Optional properties:
        - 8-bit (empty) : Set this property for SystemACE in 8 bit mode
+       - port-number = <port_number> : Set port number for particular device
 
       iii) Xilinx EMAC and Xilinx TEMAC
 
Index: linux-3.12.24-rt38-xilinx/Documentation/pmods/00-INDEX
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/pmods/00-INDEX	2014-07-20 22:06:35.341322460 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+Documentation for pmods, a set of peripheral modules provided by Digilent Inc.,
+which can be plugged to various development boards to add additional functionalities.
+These drivers are maintained by Digilent Inc.
+
+00-INDEX
+	- this file
+pmodoled.txt
+	- PmodOLED: 128 by 32 pixel 0.9" Organic LED Graphic Display
Index: linux-3.12.24-rt38-xilinx/Documentation/pmods/pmodoled.txt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/Documentation/pmods/pmodoled.txt	2014-07-20 22:06:35.347322361 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+PmodOLED
+========
+
+Copyright 2012, Digilent Inc.
+
+
+Description
+-----------
+
+The PmodOLED features an SPI-controlled monochrome OLED display,
+perfect for embedded applications requiring small, complex visual output.
+
+The PmodOLED uses a standard 12-pin connector to display output on
+a 128x32 pixel organic LED (OLED) panel. The graphic display panel uses
+the Solomon Systech SSD1306 display controller.
+
+An SPI interface is used to configure the display,
+as well as to send the bitmap data to the device.
+
+The PmodOLED displays the last image drawn on the screen until it is
+powered down or a new image is drawn to the display. Refreshing and
+updating is handled internally.
+
+The Reference Manual for PmodOLED display is available online at
+Digilent Inc. Website (www.digilentinc.com)
+
+For more information on the OLED display interface, see the
+UG-2832HSWEG04 datasheet available online or from Univisio.
+
+The OLED display uses a compatible command set from the SSD1306 device.
+For more information, see the SSD1306 datasheet available at
+www.solomon-systech.com.
+
+
+Interface
+---------
+
+Signal     Description
+
+CS         SPI Chip Select (Slave Select)
+SDIN       SPI Data In (MOSI)
+SCLK       SPI Clock
+D/C        Data/Command Control
+RES        Power Reset
+VBATC      VBAT Battery Voltage Control
+VDDC       VDD Logic Voltage Control
+
+
+Devicetree
+----------
+
+Required Properties:
+- compatible : Should be "dlgnt,pmodoled-gpio"
+- vbat-gpio :  Should specify the GPIO for VBATC, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+- vdd-gpio :  Should specify the GPIO for VDDC, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+- res-gpio :  Should specify the GPIO for RES, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+- dc-gpio :  Should specify the GPIO for D/C, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+- spi-bus-num :  Should specify the bus number for PmodOLED SPI controller.
+  This value cannot be shared by any other SPI controller present in the
+  device tree.
+- spi-sclk-gpio :  Should specify the GPIO for SCLK, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+- spi-sdin-gpio :  Should specify the GPIO for SDIN, see "gpios property" in
+  Documentation/devicetree/gpio.txt.
+
+Optional Properties:
+- spi-cs-gpio :  Should specify the GPIO for CS, see "gpios property" in
+  Documentation/devicetree/gpio.txt. If unspecified, CS is assumed to be
+  tied to ground.
+
+Examples:
+
+zed_oled {
+	compatible = "dglnt,pmodoled-gpio";
+	/* GPIO Pins */
+	vbat-gpio = <&gpiops 55 0>;
+	vdd-gpio = <&gpiops 56 0>;
+	res-gpio = <&gpiops 57 0>;
+	dc-gpio = <&gpiops 58 0>;
+	/* SPI-GPIOs */
+	spi-bus-num = <2>;
+	spi-sclk-gpio = <&gpiops 59 0>;
+	spi-sdin-gpio = <&gpiops 60 0>;
+};
+
+pmodoled_A {
+	compatible = "dglnt,pmodoled-gpio";
+	vbat-gpio = <&gpiops 88 0>;
+	vdd-gpio = <&gpiops 89 0>;
+	res-gpio = <&gpiops 87 0>;
+	dc-gpio = <&gpiops 86 0>;
+	spi-bus-num = <3>;
+	spi-sclk-gpio = <&gpiops 85 0>;
+	spi-sdin-gpio = <&gpiops 83 0>;
+	spi-cs-gpio = <&gpiops 82 0>;
+};
+
+
+Configuration
+-------------
+
+The PmodOLED is located in the kernel configuration menu at
+Device Drivers -> Pmods -> PmodOLED. The driver can be built into the kernel
+by selecting (*) for it, or loadable module by selecting (M) for it.
+
+
+Device Nodes
+------------
+
+A char device node will be created for each PmodOLED device automatically.
+The name of the node is default to the one declared in the device tree.
+
+
+Read/Writes
+-----------
+
+The driver provides a 512 Byte display buffer for the display of PmodOLED.
+The Whole screen is divided into four lines, each of them is 128 bits wide
+and 8 bits high, as shown in the figure below.
+
+    +--------------------------...----------------------------+
+    +                         Line 4                          +
+    +--------------------------...----------------------------+
+    +                         Line 3                          +
+    +--------------------------...----------------------------+
+    +                         Line 2                          +
+    +--------------------------...----------------------------+ MSB (bit 7)
+    +                         Line 1                          +
+    +--------------------------...----------------------------+ LSB (bit 0)
+byte 127                                                     byte 0
+
+Users can perform read and write functions to the device node to access the data
+inside the display buffer.
Index: linux-3.12.24-rt38-xilinx/drivers/char/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/char/Kconfig	2014-07-20 22:05:50.188067413 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/char/Kconfig	2014-07-20 22:06:35.363322097 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:381 @
 
 	  If unsure, say N.
 
+config XILINX_DEVCFG
+	tristate "Xilinx Device Configuration"
+	depends on ARCH_ZYNQ
+	help
+	  This option enables support for the Xilinx device configuration driver.
+	  If unsure, say N
+
 config R3964
 	tristate "Siemens R3964 line discipline"
 	depends on TTY
Index: linux-3.12.24-rt38-xilinx/drivers/char/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/char/Makefile	2014-07-20 22:05:50.186067446 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/char/Makefile	2014-07-20 22:06:35.373321932 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:34 @
 obj-$(CONFIG_EFI_RTC)		+= efirtc.o
 obj-$(CONFIG_DS1302)		+= ds1302.o
 obj-$(CONFIG_XILINX_HWICAP)	+= xilinx_hwicap/
+obj-$(CONFIG_XILINX_DEVCFG)	+= xilinx_devcfg.o
 ifeq ($(CONFIG_GENERIC_NVRAM),y)
   obj-$(CONFIG_NVRAM)	+= generic_nvram.o
 else
Index: linux-3.12.24-rt38-xilinx/drivers/char/xilinx_devcfg.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/char/xilinx_devcfg.c	2014-07-20 22:06:35.396321553 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq Device Config driver
+ *
+ * Copyright (c) 2011 - 2013 Xilinx 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.
+ *
+ * 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/cdev.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
+extern void zynq_slcr_init_preload_fpga(void);
+extern void zynq_slcr_init_postload_fpga(void);
+
+#define DRIVER_NAME "xdevcfg"
+#define XDEVCFG_DEVICES 1
+
+/* An array, which is set to true when the device is registered. */
+static DEFINE_MUTEX(xdevcfg_mutex);
+
+/* Constant Definitions */
+#define XDCFG_CTRL_OFFSET		0x00 /* Control Register */
+#define XDCFG_LOCK_OFFSET		0x04 /* Lock Register */
+#define XDCFG_INT_STS_OFFSET		0x0C /* Interrupt Status Register */
+#define XDCFG_INT_MASK_OFFSET		0x10 /* Interrupt Mask Register */
+#define XDCFG_STATUS_OFFSET		0x14 /* Status Register */
+#define XDCFG_DMA_SRC_ADDR_OFFSET	0x18 /* DMA Source Address Register */
+#define XDCFG_DMA_DEST_ADDR_OFFSET	0x1C /* DMA Destination Address Reg */
+#define XDCFG_DMA_SRC_LEN_OFFSET	0x20 /* DMA Source Transfer Length */
+#define XDCFG_DMA_DEST_LEN_OFFSET	0x24 /* DMA Destination Transfer */
+#define XDCFG_UNLOCK_OFFSET		0x34 /* Unlock Register */
+#define XDCFG_MCTRL_OFFSET		0x80 /* Misc. Control Register */
+
+/* Control Register Bit definitions */
+#define XDCFG_CTRL_PCFG_PROG_B_MASK	0x40000000 /* Program signal to
+						    *  Reset FPGA */
+#define XDCFG_CTRL_PCAP_PR_MASK		0x08000000 /* Enable PCAP for PR */
+#define XDCFG_CTRL_PCAP_MODE_MASK	0x04000000 /* Enable PCAP */
+#define XDCFG_CTRL_PCFG_AES_EN_MASK	0x00000E00 /* AES Enable Mask */
+#define XDCFG_CTRL_SEU_EN_MASK		0x00000100 /* SEU Enable Mask */
+#define XDCFG_CTRL_SPNIDEN_MASK		0x00000040 /* Secure Non Invasive
+						    *  Debug Enable */
+#define XDCFG_CTRL_SPIDEN_MASK		0x00000020 /* Secure Invasive
+						    *  Debug Enable */
+#define XDCFG_CTRL_NIDEN_MASK		0x00000010 /* Non-Invasive Debug
+						    *  Enable */
+#define XDCFG_CTRL_DBGEN_MASK		0x00000008 /* Invasive Debug
+						    *  Enable */
+#define XDCFG_CTRL_DAP_EN_MASK		0x00000007 /* DAP Enable Mask */
+
+/* Lock register bit definitions */
+
+#define XDCFG_LOCK_AES_EN_MASK		0x00000008 /* Lock AES_EN update */
+#define XDCFG_LOCK_SEU_MASK		0x00000004 /* Lock SEU_En update */
+#define XDCFG_LOCK_DBG_MASK		0x00000001 /* This bit locks
+						    *  security config
+						    *  including: DAP_En,
+						    *  DBGEN,NIDEN, SPNIEN */
+
+/* Miscellaneous Control Register bit definitions */
+#define XDCFG_MCTRL_PCAP_LPBK_MASK	0x00000010 /* Internal PCAP loopback */
+
+/* Status register bit definitions */
+#define XDCFG_STATUS_PCFG_INIT_MASK	0x00000010 /* FPGA init status */
+
+/* Interrupt Status/Mask Register Bit definitions */
+#define XDCFG_IXR_DMA_DONE_MASK		0x00002000 /* DMA Command Done */
+#define XDCFG_IXR_PCFG_DONE_MASK	0x00000004 /* FPGA programmed */
+#define XDCFG_IXR_ERROR_FLAGS_MASK	0x00F0F860
+#define XDCFG_IXR_ALL_MASK		0xF8F7F87F
+/* Miscellaneous constant values */
+#define XDCFG_DMA_INVALID_ADDRESS	0xFFFFFFFF  /* Invalid DMA address */
+
+static const char * const fclk_name[] = {
+	"fclk0",
+	"fclk1",
+	"fclk2",
+	"fclk3"
+};
+#define NUMFCLKS ARRAY_SIZE(fclk_name)
+
+/**
+ * struct xdevcfg_drvdata - Device Configuration driver structure
+ *
+ * @dev: Pointer to the device structure
+ * @cdev: Instance of the cdev structure
+ * @devt: Pointer to the dev_t structure
+ * @class: Pointer to device class
+ * @fclk_class: Pointer to fclk device class
+ * @dma_done: The dma_done status bit for the DMA command completion
+ * @error_status: The error status captured during the DMA transfer
+ * @irq: Interrupt number
+ * @clk: Peripheral clock for devcfg
+ * @fclk: Array holding references to the FPGA clocks
+ * @fclk_exported: Flag inidcating whether an FPGA clock is exported
+ * @is_open: The status bit to indicate whether the device is opened
+ * @sem: Instance for the mutex
+ * @lock: Instance of spinlock
+ * @base_address: The virtual device base address of the device registers
+ * @is_partial_bitstream: Status bit to indicate partial/full bitstream
+ */
+struct xdevcfg_drvdata {
+	struct device *dev;
+	struct cdev cdev;
+	dev_t devt;
+	struct class *class;
+	struct class *fclk_class;
+	int irq;
+	struct clk *clk;
+	struct clk *fclk[NUMFCLKS];
+	u8 fclk_exported[NUMFCLKS];
+	volatile bool dma_done;
+	volatile int error_status;
+	bool is_open;
+	struct mutex sem;
+	spinlock_t lock;
+	void __iomem *base_address;
+	int ep107;
+	bool is_partial_bitstream;
+	bool endian_swap;
+	char residue_buf[3];
+	int residue_len;
+};
+
+/**
+ * struct fclk_data - FPGA clock data
+ * @clk: Pointer to clock
+ * @enable: Flag indicating enable status of the clock
+ * @rate_rnd: Rate to be rounded for round rate operation
+ */
+struct fclk_data {
+	struct clk *clk;
+	int enabled;
+	unsigned long rate_rnd;
+};
+
+/* Register read/write access routines */
+#define xdevcfg_writereg(offset, val)	__raw_writel(val, offset)
+#define xdevcfg_readreg(offset)		__raw_readl(offset)
+
+/**
+ * xdevcfg_reset_pl() - Reset the programmable logic.
+ * @base_address:	The base address of the device.
+ *
+ * Must be called with PCAP clock enabled
+ */
+static void xdevcfg_reset_pl(void __iomem *base_address)
+{
+	/*
+	 * Create a rising edge on PCFG_INIT. PCFG_INIT follows PCFG_PROG_B,
+	 * so we need to * poll it after setting PCFG_PROG_B to make sure that
+	 * the rising edge happens.
+	 */
+	xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
+			(xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) |
+			 XDCFG_CTRL_PCFG_PROG_B_MASK));
+	while (!(xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
+				XDCFG_STATUS_PCFG_INIT_MASK))
+		;
+
+	xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
+			(xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) &
+			 ~XDCFG_CTRL_PCFG_PROG_B_MASK));
+	while (xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
+			XDCFG_STATUS_PCFG_INIT_MASK)
+		;
+
+	xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
+			(xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) |
+			 XDCFG_CTRL_PCFG_PROG_B_MASK));
+	while (!(xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
+				XDCFG_STATUS_PCFG_INIT_MASK))
+		;
+}
+
+/**
+ * xdevcfg_irq() - The main interrupt handler.
+ * @irq:	The interrupt number.
+ * @data:	Pointer to the driver data structure.
+ * returns: IRQ_HANDLED after the interrupt is handled.
+ **/
+static irqreturn_t xdevcfg_irq(int irq, void *data)
+{
+	u32 intr_status;
+	struct xdevcfg_drvdata *drvdata = data;
+
+	spin_lock(&drvdata->lock);
+
+	intr_status = xdevcfg_readreg(drvdata->base_address +
+					XDCFG_INT_STS_OFFSET);
+
+	/* Clear the interrupts */
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
+				intr_status);
+
+	if ((intr_status & XDCFG_IXR_DMA_DONE_MASK) == XDCFG_IXR_DMA_DONE_MASK)
+		drvdata->dma_done = 1;
+
+	if ((intr_status & XDCFG_IXR_ERROR_FLAGS_MASK) ==
+			XDCFG_IXR_ERROR_FLAGS_MASK)
+		drvdata->error_status = 1;
+
+	spin_unlock(&drvdata->lock);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xdevcfg_write() - The is the driver write function.
+ *
+ * @file:	Pointer to the file structure.
+ * @buf:	Pointer to the bitstream location.
+ * @count:	The number of bytes to be written.
+ * @ppos:	Pointer to the offset value
+ * returns:	Success or error status.
+ **/
+static ssize_t
+xdevcfg_write(struct file *file, const char __user *buf, size_t count,
+		loff_t *ppos)
+{
+	char *kbuf;
+	int status;
+	unsigned long timeout;
+	u32 intr_reg;
+	dma_addr_t dma_addr;
+	u32 transfer_length = 0;
+	struct xdevcfg_drvdata *drvdata = file->private_data;
+	size_t user_count = count;
+	int i;
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	status = mutex_lock_interruptible(&drvdata->sem);
+
+	if (status)
+		goto err_clk;
+
+	kbuf = dma_alloc_coherent(drvdata->dev, count + drvdata->residue_len,
+				  &dma_addr, GFP_KERNEL);
+	if (!kbuf) {
+		status = -ENOMEM;
+		goto err_unlock;
+	}
+
+	/* Collect stragglers from last time (0 to 3 bytes) */
+	memcpy(kbuf, drvdata->residue_buf, drvdata->residue_len);
+
+	/* Fetch user data, appending to stragglers */
+	if (copy_from_user(kbuf + drvdata->residue_len, buf, count)) {
+		status = -EFAULT;
+		goto error;
+	}
+
+	/* Include stragglers in total bytes to be handled */
+	count += drvdata->residue_len;
+
+	/* First block contains a header */
+	if (*ppos == 0 && count > 4) {
+		/* Look for sync word */
+		for (i = 0; i < count - 4; i++) {
+			if (memcmp(kbuf + i, "\x66\x55\x99\xAA", 4) == 0) {
+				pr_debug("Found normal sync word\n");
+				drvdata->endian_swap = 0;
+				break;
+			}
+			if (memcmp(kbuf + i, "\xAA\x99\x55\x66", 4) == 0) {
+				pr_debug("Found swapped sync word\n");
+				drvdata->endian_swap = 1;
+				break;
+			}
+		}
+		/* Remove the header, aligning the data on word boundary */
+		if (i != count - 4) {
+			count -= i;
+			memmove(kbuf, kbuf + i, count);
+		}
+	}
+
+	/* Save stragglers for next time */
+	drvdata->residue_len = count % 4;
+	count -= drvdata->residue_len;
+	memcpy(drvdata->residue_buf, kbuf + count, drvdata->residue_len);
+
+	/* Fixup endianess of the data */
+	if (drvdata->endian_swap) {
+		for (i = 0; i < count; i += 4) {
+			u32 *p = (u32 *)&kbuf[i];
+			*p = swab32(*p);
+		}
+	}
+
+	/* Enable DMA and error interrupts */
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
+				XDCFG_IXR_ALL_MASK);
+
+
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
+				(u32) (~(XDCFG_IXR_DMA_DONE_MASK |
+				XDCFG_IXR_ERROR_FLAGS_MASK)));
+
+	drvdata->dma_done = 0;
+	drvdata->error_status = 0;
+
+	/* Initiate DMA write command */
+	if (count < 0x1000)
+		xdevcfg_writereg(drvdata->base_address +
+			XDCFG_DMA_SRC_ADDR_OFFSET, (u32)(dma_addr + 1));
+	else
+		xdevcfg_writereg(drvdata->base_address +
+			XDCFG_DMA_SRC_ADDR_OFFSET, (u32) dma_addr);
+
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_ADDR_OFFSET,
+				(u32)XDCFG_DMA_INVALID_ADDRESS);
+	/* Convert number of bytes to number of words.  */
+	if (count % 4)
+		transfer_length	= (count / 4 + 1);
+	else
+		transfer_length	= count / 4;
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_LEN_OFFSET,
+				transfer_length);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_LEN_OFFSET, 0);
+
+	timeout = jiffies + msecs_to_jiffies(1000);
+
+	while (!drvdata->dma_done) {
+		if (time_after(jiffies, timeout)) {
+				status = -ETIMEDOUT;
+				goto error;
+		}
+	}
+
+	if (drvdata->error_status)
+		status = drvdata->error_status;
+
+	/* Disable the DMA and error interrupts */
+	intr_reg = xdevcfg_readreg(drvdata->base_address +
+					XDCFG_INT_MASK_OFFSET);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
+				intr_reg | (XDCFG_IXR_DMA_DONE_MASK |
+				XDCFG_IXR_ERROR_FLAGS_MASK));
+
+	/* If we didn't write correctly, then bail out. */
+	if (status) {
+		status = -EFAULT;
+		goto error;
+	}
+
+	*ppos += user_count;
+	status = user_count;
+
+error:
+	dma_free_coherent(drvdata->dev, count, kbuf, dma_addr);
+err_unlock:
+	mutex_unlock(&drvdata->sem);
+err_clk:
+	clk_disable(drvdata->clk);
+	return status;
+}
+
+
+/**
+ * xdevcfg_read() - The is the driver read function.
+ * @file:	Pointer to the file structure.
+ * @buf:	Pointer to the bitstream location.
+ * @count:	The number of bytes read.
+ * @ppos:	Pointer to the offsetvalue
+ * returns:	Success or error status.
+ */
+static ssize_t
+xdevcfg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+	u32 *kbuf;
+	int status;
+	unsigned long timeout;
+	dma_addr_t dma_addr;
+	struct xdevcfg_drvdata *drvdata = file->private_data;
+	u32 intr_reg;
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	status = mutex_lock_interruptible(&drvdata->sem);
+	if (status)
+		goto err_clk;
+
+	/* Get new data from the ICAP, and return was requested. */
+	kbuf = dma_alloc_coherent(drvdata->dev, count, &dma_addr, GFP_KERNEL);
+	if (!kbuf) {
+		status = -ENOMEM;
+		goto err_unlock;
+	}
+
+	drvdata->dma_done = 0;
+	drvdata->error_status = 0;
+
+	/* Enable DMA and error interrupts */
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
+				XDCFG_IXR_ALL_MASK);
+
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
+				(u32) (~(XDCFG_IXR_DMA_DONE_MASK |
+				XDCFG_IXR_ERROR_FLAGS_MASK)));
+	/* Initiate DMA read command */
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_ADDR_OFFSET,
+				(u32)XDCFG_DMA_INVALID_ADDRESS);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_ADDR_OFFSET,
+				(u32)dma_addr);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_LEN_OFFSET, 0);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_LEN_OFFSET,
+				count / 4);
+
+	timeout = jiffies + msecs_to_jiffies(1000);
+
+	while (!drvdata->dma_done) {
+		if (time_after(jiffies, timeout)) {
+			status = -ETIMEDOUT;
+			goto error;
+		}
+	}
+
+	if (drvdata->error_status)
+		status = drvdata->error_status;
+
+	/* Disable and clear DMA and error interrupts */
+	intr_reg = xdevcfg_readreg(drvdata->base_address +
+					XDCFG_INT_MASK_OFFSET);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
+				intr_reg | (XDCFG_IXR_DMA_DONE_MASK |
+				XDCFG_IXR_ERROR_FLAGS_MASK));
+
+
+	/* If we didn't read correctly, then bail out. */
+	if (status) {
+		status = -EFAULT;
+		goto error;
+	}
+
+	/* If we fail to return the data to the user, then bail out. */
+	if (copy_to_user(buf, kbuf, count)) {
+		status = -EFAULT;
+		goto error;
+	}
+
+	status = count;
+error:
+	dma_free_coherent(drvdata->dev, count, kbuf, dma_addr);
+err_unlock:
+	mutex_unlock(&drvdata->sem);
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_open() - The is the driver open function.
+ * @inode:	Pointer to the inode structure of this device.
+ * @file:	Pointer to the file structure.
+ * returns:	Success or error status.
+ */
+static int xdevcfg_open(struct inode *inode, struct file *file)
+{
+	struct xdevcfg_drvdata *drvdata;
+	int status;
+
+	drvdata = container_of(inode->i_cdev, struct xdevcfg_drvdata, cdev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	status = mutex_lock_interruptible(&drvdata->sem);
+	if (status)
+		goto err_clk;
+
+	if (drvdata->is_open) {
+		status = -EBUSY;
+		goto error;
+	}
+
+	file->private_data = drvdata;
+	drvdata->is_open = 1;
+	drvdata->endian_swap = 0;
+	drvdata->residue_len= 0;
+
+	/*
+	 * If is_partial_bitstream is set, then PROG_B is not asserted
+	 * (xdevcfg_reset_pl function) and also zynq_slcr_init_preload_fpga and
+	 * zynq_slcr_init_postload_fpga functions are not invoked.
+	 */
+	if (!drvdata->is_partial_bitstream)
+		zynq_slcr_init_preload_fpga();
+
+	/*
+	 * Only do the reset of the PL for Zynq as it causes problems on the
+	 * EP107 and the issue is not understood, but not worth investigating
+	 * as the emulation platform is very different than silicon and not a
+	 * complete implementation. Also, do not reset if it is a partial
+	 * bitstream.
+	 */
+	if ((!drvdata->ep107) && (!drvdata->is_partial_bitstream))
+		xdevcfg_reset_pl(drvdata->base_address);
+
+	xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
+			XDCFG_IXR_PCFG_DONE_MASK);
+
+error:
+	mutex_unlock(&drvdata->sem);
+err_clk:
+	clk_disable(drvdata->clk);
+	return status;
+}
+
+/**
+ * xdevcfg_release() - The is the driver release function.
+ * @inode:	Pointer to the inode structure of this device.
+ * @file:	Pointer to the file structure.
+ * returns:	Success.
+ */
+static int xdevcfg_release(struct inode *inode, struct file *file)
+{
+	struct xdevcfg_drvdata *drvdata = file->private_data;
+
+	if (!drvdata->is_partial_bitstream)
+		zynq_slcr_init_postload_fpga();
+
+	if (drvdata->residue_len)
+		printk("Did not transfer last %d bytes\n",
+			drvdata->residue_len);
+
+	drvdata->is_open = 0;
+
+	return 0;
+}
+
+static const struct file_operations xdevcfg_fops = {
+	.owner = THIS_MODULE,
+	.write = xdevcfg_write,
+	.read = xdevcfg_read,
+	.open = xdevcfg_open,
+	.release = xdevcfg_release,
+};
+
+/*
+ * The following functions are the routines provided to the user to
+ * set/get the status bit value in the control/lock registers.
+ */
+
+/**
+ * xdevcfg_set_dap_en() - This function sets the DAP bits in the
+ * control register with the given value.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	negative error if the string could not be converted
+ *		or the size of the buffer.
+ */
+static ssize_t xdevcfg_set_dap_en(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_unlock;
+
+	if (mask_bit > 7) {
+		status = -EINVAL;
+		goto err_unlock;
+	}
+
+	xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+			(ctrl_reg_status |
+			 (((u32)mask_bit) & XDCFG_CTRL_DAP_EN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_unlock:
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_dap_en_status() - The function returns the DAP_EN bits status in
+ * the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	Size of the buffer.
+ */
+static ssize_t xdevcfg_show_dap_en_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 dap_en_status;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	dap_en_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET) & XDCFG_CTRL_DAP_EN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", dap_en_status);
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_dap, 0644, xdevcfg_show_dap_en_status,
+				xdevcfg_set_dap_en);
+
+/**
+ * xdevcfg_set_dbgen() - This function sets the DBGEN bit in the
+ * control register with the given value.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_dbgen(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status | XDCFG_CTRL_DBGEN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status & (~XDCFG_CTRL_DBGEN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_dbgen_status() - The function returns the DBGEN bit status in
+ * the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	Size of the buffer.
+ */
+static ssize_t xdevcfg_show_dbgen_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 dbgen_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	dbgen_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET) & XDCFG_CTRL_DBGEN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (dbgen_status >> 3));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_dbg_in, 0644, xdevcfg_show_dbgen_status,
+				xdevcfg_set_dbgen);
+
+/**
+ * xdevcfg_set_niden() - This function sets the NIDEN bit in the
+ * control register with the given value.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_niden(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status | XDCFG_CTRL_NIDEN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status & (~XDCFG_CTRL_NIDEN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_niden_status() - The function returns the NIDEN bit status in
+ * the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	Size of the buffer.
+ */
+static ssize_t xdevcfg_show_niden_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 niden_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	niden_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET) & XDCFG_CTRL_NIDEN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (niden_status >> 4));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_dbg_nonin, 0644, xdevcfg_show_niden_status,
+			xdevcfg_set_niden);
+
+/**
+ * xdevcfg_set_spiden() - This function sets the SPIDEN bit in the
+ * control register with the given value.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_spiden(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status | XDCFG_CTRL_SPIDEN_MASK));
+	else
+
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status & (~XDCFG_CTRL_SPIDEN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_spiden_status() - The function returns the SPIDEN bit status in
+ * the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	Size of the buffer.
+ */
+static ssize_t xdevcfg_show_spiden_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 spiden_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	spiden_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SPIDEN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (spiden_status >> 5));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_sec_dbg_in, 0644, xdevcfg_show_spiden_status,
+				xdevcfg_set_spiden);
+
+/**
+ * xdevcfg_set_spniden() - This function sets the SPNIDEN bit in the
+ * control register with the given value.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or the size of buffer
+ */
+static ssize_t xdevcfg_set_spniden(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status | XDCFG_CTRL_SPNIDEN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status & (~XDCFG_CTRL_SPNIDEN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_spniden_status() - The function returns the SPNIDEN bit status
+ * in the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	Size of the buffer.
+ */
+static ssize_t xdevcfg_show_spniden_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 spniden_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	spniden_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SPNIDEN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (spniden_status >> 6));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_sec_dbg_nonin, 0644, xdevcfg_show_spniden_status,
+					xdevcfg_set_spniden);
+
+/**
+ * xdevcfg_set_seu() - This function sets the SEU_EN bit in the
+ * control register with the given value
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_seu(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status | XDCFG_CTRL_SEU_EN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status & (~XDCFG_CTRL_SEU_EN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_seu_status() - The function returns the SEU_EN bit status
+ * in the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_seu_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 seu_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	seu_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SEU_EN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (seu_status > 8));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_seu, 0644, xdevcfg_show_seu_status, xdevcfg_set_seu);
+
+/**
+ * xdevcfg_set_aes() - This function sets the AES_EN bits in the
+ * control register with either all 1s or all 0s.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ *
+ * The user must send only one bit in the buffer to notify whether he wants to
+ * either set or reset these bits.
+ */
+static ssize_t xdevcfg_set_aes(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 ctrl_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	int status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_CTRL_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status < 0)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status |
+				 XDCFG_CTRL_PCFG_AES_EN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(ctrl_reg_status &
+				 (~XDCFG_CTRL_PCFG_AES_EN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_aes_status() - The function returns the AES_EN bit status
+ * in the control register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_aes_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 aes_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	aes_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_CTRL_OFFSET) & XDCFG_CTRL_PCFG_AES_EN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (aes_status >> 9));
+
+	return status;
+}
+
+static DEVICE_ATTR(enable_aes, 0644, xdevcfg_show_aes_status, xdevcfg_set_aes);
+
+/**
+ * xdevcfg_set_aes_en_lock() - This function sets the LOCK_AES_EN bit in the
+ * lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_aes_en_lock(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 aes_en_lock_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	aes_en_lock_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_LOCK_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(aes_en_lock_status | XDCFG_LOCK_AES_EN_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(aes_en_lock_status &
+				 (~XDCFG_LOCK_AES_EN_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_aes_en_lock_status() - The function returns the LOCK_AES_EN bit
+ * status in the lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_aes_en_lock_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 aes_en_lock_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	aes_en_lock_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_LOCK_OFFSET) & XDCFG_LOCK_AES_EN_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (aes_en_lock_status >> 3));
+
+	return status;
+}
+
+static DEVICE_ATTR(aes_en_lock, 0644, xdevcfg_show_aes_en_lock_status,
+				xdevcfg_set_aes_en_lock);
+
+/**
+ * xdevcfg_set_seu_lock() - This function sets the LOCK_SEU bit in the
+ * lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_seu_lock(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 seu_lock_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	seu_lock_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_LOCK_OFFSET);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(seu_lock_status | XDCFG_LOCK_SEU_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(seu_lock_status  & (~XDCFG_LOCK_SEU_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_seu_lock_status() - The function returns the LOCK_SEU bit
+ * status in the lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_seu_lock_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 seu_lock_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	seu_lock_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_LOCK_OFFSET) & XDCFG_LOCK_SEU_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (seu_lock_status >> 2));
+
+	return status;
+}
+
+static DEVICE_ATTR(seu_lock, 0644, xdevcfg_show_seu_lock_status,
+					xdevcfg_set_seu_lock);
+
+/**
+ * xdevcfg_set_dbg_lock() - This function sets the LOCK_DBG bit in the
+ * lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_dbg_lock(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	u32 lock_reg_status;
+	unsigned long flags;
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	lock_reg_status = xdevcfg_readreg(drvdata->base_address +
+				XDCFG_LOCK_OFFSET);
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		goto err_clk;
+
+	if (mask_bit > 1) {
+		status = -EINVAL;
+		goto err_clk;
+	}
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	if (mask_bit)
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(lock_reg_status | XDCFG_LOCK_DBG_MASK));
+	else
+		xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
+				(lock_reg_status & (~XDCFG_LOCK_DBG_MASK)));
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	clk_disable(drvdata->clk);
+
+	return size;
+
+err_clk:
+	clk_disable(drvdata->clk);
+
+	return status;
+}
+
+/**
+ * xdevcfg_show_dbg_lock_status() - The function returns the LOCK_DBG bit
+ * status in the lock register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_dbg_lock_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 dbg_lock_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	dbg_lock_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_LOCK_OFFSET) & XDCFG_LOCK_DBG_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", dbg_lock_status);
+
+	return status;
+}
+
+static DEVICE_ATTR(dbg_lock, 0644, xdevcfg_show_dbg_lock_status,
+				xdevcfg_set_dbg_lock);
+
+/**
+ * xdevcfg_show_prog_done_status() - The function returns the PROG_DONE bit
+ * status in the interrupt status register.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_prog_done_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 prog_done_status;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = clk_enable(drvdata->clk);
+	if (status)
+		return status;
+
+	prog_done_status = xdevcfg_readreg(drvdata->base_address +
+			XDCFG_INT_STS_OFFSET) & XDCFG_IXR_PCFG_DONE_MASK;
+
+	clk_disable(drvdata->clk);
+
+	status = sprintf(buf, "%d\n", (prog_done_status >> 2));
+
+	return status;
+}
+
+static DEVICE_ATTR(prog_done, 0644, xdevcfg_show_prog_done_status,
+				NULL);
+
+/**
+ * xdevcfg_set_is_partial_bitstream() - This function sets the
+ * is_partial_bitstream variable. If is_partial_bitstream is set,
+ * then PROG_B is not asserted (xdevcfg_reset_pl) and also
+ * zynq_slcr_init_preload_fpga and zynq_slcr_init_postload_fpga functions
+ * are not invoked.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * @size:	The number of bytes used from the buffer
+ * returns:	-EINVAL if invalid parameter is sent or size
+ */
+static ssize_t xdevcfg_set_is_partial_bitstream(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	unsigned long mask_bit;
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = strict_strtoul(buf, 10, &mask_bit);
+
+	if (status)
+		return status;
+
+	if (mask_bit > 1)
+		return -EINVAL;
+
+	if (mask_bit)
+		drvdata->is_partial_bitstream = 1;
+	else
+		drvdata->is_partial_bitstream = 0;
+
+	return size;
+}
+
+/**
+ * xdevcfg_show_is_partial_bitstream_status() - The function returns the
+ * value of is_partial_bitstream variable.
+ * @dev:	Pointer to the device structure.
+ * @attr:	Pointer to the device attribute structure.
+ * @buf:	Pointer to the buffer location for the configuration
+ *		data.
+ * returns:	size of the buffer.
+ */
+static ssize_t xdevcfg_show_is_partial_bitstream_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t status;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	status = sprintf(buf, "%d\n", drvdata->is_partial_bitstream);
+
+	return status;
+}
+
+static DEVICE_ATTR(is_partial_bitstream, 0644,
+				xdevcfg_show_is_partial_bitstream_status,
+				xdevcfg_set_is_partial_bitstream);
+
+static const struct attribute *xdevcfg_attrs[] = {
+	&dev_attr_prog_done.attr, /* PCFG_DONE bit in Intr Status register */
+	&dev_attr_dbg_lock.attr, /* Debug lock bit in Lock register */
+	&dev_attr_seu_lock.attr, /* SEU lock bit in Lock register */
+	&dev_attr_aes_en_lock.attr, /* AES EN lock bit in Lock register */
+	&dev_attr_enable_aes.attr, /* AES EN bit in Control register */
+	&dev_attr_enable_seu.attr, /* SEU EN bit in Control register */
+	&dev_attr_enable_sec_dbg_nonin.attr, /*SPNIDEN bit in Control register*/
+	&dev_attr_enable_sec_dbg_in.attr, /*SPIDEN bit in Control register */
+	&dev_attr_enable_dbg_nonin.attr, /* NIDEN bit in Control register */
+	&dev_attr_enable_dbg_in.attr, /* DBGEN bit in Control register */
+	&dev_attr_enable_dap.attr, /* DAP_EN bits in Control register */
+	&dev_attr_is_partial_bitstream.attr, /* Flag for partial bitstream */
+	NULL,
+};
+
+
+static const struct attribute_group xdevcfg_attr_group = {
+	.attrs = (struct attribute **) xdevcfg_attrs,
+};
+
+static ssize_t fclk_enable_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->enabled);
+}
+
+static ssize_t fclk_enable_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned long enable;
+	int ret;
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	ret = kstrtoul(buf, 0, &enable);
+	if (ret)
+		return -EINVAL;
+
+	enable = !!enable;
+	if (enable == pdata->enabled)
+		return count;
+
+	if (enable)
+		ret = clk_enable(pdata->clk);
+	else
+		clk_disable(pdata->clk);
+
+	if (ret)
+		return ret;
+
+	pdata->enabled = enable;
+	return count;
+}
+
+static DEVICE_ATTR(enable, 0644, fclk_enable_show, fclk_enable_store);
+
+static ssize_t fclk_set_rate_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%lu\n", clk_get_rate(pdata->clk));
+}
+
+static ssize_t fclk_set_rate_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	unsigned long rate;
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	ret = kstrtoul(buf, 0, &rate);
+	if (ret)
+		return -EINVAL;
+
+	rate = clk_round_rate(pdata->clk, rate);
+	ret = clk_set_rate(pdata->clk, rate);
+
+	return ret ? ret : count;
+}
+
+static DEVICE_ATTR(set_rate, 0644, fclk_set_rate_show, fclk_set_rate_store);
+
+static ssize_t fclk_round_rate_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%lu => %lu\n", pdata->rate_rnd,
+			clk_round_rate(pdata->clk, pdata->rate_rnd));
+}
+
+static ssize_t fclk_round_rate_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	unsigned long rate;
+	struct fclk_data *pdata = dev_get_drvdata(dev);
+
+	ret = kstrtoul(buf, 0, &rate);
+	if (ret)
+		return -EINVAL;
+
+	pdata->rate_rnd = rate;
+
+	return count;
+}
+
+static DEVICE_ATTR(round_rate, 0644, fclk_round_rate_show,
+		fclk_round_rate_store);
+
+static const struct attribute *fclk_ctrl_attrs[] = {
+	&dev_attr_enable.attr,
+	&dev_attr_set_rate.attr,
+	&dev_attr_round_rate.attr,
+	NULL,
+};
+
+static const struct attribute_group fclk_ctrl_attr_grp = {
+	.attrs = (struct attribute **)fclk_ctrl_attrs,
+};
+
+static ssize_t xdevcfg_fclk_export_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	int i, ret;
+	struct device *subdev;
+	struct fclk_data *fdata;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		if (!strncmp(buf, fclk_name[i], strlen(fclk_name[i])))
+			break;
+	}
+
+	if (i < NUMFCLKS && !drvdata->fclk_exported[i]) {
+		drvdata->fclk_exported[i] = 1;
+		subdev = device_create(drvdata->fclk_class, dev, MKDEV(0, 0),
+				NULL, fclk_name[i]);
+		if (IS_ERR(subdev))
+			return PTR_ERR(subdev);
+		ret = clk_prepare(drvdata->fclk[i]);
+		if (ret)
+			return ret;
+		fdata = kzalloc(sizeof(*fdata), GFP_KERNEL);
+		if (!fdata) {
+			ret = -ENOMEM;
+			goto err_unprepare;
+		}
+		fdata->clk = drvdata->fclk[i];
+		dev_set_drvdata(subdev, fdata);
+		ret = sysfs_create_group(&subdev->kobj, &fclk_ctrl_attr_grp);
+		if (ret)
+			goto err_free;
+	} else {
+		return -EINVAL;
+	}
+
+	return size;
+
+err_free:
+	kfree(fdata);
+err_unprepare:
+	clk_unprepare(drvdata->fclk[i]);
+
+	return ret;
+}
+
+static ssize_t xdevcfg_fclk_export_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int i;
+	ssize_t count = 0;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		if (!drvdata->fclk_exported[i])
+			count += scnprintf(buf + count, PAGE_SIZE - count,
+					"%s\n", fclk_name[i]);
+	}
+	return count;
+}
+
+static DEVICE_ATTR(fclk_export, 0644, xdevcfg_fclk_export_show,
+		xdevcfg_fclk_export_store);
+
+static int match_fclk(struct device *dev, const void *data)
+{
+	struct fclk_data *fdata = dev_get_drvdata(dev);
+
+	return fdata->clk == data;
+}
+
+static ssize_t xdevcfg_fclk_unexport_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	int i;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		if (!strncmp(buf, fclk_name[i], strlen(fclk_name[i])))
+			break;
+	}
+
+	if (i < NUMFCLKS && drvdata->fclk_exported[i]) {
+		struct fclk_data *fdata;
+		struct device *subdev;
+
+		drvdata->fclk_exported[i] = 0;
+		subdev = class_find_device(drvdata->fclk_class, NULL,
+				drvdata->fclk[i], match_fclk);
+		fdata = dev_get_drvdata(subdev);
+		if (fdata->enabled)
+			clk_disable(fdata->clk);
+		clk_unprepare(fdata->clk);
+		kfree(fdata);
+		device_unregister(subdev);
+		put_device(subdev);
+	} else {
+		return -EINVAL;
+	}
+
+	return size;
+}
+
+static ssize_t xdevcfg_fclk_unexport_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int i;
+	ssize_t count = 0;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		if (drvdata->fclk_exported[i])
+			count += scnprintf(buf + count, PAGE_SIZE - count,
+					"%s\n", fclk_name[i]);
+	}
+	return count;
+}
+
+static DEVICE_ATTR(fclk_unexport, 0644, xdevcfg_fclk_unexport_show,
+		xdevcfg_fclk_unexport_store);
+
+static const struct attribute *fclk_exp_attrs[] = {
+	&dev_attr_fclk_export.attr,
+	&dev_attr_fclk_unexport.attr,
+	NULL,
+};
+
+static const struct attribute_group fclk_exp_attr_grp = {
+	.attrs = (struct attribute **)fclk_exp_attrs,
+};
+
+static void xdevcfg_fclk_init(struct device *dev)
+{
+	int i;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		drvdata->fclk[i] = clk_get(dev, fclk_name[i]);
+		if (IS_ERR(drvdata->fclk[i])) {
+			dev_warn(dev, "fclk not found\n");
+			return;
+		}
+	}
+
+	drvdata->fclk_class = class_create(THIS_MODULE, "fclk");
+	if (IS_ERR(drvdata->fclk_class)) {
+		dev_warn(dev, "failed to create fclk class\n");
+		return;
+	}
+	sysfs_create_group(&dev->kobj, &fclk_exp_attr_grp);
+
+	return;
+}
+
+static void xdevcfg_fclk_remove(struct device *dev)
+{
+	int i;
+	struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
+
+	for (i = 0; i < NUMFCLKS; i++) {
+		if (drvdata->fclk_exported[i]) {
+			struct fclk_data *fdata;
+			struct device *subdev;
+
+			drvdata->fclk_exported[i] = 0;
+			subdev = class_find_device(drvdata->fclk_class, NULL,
+					drvdata->fclk[i], match_fclk);
+			fdata = dev_get_drvdata(subdev);
+			if (fdata->enabled)
+				clk_disable(fdata->clk);
+			clk_unprepare(fdata->clk);
+			kfree(fdata);
+			device_unregister(subdev);
+			put_device(subdev);
+
+		}
+	}
+
+	class_destroy(drvdata->fclk_class);
+	sysfs_remove_group(&dev->kobj, &fclk_exp_attr_grp);
+
+	return;
+}
+
+/**
+ * xdevcfg_drv_probe -  Probe call for the device.
+ *
+ * @pdev:	handle to the platform device structure.
+ * Returns 0 on success, negative error otherwise.
+ *
+ * It does all the memory allocation and registration for the device.
+ */
+static int xdevcfg_drv_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct xdevcfg_drvdata *drvdata;
+	dev_t devt;
+	int retval;
+	u32 ctrlreg;
+	struct device_node *np;
+	const void *prop;
+	int size;
+	struct device *dev;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	drvdata->base_address = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(drvdata->base_address))
+		return PTR_ERR(drvdata->base_address);
+
+	drvdata->irq = platform_get_irq(pdev, 0);
+	retval = devm_request_irq(&pdev->dev, drvdata->irq, &xdevcfg_irq,
+				0, dev_name(&pdev->dev), drvdata);
+	if (retval) {
+		dev_err(&pdev->dev, "No IRQ available");
+		return retval;
+	}
+
+	platform_set_drvdata(pdev, drvdata);
+	spin_lock_init(&drvdata->lock);
+	mutex_init(&drvdata->sem);
+	drvdata->is_open = 0;
+	drvdata->is_partial_bitstream = 0;
+	drvdata->dma_done = 0;
+	drvdata->error_status = 0;
+	dev_info(&pdev->dev, "ioremap %pa to %p\n",
+		 &res->start, drvdata->base_address);
+
+	drvdata->clk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(drvdata->clk)) {
+		dev_err(&pdev->dev, "input clock not found\n");
+		return PTR_ERR(drvdata->clk);
+	}
+
+	retval = clk_prepare_enable(drvdata->clk);
+	if (retval) {
+		dev_err(&pdev->dev, "unable to enable clock\n");
+		return retval;
+	}
+
+	/*
+	 * Figure out from the device tree if this is running on the EP107
+	 * emulation platform as it doesn't match the silicon exactly and the
+	 * driver needs to work accordingly.
+	 */
+	np = of_get_next_parent(pdev->dev.of_node);
+	np = of_get_next_parent(np);
+	prop = of_get_property(np, "compatible", &size);
+
+	if (prop != NULL) {
+		if ((strcmp((const char *)prop, "xlnx,zynq-ep107")) == 0)
+			drvdata->ep107 = 1;
+		else
+			drvdata->ep107 = 0;
+	}
+
+	/* Unlock the device */
+	xdevcfg_writereg(drvdata->base_address + XDCFG_UNLOCK_OFFSET,
+				0x757BDF0D);
+
+	/*
+	 * Set the configuration register with the following options
+	 *  - Reset FPGA
+	 *  - Enable PCAP interface for Partial reconfiguration
+	 *  - Enable the PCAP interface
+	 *  - Set the throughput rate for maximum speed
+	 *  - Se the CPU in user mode
+	 */
+	ctrlreg = xdevcfg_readreg(drvdata->base_address + XDCFG_CTRL_OFFSET);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
+				(XDCFG_CTRL_PCFG_PROG_B_MASK |
+				XDCFG_CTRL_PCAP_PR_MASK |
+				XDCFG_CTRL_PCAP_MODE_MASK |
+				ctrlreg));
+
+	/* Ensure internal PCAP loopback is disabled */
+	ctrlreg = xdevcfg_readreg(drvdata->base_address + XDCFG_MCTRL_OFFSET);
+	xdevcfg_writereg(drvdata->base_address + XDCFG_MCTRL_OFFSET,
+				(~XDCFG_MCTRL_PCAP_LPBK_MASK &
+				ctrlreg));
+
+
+	retval = alloc_chrdev_region(&devt, 0, XDEVCFG_DEVICES, DRIVER_NAME);
+	if (retval < 0)
+		goto failed5;
+
+	drvdata->devt = devt;
+
+	cdev_init(&drvdata->cdev, &xdevcfg_fops);
+	drvdata->cdev.owner = THIS_MODULE;
+	retval = cdev_add(&drvdata->cdev, devt, 1);
+	if (retval) {
+		dev_err(&pdev->dev, "cdev_add() failed\n");
+		goto failed6;
+	}
+
+	drvdata->class = class_create(THIS_MODULE, DRIVER_NAME);
+	if (IS_ERR(drvdata->class)) {
+		dev_err(&pdev->dev, "failed to create class\n");
+		goto failed6;
+	}
+
+	dev = device_create(drvdata->class, &pdev->dev, devt, drvdata,
+			DRIVER_NAME);
+	if (IS_ERR(dev)) {
+			dev_err(&pdev->dev, "unable to create device\n");
+			goto failed7;
+	}
+
+	/* create sysfs files for the device */
+	retval = sysfs_create_group(&(pdev->dev.kobj), &xdevcfg_attr_group);
+	if (retval) {
+		dev_err(&pdev->dev, "Failed to create sysfs attr group\n");
+		cdev_del(&drvdata->cdev);
+		goto failed8;
+	}
+
+	xdevcfg_fclk_init(&pdev->dev);
+
+	clk_disable(drvdata->clk);
+
+	return 0;		/* Success */
+
+failed8:
+	device_destroy(drvdata->class, drvdata->devt);
+failed7:
+	class_destroy(drvdata->class);
+failed6:
+	/* Unregister char driver */
+	unregister_chrdev_region(devt, XDEVCFG_DEVICES);
+failed5:
+	clk_disable_unprepare(drvdata->clk);
+
+	return retval;
+}
+
+/**
+ * xdevcfg_drv_remove -  Remove call for the device.
+ *
+ * @pdev:	handle to the platform device structure.
+ * Returns 0 or error status.
+ *
+ * Unregister the device after releasing the resources.
+ */
+static int xdevcfg_drv_remove(struct platform_device *pdev)
+{
+	struct xdevcfg_drvdata *drvdata;
+
+	drvdata = platform_get_drvdata(pdev);
+
+	if (!drvdata)
+		return -ENODEV;
+
+	unregister_chrdev_region(drvdata->devt, XDEVCFG_DEVICES);
+
+	sysfs_remove_group(&pdev->dev.kobj, &xdevcfg_attr_group);
+
+	xdevcfg_fclk_remove(&pdev->dev);
+	device_destroy(drvdata->class, drvdata->devt);
+	class_destroy(drvdata->class);
+	cdev_del(&drvdata->cdev);
+	clk_unprepare(drvdata->clk);
+
+	return 0;		/* Success */
+}
+
+static struct of_device_id xdevcfg_of_match[] = {
+	{ .compatible = "xlnx,ps7-dev-cfg-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xdevcfg_of_match);
+
+/* Driver Structure */
+static struct platform_driver xdevcfg_platform_driver = {
+	.probe = xdevcfg_drv_probe,
+	.remove = xdevcfg_drv_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DRIVER_NAME,
+		.of_match_table = xdevcfg_of_match,
+	},
+};
+
+module_platform_driver(xdevcfg_platform_driver);
+
+MODULE_AUTHOR("Xilinx, Inc");
+MODULE_DESCRIPTION("Xilinx Device Config Driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/char/xilinx_hwicap/xilinx_hwicap.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/char/xilinx_hwicap/xilinx_hwicap.c	2014-07-20 22:05:50.187067430 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/char/xilinx_hwicap/xilinx_hwicap.c	2014-07-20 22:06:35.412321289 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:734 @
 	iounmap(drvdata->base_address);
 	release_mem_region(drvdata->mem_start, drvdata->mem_size);
 	kfree(drvdata);
-	dev_set_drvdata(dev, NULL);
 
 	mutex_lock(&icap_sem);
 	probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
Index: linux-3.12.24-rt38-xilinx/drivers/clk/clk.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/clk/clk.c	2014-07-20 22:05:50.220066885 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/clk/clk.c	2014-07-20 22:06:35.433320943 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:967 @
  * @rate: the rate which is to be rounded
  *
  * Takes in a rate as input and rounds it to a rate that the clk can actually
- * use which is then returned.  If clk doesn't support round_rate operation
- * then the parent rate is returned.
+ * use and does not exceed the requested frequency, which is then returned.
+ * If clk doesn't support round_rate operation then the parent rate
+ * is returned.
  */
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:984 @
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
 /**
+ * clk_round_rate_nearest - round the given rate for a clk
+ * @clk: the clk for which we are rounding a rate
+ * @rate: the rate which is to be rounded
+ *
+ * Takes in a rate as input and rounds it to the closest rate that the clk
+ * can actually use which is then returned. If clk doesn't support
+ * round_rate operation then the parent rate is returned.
+ */
+long clk_round_rate_nearest(struct clk *clk, unsigned long rate)
+{
+	long lower_limit = clk_round_rate(clk, rate);
+	long upper_limit = clk_round_rate(clk, rate + (rate - lower_limit));
+
+	if (rate - lower_limit < upper_limit - rate)
+		return lower_limit;
+	else
+		return upper_limit;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate_nearest);
+
+/**
  * __clk_notify - call clk notifier chain
  * @clk: struct clk * that is changing rate
  * @msg: clk notifier type (see include/linux/clk.h)
Index: linux-3.12.24-rt38-xilinx/drivers/clk/clk-si570.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/clk/clk-si570.c	2014-07-20 22:06:35.446320728 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
+ *
+ * Copyright (C) 2010, 2011 Ericsson AB.
+ * Copyright (C) 2011 Guenter Roeck.
+ * Copyright (C) 2011 - 2013 Xilinx Inc.
+ *
+ * Author: Guenter Roeck <guenter.roeck@ericsson.com>
+ *	   Sören Brinkmann <soren.brinkmann@xilinx.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* Si570 registers */
+#define SI570_REG_HS_N1		7
+#define SI570_REG_N1_RFREQ0	8
+#define SI570_REG_RFREQ1	9
+#define SI570_REG_RFREQ2	10
+#define SI570_REG_RFREQ3	11
+#define SI570_REG_RFREQ4	12
+#define SI570_REG_CONTROL	135
+#define SI570_REG_FREEZE_DCO	137
+#define SI570_DIV_OFFSET_7PPM	6
+
+#define HS_DIV_SHIFT		5
+#define HS_DIV_MASK		0xe0
+#define HS_DIV_OFFSET		4
+#define N1_6_2_MASK		0x1f
+#define N1_1_0_MASK		0xc0
+#define RFREQ_37_32_MASK	0x3f
+
+#define SI570_MIN_FREQ		10000000L
+#define SI570_MAX_FREQ		1417500000L
+#define SI598_MAX_FREQ		525000000L
+
+#define FDCO_MIN		4850000000LL
+#define FDCO_MAX		5670000000LL
+
+#define SI570_CNTRL_RECALL	(1 << 0)
+#define SI570_CNTRL_FREEZE_M	(1 << 5)
+#define SI570_CNTRL_NEWFREQ	(1 << 6)
+
+#define SI570_FREEZE_DCO	(1 << 4)
+
+/**
+ * struct clk_si570:
+ * @hw:	Clock hw struct
+ * @regmap:	Device's regmap
+ * @div_offset:	Rgister offset for dividers
+ * @max_freq:	Maximum frequency for this device
+ * @fxtal:	Factory xtal frequency
+ * @n1:		Clock divider N1
+ * @hs_div:	Clock divider HSDIV
+ * @rfreq:	Clock multiplier RFREQ
+ * @frequency:	Current output frequency
+ * @i2c_client:	I2C client pointer
+ */
+struct clk_si570 {
+	struct clk_hw hw;
+	struct regmap *regmap;
+	unsigned int div_offset;
+	u64 max_freq;
+	u64 fxtal;
+	unsigned int n1;
+	unsigned int hs_div;
+	u64 rfreq;
+	u64 frequency;
+	struct i2c_client *i2c_client;
+};
+#define to_clk_si570(_hw)	container_of(_hw, struct clk_si570, hw)
+
+enum clk_si570_variant {
+	si57x,
+	si59x
+};
+
+/**
+ * si570_get_divs() - Read clock dividers from HW
+ * @data:	Pointer to struct clk_si570
+ * @rfreq:	Fractional multiplier (output)
+ * @n1:		Divider N1 (output)
+ * @hs_div:	Divider HSDIV (output)
+ * Returns 0 on success, negative errno otherwise.
+ *
+ * Retrieve clock dividers and multipliers from the HW.
+ */
+static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
+		unsigned int *n1, unsigned int *hs_div)
+{
+	int err;
+	u8 reg[6];
+	u64 tmp;
+
+	err = regmap_bulk_read(data->regmap, SI570_REG_HS_N1 + data->div_offset,
+			reg, ARRAY_SIZE(reg));
+	if (err)
+		return err;
+
+	*hs_div = ((reg[0] & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
+	*n1 = ((reg[0] & N1_6_2_MASK) << 2) + ((reg[1] & N1_1_0_MASK) >> 6) + 1;
+	/* Handle invalid cases */
+	if (*n1 > 1)
+		*n1 &= ~1;
+
+	tmp = reg[1] & RFREQ_37_32_MASK;
+	tmp = (tmp << 8) + reg[2];
+	tmp = (tmp << 8) + reg[3];
+	tmp = (tmp << 8) + reg[4];
+	tmp = (tmp << 8) + reg[5];
+	*rfreq = tmp;
+
+	return 0;
+}
+
+/**
+ * si570_get_defaults() - Get default values
+ * @data:	Driver data structure
+ * @fout:	Factory frequency output
+ * Returns 0 on success, negative errno otherwise.
+ */
+static int si570_get_defaults(struct clk_si570 *data, u64 fout)
+{
+	int err;
+	u64 fdco;
+
+	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
+
+	err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
+	if (err)
+		return err;
+
+	/*
+	 * Accept optional precision loss to avoid arithmetic overflows.
+	 * Acceptable per Silicon Labs Application Note AN334.
+	 */
+	fdco = fout * data->n1 * data->hs_div;
+	if (fdco >= (1LL << 36))
+		data->fxtal = div64_u64(fdco << 24, data->rfreq >> 4);
+	else
+		data->fxtal = div64_u64(fdco << 28, data->rfreq);
+
+	data->frequency = fout;
+
+	return 0;
+}
+
+/**
+ * si570_update_rfreq() - Update clock multiplier
+ * @data:	Driver data structure
+ * Passes on regmap_bulk_write() return value.
+ */
+static int si570_update_rfreq(struct clk_si570 *data)
+{
+	u8 reg[5];
+
+	reg[0] = ((data->n1 - 1) << 6) |
+		((data->rfreq >> 32) & RFREQ_37_32_MASK);
+	reg[1] = (data->rfreq >> 24) & 0xff;
+	reg[2] = (data->rfreq >> 16) & 0xff;
+	reg[3] = (data->rfreq >> 8) & 0xff;
+	reg[4] = data->rfreq & 0xff;
+
+	return regmap_bulk_write(data->regmap, SI570_REG_N1_RFREQ0 +
+			data->div_offset, reg, ARRAY_SIZE(reg));
+}
+
+/**
+ * si570_calc_divs() - Caluclate clock dividers
+ * @frequency:	Target frequency
+ * @data:	Driver data structure
+ * @out_rfreq:	RFREG fractional multiplier (output)
+ * @out_n1:	Clock divider N1 (output)
+ * @out_hs_div:	Clock divider HSDIV (output)
+ * Returns 0 on success, negative errno otherwise.
+ *
+ * Calculate the clock dividers (@out_hs_div, @out_n1) and clock multiplier
+ * (@out_rfreq) for a given target @frequency.
+ */
+static int si570_calc_divs(unsigned long frequency, struct clk_si570 *data,
+		u64 *out_rfreq, unsigned int *out_n1, unsigned int *out_hs_div)
+{
+	int i;
+	unsigned int n1, hs_div;
+	u64 fdco, best_fdco = ULLONG_MAX;
+	static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
+
+	for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
+		hs_div = si570_hs_div_values[i];
+		/* Calculate lowest possible value for n1 */
+		n1 = div_u64(div_u64(FDCO_MIN, hs_div), frequency);
+		if (!n1 || (n1 & 1))
+			n1++;
+		while (n1 <= 128) {
+			fdco = (u64)frequency * (u64)hs_div * (u64)n1;
+			if (fdco > FDCO_MAX)
+				break;
+			if (fdco >= FDCO_MIN && fdco < best_fdco) {
+				*out_n1 = n1;
+				*out_hs_div = hs_div;
+				*out_rfreq = div64_u64(fdco << 28, data->fxtal);
+				best_fdco = fdco;
+			}
+			n1 += (n1 == 1 ? 1 : 2);
+		}
+	}
+
+	if (best_fdco == ULLONG_MAX)
+		return -EINVAL;
+
+	return 0;
+}
+
+static unsigned long si570_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	int err;
+	u64 rfreq, rate;
+	unsigned int n1, hs_div;
+	struct clk_si570 *data = to_clk_si570(hw);
+
+	err = si570_get_divs(data, &rfreq, &n1, &hs_div);
+	if (err) {
+		dev_err(&data->i2c_client->dev, "unable to recalc rate\n");
+		return data->frequency;
+	}
+
+	rfreq = div_u64(rfreq, hs_div * n1);
+	rate = (data->fxtal * rfreq) >> 28;
+
+	return rate;
+}
+
+static long si570_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *parent_rate)
+{
+	int err;
+	u64 rfreq;
+	unsigned int n1, hs_div;
+	struct clk_si570 *data = to_clk_si570(hw);
+
+	if (!rate)
+		return 0;
+
+	if (div64_u64(abs(rate - data->frequency) * 10000LL,
+				data->frequency) < 35) {
+		rfreq = div64_u64((data->rfreq * rate) +
+				div64_u64(data->frequency, 2), data->frequency);
+		n1 = data->n1;
+		hs_div = data->hs_div;
+
+	} else {
+		err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div);
+		if (err) {
+			dev_err(&data->i2c_client->dev,
+					"unable to round rate\n");
+			return 0;
+		}
+	}
+
+	return rate;
+}
+
+/**
+ * si570_set_frequency() - Adjust output frequency
+ * @data:	Driver data structure
+ * @frequency:	Target frequency
+ * Returns 0 on success.
+ *
+ * Update output frequency for big frequency changes (> 3,500 ppm).
+ */
+static int si570_set_frequency(struct clk_si570 *data, unsigned long frequency)
+{
+	int err;
+
+	err = si570_calc_divs(frequency, data, &data->rfreq, &data->n1,
+			&data->hs_div);
+	if (err)
+		return err;
+
+	/*
+	 * The DCO reg should be accessed with a read-modify-write operation
+	 * per AN334
+	 */
+	regmap_write(data->regmap, SI570_REG_FREEZE_DCO, SI570_FREEZE_DCO);
+	regmap_write(data->regmap, SI570_REG_HS_N1 + data->div_offset,
+			((data->hs_div - HS_DIV_OFFSET) << HS_DIV_SHIFT) |
+			(((data->n1 - 1) >> 2) & N1_6_2_MASK));
+	si570_update_rfreq(data);
+	regmap_write(data->regmap, SI570_REG_FREEZE_DCO, 0);
+	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_NEWFREQ);
+
+	/* Applying a new frequency can take up to 10ms */
+	usleep_range(10000, 12000);
+
+	return 0;
+}
+
+/**
+ * si570_set_frequency_small() - Adjust output frequency
+ * @data:	Driver data structure
+ * @frequency:	Target frequency
+ * Returns 0 on success.
+ *
+ * Update output frequency for small frequency changes (< 3,500 ppm).
+ */
+static int si570_set_frequency_small(struct clk_si570 *data,
+				     unsigned long frequency)
+{
+	/*
+	 * This is a re-implementation of DIV_ROUND_CLOSEST
+	 * using the div64_u64 function lieu of letting the compiler
+	 * insert EABI calls
+	 */
+	data->rfreq = div64_u64((data->rfreq * frequency) +
+			div_u64(data->frequency, 2), data->frequency);
+	regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_FREEZE_M);
+	si570_update_rfreq(data);
+	regmap_write(data->regmap, SI570_REG_CONTROL, 0);
+
+	/* Applying a new frequency (small change) can take up to 100us */
+	usleep_range(100, 200);
+
+	return 0;
+}
+
+static int si570_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_si570 *data = to_clk_si570(hw);
+	struct i2c_client *client = data->i2c_client;
+	int err;
+
+	if (rate < SI570_MIN_FREQ || rate > data->max_freq) {
+		dev_err(&client->dev,
+			"requested frequency %lu Hz is out of range\n", rate);
+		return -EINVAL;
+	}
+
+	if (div64_u64(abs(rate - data->frequency) * 10000LL,
+				data->frequency) < 35)
+		err = si570_set_frequency_small(data, rate);
+	else
+		err = si570_set_frequency(data, rate);
+
+	if (err)
+		return err;
+
+	data->frequency = rate;
+
+	return 0;
+}
+
+static const struct clk_ops si570_clk_ops = {
+	.recalc_rate = si570_recalc_rate,
+	.round_rate = si570_round_rate,
+	.set_rate = si570_set_rate,
+};
+
+static bool si570_regmap_is_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SI570_REG_CONTROL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SI570_REG_HS_N1 ... (SI570_REG_RFREQ4 + SI570_DIV_OFFSET_7PPM):
+	case SI570_REG_CONTROL:
+	case SI570_REG_FREEZE_DCO:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static struct regmap_config si570_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.max_register = 137,
+	.writeable_reg = si570_regmap_is_writeable,
+	.volatile_reg = si570_regmap_is_volatile,
+};
+
+static int si570_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct clk_si570 *data;
+	struct clk_init_data init;
+	struct clk *clk;
+	u32 initial_fout, factory_fout, stability;
+	int err;
+	enum clk_si570_variant variant = id->driver_data;
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	init.ops = &si570_clk_ops;
+	init.flags = CLK_IS_ROOT;
+	init.num_parents = 0;
+	data->hw.init = &init;
+	data->i2c_client = client;
+
+	if (variant == si57x) {
+		err = of_property_read_u32(client->dev.of_node,
+				"temperature-stability", &stability);
+		if (err) {
+			dev_err(&client->dev,
+				  "'temperature-stability' property missing\n");
+			return err;
+		}
+		/* adjust register offsets for 7ppm devices */
+		if (stability == 7)
+			data->div_offset = SI570_DIV_OFFSET_7PPM;
+
+		data->max_freq = SI570_MAX_FREQ;
+	} else {
+		data->max_freq = SI598_MAX_FREQ;
+	}
+
+	if (of_property_read_string(client->dev.of_node, "clock-output-names",
+			&init.name))
+		init.name = client->dev.of_node->name;
+
+	err = of_property_read_u32(client->dev.of_node, "factory-fout",
+			&factory_fout);
+	if (err) {
+		dev_err(&client->dev, "'factory-fout' property missing\n");
+		return err;
+	}
+
+	data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
+	if (IS_ERR(data->regmap)) {
+		dev_err(&client->dev, "failed to allocate register map\n");
+		return PTR_ERR(data->regmap);
+	}
+
+	i2c_set_clientdata(client, data);
+	err = si570_get_defaults(data, factory_fout);
+	if (err)
+		return err;
+
+	clk = devm_clk_register(&client->dev, &data->hw);
+	if (IS_ERR(clk)) {
+		dev_err(&client->dev, "clock registration failed\n");
+		return PTR_ERR(clk);
+	}
+	err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
+			clk);
+	if (err) {
+		dev_err(&client->dev, "unable to add clk provider\n");
+		return err;
+	}
+
+	/* Read the requested initial output frequency from device tree */
+	if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
+				&initial_fout)) {
+		err = clk_set_rate(clk, initial_fout);
+		if (err) {
+			of_clk_del_provider(client->dev.of_node);
+			return err;
+		}
+	}
+
+	/* Display a message indicating that we've successfully registered */
+	dev_info(&client->dev, "registered, current frequency %llu Hz\n",
+			data->frequency);
+
+	return 0;
+}
+
+static int si570_remove(struct i2c_client *client)
+{
+	of_clk_del_provider(client->dev.of_node);
+	return 0;
+}
+
+static const struct i2c_device_id si570_id[] = {
+	{ "si570", si57x },
+	{ "si571", si57x },
+	{ "si598", si59x },
+	{ "si599", si59x },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, si570_id);
+
+static const struct of_device_id clk_si570_of_match[] = {
+	{ .compatible = "silabs,si570" },
+	{ .compatible = "silabs,si571" },
+	{ .compatible = "silabs,si598" },
+	{ .compatible = "silabs,si599" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, clk_si570_of_match);
+
+static struct i2c_driver si570_driver = {
+	.driver = {
+		.name = "si570",
+		.of_match_table = of_match_ptr(clk_si570_of_match),
+	},
+	.probe		= si570_probe,
+	.remove		= si570_remove,
+	.id_table	= si570_id,
+};
+module_i2c_driver(si570_driver);
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com");
+MODULE_DESCRIPTION("Si570 driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/clk/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/clk/Kconfig	2014-07-20 22:05:50.224066819 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/clk/Kconfig	2014-07-20 22:06:35.462320464 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:67 @
 	  This driver supports Silicon Labs 5351A/B/C programmable clock
 	  generators.
 
+config COMMON_CLK_SI570
+	tristate "Clock driver for SiLabs 570 and compatible devices"
+	depends on I2C
+	depends on OF
+	select REGMAP_I2C
+	help
+	---help---
+	  This driver supports Silicon Labs 570/571/598/599 programmable
+	  clock generators.
+
 config COMMON_CLK_S2MPS11
 	tristate "Clock driver for S2MPS11 MFD"
 	depends on MFD_SEC_CORE
Index: linux-3.12.24-rt38-xilinx/drivers/clk/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/clk/Makefile	2014-07-20 22:05:50.222066852 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/clk/Makefile	2014-07-20 22:06:35.504319771 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:43 @
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
+obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
 obj-$(CONFIG_CLK_TWL6040)	+= clk-twl6040.o
 obj-$(CONFIG_CLK_PPC_CORENET)	+= clk-ppc-corenet.o
Index: linux-3.12.24-rt38-xilinx/drivers/clk/zynq/clkc.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/clk/zynq/clkc.c	2014-07-20 22:05:50.221066869 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/clk/zynq/clkc.c	2014-07-20 22:06:35.521319491 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:23 @
 
 #include <linux/clk/zynq.h>
 #include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:50 @
 #define SLCR_CAN_MIOCLK_CTRL		(zynq_slcr_base_priv + 0x160)
 #define SLCR_DBG_CLK_CTRL		(zynq_slcr_base_priv + 0x164)
 #define SLCR_PCAP_CLK_CTRL		(zynq_slcr_base_priv + 0x168)
+#define SLCR_TOPSW_CLK_CTRL		(zynq_slcr_base_priv + 0x16c)
 #define SLCR_FPGA0_CLK_CTRL		(zynq_slcr_base_priv + 0x170)
 #define SLCR_621_TRUE			(zynq_slcr_base_priv + 0x1c4)
 #define SLCR_SWDT_CLK_SEL		(zynq_slcr_base_priv + 0x304)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:105 @
 static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"};
 static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"};
 
+#ifdef CONFIG_SUSPEND
+unsigned int zynq_clk_suspended;
+static struct clk *armpll_save_parent;
+static struct clk *iopll_save_parent;
+
+#define TOPSW_CLK_CTRL_DIS_MASK	BIT(0)
+
+int zynq_clk_suspend_early(void)
+{
+	int ret;
+
+	zynq_clk_suspended = 1;
+
+	iopll_save_parent = clk_get_parent(clks[iopll]);
+	armpll_save_parent = clk_get_parent(clks[armpll]);
+
+	ret = clk_set_parent(clks[iopll], ps_clk);
+	if (ret)
+		pr_info("%s: reparent iopll failed %d\n", __func__, ret);
+
+	ret = clk_set_parent(clks[armpll], ps_clk);
+	if (ret)
+		pr_info("%s: reparent armpll failed %d\n", __func__, ret);
+
+	return 0;
+}
+
+void zynq_clk_resume_late(void)
+{
+	clk_set_parent(clks[armpll], armpll_save_parent);
+	clk_set_parent(clks[iopll], iopll_save_parent);
+
+	zynq_clk_suspended = 0;
+}
+
+void zynq_clk_topswitch_enable(void)
+{
+	u32 reg;
+
+	reg = readl(SLCR_TOPSW_CLK_CTRL);
+	reg &= ~TOPSW_CLK_CTRL_DIS_MASK;
+	writel(reg, SLCR_TOPSW_CLK_CTRL);
+}
+
+void zynq_clk_topswitch_disable(void)
+{
+	u32 reg;
+
+	reg = readl(SLCR_TOPSW_CLK_CTRL);
+	reg |= TOPSW_CLK_CTRL_DIS_MASK;
+	writel(reg, SLCR_TOPSW_CLK_CTRL);
+}
+#endif
+
 static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
 		const char *clk_name, void __iomem *fclk_ctrl_reg,
-		const char **parents)
+		const char **parents, int enable)
 {
 	struct clk *clk;
+	u32 enable_reg;
 	char *mux_name;
 	char *div0_name;
 	char *div1_name;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:201 @
 	clks[fclk] = clk_register_gate(NULL, clk_name,
 			div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
 			0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
+	enable_reg = readl(fclk_gate_reg) & 1;
+	if (enable && !enable_reg) {
+		if (clk_prepare_enable(clks[fclk]))
+			pr_warn("%s: FCLK%u enable failed\n", __func__,
+					fclk - fclk0);
+	}
 	kfree(mux_name);
 	kfree(div0_name);
 	kfree(div1_name);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:265 @
 	int ret;
 	struct clk *clk;
 	char *clk_name;
+	unsigned int fclk_enable;
 	const char *clk_output_name[clk_max];
 	const char *cpu_parents[4];
 	const char *periph_parents[4];
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:300 @
 	ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT,
 			tmp);
 
+	ret = of_property_read_u32(np, "fclk-enable", &fclk_enable);
+	if (ret)
+		fclk_enable = 0xf;
+
 	/* PLLs */
 	clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
 			SLCR_PLL_STATUS, 0, &armpll_lock);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:335 @
 	clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x],
 			"cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
 			SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock);
+	clk_register_clkdev(clks[cpu_6or4x], "cpufreq_clk", NULL);
 
 	clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0,
 			1, 2);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:398 @
 	clk_prepare_enable(clks[dci]);
 
 	/* Peripheral clocks */
-	for (i = fclk0; i <= fclk3; i++)
+	for (i = fclk0; i <= fclk3; i++) {
+		int enable = !!(fclk_enable & BIT(i - fclk0));
 		zynq_clk_register_fclk(i, clk_output_name[i],
 				SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
-				periph_parents);
+				periph_parents, enable);
+	}
 
 	zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
 			SLCR_LQSPI_CLK_CTRL, periph_parents, 0);
Index: linux-3.12.24-rt38-xilinx/drivers/clocksource/cadence_ttc_timer.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/clocksource/cadence_ttc_timer.c	2014-07-20 22:05:50.170067710 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/clocksource/cadence_ttc_timer.c	2014-07-20 22:06:35.537319227 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:70 @
  * struct ttc_timer - This definition defines local timer structure
  *
  * @base_addr:	Base address of timer
+ * @freq:	Timer input clock frequency
  * @clk:	Associated clock source
  * @clk_rate_change_nb	Notifier block for clock rate changes
  */
 struct ttc_timer {
 	void __iomem *base_addr;
+	unsigned long freq;
 	struct clk *clk;
 	struct notifier_block clk_rate_change_nb;
 };
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:202 @
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		ttc_set_interval(timer,
-				DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk),
+				DIV_ROUND_CLOSEST(ttce->ttc.freq,
 					PRESCALE * HZ));
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:224 @
 	}
 }
 
-static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
-		unsigned long event, void *data)
-{
-	struct clk_notifier_data *ndata = data;
-	struct ttc_timer *ttc = to_ttc_timer(nb);
-	struct ttc_timer_clocksource *ttccs = container_of(ttc,
-			struct ttc_timer_clocksource, ttc);
-
-	switch (event) {
-	case POST_RATE_CHANGE:
-		/*
-		 * Do whatever is necessary to maintain a proper time base
-		 *
-		 * I cannot find a way to adjust the currently used clocksource
-		 * to the new frequency. __clocksource_updatefreq_hz() sounds
-		 * good, but does not work. Not sure what's that missing.
-		 *
-		 * This approach works, but triggers two clocksource switches.
-		 * The first after unregister to clocksource jiffies. And
-		 * another one after the register to the newly registered timer.
-		 *
-		 * Alternatively we could 'waste' another HW timer to ping pong
-		 * between clock sources. That would also use one register and
-		 * one unregister call, but only trigger one clocksource switch
-		 * for the cost of another HW timer used by the OS.
-		 */
-		clocksource_unregister(&ttccs->cs);
-		clocksource_register_hz(&ttccs->cs,
-				ndata->new_rate / PRESCALE);
-		/* fall through */
-	case PRE_RATE_CHANGE:
-	case ABORT_RATE_CHANGE:
-	default:
-		return NOTIFY_DONE;
-	}
-}
-
 static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
 {
 	struct ttc_timer_clocksource *ttccs;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:241 @
 		return;
 	}
 
-	ttccs->ttc.clk_rate_change_nb.notifier_call =
-		ttc_rate_change_clocksource_cb;
-	ttccs->ttc.clk_rate_change_nb.next = NULL;
-	if (clk_notifier_register(ttccs->ttc.clk,
-				&ttccs->ttc.clk_rate_change_nb))
-		pr_warn("Unable to register clock notifier.\n");
-
+	ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk);
 	ttccs->ttc.base_addr = base;
 	ttccs->cs.name = "ttc_clocksource";
 	ttccs->cs.rating = 200;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:260 @
 	__raw_writel(CNT_CNTRL_RESET,
 		     ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
 
-	err = clocksource_register_hz(&ttccs->cs,
-			clk_get_rate(ttccs->ttc.clk) / PRESCALE);
+	err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
 	if (WARN_ON(err)) {
 		kfree(ttccs);
 		return;
 	}
 
 	ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET;
-	setup_sched_clock(ttc_sched_clock_read, 16,
-			clk_get_rate(ttccs->ttc.clk) / PRESCALE);
+	setup_sched_clock(ttc_sched_clock_read, 16, ttccs->ttc.freq / PRESCALE);
 }
 
 static int ttc_rate_change_clockevent_cb(struct notifier_block *nb,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:294 @
 				ndata->new_rate / PRESCALE);
 		local_irq_restore(flags);
 
+		/* update cached frequency */
+		ttc->freq = ndata->new_rate;
+
+		if (ttcce->ce.mode == CLOCK_EVT_MODE_PERIODIC)
+			ttc_set_interval(ttc, DIV_ROUND_CLOSEST(ttc->freq,
+						PRESCALE * HZ));
+
 		/* fall through */
 	}
 	case PRE_RATE_CHANGE:
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:334 @
 	if (clk_notifier_register(ttcce->ttc.clk,
 				&ttcce->ttc.clk_rate_change_nb))
 		pr_warn("Unable to register clock notifier.\n");
+	ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk);
 
 	ttcce->ttc.base_addr = base;
 	ttcce->ce.name = "ttc_clockevent";
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:364 @
 	}
 
 	clockevents_config_and_register(&ttcce->ce,
-			clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe);
+			ttcce->ttc.freq / PRESCALE, 1, 0xfffe);
 }
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:426 @
 }
 
 CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);
+CLOCKSOURCE_OF_DECLARE(ttc1, "xlnx,ps7-ttc-1.00.a", ttc_timer_init);
Index: linux-3.12.24-rt38-xilinx/drivers/cpufreq/Kconfig.arm
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/cpufreq/Kconfig.arm	2014-07-20 22:05:50.175067628 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/cpufreq/Kconfig.arm	2014-07-20 22:06:35.550319013 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:238 @
 	default y
 	help
 	  This adds the CPUFreq driver support for TEGRA SOCs.
+
+config ARM_ZYNQ_CPUFREQ
+	bool "Xilinx Zynq"
+	depends on ARCH_ZYNQ
+	default n
+	select CPU_FREQ_TABLE
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver for Xilinx Zynq SoCs.
+
Index: linux-3.12.24-rt38-xilinx/drivers/cpufreq/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/cpufreq/Makefile	2014-07-20 22:05:50.174067644 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/cpufreq/Makefile	2014-07-20 22:06:35.560318848 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:80 @
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)	+= sa1110-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA_CPUFREQ)		+= tegra-cpufreq.o
+obj-$(CONFIG_ARM_ZYNQ_CPUFREQ)     	+= zynq-cpufreq.o
 
 ##################################################################################
 # PowerPC platform drivers
Index: linux-3.12.24-rt38-xilinx/drivers/cpufreq/zynq-cpufreq.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/cpufreq/zynq-cpufreq.c	2014-07-20 22:06:35.575318600 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * CPU frequency scaling for Zynq
+ *
+ * Based on drivers/cpufreq/omap-cpufreq.c,
+ * Copyright (C) 2005 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clk/zynq.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/opp.h>
+#include <linux/platform_device.h>
+#include <asm/smp_plat.h>
+#include <asm/cpu.h>
+
+static atomic_t freq_table_users = ATOMIC_INIT(0);
+static struct cpufreq_frequency_table *freq_table;
+static struct device *mpu_dev;
+static struct clk *cpuclk;
+
+static int zynq_verify_speed(struct cpufreq_policy *policy)
+{
+	if (!freq_table)
+		return -EINVAL;
+	return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int zynq_getspeed(unsigned int cpu)
+{
+	unsigned long rate;
+
+	if (cpu >= num_present_cpus())
+		return 0;
+
+	rate = clk_get_rate(cpuclk) / 1000;
+	return rate;
+}
+
+static int zynq_target(struct cpufreq_policy *policy,
+		       unsigned int target_freq,
+		       unsigned int relation)
+{
+	unsigned int i;
+	int ret = 0;
+	struct cpufreq_freqs freqs;
+
+#ifdef CONFIG_SUSPEND
+	if (zynq_clk_suspended)
+		return -EPERM;
+#endif
+
+	if (!freq_table) {
+		dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
+			policy->cpu);
+		return -EINVAL;
+	}
+
+	ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+					     relation, &i);
+	if (ret) {
+		dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
+			__func__, policy->cpu, target_freq, ret);
+		return ret;
+	}
+	freqs.new = freq_table[i].frequency;
+	if (!freqs.new) {
+		dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
+			policy->cpu, target_freq);
+		return -EINVAL;
+	}
+
+	freqs.old = zynq_getspeed(policy->cpu);
+	freqs.cpu = policy->cpu;
+
+	if (freqs.old == freqs.new && policy->cur == freqs.new)
+		return ret;
+
+	/* notifiers */
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+
+	dev_dbg(mpu_dev, "cpufreq-zynq: %u MHz --> %u MHz\n",
+		freqs.old / 1000, freqs.new / 1000);
+
+	ret = clk_set_rate(cpuclk, freqs.new * 1000);
+
+	freqs.new = zynq_getspeed(policy->cpu);
+
+	/* notifiers */
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+
+	return ret;
+}
+
+static inline void freq_table_free(void)
+{
+	if (atomic_dec_and_test(&freq_table_users))
+		opp_free_cpufreq_table(mpu_dev, &freq_table);
+}
+
+static int __cpuinit zynq_cpu_init(struct cpufreq_policy *policy)
+{
+	int result = 0;
+
+	cpuclk = devm_clk_get(mpu_dev, "cpufreq_clk");
+	if (IS_ERR(cpuclk)) {
+		dev_err(mpu_dev, "cpufreq_clk clock not found.");
+		return PTR_ERR(cpuclk);
+	}
+
+	if (policy->cpu >= num_possible_cpus())
+		return -EINVAL;
+
+	policy->cur = policy->min = policy->max = zynq_getspeed(policy->cpu);
+
+	if (!freq_table)
+		result = opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+	if (result) {
+		dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
+			__func__, policy->cpu, result);
+		return result;
+	}
+
+	atomic_inc(&freq_table_users);
+
+	result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+	if (result) {
+		freq_table_free();
+		return result;
+	}
+
+	cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+	policy->cur = zynq_getspeed(policy->cpu);
+
+	/*
+	 * On Zynq configuartion, both processors share the voltage
+	 * and clock. So both CPUs needs to be scaled together and hence
+	 * needs software co-ordination. Use cpufreq affected_cpus
+	 * interface to handle this scenario. Additional is_smp() check
+	 * is to keep SMP_ON_UP build working.
+	 */
+	if (is_smp()) {
+		policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+		cpumask_setall(policy->cpus);
+	}
+
+	/* FIXME: what's the actual transition time? */
+	policy->cpuinfo.transition_latency = 300 * 1000;
+
+	return 0;
+}
+
+static int zynq_cpu_exit(struct cpufreq_policy *policy)
+{
+	freq_table_free();
+	return 0;
+}
+
+static struct freq_attr *zynq_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver zynq_cpufreq_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= zynq_verify_speed,
+	.target		= zynq_target,
+	.get		= zynq_getspeed,
+	.init		= zynq_cpu_init,
+	.exit		= zynq_cpu_exit,
+	.name		= "Zynq cpufreq",
+	.attr		= zynq_cpufreq_attr,
+};
+
+static int __init zynq_cpufreq_init(void)
+{
+	struct device *dev = get_cpu_device(0);
+
+	if (!dev) {
+		pr_warn("%s: Error: device not found.", __func__);
+		return -EINVAL;
+	}
+	mpu_dev = dev;
+	return cpufreq_register_driver(&zynq_cpufreq_driver);
+}
+
+static void __exit zynq_cpufreq_exit(void)
+{
+	cpufreq_unregister_driver(&zynq_cpufreq_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for Zynq");
+MODULE_LICENSE("GPL");
+module_init(zynq_cpufreq_init);
+module_exit(zynq_cpufreq_exit);
Index: linux-3.12.24-rt38-xilinx/drivers/dma/dmatest.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/dma/dmatest.c	2014-07-20 22:05:50.149068057 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/dma/dmatest.c	2014-07-20 22:06:35.597318237 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:629 @
 			break;
 		}
 
+		align = 3;
 		len = dmatest_random() % params->buf_size + 1;
 		len = (len >> align) << align;
 		if (!len)
Index: linux-3.12.24-rt38-xilinx/drivers/dma/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/dma/Kconfig	2014-07-20 22:05:50.163067826 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/dma/Kconfig	2014-07-20 22:06:35.609318040 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:36 @
 
 comment "DMA Devices"
 
+source "drivers/dma/xilinx/Kconfig"
+
 config INTEL_MID_DMAC
 	tristate "Intel MID DMA support for Peripheral DMA controllers"
 	depends on PCI && X86
Index: linux-3.12.24-rt38-xilinx/drivers/dma/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/dma/Makefile	2014-07-20 22:05:50.162067842 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/dma/Makefile	2014-07-20 22:06:35.619317875 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:44 @
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
 obj-$(CONFIG_TI_CPPI41) += cppi41.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
+obj-$(CONFIG_XILINX_DMA_ENGINES) += xilinx/
Index: linux-3.12.24-rt38-xilinx/drivers/dma/pl330.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/dma/pl330.c	2014-07-20 22:05:50.161067858 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/dma/pl330.c	2014-07-20 22:06:35.639317545 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2925 @
 
 	amba_set_drvdata(adev, pdmac);
 
-	irq = adev->irq[0];
-	ret = request_irq(irq, pl330_irq_handler, 0,
-			dev_name(&adev->dev), pi);
-	if (ret)
-		return ret;
+	for (i = 0; i <= AMBA_NR_IRQS; i++) {
+		irq = adev->irq[i];
+		if (irq) {
+			ret = devm_request_irq(&adev->dev, irq,
+					       pl330_irq_handler, 0,
+					       dev_name(&adev->dev), pi);
+			if (ret)
+				return ret;
+		} else {
+			break;
+		}
+	}
 
 	pi->pcfg.periph_id = adev->periphid;
 	ret = pl330_add(pi);
 	if (ret)
-		goto probe_err1;
+		return ret;
 
 	INIT_LIST_HEAD(&pdmac->desc_pool);
 	spin_lock_init(&pdmac->pool_lock);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3054 @
 	}
 probe_err2:
 	pl330_del(pi);
-probe_err1:
-	free_irq(irq, pi);
 
 	return ret;
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3063 @
 	struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev);
 	struct dma_pl330_chan *pch, *_p;
 	struct pl330_info *pi;
-	int irq;
 
 	if (!pdmac)
 		return 0;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3089 @
 
 	pl330_del(pi);
 
-	irq = adev->irq[0];
-	free_irq(irq, pi);
-
 	return 0;
 }
 
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/axidmatest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/axidmatest.c	2014-07-20 22:06:35.657317248 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * XILINX AXI DMA Engine test module
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ * Based on Atmel DMA Test Client
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/amba/xilinx_dma.h>
+
+static unsigned int test_buf_size = 64;
+module_param(test_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
+
+static unsigned int iterations;
+module_param(iterations, uint, S_IRUGO);
+MODULE_PARM_DESC(iterations,
+		"Iterations before stopping test (default: infinite)");
+
+/*
+ * Initialization patterns. All bytes in the source buffer has bit 7
+ * set, all bytes in the destination buffer has bit 7 cleared.
+ *
+ * Bit 6 is set for all bytes which are to be copied by the DMA
+ * engine. Bit 5 is set for all bytes which are to be overwritten by
+ * the DMA engine.
+ *
+ * The remaining bits are the inverse of a counter which increments by
+ * one for each byte address.
+ */
+#define PATTERN_SRC		0x80
+#define PATTERN_DST		0x00
+#define PATTERN_COPY		0x40
+#define PATTERN_OVERWRITE	0x20
+#define PATTERN_COUNT_MASK	0x1f
+
+struct dmatest_slave_thread {
+	struct list_head node;
+	struct task_struct *task;
+	struct dma_chan *tx_chan;
+	struct dma_chan *rx_chan;
+	u8 **srcs;
+	u8 **dsts;
+	enum dma_transaction_type type;
+};
+
+struct dmatest_chan {
+	struct list_head node;
+	struct dma_chan *chan;
+	struct list_head threads;
+};
+
+/*
+ * These are protected by dma_list_mutex since they're only used by
+ * the DMA filter function callback
+ */
+static LIST_HEAD(dmatest_channels);
+static unsigned int nr_channels;
+
+static unsigned long dmatest_random(void)
+{
+	unsigned long buf;
+
+	get_random_bytes(&buf, sizeof(buf));
+	return buf;
+}
+
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_SRC | PATTERN_COPY
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		buf++;
+	}
+}
+
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	}
+}
+
+static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
+		unsigned int counter, bool is_srcbuf)
+{
+	u8 diff = actual ^ pattern;
+	u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
+	const char *thread_name = current->comm;
+
+	if (is_srcbuf)
+		pr_warn(
+		"%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if ((pattern & PATTERN_COPY)
+			&& (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
+		pr_warn(
+		"%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if (diff & PATTERN_SRC)
+		pr_warn(
+		"%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else
+		pr_warn(
+		"%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+}
+
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
+		unsigned int end, unsigned int counter, u8 pattern,
+		bool is_srcbuf)
+{
+	unsigned int i;
+	unsigned int error_count = 0;
+	u8 actual;
+	u8 expected;
+	u8 *buf;
+	unsigned int counter_orig = counter;
+
+	for (; (buf = *bufs); bufs++) {
+		counter = counter_orig;
+		for (i = start; i < end; i++) {
+			actual = buf[i];
+			expected = pattern | (~counter & PATTERN_COUNT_MASK);
+			if (actual != expected) {
+				if (error_count < 32)
+					dmatest_mismatch(actual, pattern, i,
+							counter, is_srcbuf);
+				error_count++;
+			}
+			counter++;
+		}
+	}
+
+	if (error_count > 32)
+		pr_warn("%s: %u errors suppressed\n",
+			current->comm, error_count - 32);
+
+	return error_count;
+}
+
+static void dmatest_slave_tx_callback(void *completion)
+{
+	complete(completion);
+}
+
+static void dmatest_slave_rx_callback(void *completion)
+{
+	complete(completion);
+}
+
+/* Function for slave transfers
+ * Each thread requires 2 channels, one for transmit, and one for receive
+ */
+static int dmatest_slave_func(void *data)
+{
+	struct dmatest_slave_thread	*thread = data;
+	struct dma_chan *tx_chan;
+	struct dma_chan *rx_chan;
+	const char *thread_name;
+	unsigned int src_off, dst_off, len;
+	unsigned int error_count;
+	unsigned int failed_tests = 0;
+	unsigned int total_tests = 0;
+	dma_cookie_t tx_cookie;
+	dma_cookie_t rx_cookie;
+	enum dma_status status;
+	enum dma_ctrl_flags flags;
+	int ret;
+	int src_cnt;
+	int dst_cnt;
+	int bd_cnt = 11;
+	int i;
+	struct xilinx_dma_config config;
+	thread_name = current->comm;
+
+	ret = -ENOMEM;
+
+	/* JZ: limit testing scope here */
+	iterations = 5;
+	test_buf_size = 700;
+
+	smp_rmb();
+	tx_chan = thread->tx_chan;
+	rx_chan = thread->rx_chan;
+	src_cnt = dst_cnt = bd_cnt;
+
+	thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->srcs)
+		goto err_srcs;
+	for (i = 0; i < src_cnt; i++) {
+		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->srcs[i])
+			goto err_srcbuf;
+	}
+	thread->srcs[i] = NULL;
+
+	thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->dsts)
+		goto err_dsts;
+	for (i = 0; i < dst_cnt; i++) {
+		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->dsts[i])
+			goto err_dstbuf;
+	}
+	thread->dsts[i] = NULL;
+
+	set_user_nice(current, 10);
+
+	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
+
+	while (!kthread_should_stop()
+		&& !(iterations && total_tests >= iterations)) {
+		struct dma_device *tx_dev = tx_chan->device;
+		struct dma_device *rx_dev = rx_chan->device;
+		struct dma_async_tx_descriptor *txd = NULL;
+		struct dma_async_tx_descriptor *rxd = NULL;
+		dma_addr_t dma_srcs[src_cnt];
+		dma_addr_t dma_dsts[dst_cnt];
+		struct completion rx_cmp;
+		struct completion tx_cmp;
+		unsigned long rx_tmo =
+				msecs_to_jiffies(300000); /* RX takes longer */
+		unsigned long tx_tmo = msecs_to_jiffies(30000);
+		u8 align = 0;
+		struct scatterlist tx_sg[bd_cnt];
+		struct scatterlist rx_sg[bd_cnt];
+
+		total_tests++;
+
+		/* honor larger alignment restrictions */
+		align = tx_dev->copy_align;
+		if (rx_dev->copy_align > align)
+			align = rx_dev->copy_align;
+
+		if (1 << align > test_buf_size) {
+			pr_err("%u-byte buffer too small for %d-byte alignment\n",
+				test_buf_size, 1 << align);
+			break;
+		}
+
+		len = dmatest_random() % test_buf_size + 1;
+		len = (len >> align) << align;
+		if (!len)
+			len = 1 << align;
+		src_off = dmatest_random() % (test_buf_size - len + 1);
+		dst_off = dmatest_random() % (test_buf_size - len + 1);
+
+		src_off = (src_off >> align) << align;
+		dst_off = (dst_off >> align) << align;
+
+		dmatest_init_srcs(thread->srcs, src_off, len);
+		dmatest_init_dsts(thread->dsts, dst_off, len);
+
+		for (i = 0; i < src_cnt; i++) {
+			u8 *buf = thread->srcs[i] + src_off;
+
+			dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len,
+							DMA_MEM_TO_DEV);
+		}
+
+		for (i = 0; i < dst_cnt; i++) {
+			dma_dsts[i] = dma_map_single(rx_dev->dev,
+							thread->dsts[i],
+							test_buf_size,
+							DMA_MEM_TO_DEV);
+
+			dma_unmap_single(rx_dev->dev, dma_dsts[i],
+							test_buf_size,
+							DMA_MEM_TO_DEV);
+
+			dma_dsts[i] = dma_map_single(rx_dev->dev,
+							thread->dsts[i],
+							test_buf_size,
+							DMA_DEV_TO_MEM);
+		}
+
+		sg_init_table(tx_sg, bd_cnt);
+		sg_init_table(rx_sg, bd_cnt);
+
+		for (i = 0; i < bd_cnt; i++) {
+			sg_dma_address(&tx_sg[i]) = dma_srcs[i];
+			sg_dma_address(&rx_sg[i]) = dma_dsts[i] + dst_off;
+
+			sg_dma_len(&tx_sg[i]) = len;
+			sg_dma_len(&rx_sg[i]) = len;
+
+		}
+
+		/* Only one interrupt */
+		config.coalesc = 1;
+		config.delay = 0;
+		rx_dev->device_control(rx_chan, DMA_SLAVE_CONFIG,
+				(unsigned long)&config);
+
+		config.coalesc = 1;
+		config.delay = 0;
+		tx_dev->device_control(tx_chan, DMA_SLAVE_CONFIG,
+				(unsigned long)&config);
+
+		rxd = rx_dev->device_prep_slave_sg(rx_chan, rx_sg, bd_cnt,
+				DMA_DEV_TO_MEM, flags, NULL);
+
+		txd = tx_dev->device_prep_slave_sg(tx_chan, tx_sg, bd_cnt,
+				DMA_MEM_TO_DEV, flags, NULL);
+
+		if (!rxd || !txd) {
+			for (i = 0; i < src_cnt; i++)
+				dma_unmap_single(tx_dev->dev, dma_srcs[i], len,
+						DMA_MEM_TO_DEV);
+			for (i = 0; i < dst_cnt; i++)
+				dma_unmap_single(rx_dev->dev, dma_dsts[i],
+						test_buf_size,
+						DMA_DEV_TO_MEM);
+			pr_warn(
+			"%s: #%u: prep error with src_off=0x%x ",
+				thread_name, total_tests - 1, src_off);
+			pr_warn("dst_off=0x%x len=0x%x\n",
+					dst_off, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+
+		init_completion(&rx_cmp);
+		rxd->callback = dmatest_slave_rx_callback;
+		rxd->callback_param = &rx_cmp;
+		rx_cookie = rxd->tx_submit(rxd);
+
+		init_completion(&tx_cmp);
+		txd->callback = dmatest_slave_tx_callback;
+		txd->callback_param = &tx_cmp;
+		tx_cookie = txd->tx_submit(txd);
+
+		if (dma_submit_error(rx_cookie) ||
+				dma_submit_error(tx_cookie)) {
+			pr_warn(
+			"%s: #%u: submit error %d/%d with src_off=0x%x ",
+					thread_name, total_tests - 1,
+					rx_cookie, tx_cookie, src_off);
+			pr_warn("dst_off=0x%x len=0x%x\n",
+					dst_off, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+		dma_async_issue_pending(tx_chan);
+		dma_async_issue_pending(rx_chan);
+
+		tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo);
+
+		status = dma_async_is_tx_complete(tx_chan, tx_cookie,
+							NULL, NULL);
+
+		if (tx_tmo == 0) {
+			pr_warn("%s: #%u: tx test timed out\n",
+				   thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warn(
+			"%s: #%u: tx got completion callback, ",
+				   thread_name, total_tests - 1);
+			pr_warn("but status is \'%s\'\n",
+				   status == DMA_ERROR ? "error" :
+							"in progress");
+			failed_tests++;
+			continue;
+		}
+
+		rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo);
+		status = dma_async_is_tx_complete(rx_chan, rx_cookie,
+							NULL, NULL);
+
+		if (rx_tmo == 0) {
+			pr_warn("%s: #%u: rx test timed out\n",
+				   thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warn(
+			"%s: #%u: rx got completion callback, ",
+				   thread_name, total_tests - 1);
+			pr_warn("but status is \'%s\'\n",
+				   status == DMA_ERROR ? "error" :
+							"in progress");
+			failed_tests++;
+			continue;
+		}
+
+		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
+		for (i = 0; i < dst_cnt; i++)
+			dma_unmap_single(rx_dev->dev, dma_dsts[i],
+					test_buf_size, DMA_DEV_TO_MEM);
+
+		error_count = 0;
+
+		pr_debug("%s: verifying source buffer...\n", thread_name);
+		error_count += dmatest_verify(thread->srcs, 0, src_off,
+				0, PATTERN_SRC, true);
+		error_count += dmatest_verify(thread->srcs, src_off,
+				src_off + len, src_off,
+				PATTERN_SRC | PATTERN_COPY, true);
+		error_count += dmatest_verify(thread->srcs, src_off + len,
+				test_buf_size, src_off + len,
+				PATTERN_SRC, true);
+
+		pr_debug("%s: verifying dest buffer...\n",
+				thread->task->comm);
+		error_count += dmatest_verify(thread->dsts, 0, dst_off,
+				0, PATTERN_DST, false);
+		error_count += dmatest_verify(thread->dsts, dst_off,
+				dst_off + len, src_off,
+				PATTERN_SRC | PATTERN_COPY, false);
+		error_count += dmatest_verify(thread->dsts, dst_off + len,
+				test_buf_size, dst_off + len,
+				PATTERN_DST, false);
+
+		if (error_count) {
+			pr_warn("%s: #%u: %u errors with ",
+				thread_name, total_tests - 1, error_count);
+			pr_warn("src_off=0x%x dst_off=0x%x len=0x%x\n",
+				src_off, dst_off, len);
+			failed_tests++;
+		} else {
+			pr_debug("%s: #%u: No errors with ",
+				thread_name, total_tests - 1);
+			pr_debug("src_off=0x%x dst_off=0x%x len=0x%x\n",
+				src_off, dst_off, len);
+		}
+	}
+
+	ret = 0;
+	for (i = 0; thread->dsts[i]; i++)
+		kfree(thread->dsts[i]);
+err_dstbuf:
+	kfree(thread->dsts);
+err_dsts:
+	for (i = 0; thread->srcs[i]; i++)
+		kfree(thread->srcs[i]);
+err_srcbuf:
+	kfree(thread->srcs);
+err_srcs:
+	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
+			thread_name, total_tests, failed_tests, ret);
+
+	if (iterations > 0)
+		while (!kthread_should_stop()) {
+			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
+			interruptible_sleep_on(&wait_dmatest_exit);
+		}
+
+	return ret;
+}
+
+static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
+{
+	struct dmatest_slave_thread *thread;
+	struct dmatest_slave_thread *_thread;
+	int ret;
+
+	list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
+		ret = kthread_stop(thread->task);
+		pr_debug("dmatest: thread %s exited with status %d\n",
+				thread->task->comm, ret);
+		list_del(&thread->node);
+		kfree(thread);
+	}
+	kfree(dtc);
+}
+
+static int dmatest_add_slave_threads(struct dmatest_chan *tx_dtc,
+					struct dmatest_chan *rx_dtc)
+{
+	struct dmatest_slave_thread *thread;
+	struct dma_chan *tx_chan = tx_dtc->chan;
+	struct dma_chan *rx_chan = rx_dtc->chan;
+
+	thread = kzalloc(sizeof(struct dmatest_slave_thread), GFP_KERNEL);
+	if (!thread) {
+		pr_warn("dmatest: No memory for slave thread %s-%s\n",
+				dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+
+	}
+
+	thread->tx_chan = tx_chan;
+	thread->rx_chan = rx_chan;
+	thread->type = (enum dma_transaction_type)DMA_SLAVE;
+	smp_wmb();
+	thread->task = kthread_run(dmatest_slave_func, thread, "%s-%s",
+		dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+	if (IS_ERR(thread->task)) {
+		pr_warn("dmatest: Failed to run thread %s-%s\n",
+				dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+		kfree(thread);
+	}
+
+	/* srcbuf and dstbuf are allocated by the thread itself */
+
+	list_add_tail(&thread->node, &tx_dtc->threads);
+
+	/* Added one thread with 2 channels */
+	return 1;
+}
+
+static int dmatest_add_slave_channels(struct dma_chan *tx_chan,
+					struct dma_chan *rx_chan)
+{
+	struct dmatest_chan *tx_dtc;
+	struct dmatest_chan *rx_dtc;
+	unsigned int thread_count = 0;
+
+	tx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+	if (!tx_dtc) {
+		pr_warn("dmatest: No memory for tx %s\n",
+				dma_chan_name(tx_chan));
+		return -ENOMEM;
+	}
+
+	rx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+	if (!rx_dtc) {
+		pr_warn("dmatest: No memory for rx %s\n",
+				dma_chan_name(rx_chan));
+		return -ENOMEM;
+	}
+
+	tx_dtc->chan = tx_chan;
+	rx_dtc->chan = rx_chan;
+	INIT_LIST_HEAD(&tx_dtc->threads);
+	INIT_LIST_HEAD(&rx_dtc->threads);
+
+	dmatest_add_slave_threads(tx_dtc, rx_dtc);
+	thread_count += 1;
+
+	pr_info("dmatest: Started %u threads using %s %s\n",
+		thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+
+	list_add_tail(&tx_dtc->node, &dmatest_channels);
+	list_add_tail(&rx_dtc->node, &dmatest_channels);
+	nr_channels += 2;
+
+	return 0;
+}
+
+static bool xdma_filter(struct dma_chan *chan, void *param)
+{
+	pr_debug("dmatest: Private is %x\n", *((int *)chan->private));
+
+	if (*((int *)chan->private) == *(int *)param)
+		return true;
+
+	return false;
+}
+
+static int __init dmatest_init(void)
+{
+	dma_cap_mask_t mask;
+	struct dma_chan *chan;
+	int err = 0;
+
+	/* JZ for slave transfer channels */
+	enum dma_data_direction direction;
+	struct dma_chan *rx_chan;
+	u32 match, device_id = 0;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask);
+
+	for (;;) {
+		direction = DMA_MEM_TO_DEV;
+		match = (direction & 0xFF) | XILINX_DMA_IP_DMA |
+				(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
+		pr_debug("dmatest: match is %x\n", match);
+
+		chan = dma_request_channel(mask, xdma_filter, (void *)&match);
+
+		if (chan)
+			pr_debug("dmatest: Found tx device\n");
+		else
+			pr_debug("dmatest: No more tx channels available\n");
+
+		direction = DMA_DEV_TO_MEM;
+		match = (direction & 0xFF) | XILINX_DMA_IP_DMA |
+				(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
+		rx_chan = dma_request_channel(mask, xdma_filter, &match);
+
+		if (rx_chan)
+			pr_debug("dmatest: Found rx device\n");
+		else
+			pr_debug("dmatest: No more rx channels available\n");
+
+		if (chan && rx_chan) {
+			err = dmatest_add_slave_channels(chan, rx_chan);
+			if (err) {
+				dma_release_channel(chan);
+				dma_release_channel(rx_chan);
+			}
+		} else
+			break;
+
+		device_id++;
+	}
+
+	return err;
+}
+/* when compiled-in wait for drivers to load first */
+late_initcall(dmatest_init);
+
+static void __exit dmatest_exit(void)
+{
+	struct dmatest_chan *dtc, *_dtc;
+	struct dma_chan *chan;
+
+	list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) {
+		list_del(&dtc->node);
+		chan = dtc->chan;
+		dmatest_cleanup_channel(dtc);
+		pr_debug("dmatest: dropped channel %s\n",
+			dma_chan_name(chan));
+		dma_release_channel(chan);
+	}
+}
+module_exit(dmatest_exit);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx AXI DMA Test Client");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/cdmatest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/cdmatest.c	2014-07-20 22:06:35.736315945 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * XILINX CDMA Engine test module
+ *
+ * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
+ *
+ * Based on Atmel DMA Test Client
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/amba/xilinx_dma.h>
+
+static unsigned int test_buf_size = 64;
+module_param(test_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
+
+static char test_channel[20];
+module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO);
+MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
+
+static char test_device[20];
+module_param_string(device, test_device, sizeof(test_device), S_IRUGO);
+MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
+
+static unsigned int threads_per_chan = 1;
+module_param(threads_per_chan, uint, S_IRUGO);
+MODULE_PARM_DESC(threads_per_chan,
+		"Number of threads to start per channel (default: 1)");
+
+static unsigned int max_channels;
+module_param(max_channels, uint, S_IRUGO);
+MODULE_PARM_DESC(max_channels,
+		"Maximum number of channels to use (default: all)");
+
+static unsigned int iterations;
+module_param(iterations, uint, S_IRUGO);
+MODULE_PARM_DESC(iterations,
+		"Iterations before stopping test (default: infinite)");
+
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+		"Number of xor source buffers (default: 3)");
+
+static unsigned int pq_sources = 3;
+module_param(pq_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(pq_sources,
+		"Number of p+q source buffers (default: 3)");
+
+/*
+ * Initialization patterns. All bytes in the source buffer has bit 7
+ * set, all bytes in the destination buffer has bit 7 cleared.
+ *
+ * Bit 6 is set for all bytes which are to be copied by the DMA
+ * engine. Bit 5 is set for all bytes which are to be overwritten by
+ * the DMA engine.
+ *
+ * The remaining bits are the inverse of a counter which increments by
+ * one for each byte address.
+ */
+#define PATTERN_SRC		0x80
+#define PATTERN_DST		0x00
+#define PATTERN_COPY		0x40
+#define PATTERN_OVERWRITE	0x20
+#define PATTERN_COUNT_MASK	0x1f
+
+struct cdmatest_thread {
+	struct list_head node;
+	struct task_struct *task;
+	struct dma_chan *chan;
+	u8 **srcs;
+	u8 **dsts;
+	enum dma_transaction_type type;
+};
+
+struct cdmatest_chan {
+	struct list_head node;
+	struct dma_chan *chan;
+	struct list_head threads;
+};
+
+/*
+ * These are protected by dma_list_mutex since they're only used by
+ * the DMA filter function callback
+ */
+static LIST_HEAD(cdmatest_channels);
+static unsigned int nr_channels;
+
+static bool cdmatest_match_channel(struct dma_chan *chan)
+{
+	if (test_channel[0] == '\0')
+		return true;
+	return strcmp(dma_chan_name(chan), test_channel) == 0;
+}
+
+static bool cdmatest_match_device(struct dma_device *device)
+{
+	if (test_device[0] == '\0')
+		return true;
+	return strcmp(dev_name(device->dev), test_device) == 0;
+}
+
+static unsigned long cdmatest_random(void)
+{
+	unsigned long buf;
+
+	get_random_bytes(&buf, sizeof(buf));
+	return buf;
+}
+
+static void cdmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_SRC | PATTERN_COPY
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		buf++;
+	}
+}
+
+static void cdmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	}
+}
+
+static void cdmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
+		unsigned int counter, bool is_srcbuf)
+{
+	u8 diff = actual ^ pattern;
+	u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
+	const char *thread_name = current->comm;
+
+	if (is_srcbuf)
+		pr_warn(
+		"%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if ((pattern & PATTERN_COPY)
+			&& (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
+		pr_warn(
+		"%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if (diff & PATTERN_SRC)
+		pr_warn(
+		"%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else
+		pr_warn(
+		"%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+}
+
+static unsigned int cdmatest_verify(u8 **bufs, unsigned int start,
+		unsigned int end, unsigned int counter, u8 pattern,
+		bool is_srcbuf)
+{
+	unsigned int i;
+	unsigned int error_count = 0;
+	u8 actual;
+	u8 expected;
+	u8 *buf;
+	unsigned int counter_orig = counter;
+
+	for (; (buf = *bufs); bufs++) {
+		counter = counter_orig;
+		for (i = start; i < end; i++) {
+			actual = buf[i];
+			expected = pattern | (~counter & PATTERN_COUNT_MASK);
+			if (actual != expected) {
+				if (error_count < 32)
+					cdmatest_mismatch(actual, pattern, i,
+							counter, is_srcbuf);
+				error_count++;
+			}
+			counter++;
+		}
+	}
+
+	if (error_count > 32)
+		pr_warn("%s: %u errors suppressed\n",
+			current->comm, error_count - 32);
+
+	return error_count;
+}
+
+static void cdmatest_callback(void *completion)
+{
+	complete(completion);
+}
+
+/*
+ * This function repeatedly tests DMA transfers of various lengths and
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
+ *
+ * Before each test, the source and destination buffer is initialized
+ * with a known pattern. This pattern is different depending on
+ * whether it's in an area which is supposed to be copied or
+ * overwritten, and different in the source and destination buffers.
+ * So if the DMA engine doesn't copy exactly what we tell it to copy,
+ * we'll notice.
+ */
+static int cdmatest_func(void *data)
+{
+	struct cdmatest_thread *thread = data;
+	struct dma_chan *chan;
+	const char *thread_name;
+	unsigned int src_off, dst_off, len;
+	unsigned int error_count;
+	unsigned int failed_tests = 0;
+	unsigned int total_tests = 0;
+	dma_cookie_t cookie;
+	enum dma_status status;
+	enum dma_ctrl_flags flags;
+	u8 pq_coefs[pq_sources + 1];
+	int ret;
+	int src_cnt;
+	int dst_cnt;
+	int i;
+
+	thread_name = current->comm;
+
+	ret = -ENOMEM;
+
+	/* JZ: limit testing scope here */
+	iterations = 5;
+
+	smp_rmb();
+	chan = thread->chan;
+	if (thread->type == DMA_MEMCPY)
+		src_cnt = dst_cnt = 1;
+	else if (thread->type == DMA_XOR) {
+		src_cnt = xor_sources | 1;
+				/* force odd to ensure dst = src */
+		dst_cnt = 1;
+	} else if (thread->type == DMA_PQ) {
+		src_cnt = pq_sources | 1;
+				/* force odd to ensure dst = src */
+		dst_cnt = 2;
+		for (i = 0; i < src_cnt; i++)
+			pq_coefs[i] = 1;
+	} else
+		goto err_srcs;
+
+	thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->srcs)
+		goto err_srcs;
+	for (i = 0; i < src_cnt; i++) {
+		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->srcs[i])
+			goto err_srcbuf;
+	}
+	thread->srcs[i] = NULL;
+
+	thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->dsts)
+		goto err_dsts;
+	for (i = 0; i < dst_cnt; i++) {
+		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->dsts[i])
+			goto err_dstbuf;
+	}
+	thread->dsts[i] = NULL;
+
+	set_user_nice(current, 10);
+
+	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
+
+	while (!kthread_should_stop()
+		&& !(iterations && total_tests >= iterations)) {
+		struct dma_device *dev = chan->device;
+		struct dma_async_tx_descriptor *tx = NULL;
+		dma_addr_t dma_srcs[src_cnt];
+		dma_addr_t dma_dsts[dst_cnt];
+		struct completion cmp;
+		unsigned long tmo = msecs_to_jiffies(3000);
+		u8 align = 0;
+
+		total_tests++;
+
+		/* honor alignment restrictions */
+		if (thread->type == DMA_MEMCPY)
+			align = dev->copy_align;
+		else if (thread->type == DMA_XOR)
+			align = dev->xor_align;
+		else if (thread->type == DMA_PQ)
+			align = dev->pq_align;
+
+		if (1 << align > test_buf_size) {
+			pr_err("%u-byte buffer too small for %d-byte alignment\n",
+			       test_buf_size, 1 << align);
+			break;
+		}
+
+		len = cdmatest_random() % test_buf_size + 1;
+		len = (len >> align) << align;
+		if (!len)
+			len = 1 << align;
+		src_off = cdmatest_random() % (test_buf_size - len + 1);
+		dst_off = cdmatest_random() % (test_buf_size - len + 1);
+
+		src_off = (src_off >> align) << align;
+		dst_off = (dst_off >> align) << align;
+
+		cdmatest_init_srcs(thread->srcs, src_off, len);
+		cdmatest_init_dsts(thread->dsts, dst_off, len);
+
+		for (i = 0; i < src_cnt; i++) {
+			u8 *buf = thread->srcs[i] + src_off;
+
+			dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+							DMA_MEM_TO_DEV);
+		}
+		/* map with DMA_MEM_TO_MEM to force writeback/invalidate */
+		for (i = 0; i < dst_cnt; i++) {
+			dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+							test_buf_size,
+							DMA_MEM_TO_MEM);
+		}
+
+		if (thread->type == DMA_MEMCPY) {
+			tx = dev->device_prep_dma_memcpy(chan,
+							dma_dsts[0] + dst_off,
+							dma_srcs[0], len,
+							flags);
+
+		} else if (thread->type == DMA_XOR)
+			tx = dev->device_prep_dma_xor(chan,
+							dma_dsts[0] + dst_off,
+							dma_srcs, src_cnt,
+							len, flags);
+		else if (thread->type == DMA_PQ) {
+			dma_addr_t dma_pq[dst_cnt];
+
+			for (i = 0; i < dst_cnt; i++)
+				dma_pq[i] = dma_dsts[i] + dst_off;
+			tx = dev->device_prep_dma_pq(chan, dma_pq, dma_srcs,
+							src_cnt, pq_coefs,
+							len, flags);
+		}
+
+		if (!tx) {
+			for (i = 0; i < src_cnt; i++)
+				dma_unmap_single(dev->dev, dma_srcs[i], len,
+							DMA_MEM_TO_DEV);
+			for (i = 0; i < dst_cnt; i++)
+				dma_unmap_single(dev->dev, dma_dsts[i],
+							test_buf_size,
+							DMA_MEM_TO_MEM);
+			pr_warn(
+			"%s: #%u: prep error with src_off=0x%x ",
+				thread_name, total_tests - 1, src_off);
+			pr_warn("dst_off=0x%x len=0x%x\n",
+					dst_off, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+
+		init_completion(&cmp);
+		tx->callback = cdmatest_callback;
+		tx->callback_param = &cmp;
+		cookie = tx->tx_submit(tx);
+
+		if (dma_submit_error(cookie)) {
+			pr_warn(
+			"%s: #%u: submit error %d with src_off=0x%x ",
+					thread_name, total_tests - 1,
+					cookie, src_off);
+			pr_warn("dst_off=0x%x len=0x%x\n",
+					dst_off, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+		dma_async_issue_pending(chan);
+
+		tmo = wait_for_completion_timeout(&cmp, tmo);
+		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
+
+		if (tmo == 0) {
+			pr_warn("%s: #%u: test timed out\n",
+					thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warn(
+			"%s: #%u: got completion callback, ",
+					thread_name, total_tests - 1);
+			pr_warn("but status is \'%s\'\n",
+					status == DMA_ERROR ? "error" :
+							"in progress");
+			failed_tests++;
+			continue;
+		}
+
+		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
+		for (i = 0; i < dst_cnt; i++)
+			dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+					DMA_MEM_TO_MEM);
+
+		error_count = 0;
+
+		pr_debug("%s: verifying source buffer...\n", thread_name);
+		error_count += cdmatest_verify(thread->srcs, 0, src_off,
+				0, PATTERN_SRC, true);
+		error_count += cdmatest_verify(thread->srcs, src_off,
+				src_off + len, src_off,
+				PATTERN_SRC | PATTERN_COPY, true);
+		error_count += cdmatest_verify(thread->srcs, src_off + len,
+				test_buf_size, src_off + len,
+				PATTERN_SRC, true);
+
+		pr_debug("%s: verifying dest buffer...\n",
+				thread->task->comm);
+		error_count += cdmatest_verify(thread->dsts, 0, dst_off,
+				0, PATTERN_DST, false);
+		error_count += cdmatest_verify(thread->dsts, dst_off,
+				dst_off + len, src_off,
+				PATTERN_SRC | PATTERN_COPY, false);
+		error_count += cdmatest_verify(thread->dsts, dst_off + len,
+				test_buf_size, dst_off + len,
+				PATTERN_DST, false);
+
+		if (error_count) {
+			pr_warn("%s: #%u: %u errors with ",
+				thread_name, total_tests - 1, error_count);
+			pr_warn("src_off=0x%x dst_off=0x%x len=0x%x\n",
+				src_off, dst_off, len);
+			failed_tests++;
+		} else {
+			pr_debug("%s: #%u: No errors with ",
+				thread_name, total_tests - 1);
+			pr_debug("src_off=0x%x dst_off=0x%x len=0x%x\n",
+				src_off, dst_off, len);
+		}
+	}
+
+	ret = 0;
+	for (i = 0; thread->dsts[i]; i++)
+		kfree(thread->dsts[i]);
+err_dstbuf:
+	kfree(thread->dsts);
+err_dsts:
+	for (i = 0; thread->srcs[i]; i++)
+		kfree(thread->srcs[i]);
+err_srcbuf:
+	kfree(thread->srcs);
+err_srcs:
+	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
+			thread_name, total_tests, failed_tests, ret);
+
+	if (iterations > 0)
+		while (!kthread_should_stop()) {
+			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_cdmatest_exit);
+			interruptible_sleep_on(&wait_cdmatest_exit);
+		}
+
+	return ret;
+}
+
+static void cdmatest_cleanup_channel(struct cdmatest_chan *dtc)
+{
+	struct cdmatest_thread *thread;
+	struct cdmatest_thread *_thread;
+	int ret;
+
+	list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
+		ret = kthread_stop(thread->task);
+		pr_debug("cdmatest: thread %s exited with status %d\n",
+				thread->task->comm, ret);
+		list_del(&thread->node);
+		kfree(thread);
+	}
+	kfree(dtc);
+}
+
+static int cdmatest_add_threads(struct cdmatest_chan *dtc,
+				enum dma_transaction_type type)
+{
+	struct cdmatest_thread *thread;
+	struct dma_chan *chan = dtc->chan;
+	char *op;
+	unsigned int i;
+
+	if (type == DMA_MEMCPY)
+		op = "copy";
+	else if (type == DMA_XOR)
+		op = "xor";
+	else if (type == DMA_PQ)
+		op = "pq";
+	else
+		return -EINVAL;
+
+	for (i = 0; i < threads_per_chan; i++) {
+		thread = kzalloc(sizeof(struct cdmatest_thread), GFP_KERNEL);
+		if (!thread) {
+			pr_warn("cdmatest: No memory for %s-%s%u\n",
+					dma_chan_name(chan), op, i);
+
+			break;
+		}
+		thread->chan = dtc->chan;
+		thread->type = type;
+		smp_wmb();
+		thread->task = kthread_run(cdmatest_func, thread, "%s-%s%u",
+				dma_chan_name(chan), op, i);
+		if (IS_ERR(thread->task)) {
+			pr_warn("cdmatest: Failed to run thread %s-%s%u\n",
+					dma_chan_name(chan), op, i);
+			kfree(thread);
+			break;
+		}
+
+		/* srcbuf and dstbuf are allocated by the thread itself */
+
+		list_add_tail(&thread->node, &dtc->threads);
+	}
+
+	return i;
+}
+
+static int cdmatest_add_channel(struct dma_chan *chan)
+{
+	struct cdmatest_chan *dtc;
+	struct dma_device *dma_dev = chan->device;
+	unsigned int thread_count = 0;
+	int cnt;
+
+	dtc = kmalloc(sizeof(struct cdmatest_chan), GFP_KERNEL);
+	if (!dtc) {
+		pr_warn("cdmatest: No memory for %s\n", dma_chan_name(chan));
+		return -ENOMEM;
+	}
+
+	dtc->chan = chan;
+	INIT_LIST_HEAD(&dtc->threads);
+
+	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+		cnt = cdmatest_add_threads(dtc, DMA_MEMCPY);
+		thread_count += cnt > 0 ? cnt : 0;
+	}
+	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+		cnt = cdmatest_add_threads(dtc, DMA_XOR);
+		thread_count += cnt > 0 ? cnt : 0;
+	}
+	if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
+		cnt = cdmatest_add_threads(dtc, DMA_PQ);
+		thread_count += cnt > 0 ? cnt : 0;
+	}
+
+	pr_info("cdmatest: Started %u threads using %s\n",
+		thread_count, dma_chan_name(chan));
+
+	list_add_tail(&dtc->node, &cdmatest_channels);
+	nr_channels++;
+
+	return 0;
+}
+
+static bool filter(struct dma_chan *chan, void *param)
+{
+	if (!cdmatest_match_channel(chan) ||
+			!cdmatest_match_device(chan->device))
+		return false;
+
+	return true;
+}
+
+static int __init cdmatest_init(void)
+{
+	dma_cap_mask_t mask;
+	struct dma_chan *chan;
+	int err = 0;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+	for (;;) {
+		chan = dma_request_channel(mask, filter, NULL);
+
+		if (chan) {
+			err = cdmatest_add_channel(chan);
+			if (err) {
+				dma_release_channel(chan);
+				break; /* add_channel failed, punt */
+			}
+		} else
+			break; /* no more channels available */
+		if (max_channels && nr_channels >= max_channels)
+			break; /* we have all we need */
+	}
+
+	return err;
+}
+/* when compiled-in wait for drivers to load first */
+late_initcall(cdmatest_init);
+
+static void __exit cdmatest_exit(void)
+{
+	struct cdmatest_chan *dtc, *_dtc;
+	struct dma_chan *chan;
+
+	list_for_each_entry_safe(dtc, _dtc, &cdmatest_channels, node) {
+		list_del(&dtc->node);
+		chan = dtc->chan;
+		cdmatest_cleanup_channel(dtc);
+		pr_debug("cdmatest: dropped channel %s\n",
+			 dma_chan_name(chan));
+		dma_release_channel(chan);
+	}
+}
+module_exit(cdmatest_exit);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx AXI CDMA Test Client");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/Kconfig	2014-07-20 22:06:35.748315747 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# XILINX DMA Engines configuration
+#
+
+menuconfig XILINX_DMA_ENGINES
+	bool "Xilinx DMA Engines"
+	help
+	  Enable support for the Xilinx DMA controllers. It supports three DMA
+	  engines: Axi Central DMA (memory to memory transfer), Axi DMA (memory and
+	  device transfer), and Axi VDMA (memory and video device transfer).
+
+if XILINX_DMA_ENGINES
+
+config XILINX_AXIDMA
+	tristate "Xilinx AXI DMA Engine"
+	select DMA_ENGINE
+	help
+	  Enable support for Xilinx Axi DMA (memory and device transfer).
+
+config XILINX_DMATEST
+	tristate "DMA Test client for AXI DMA"
+	depends on XILINX_AXIDMA
+	help
+	  Simple DMA test client. Say N unless you're debugging a
+	  DMA Device driver.
+
+config XILINX_AXIVDMA
+	tristate "Xilinx AXI VDMA Engine"
+	select DMA_ENGINE
+	help
+	  Enable support for Xilinx Axi VDMA (memory and video device transfer).
+
+config XILINX_VDMATEST
+	tristate "DMA Test client for VDMA"
+	depends on XILINX_AXIVDMA
+	help
+	  Simple DMA test client. Say N unless you're debugging a
+	  DMA Device driver.
+
+config XILINX_AXICDMA
+	tristate "Xilinx AXI CDMA Engine"
+	select DMA_ENGINE
+	help
+	  Enable support for Xilinx Axi Central DMA (memory to memory transfer).
+
+config XILINX_CDMATEST
+	tristate "DMA Test client for CDMA"
+	depends on XILINX_AXICDMA
+	help
+	  Simple DMA test client. Say N unless you're debugging a
+	  DMA Device driver.
+
+endif # XILINX_DMA_ENGINES
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/Makefile	2014-07-20 22:06:35.753315664 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3 @
+obj-$(CONFIG_XILINX_AXIDMA) += xilinx_axidma.o
+obj-$(CONFIG_XILINX_DMATEST) += axidmatest.o
+obj-$(CONFIG_XILINX_AXIVDMA) += xilinx_axivdma.o
+obj-$(CONFIG_XILINX_VDMATEST) += vdmatest.o
+obj-$(CONFIG_XILINX_AXICDMA) += xilinx_axicdma.o
+obj-$(CONFIG_XILINX_CDMATEST) += cdmatest.o
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/vdmatest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/vdmatest.c	2014-07-20 22:06:35.767315433 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * XILINX VDMA Engine test client driver
+ *
+ * Copyright (C) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Based on Atmel DMA Test Client
+ *
+ * Description:
+ * This is a simple Xilinx VDMA test client for AXI VDMA driver.
+ * This test assumes both the channels of VDMA are enabled in the
+ * hardware design and configured in back-to-back connection. Test
+ * starts by pumping the data onto one channel (MM2S) and then
+ * compares the data that is received on the other channel (S2MM).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+
+static unsigned int test_buf_size = 64;
+module_param(test_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
+
+static unsigned int iterations;
+module_param(iterations, uint, S_IRUGO);
+MODULE_PARM_DESC(iterations,
+		"Iterations before stopping test (default: infinite)");
+
+/*
+ * Initialization patterns. All bytes in the source buffer has bit 7
+ * set, all bytes in the destination buffer has bit 7 cleared.
+ *
+ * Bit 6 is set for all bytes which are to be copied by the DMA
+ * engine. Bit 5 is set for all bytes which are to be overwritten by
+ * the DMA engine.
+ *
+ * The remaining bits are the inverse of a counter which increments by
+ * one for each byte address.
+ */
+#define PATTERN_SRC		0x80
+#define PATTERN_DST		0x00
+#define PATTERN_COPY		0x40
+#define PATTERN_OVERWRITE	0x20
+#define PATTERN_COUNT_MASK	0x1f
+
+/* Maximum number of frame buffers */
+#define MAX_NUM_FRAMES	32
+
+/**
+ * struct vdmatest_slave_thread - VDMA test thread
+ * @node: Thread node
+ * @task: Task structure pointer
+ * @tx_chan: Tx channel pointer
+ * @rx_chan: Rx Channel pointer
+ * @srcs: Source buffer
+ * @dsts: Destination buffer
+ * @type: DMA transaction type
+ */
+struct xilinx_vdmatest_slave_thread {
+	struct list_head node;
+	struct task_struct *task;
+	struct dma_chan *tx_chan;
+	struct dma_chan *rx_chan;
+	u8 **srcs;
+	u8 **dsts;
+	enum dma_transaction_type type;
+};
+
+/**
+ * struct vdmatest_chan - VDMA Test channel
+ * @node: Channel node
+ * @chan: DMA channel pointer
+ * @threads: List of VDMA test threads
+ */
+struct xilinx_vdmatest_chan {
+	struct list_head node;
+	struct dma_chan *chan;
+	struct list_head threads;
+};
+
+/* Global variables */
+static LIST_HEAD(xilinx_vdmatest_channels);
+static unsigned int nr_channels;
+static unsigned int frm_cnt;
+static dma_addr_t dma_srcs[MAX_NUM_FRAMES];
+static dma_addr_t dma_dsts[MAX_NUM_FRAMES];
+static struct scatterlist tx_sg[MAX_NUM_FRAMES];
+static struct scatterlist rx_sg[MAX_NUM_FRAMES];
+
+static void xilinx_vdmatest_init_srcs(u8 **bufs, unsigned int start,
+					unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		for (; i < start + len; i++)
+			buf[i] = PATTERN_SRC | PATTERN_COPY
+				| (~i & PATTERN_COUNT_MASK);
+		for (; i < test_buf_size; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		buf++;
+	}
+}
+
+static void xilinx_vdmatest_init_dsts(u8 **bufs, unsigned int start,
+					unsigned int len)
+{
+	unsigned int i;
+	u8 *buf;
+
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+		for (; i < start + len; i++)
+			buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+				| (~i & PATTERN_COUNT_MASK);
+		for (; i < test_buf_size; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	}
+}
+
+static void xilinx_vdmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
+		unsigned int counter, bool is_srcbuf)
+{
+	u8 diff = actual ^ pattern;
+	u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
+	const char *thread_name = current->comm;
+
+	if (is_srcbuf)
+		pr_warn(
+		"%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if ((pattern & PATTERN_COPY)
+			&& (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
+		pr_warn(
+		"%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else if (diff & PATTERN_SRC)
+		pr_warn(
+		"%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+	else
+		pr_warn(
+		"%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
+				thread_name, index, expected, actual);
+}
+
+static unsigned int xilinx_vdmatest_verify(u8 **bufs, unsigned int start,
+		unsigned int end, unsigned int counter, u8 pattern,
+		bool is_srcbuf)
+{
+	unsigned int i, error_count = 0;
+	u8 actual, expected, *buf;
+	unsigned int counter_orig = counter;
+
+	for (; (buf = *bufs); bufs++) {
+		counter = counter_orig;
+		for (i = start; i < end; i++) {
+			actual = buf[i];
+			expected = pattern | (~counter & PATTERN_COUNT_MASK);
+			if (actual != expected) {
+				if (error_count < 32)
+					xilinx_vdmatest_mismatch(actual,
+							pattern, i,
+							counter, is_srcbuf);
+				error_count++;
+			}
+			counter++;
+		}
+	}
+
+	if (error_count > 32)
+		pr_warn("%s: %u errors suppressed\n",
+			current->comm, error_count - 32);
+
+	return error_count;
+}
+
+static void xilinx_vdmatest_slave_tx_callback(void *completion)
+{
+	pr_debug("Got tx callback\n");
+	complete(completion);
+}
+
+static void xilinx_vdmatest_slave_rx_callback(void *completion)
+{
+	pr_debug("Got rx callback\n");
+	complete(completion);
+}
+
+/*
+ * Function for slave transfers
+ * Each thread requires 2 channels, one for transmit, and one for receive
+ */
+static int xilinx_vdmatest_slave_func(void *data)
+{
+	struct xilinx_vdmatest_slave_thread *thread = data;
+	struct dma_chan *tx_chan, *rx_chan;
+	const char *thread_name;
+	unsigned int len, error_count;
+	unsigned int failed_tests = 0, total_tests = 0;
+	dma_cookie_t tx_cookie, rx_cookie;
+	enum dma_status status;
+	enum dma_ctrl_flags flags;
+	int ret = -ENOMEM, i;
+	int hsize = 64, vsize = 32;
+	struct xilinx_vdma_config config;
+
+	thread_name = current->comm;
+
+	/* Limit testing scope here */
+	iterations = 1;
+	test_buf_size = hsize * vsize;
+
+	/* This barrier ensures 'thread' is initialized and
+	 * we get valid DMA channels
+	 */
+	smp_rmb();
+	tx_chan = thread->tx_chan;
+	rx_chan = thread->rx_chan;
+
+	thread->srcs = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->srcs)
+		goto err_srcs;
+	for (i = 0; i < frm_cnt; i++) {
+		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->srcs[i])
+			goto err_srcbuf;
+	}
+
+	thread->dsts = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->dsts)
+		goto err_dsts;
+	for (i = 0; i < frm_cnt; i++) {
+		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->dsts[i])
+			goto err_dstbuf;
+	}
+
+	set_user_nice(current, 10);
+
+	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
+
+	while (!kthread_should_stop()
+		&& !(iterations && total_tests >= iterations)) {
+		struct dma_device *tx_dev = tx_chan->device;
+		struct dma_device *rx_dev = rx_chan->device;
+		struct dma_async_tx_descriptor *txd = NULL;
+		struct dma_async_tx_descriptor *rxd = NULL;
+		struct completion rx_cmp, tx_cmp;
+		unsigned long rx_tmo =
+				msecs_to_jiffies(30000); /* RX takes longer */
+		unsigned long tx_tmo = msecs_to_jiffies(30000);
+		u8 align = 0;
+
+		total_tests++;
+
+		/* honor larger alignment restrictions */
+		align = tx_dev->copy_align;
+		if (rx_dev->copy_align > align)
+			align = rx_dev->copy_align;
+
+		if (1 << align > test_buf_size) {
+			pr_err("%u-byte buffer too small for %d-byte alignment\n",
+			       test_buf_size, 1 << align);
+			break;
+		}
+
+		len = test_buf_size;
+		xilinx_vdmatest_init_srcs(thread->srcs, 0, len);
+		xilinx_vdmatest_init_dsts(thread->dsts, 0, len);
+
+		sg_init_table(tx_sg, frm_cnt);
+		sg_init_table(rx_sg, frm_cnt);
+
+		for (i = 0; i < frm_cnt; i++) {
+			u8 *buf = thread->srcs[i];
+
+			dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len,
+							DMA_MEM_TO_DEV);
+			pr_debug("src buf %x dma %x\n", (unsigned int)buf,
+				 (unsigned int)dma_srcs[i]);
+			sg_dma_address(&tx_sg[i]) = dma_srcs[i];
+			sg_dma_len(&tx_sg[i]) = len;
+		}
+
+		for (i = 0; i < frm_cnt; i++) {
+			dma_dsts[i] = dma_map_single(rx_dev->dev,
+							thread->dsts[i],
+							test_buf_size,
+							DMA_DEV_TO_MEM);
+			pr_debug("dst %x dma %x\n",
+				 (unsigned int)thread->dsts[i],
+				 (unsigned int)dma_dsts[i]);
+			sg_dma_address(&rx_sg[i]) = dma_dsts[i];
+			sg_dma_len(&rx_sg[i]) = len;
+		}
+
+		/* Zero out configuration */
+		memset(&config, 0, sizeof(struct xilinx_vdma_config));
+
+		/* Set up hardware configuration information */
+		config.vsize = vsize;
+		config.hsize = hsize;
+		config.stride = hsize;
+		config.frm_cnt_en = 1;
+		config.coalesc = frm_cnt * 10;
+		config.park = 1;
+		tx_dev->device_control(tx_chan, DMA_SLAVE_CONFIG,
+					(unsigned long)&config);
+
+		config.park = 0;
+		rx_dev->device_control(rx_chan, DMA_SLAVE_CONFIG,
+					(unsigned long)&config);
+
+		rxd = rx_dev->device_prep_slave_sg(rx_chan, rx_sg, frm_cnt,
+				DMA_DEV_TO_MEM, flags, NULL);
+
+		txd = tx_dev->device_prep_slave_sg(tx_chan, tx_sg, frm_cnt,
+				DMA_MEM_TO_DEV, flags, NULL);
+
+		if (!rxd || !txd) {
+			for (i = 0; i < frm_cnt; i++)
+				dma_unmap_single(tx_dev->dev, dma_srcs[i], len,
+						DMA_MEM_TO_DEV);
+			for (i = 0; i < frm_cnt; i++)
+				dma_unmap_single(rx_dev->dev, dma_dsts[i],
+						test_buf_size,
+						DMA_DEV_TO_MEM);
+			pr_warn("%s: #%u: prep error with len=0x%x ",
+					thread_name, total_tests - 1, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+
+		init_completion(&rx_cmp);
+		rxd->callback = xilinx_vdmatest_slave_rx_callback;
+		rxd->callback_param = &rx_cmp;
+		rx_cookie = rxd->tx_submit(rxd);
+
+		init_completion(&tx_cmp);
+		txd->callback = xilinx_vdmatest_slave_tx_callback;
+		txd->callback_param = &tx_cmp;
+		tx_cookie = txd->tx_submit(txd);
+
+		if (dma_submit_error(rx_cookie) ||
+				dma_submit_error(tx_cookie)) {
+			pr_warn("%s: #%u: submit error %d/%d with len=0x%x ",
+					thread_name, total_tests - 1,
+					rx_cookie, tx_cookie, len);
+			msleep(100);
+			failed_tests++;
+			continue;
+		}
+		dma_async_issue_pending(tx_chan);
+		dma_async_issue_pending(rx_chan);
+
+		tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo);
+
+		status = dma_async_is_tx_complete(tx_chan, tx_cookie,
+							NULL, NULL);
+
+		if (tx_tmo == 0) {
+			pr_warn("%s: #%u: tx test timed out\n",
+					thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warn(
+			"%s: #%u: tx got completion callback, ",
+				   thread_name, total_tests - 1);
+			pr_warn("but status is \'%s\'\n",
+				   status == DMA_ERROR ? "error" :
+							"in progress");
+			failed_tests++;
+			continue;
+		}
+
+		rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo);
+		status = dma_async_is_tx_complete(rx_chan, rx_cookie,
+							NULL, NULL);
+
+		if (rx_tmo == 0) {
+			pr_warn("%s: #%u: rx test timed out\n",
+					thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warn(
+			"%s: #%u: rx got completion callback, ",
+					thread_name, total_tests - 1);
+			pr_warn("but status is \'%s\'\n",
+					status == DMA_ERROR ? "error" :
+							"in progress");
+			failed_tests++;
+			continue;
+		}
+
+		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
+		for (i = 0; i < frm_cnt; i++)
+			dma_unmap_single(rx_dev->dev, dma_dsts[i],
+					 test_buf_size, DMA_DEV_TO_MEM);
+
+		error_count = 0;
+
+		pr_debug("%s: verifying source buffer...\n", thread_name);
+		error_count += xilinx_vdmatest_verify(thread->srcs, 0, 0,
+				0, PATTERN_SRC, true);
+		error_count += xilinx_vdmatest_verify(thread->srcs, 0,
+				len, 0, PATTERN_SRC | PATTERN_COPY, true);
+		error_count += xilinx_vdmatest_verify(thread->srcs, len,
+				test_buf_size, len, PATTERN_SRC, true);
+
+		pr_debug("%s: verifying dest buffer...\n",
+				thread->task->comm);
+		error_count += xilinx_vdmatest_verify(thread->dsts, 0, 0,
+				0, PATTERN_DST, false);
+		error_count += xilinx_vdmatest_verify(thread->dsts, 0,
+				len, 0, PATTERN_SRC | PATTERN_COPY, false);
+		error_count += xilinx_vdmatest_verify(thread->dsts, len,
+				test_buf_size, len, PATTERN_DST, false);
+
+		if (error_count) {
+			pr_warn("%s: #%u: %u errors with len=0x%x\n",
+				thread_name, total_tests - 1, error_count, len);
+			failed_tests++;
+		} else {
+			pr_debug("%s: #%u: No errors with len=0x%x\n",
+				thread_name, total_tests - 1, len);
+		}
+	}
+
+	ret = 0;
+	for (i = 0; thread->dsts[i]; i++)
+		kfree(thread->dsts[i]);
+err_dstbuf:
+	kfree(thread->dsts);
+err_dsts:
+	for (i = 0; thread->srcs[i]; i++)
+		kfree(thread->srcs[i]);
+err_srcbuf:
+	kfree(thread->srcs);
+err_srcs:
+	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
+			thread_name, total_tests, failed_tests, ret);
+
+	if (iterations > 0)
+		while (!kthread_should_stop()) {
+			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_vdmatest_exit);
+			interruptible_sleep_on(&wait_vdmatest_exit);
+		}
+
+	return ret;
+}
+
+static void xilinx_vdmatest_cleanup_channel(struct xilinx_vdmatest_chan *dtc)
+{
+	struct xilinx_vdmatest_slave_thread *thread, *_thread;
+	int ret;
+
+	list_for_each_entry_safe(thread, _thread,
+				&dtc->threads, node) {
+		ret = kthread_stop(thread->task);
+		pr_info("xilinx_vdmatest: thread %s exited with status %d\n",
+				thread->task->comm, ret);
+		list_del(&thread->node);
+		kfree(thread);
+	}
+	kfree(dtc);
+}
+
+static int
+xilinx_vdmatest_add_slave_threads(struct xilinx_vdmatest_chan *tx_dtc,
+					struct xilinx_vdmatest_chan *rx_dtc)
+{
+	struct xilinx_vdmatest_slave_thread *thread;
+	struct dma_chan *tx_chan = tx_dtc->chan;
+	struct dma_chan *rx_chan = rx_dtc->chan;
+
+	thread = kzalloc(sizeof(struct xilinx_vdmatest_slave_thread),
+			GFP_KERNEL);
+	if (!thread)
+		pr_warn("xilinx_vdmatest: No memory for slave thread %s-%s\n",
+			   dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+
+	thread->tx_chan = tx_chan;
+	thread->rx_chan = rx_chan;
+	thread->type = (enum dma_transaction_type)DMA_SLAVE;
+
+	/* This barrier ensures the DMA channels in the 'thread'
+	 * are initialized
+	 */
+	smp_wmb();
+	thread->task = kthread_run(xilinx_vdmatest_slave_func, thread, "%s-%s",
+		dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+	if (IS_ERR(thread->task)) {
+		pr_warn("xilinx_vdmatest: Failed to run thread %s-%s\n",
+				dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+		kfree(thread);
+	}
+
+	list_add_tail(&thread->node, &tx_dtc->threads);
+
+	/* Added one thread with 2 channels */
+	return 1;
+}
+
+static int xilinx_vdmatest_add_slave_channels(struct dma_chan *tx_chan,
+					struct dma_chan *rx_chan)
+{
+	struct xilinx_vdmatest_chan *tx_dtc, *rx_dtc;
+	unsigned int thread_count = 0;
+
+	tx_dtc = kmalloc(sizeof(struct xilinx_vdmatest_chan), GFP_KERNEL);
+	if (!tx_dtc)
+		return -ENOMEM;
+
+	rx_dtc = kmalloc(sizeof(struct xilinx_vdmatest_chan), GFP_KERNEL);
+	if (!rx_dtc)
+		return -ENOMEM;
+
+	tx_dtc->chan = tx_chan;
+	rx_dtc->chan = rx_chan;
+	INIT_LIST_HEAD(&tx_dtc->threads);
+	INIT_LIST_HEAD(&rx_dtc->threads);
+
+	xilinx_vdmatest_add_slave_threads(tx_dtc, rx_dtc);
+	thread_count += 1;
+
+	pr_info("xilinx_vdmatest: Started %u threads using %s %s\n",
+		thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan));
+
+	list_add_tail(&tx_dtc->node, &xilinx_vdmatest_channels);
+	list_add_tail(&rx_dtc->node, &xilinx_vdmatest_channels);
+	nr_channels += 2;
+
+	return 0;
+}
+
+static int xilinx_vdmatest_probe(struct platform_device *pdev)
+{
+	struct dma_chan *chan, *rx_chan;
+	int err;
+
+	err = of_property_read_u32(pdev->dev.of_node,
+					"xlnx,num-fstores", &frm_cnt);
+	if (err < 0) {
+		pr_err("xilinx_vdmatest: missing xlnx,num-fstores property\n");
+		return err;
+	}
+
+	chan = dma_request_slave_channel(&pdev->dev, "vdma0");
+	if (IS_ERR(chan)) {
+		pr_err("xilinx_vdmatest: No Tx channel\n");
+		return PTR_ERR(chan);
+	}
+
+	rx_chan = dma_request_slave_channel(&pdev->dev, "vdma1");
+	if (IS_ERR(rx_chan)) {
+		err = PTR_ERR(rx_chan);
+		pr_err("xilinx_vdmatest: No Rx channel\n");
+		goto free_tx;
+	}
+
+	err = xilinx_vdmatest_add_slave_channels(chan, rx_chan);
+	if (err) {
+		pr_err("xilinx_vdmatest: Unable to add channels\n");
+		goto free_rx;
+	}
+	return 0;
+
+free_rx:
+	dma_release_channel(rx_chan);
+free_tx:
+	dma_release_channel(chan);
+
+	return err;
+}
+
+static int xilinx_vdmatest_remove(struct platform_device *pdev)
+{
+	struct xilinx_vdmatest_chan *dtc, *_dtc;
+	struct dma_chan *chan;
+
+	list_for_each_entry_safe(dtc, _dtc, &xilinx_vdmatest_channels, node) {
+		list_del(&dtc->node);
+		chan = dtc->chan;
+		xilinx_vdmatest_cleanup_channel(dtc);
+		pr_info("xilinx_vdmatest: dropped channel %s\n",
+			dma_chan_name(chan));
+		dma_release_channel(chan);
+	}
+	return 0;
+}
+
+static const struct of_device_id xilinx_vdmatest_of_ids[] = {
+	{ .compatible = "xlnx,axi-vdma-test",},
+	{}
+};
+
+static struct platform_driver xilinx_vdmatest_driver = {
+	.driver = {
+		.name = "xilinx_vdmatest",
+		.owner = THIS_MODULE,
+		.of_match_table = xilinx_vdmatest_of_ids,
+	},
+	.probe = xilinx_vdmatest_probe,
+	.remove = xilinx_vdmatest_remove,
+};
+
+module_platform_driver(xilinx_vdmatest_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx AXI VDMA Test Client");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axicdma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axicdma.c	2014-07-20 22:06:35.781315202 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Central DMA Engine support
+ *
+ * Copyright (C) 2010 - 2013 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  . Axi CDMA engine, it does transfers between memory and memory
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/dmapool.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Hw specific definitions */
+#define XILINX_CDMA_MAX_TRANS_LEN	0x7FFFFF /* Max transfer length */
+
+/* Register Offsets */
+#define XILINX_CDMA_CONTROL_OFFSET	0x00 /* Control Reg */
+#define XILINX_CDMA_STATUS_OFFSET	0x04 /* Status Reg */
+#define XILINX_CDMA_CDESC_OFFSET	0x08 /* Current descriptor Reg */
+#define XILINX_CDMA_TDESC_OFFSET	0x10 /* Tail descriptor Reg */
+#define XILINX_CDMA_SRCADDR_OFFSET	0x18 /* Source Address Reg */
+#define XILINX_CDMA_DSTADDR_OFFSET	0x20 /* Dest Address Reg */
+#define XILINX_CDMA_BTT_OFFSET		0x28 /* Bytes to transfer Reg */
+
+/* General register bits definitions */
+#define XILINX_CDMA_CR_RESET_MASK	0x00000004 /* Reset DMA engine */
+
+#define XILINX_CDMA_SR_IDLE_MASK	0x00000002 /* DMA channel idle */
+
+#define XILINX_CDMA_XR_IRQ_IOC_MASK	0x00001000 /* Completion interrupt */
+#define XILINX_CDMA_XR_IRQ_DELAY_MASK	0x00002000 /* Delay interrupt */
+#define XILINX_CDMA_XR_IRQ_ERROR_MASK	0x00004000 /* Error interrupt */
+#define XILINX_CDMA_XR_IRQ_ALL_MASK	0x00007000 /* All interrupts */
+
+#define XILINX_CDMA_XR_DELAY_MASK	0xFF000000 /* Delay timeout counter */
+#define XILINX_CDMA_XR_COALESCE_MASK	0x00FF0000 /* Coalesce counter */
+
+#define XILINX_CDMA_DELAY_SHIFT		24 /* Delay counter shift */
+#define XILINX_CDMA_COALESCE_SHIFT	16 /* Coaelsce counter shift */
+
+#define XILINX_CDMA_DELAY_MAX		0xFF /* Maximum delay counter value */
+/* Maximum coalescing counter value */
+#define XILINX_CDMA_COALESCE_MAX	0xFF
+
+#define XILINX_CDMA_CR_SGMODE_MASK	0x00000008 /* Scatter gather mode */
+
+/* BD definitions for Axi Cdma */
+#define XILINX_CDMA_BD_STS_ALL_MASK	0xF0000000
+
+/* Feature encodings */
+#define XILINX_CDMA_FTR_DATA_WIDTH_MASK	0x000000FF /* Data width mask, 1024 */
+#define XILINX_CDMA_FTR_HAS_SG		0x00000100 /* Has SG */
+#define XILINX_CDMA_FTR_HAS_SG_SHIFT	8 /* Has SG shift */
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_CDMA_RESET_LOOP	1000000
+#define XILINX_CDMA_HALT_LOOP	1000000
+
+/* Hardware descriptor */
+struct xilinx_cdma_desc_hw {
+	u32 next_desc;	/* 0x00 */
+	u32 pad1;	/* 0x04 */
+	u32 src_addr;	/* 0x08 */
+	u32 pad2;	/* 0x0C */
+	u32 dest_addr;	/* 0x10 */
+	u32 pad3;	/* 0x14 */
+	u32 control;	/* 0x18 */
+	u32 status;	/* 0x1C */
+} __aligned(64);
+
+/* Software descriptor */
+struct xilinx_cdma_desc_sw {
+	struct xilinx_cdma_desc_hw hw;
+	struct list_head node;
+	struct list_head tx_list;
+	struct dma_async_tx_descriptor async_tx;
+} __aligned(64);
+
+/* Per DMA specific operations should be embedded in the channel structure */
+struct xilinx_cdma_chan {
+	void __iomem *regs;			/* Control status registers */
+	dma_cookie_t completed_cookie;		/* Maximum cookie completed */
+	dma_cookie_t cookie;			/* The current cookie */
+	spinlock_t lock;			/* Descriptor operation lock */
+	bool sg_waiting;			/* SG transfer waiting */
+	struct list_head active_list;		/* Active descriptors */
+	struct list_head pending_list;		/* Descriptors waiting */
+	struct dma_chan common;			/* DMA common channel */
+	struct dma_pool *desc_pool;		/* Descriptors pool */
+	struct device *dev;			/* The dma device */
+	int irq;				/* Channel IRQ */
+	int id;					/* Channel ID */
+	enum dma_transfer_direction direction;	/* Transfer direction */
+	int max_len;				/* Max data len per transfer */
+	bool is_lite;				/* Whether is light build */
+	bool has_sg;				/* Support scatter transfers */
+	bool has_dre;				/* For unaligned transfers */
+	int err;				/* Channel has errors */
+	struct tasklet_struct tasklet;		/* Cleanup work after irq */
+	u32 feature;				/* IP feature */
+	u32 private;				/* Match info for
+							channel request */
+	void (*start_transfer)(struct xilinx_cdma_chan *chan);
+	struct xilinx_cdma_config config;	/* Device configuration info */
+};
+
+struct xilinx_cdma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_cdma_chan *chan;
+	u32 feature;
+};
+
+#define to_xilinx_chan(chan) \
+	container_of(chan, struct xilinx_cdma_chan, common)
+
+/* IO accessors */
+static inline void
+cdma_write(struct xilinx_cdma_chan *chan, u32 reg, u32 val)
+{
+	writel(val, chan->regs + reg);
+}
+
+static inline u32 cdma_read(struct xilinx_cdma_chan *chan, u32 reg)
+{
+	return readl(chan->regs + reg);
+}
+
+/* Required functions */
+
+static int xilinx_cdma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Has this channel already been allocated? */
+	if (chan->desc_pool)
+		return 1;
+
+	/*
+	 * We need the descriptor to be aligned to 64bytes
+	 * for meeting Xilinx DMA specification requirement.
+	 */
+	chan->desc_pool =
+		dma_pool_create("xilinx_cdma_desc_pool",
+				chan->dev,
+				sizeof(struct xilinx_cdma_desc_sw),
+				__alignof__(struct xilinx_cdma_desc_sw), 0);
+	if (!chan->desc_pool) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptor pool\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	chan->completed_cookie = 1;
+	chan->cookie = 1;
+
+	/* there is at least one descriptor free to be allocated */
+	return 1;
+}
+
+static void xilinx_cdma_free_desc_list(struct xilinx_cdma_chan *chan,
+				       struct list_head *list)
+{
+	struct xilinx_cdma_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+static void xilinx_cdma_free_desc_list_reverse(struct xilinx_cdma_chan *chan,
+					       struct list_head *list)
+{
+	struct xilinx_cdma_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe_reverse(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+static void xilinx_cdma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
+
+	dev_dbg(chan->dev, "Free all channel resources.\n");
+	spin_lock_irqsave(&chan->lock, flags);
+	xilinx_cdma_free_desc_list(chan, &chan->active_list);
+	xilinx_cdma_free_desc_list(chan, &chan->pending_list);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	dma_pool_destroy(chan->desc_pool);
+	chan->desc_pool = NULL;
+}
+
+static enum dma_status xilinx_cdma_desc_status(struct xilinx_cdma_chan *chan,
+					       struct xilinx_cdma_desc_sw *desc)
+{
+	return dma_async_is_complete(desc->async_tx.cookie,
+				     chan->completed_cookie,
+				     chan->cookie);
+}
+
+static void xilinx_cdma_chan_desc_cleanup(struct xilinx_cdma_chan *chan)
+{
+	struct xilinx_cdma_desc_sw *desc, *_desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	list_for_each_entry_safe(desc, _desc, &chan->active_list, node) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		if (xilinx_cdma_desc_status(chan, desc) == DMA_IN_PROGRESS)
+			break;
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static enum dma_status xilinx_tx_status(struct dma_chan *dchan,
+					dma_cookie_t cookie,
+					struct dma_tx_state *txstate)
+{
+	struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+
+	xilinx_cdma_chan_desc_cleanup(chan);
+
+	last_used = dchan->cookie;
+	last_complete = chan->completed_cookie;
+
+	dma_set_tx_state(txstate, last_complete, last_used, 0);
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static int cdma_is_idle(struct xilinx_cdma_chan *chan)
+{
+	return cdma_read(chan, XILINX_CDMA_STATUS_OFFSET) &
+	       XILINX_CDMA_SR_IDLE_MASK;
+}
+
+/* Only needed for Axi CDMA v2_00_a or earlier core */
+static void cdma_sg_toggle(struct xilinx_cdma_chan *chan)
+{
+	cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+		   cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) &
+		   ~XILINX_CDMA_CR_SGMODE_MASK);
+
+	cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+		   cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) |
+		   XILINX_CDMA_CR_SGMODE_MASK);
+}
+
+static void xilinx_cdma_start_transfer(struct xilinx_cdma_chan *chan)
+{
+	unsigned long flags;
+	struct xilinx_cdma_desc_sw *desch, *desct;
+	struct xilinx_cdma_desc_hw *hw;
+
+	if (chan->err)
+		return;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	if (list_empty(&chan->pending_list))
+		goto out_unlock;
+
+	/* If hardware is busy, cannot submit */
+	if (!cdma_is_idle(chan)) {
+		dev_dbg(chan->dev, "DMA controller still busy %x\n",
+			cdma_read(chan, XILINX_CDMA_STATUS_OFFSET));
+		goto out_unlock;
+	}
+
+	/* Enable interrupts */
+	cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+		   cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) |
+		   XILINX_CDMA_XR_IRQ_ALL_MASK);
+
+	desch = list_first_entry(&chan->pending_list,
+				 struct xilinx_cdma_desc_sw, node);
+
+	if (chan->has_sg) {
+
+		/* If hybrid mode, append pending list to active list */
+		desct = container_of(chan->pending_list.prev,
+				     struct xilinx_cdma_desc_sw, node);
+
+		list_splice_tail_init(&chan->pending_list, &chan->active_list);
+
+		/*
+		 * If hardware is idle, then all descriptors on the active list
+		 * are done, start new transfers
+		 */
+		cdma_sg_toggle(chan);
+
+		cdma_write(chan, XILINX_CDMA_CDESC_OFFSET,
+			   desch->async_tx.phys);
+
+		/* Update tail ptr register and start the transfer */
+		cdma_write(chan, XILINX_CDMA_TDESC_OFFSET,
+			   desch->async_tx.phys);
+		goto out_unlock;
+	}
+
+	/* In simple mode */
+	list_del(&desch->node);
+	list_add_tail(&desch->node, &chan->active_list);
+
+	hw = &desch->hw;
+
+	cdma_write(chan, XILINX_CDMA_SRCADDR_OFFSET, hw->src_addr);
+	cdma_write(chan, XILINX_CDMA_DSTADDR_OFFSET, hw->dest_addr);
+
+	/* Start the transfer */
+	cdma_write(chan, XILINX_CDMA_BTT_OFFSET,
+		   hw->control & XILINX_CDMA_MAX_TRANS_LEN);
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/*
+ * If sg mode, link the pending list to running list; if simple mode, get the
+ * head of the pending list and submit it to hw
+ */
+static void xilinx_cdma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_cdma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_cdma_start_transfer(chan);
+}
+
+/**
+ * xilinx_cdma_update_completed_cookie - Update the completed cookie.
+ * @chan : xilinx DMA channel
+ *
+ * CONTEXT: hardirq
+ */
+static void xilinx_cdma_update_completed_cookie(struct xilinx_cdma_chan *chan)
+{
+	struct xilinx_cdma_desc_sw *desc = NULL;
+	struct xilinx_cdma_desc_hw *hw = NULL;
+	unsigned long flags;
+	dma_cookie_t cookie = -EBUSY;
+	int done = 0;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	if (list_empty(&chan->active_list)) {
+		dev_dbg(chan->dev, "no running descriptors\n");
+		goto out_unlock;
+	}
+
+	/* Get the last completed descriptor, update the cookie to that */
+	list_for_each_entry(desc, &chan->active_list, node) {
+		if (chan->has_sg) {
+			hw = &desc->hw;
+
+			/* If a BD has no status bits set, hw has it */
+			if (!(hw->status & XILINX_CDMA_BD_STS_ALL_MASK)) {
+				break;
+			} else {
+				done = 1;
+				cookie = desc->async_tx.cookie;
+			}
+		} else {
+			/* In non-SG mode, all active entries are done */
+			done = 1;
+			cookie = desc->async_tx.cookie;
+		}
+	}
+
+	if (done)
+		chan->completed_cookie = cookie;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/* Reset hardware */
+static int cdma_reset(struct xilinx_cdma_chan *chan)
+{
+	int loop = XILINX_CDMA_RESET_LOOP;
+	u32 tmp;
+
+	cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+		   cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) |
+		   XILINX_CDMA_CR_RESET_MASK);
+
+	tmp = cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) &
+	      XILINX_CDMA_CR_RESET_MASK;
+
+	/* Wait for the hardware to finish reset */
+	while (loop && tmp) {
+		tmp = cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET) &
+		      XILINX_CDMA_CR_RESET_MASK;
+		loop -= 1;
+	}
+
+	if (!loop) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET),
+			cdma_read(chan, XILINX_CDMA_STATUS_OFFSET));
+		return -EBUSY;
+	}
+
+	/* For Axi CDMA, always do sg transfers if sg mode is built in */
+	if (chan->has_sg)
+		cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+			   tmp | XILINX_CDMA_CR_SGMODE_MASK);
+
+	return 0;
+}
+
+
+static irqreturn_t cdma_intr_handler(int irq, void *data)
+{
+	struct xilinx_cdma_chan *chan = data;
+	int update_cookie = 0;
+	int to_transfer = 0;
+	u32 stat, reg;
+
+	reg = cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET);
+
+	/* Disable intr */
+	cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET,
+		   reg & ~XILINX_CDMA_XR_IRQ_ALL_MASK);
+
+	stat = cdma_read(chan, XILINX_CDMA_STATUS_OFFSET);
+	if (!(stat & XILINX_CDMA_XR_IRQ_ALL_MASK))
+		return IRQ_NONE;
+
+	/* Ack the interrupts */
+	cdma_write(chan, XILINX_CDMA_STATUS_OFFSET,
+		   XILINX_CDMA_XR_IRQ_ALL_MASK);
+
+	/* Check for only the interrupts which are enabled */
+	stat &= (reg & XILINX_CDMA_XR_IRQ_ALL_MASK);
+
+	if (stat & XILINX_CDMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev,
+			"Channel %x has errors %x, cdr %x tdr %x\n",
+			(u32)chan,
+			(u32)cdma_read(chan, XILINX_CDMA_STATUS_OFFSET),
+			(u32)cdma_read(chan, XILINX_CDMA_CDESC_OFFSET),
+			(u32)cdma_read(chan, XILINX_CDMA_TDESC_OFFSET));
+		chan->err = 1;
+	}
+
+	/*
+	 * Device takes too long to do the transfer when user requires
+	 * responsiveness
+	 */
+	if (stat & XILINX_CDMA_XR_IRQ_DELAY_MASK)
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+
+	if (stat & XILINX_CDMA_XR_IRQ_IOC_MASK) {
+		update_cookie = 1;
+		to_transfer = 1;
+	}
+
+	if (update_cookie)
+		xilinx_cdma_update_completed_cookie(chan);
+
+	if (to_transfer)
+		chan->start_transfer(chan);
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+static void cdma_do_tasklet(unsigned long data)
+{
+	struct xilinx_cdma_chan *chan = (struct xilinx_cdma_chan *)data;
+
+	xilinx_cdma_chan_desc_cleanup(chan);
+}
+
+/* Append the descriptor list to the pending list */
+static void append_desc_queue(struct xilinx_cdma_chan *chan,
+			      struct xilinx_cdma_desc_sw *desc)
+{
+	struct xilinx_cdma_desc_sw *tail =
+		container_of(chan->pending_list.prev,
+			     struct xilinx_cdma_desc_sw, node);
+	struct xilinx_cdma_desc_hw *hw;
+
+	if (list_empty(&chan->pending_list))
+		goto out_splice;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 */
+	hw = &(tail->hw);
+	hw->next_desc = (u32)desc->async_tx.phys;
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+out_splice:
+	list_splice_tail_init(&desc->tx_list, &chan->pending_list);
+}
+
+/*
+ * Assign cookie to each descriptor, and append the descriptors to the pending
+ * list
+ */
+static dma_cookie_t xilinx_cdma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_cdma_chan *chan = to_xilinx_chan(tx->chan);
+	struct xilinx_cdma_desc_sw *desc =
+		container_of(tx, struct xilinx_cdma_desc_sw, async_tx);
+	struct xilinx_cdma_desc_sw *child;
+	unsigned long flags;
+	dma_cookie_t cookie = -EBUSY;
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		if (!cdma_reset(chan))
+			chan->err = 0;
+		else
+			return cookie;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	/*
+	 * assign cookies to all of the software descriptors
+	 * that make up this transaction
+	 */
+	cookie = chan->cookie;
+	list_for_each_entry(child, &desc->tx_list, node) {
+		cookie++;
+		if (cookie < 0)
+			cookie = DMA_MIN_COOKIE;
+
+		child->async_tx.cookie = cookie;
+	}
+
+	chan->cookie = cookie;
+
+	/* put this transaction onto the tail of the pending queue */
+	append_desc_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+static struct xilinx_cdma_desc_sw *xilinx_cdma_alloc_descriptor(
+	struct xilinx_cdma_chan *chan)
+{
+	struct xilinx_cdma_desc_sw *desc;
+	dma_addr_t pdesc;
+
+	desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc);
+	if (!desc) {
+		dev_dbg(chan->dev, "out of memory for desc\n");
+		return NULL;
+	}
+
+	memset(desc, 0, sizeof(*desc));
+	INIT_LIST_HEAD(&desc->tx_list);
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_cdma_tx_submit;
+	desc->async_tx.phys = pdesc;
+
+	return desc;
+}
+
+/**
+ * xilinx_cdma_prep_memcpy - prepare descriptors for a memcpy transaction
+ * @dchan: DMA channel
+ * @dma_dst: destination address
+ * @dma_src: source address
+ * @len: transfer length
+ * @flags: transfer ack flags
+ */
+static struct dma_async_tx_descriptor *xilinx_cdma_prep_memcpy(
+	struct dma_chan *dchan, dma_addr_t dma_dst, dma_addr_t dma_src,
+	size_t len, unsigned long flags)
+{
+	struct xilinx_cdma_chan *chan;
+	struct xilinx_cdma_desc_sw *first = NULL, *prev = NULL, *new;
+	struct xilinx_cdma_desc_hw *hw, *prev_hw;
+	size_t copy;
+	dma_addr_t src = dma_src;
+	dma_addr_t dst = dma_dst;
+
+	if (!dchan)
+		return NULL;
+
+	if (!len)
+		return NULL;
+
+	chan = to_xilinx_chan(dchan);
+
+	if (chan->err) {
+
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		if (!cdma_reset(chan))
+			chan->err = 0;
+		else
+			return NULL;
+	}
+
+	/*
+	 * If build does not have Data Realignment Engine (DRE),
+	 * src has to be aligned
+	 */
+	if (!chan->has_dre) {
+		if ((dma_src &
+		     (chan->feature & XILINX_CDMA_FTR_DATA_WIDTH_MASK)) ||
+		    (dma_dst &
+		     (chan->feature & XILINX_CDMA_FTR_DATA_WIDTH_MASK))) {
+
+			dev_err(chan->dev,
+				"Src/Dest address not aligned when no DRE\n");
+
+			return NULL;
+		}
+	}
+
+	do {
+		/* Allocate descriptor from DMA pool */
+		new = xilinx_cdma_alloc_descriptor(chan);
+		if (!new) {
+			dev_err(chan->dev,
+				"No free memory for link descriptor\n");
+			goto fail;
+		}
+
+		copy = min_t(size_t, len, chan->max_len);
+
+		/* if lite build, transfer cannot cross page boundary */
+		if (chan->is_lite)
+			copy = min(copy, (size_t)(PAGE_MASK -
+						  (src & PAGE_MASK)));
+
+		if (!copy) {
+			dev_err(chan->dev,
+				"Got zero transfer length for %x\n",
+				(unsigned int)src);
+			goto fail;
+		}
+
+		hw = &(new->hw);
+		hw->control =
+			(hw->control & ~XILINX_CDMA_MAX_TRANS_LEN) | copy;
+		hw->src_addr = src;
+		hw->dest_addr = dst;
+
+		if (!first)
+			first = new;
+		else {
+			prev_hw = &(prev->hw);
+			prev_hw->next_desc = new->async_tx.phys;
+		}
+
+		new->async_tx.cookie = 0;
+		async_tx_ack(&new->async_tx);
+
+		prev = new;
+		len -= copy;
+		src += copy;
+		dst += copy;
+
+		/* Insert the descriptor to the list */
+		list_add_tail(&new->node, &first->tx_list);
+	} while (len);
+
+	/* Link the last BD with the first BD */
+	hw->next_desc = first->async_tx.phys;
+
+	new->async_tx.flags = flags; /* client is in control of this ack */
+	new->async_tx.cookie = -EBUSY;
+
+	return &first->async_tx;
+
+fail:
+	if (!first)
+		return NULL;
+
+	xilinx_cdma_free_desc_list_reverse(chan, &first->tx_list);
+	return NULL;
+}
+
+/* Run-time device configuration for Axi CDMA */
+static int xilinx_cdma_device_control(struct dma_chan *dchan,
+				      enum dma_ctrl_cmd cmd, unsigned long arg)
+{
+	struct xilinx_cdma_chan *chan;
+	unsigned long flags;
+
+	if (!dchan)
+		return -EINVAL;
+
+	chan = to_xilinx_chan(dchan);
+
+	if (cmd == DMA_TERMINATE_ALL) {
+		spin_lock_irqsave(&chan->lock, flags);
+
+		/* Remove and free all of the descriptors in the lists */
+		xilinx_cdma_free_desc_list(chan, &chan->pending_list);
+		xilinx_cdma_free_desc_list(chan, &chan->active_list);
+
+		spin_unlock_irqrestore(&chan->lock, flags);
+		return 0;
+	} else if (cmd == DMA_SLAVE_CONFIG) {
+		/*
+		 * Configure interrupt coalescing and delay counter
+		 * Use value XILINX_CDMA_NO_CHANGE to signal no change
+		 */
+		struct xilinx_cdma_config *cfg =
+			(struct xilinx_cdma_config *)arg;
+		u32 reg = cdma_read(chan, XILINX_CDMA_CONTROL_OFFSET);
+
+		if (cfg->coalesc <= XILINX_CDMA_COALESCE_MAX) {
+			reg &= ~XILINX_CDMA_XR_COALESCE_MASK;
+			reg |= cfg->coalesc << XILINX_CDMA_COALESCE_SHIFT;
+
+			chan->config.coalesc = cfg->coalesc;
+		}
+
+		if (cfg->delay <= XILINX_CDMA_DELAY_MAX) {
+			reg &= ~XILINX_CDMA_XR_DELAY_MASK;
+			reg |= cfg->delay << XILINX_CDMA_DELAY_SHIFT;
+			chan->config.delay = cfg->delay;
+		}
+
+		cdma_write(chan, XILINX_CDMA_CONTROL_OFFSET, reg);
+
+		return 0;
+	}
+
+	return -ENXIO;
+}
+
+static void xilinx_cdma_free_channels(struct xilinx_cdma_device *xdev)
+{
+
+	list_del(&xdev->chan->common.device_node);
+	tasklet_kill(&xdev->chan->tasklet);
+	irq_dispose_mapping(xdev->chan->irq);
+}
+
+/*
+ * Probing channels
+ *
+ * . Get channel features from the device tree entry
+ * . Initialize special channel handling routines
+ */
+static int xilinx_cdma_chan_probe(struct xilinx_cdma_device *xdev,
+				  struct device_node *node, u32 feature)
+{
+	struct xilinx_cdma_chan *chan;
+	int err;
+	u32 device_id, value, width = 0;
+
+	/* alloc channel */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->feature = feature;
+	chan->max_len = XILINX_CDMA_MAX_TRANS_LEN;
+
+	chan->has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (err) {
+		dev_err(xdev->dev, "unable to read datawidth property");
+		return err;
+	} else {
+		width = value >> 3; /* convert bits to bytes */
+
+		/* If data width is greater than 8 bytes, DRE is not in hw */
+		if (width > 8)
+			chan->has_dre = 0;
+
+		chan->feature |= width - 1;
+	}
+
+	err = of_property_read_u32(node, "xlnx,device-id", &device_id);
+	if (err) {
+		dev_err(xdev->dev, "unable to read device id property");
+		return err;
+	}
+
+	chan->direction = DMA_MEM_TO_MEM;
+	chan->start_transfer = xilinx_cdma_start_transfer;
+
+	chan->has_sg = (xdev->feature & XILINX_CDMA_FTR_HAS_SG) >>
+		       XILINX_CDMA_FTR_HAS_SG_SHIFT;
+
+	chan->is_lite = of_property_read_bool(node, "xlnx,lite-mode");
+	if (chan->is_lite) {
+		err = of_property_read_u32(node, "xlnx,max-burst-len", &value);
+		if (err) {
+			dev_err(xdev->dev, "unable to read max burstlen property");
+			return err;
+		}
+		if (value) {
+			if (!width) {
+				dev_err(xdev->dev,
+					"Lite mode w/o data width property\n");
+				return -EPERM;
+			}
+			chan->max_len = width * value;
+		}
+	}
+
+	chan->regs = xdev->regs;
+
+	/*
+	 * Used by dmatest channel matching in slave transfers
+	 * Can change it to be a structure to have more matching information
+	 */
+	chan->private = (chan->direction & 0xFF) | XILINX_DMA_IP_CDMA |
+			(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
+	chan->common.private = (void *)&(chan->private);
+
+	if (!chan->has_dre)
+		xdev->common.copy_align = fls(width - 1);
+
+	chan->dev = xdev->dev;
+	xdev->chan = chan;
+
+	/* Initialize the channel */
+	err = cdma_reset(chan);
+	if (err) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->active_list);
+
+	chan->common.device = &xdev->common;
+
+	/* Find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = devm_request_irq(xdev->dev, chan->irq, cdma_intr_handler,
+			       IRQF_SHARED,
+			       "xilinx-cdma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ\n");
+		return err;
+	}
+
+	tasklet_init(&chan->tasklet, cdma_do_tasklet, (unsigned long)chan);
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+
+	return 0;
+}
+
+static int xilinx_cdma_probe(struct platform_device *pdev)
+{
+	struct xilinx_cdma_device *xdev;
+	struct device_node *child, *node;
+	struct resource *res;
+	int ret;
+	u32 value;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &(pdev->dev);
+	INIT_LIST_HEAD(&xdev->common.channels);
+
+	node = pdev->dev.of_node;
+
+	/* iomap registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Check if SG is enabled */
+	value = of_property_read_bool(node, "xlnx,include-sg");
+	if (value)
+		xdev->feature |= XILINX_CDMA_FTR_HAS_SG;
+
+	/* Axi CDMA only does memcpy */
+	dma_cap_set(DMA_MEMCPY, xdev->common.cap_mask);
+	xdev->common.device_prep_dma_memcpy = xilinx_cdma_prep_memcpy;
+
+	xdev->common.device_control = xilinx_cdma_device_control;
+	xdev->common.device_issue_pending = xilinx_cdma_issue_pending;
+	xdev->common.device_alloc_chan_resources =
+		xilinx_cdma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+		xilinx_cdma_free_chan_resources;
+	xdev->common.device_tx_status = xilinx_tx_status;
+	xdev->common.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, xdev);
+
+	for_each_child_of_node(node, child) {
+		ret = xilinx_cdma_chan_probe(xdev, child, xdev->feature);
+		if (ret) {
+			dev_err(&pdev->dev, "Probing channels failed\n");
+			goto free_chan_resources;
+		}
+	}
+
+	ret = dma_async_device_register(&xdev->common);
+	if (ret) {
+		dev_err(&pdev->dev, "CDMA device registration failed\n");
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "Probing xilinx axi cdma engine...Successful\n");
+
+	return 0;
+
+free_chan_resources:
+	xilinx_cdma_free_channels(xdev);
+
+	return ret;
+}
+
+static int xilinx_cdma_remove(struct platform_device *pdev)
+{
+	struct xilinx_cdma_device *xdev;
+
+	xdev = platform_get_drvdata(pdev);
+	dma_async_device_unregister(&xdev->common);
+
+	xilinx_cdma_free_channels(xdev);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_cdma_of_match[] = {
+	{ .compatible = "xlnx,axi-cdma", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, xilinx_cdma_of_match);
+
+static struct platform_driver xilinx_cdma_driver = {
+	.driver = {
+		.name = "xilinx-cdma",
+		.owner = THIS_MODULE,
+		.of_match_table = xilinx_cdma_of_match,
+	},
+	.probe = xilinx_cdma_probe,
+	.remove = xilinx_cdma_remove,
+};
+
+module_platform_driver(xilinx_cdma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx CDMA driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axidma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axidma.c	2014-07-20 22:06:35.799314906 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI DMA Engine support
+ *
+ * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  . Axi DMA engine, it does transfers between memory and device. It can be
+ *    configured to have one channel or two channels. If configured as two
+ *    channels, one is to transmit to a device and another is to receive from
+ *    a device.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/dmapool.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Hw specific definitions */
+#define XILINX_DMA_MAX_CHANS_PER_DEVICE	0x2 /* Max no of channels */
+#define XILINX_DMA_MAX_TRANS_LEN	0x7FFFFF /* Max transfer length */
+
+/* Register Offsets */
+#define XILINX_DMA_CONTROL_OFFSET	0x00 /* Control Reg */
+#define XILINX_DMA_STATUS_OFFSET	0x04 /* Status Reg */
+#define XILINX_DMA_CDESC_OFFSET		0x08 /* Current descriptor Reg */
+#define XILINX_DMA_TDESC_OFFSET		0x10 /* Tail descriptor Reg */
+#define XILINX_DMA_SRCADDR_OFFSET	0x18 /* Source Address Reg */
+#define XILINX_DMA_DSTADDR_OFFSET	0x20 /* Dest Address Reg */
+#define XILINX_DMA_BTT_OFFSET		0x28 /* Bytes to transfer Reg */
+
+/* General register bits definitions */
+#define XILINX_DMA_CR_RESET_MASK	0x00000004 /* Reset DMA engine */
+#define XILINX_DMA_CR_RUNSTOP_MASK	0x00000001 /* Start/stop DMA engine */
+
+#define XILINX_DMA_SR_HALTED_MASK	0x00000001 /* DMA channel halted */
+#define XILINX_DMA_SR_IDLE_MASK		0x00000002 /* DMA channel idle */
+
+#define XILINX_DMA_XR_IRQ_IOC_MASK	0x00001000 /* Completion interrupt */
+#define XILINX_DMA_XR_IRQ_DELAY_MASK	0x00002000 /* Delay interrupt */
+#define XILINX_DMA_XR_IRQ_ERROR_MASK	0x00004000 /* Error interrupt */
+#define XILINX_DMA_XR_IRQ_ALL_MASK	0x00007000 /* All interrupts */
+
+#define XILINX_DMA_XR_DELAY_MASK	0xFF000000 /* Delay timeout counter */
+#define XILINX_DMA_XR_COALESCE_MASK	0x00FF0000 /* Coalesce counter */
+
+#define XILINX_DMA_DELAY_SHIFT		24 /* Delay timeout counter shift */
+#define XILINX_DMA_COALESCE_SHIFT	16 /* Coalesce counter shift */
+
+#define XILINX_DMA_DELAY_MAX		0xFF /* Maximum delay counter value */
+#define XILINX_DMA_COALESCE_MAX		0xFF /* Max coalescing counter value */
+
+#define XILINX_DMA_RX_CHANNEL_OFFSET	0x30 /* S2MM Channel Offset */
+
+/* BD definitions for AXI Dma */
+#define XILINX_DMA_BD_STS_ALL_MASK	0xF0000000
+#define XILINX_DMA_BD_SOP		0x08000000 /* Start of packet bit */
+#define XILINX_DMA_BD_EOP		0x04000000 /* End of packet bit */
+
+/* Feature encodings */
+#define XILINX_DMA_FTR_HAS_SG		0x00000100 /* Has SG */
+#define XILINX_DMA_FTR_HAS_SG_SHIFT	8 /* Has SG shift */
+/* Optional feature for dma */
+#define XILINX_DMA_FTR_STSCNTRL_STRM	0x00010000
+
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_DMA_RESET_LOOP		1000000
+#define XILINX_DMA_HALT_LOOP		1000000
+
+#if defined(CONFIG_XILINX_DMATEST) || defined(CONFIG_XILINX_DMATEST_MODULE)
+# define TEST_DMA_WITH_LOOPBACK
+#endif
+
+/* Hardware descriptor */
+struct xilinx_dma_desc_hw {
+	u32 next_desc;	/* 0x00 */
+	u32 pad1;	/* 0x04 */
+	u32 buf_addr;	/* 0x08 */
+	u32 pad2;	/* 0x0C */
+	u32 pad3;	/* 0x10 */
+	u32 pad4;	/* 0x14 */
+	u32 control;	/* 0x18 */
+	u32 status;	/* 0x1C */
+	u32 app_0;	/* 0x20 */
+	u32 app_1;	/* 0x24 */
+	u32 app_2;	/* 0x28 */
+	u32 app_3;	/* 0x2C */
+	u32 app_4;	/* 0x30 */
+} __aligned(64);
+
+/* Software descriptor */
+struct xilinx_dma_desc_sw {
+	struct xilinx_dma_desc_hw hw;
+	struct list_head node;
+	struct list_head tx_list;
+	struct dma_async_tx_descriptor async_tx;
+} __aligned(64);
+
+/* Per DMA specific operations should be embedded in the channel structure */
+struct xilinx_dma_chan {
+	void __iomem *regs;		/* Control status registers */
+	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
+	dma_cookie_t cookie;		/* The current cookie */
+	spinlock_t lock;		/* Descriptor operation lock */
+	bool sg_waiting;		/* Scatter gather transfer waiting */
+	struct list_head active_list;	/* Active descriptors */
+	struct list_head pending_list;	/* Descriptors waiting */
+	struct dma_chan common;		/* DMA common channel */
+	struct dma_pool *desc_pool;	/* Descriptors pool */
+	struct device *dev;		/* The dma device */
+	int irq;			/* Channel IRQ */
+	int id;				/* Channel ID */
+	enum dma_transfer_direction direction;
+					/* Transfer direction */
+	int max_len;			/* Maximum data len per transfer */
+	bool has_sg;			/* Support scatter transfers */
+	bool has_dre;			/* Support unaligned transfers */
+	int err;			/* Channel has errors */
+	struct tasklet_struct tasklet;	/* Cleanup work after irq */
+	u32 feature;			/* IP feature */
+	u32 private;			/* Match info for channel request */
+	void (*start_transfer)(struct xilinx_dma_chan *chan);
+	struct xilinx_dma_config config;
+					/* Device configuration info */
+};
+
+/* DMA Device Structure */
+struct xilinx_dma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
+	u32 feature;
+};
+
+#define to_xilinx_chan(chan) \
+	container_of(chan, struct xilinx_dma_chan, common)
+
+/* IO accessors */
+static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 val)
+{
+	writel(val, chan->regs + reg);
+}
+
+static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return readl(chan->regs + reg);
+}
+
+static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Has this channel already been allocated? */
+	if (chan->desc_pool)
+		return 1;
+
+	/*
+	 * We need the descriptor to be aligned to 64bytes
+	 * for meeting Xilinx DMA specification requirement.
+	 */
+	chan->desc_pool =
+		dma_pool_create("xilinx_dma_desc_pool", chan->dev,
+				sizeof(struct xilinx_dma_desc_sw),
+				__alignof__(struct xilinx_dma_desc_sw), 0);
+	if (!chan->desc_pool) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptor pool\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	chan->completed_cookie = 1;
+	chan->cookie = 1;
+
+	/* There is at least one descriptor free to be allocated */
+	return 1;
+}
+
+static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
+				      struct list_head *list)
+{
+	struct xilinx_dma_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+static void xilinx_dma_free_desc_list_reverse(struct xilinx_dma_chan *chan,
+					      struct list_head *list)
+{
+	struct xilinx_dma_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe_reverse(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
+
+	dev_dbg(chan->dev, "Free all channel resources.\n");
+	spin_lock_irqsave(&chan->lock, flags);
+	xilinx_dma_free_desc_list(chan, &chan->active_list);
+	xilinx_dma_free_desc_list(chan, &chan->pending_list);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	dma_pool_destroy(chan->desc_pool);
+	chan->desc_pool = NULL;
+}
+
+static enum dma_status xilinx_dma_desc_status(struct xilinx_dma_chan *chan,
+					      struct xilinx_dma_desc_sw *desc)
+{
+	return dma_async_is_complete(desc->async_tx.cookie,
+				     chan->completed_cookie,
+				     chan->cookie);
+}
+
+static void xilinx_chan_desc_cleanup(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_desc_sw *desc, *_desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	list_for_each_entry_safe(desc, _desc, &chan->active_list, node) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		if (xilinx_dma_desc_status(chan, desc) == DMA_IN_PROGRESS)
+			break;
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static enum dma_status xilinx_tx_status(struct dma_chan *dchan,
+					dma_cookie_t cookie,
+					struct dma_tx_state *txstate)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+
+	xilinx_chan_desc_cleanup(chan);
+
+	last_used = dchan->cookie;
+	last_complete = chan->completed_cookie;
+
+	dma_set_tx_state(txstate, last_complete, last_used, 0);
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static int dma_is_running(struct xilinx_dma_chan *chan)
+{
+	return !(dma_read(chan, XILINX_DMA_STATUS_OFFSET) &
+		 XILINX_DMA_SR_HALTED_MASK) &&
+	       (dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+		XILINX_DMA_CR_RUNSTOP_MASK);
+}
+
+static int dma_is_idle(struct xilinx_dma_chan *chan)
+{
+	return dma_read(chan, XILINX_DMA_STATUS_OFFSET) &
+	       XILINX_DMA_SR_IDLE_MASK;
+}
+
+/* Stop the hardware, the ongoing transfer will be finished */
+static void dma_halt(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_HALT_LOOP;
+
+	dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+		  dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+		  ~XILINX_DMA_CR_RUNSTOP_MASK);
+
+	/* Wait for the hardware to halt */
+	while (loop) {
+		if (!(dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+		      XILINX_DMA_CR_RUNSTOP_MASK))
+			break;
+
+		loop -= 1;
+	}
+
+	if (!loop) {
+		pr_debug("Cannot stop channel %x: %x\n",
+			 (unsigned int)chan,
+			 (unsigned int)dma_read(chan,
+						XILINX_DMA_CONTROL_OFFSET));
+		chan->err = 1;
+	}
+}
+
+/* Start the hardware. Transfers are not started yet */
+static void dma_start(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_HALT_LOOP;
+
+	dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+		  dma_read(chan, XILINX_DMA_CONTROL_OFFSET) |
+		  XILINX_DMA_CR_RUNSTOP_MASK);
+
+	/* Wait for the hardware to start */
+	while (loop) {
+		if (dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+		    XILINX_DMA_CR_RUNSTOP_MASK)
+			break;
+
+		loop -= 1;
+	}
+
+	if (!loop) {
+		pr_debug("Cannot start channel %x: %x\n",
+			 (unsigned int)chan,
+			 (unsigned int)dma_read(chan,
+						XILINX_DMA_CONTROL_OFFSET));
+
+		chan->err = 1;
+	}
+}
+
+static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
+{
+	unsigned long flags;
+	struct xilinx_dma_desc_sw *desch, *desct;
+	struct xilinx_dma_desc_hw *hw;
+
+	if (chan->err)
+		return;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	if (list_empty(&chan->pending_list))
+		goto out_unlock;
+
+	/* If hardware is busy, cannot submit */
+	if (dma_is_running(chan) && !dma_is_idle(chan)) {
+		dev_dbg(chan->dev, "DMA controller still busy\n");
+		goto out_unlock;
+	}
+
+	/*
+	 * If hardware is idle, then all descriptors on active list are
+	 * done, start new transfers
+	 */
+	dma_halt(chan);
+
+	if (chan->err)
+		goto out_unlock;
+
+	if (chan->has_sg) {
+		desch = list_first_entry(&chan->pending_list,
+					 struct xilinx_dma_desc_sw, node);
+
+		desct = container_of(chan->pending_list.prev,
+				     struct xilinx_dma_desc_sw, node);
+
+		dma_write(chan, XILINX_DMA_CDESC_OFFSET, desch->async_tx.phys);
+
+		dma_start(chan);
+
+		if (chan->err)
+			goto out_unlock;
+		list_splice_tail_init(&chan->pending_list, &chan->active_list);
+
+		/* Enable interrupts */
+		dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+			  dma_read(chan, XILINX_DMA_CONTROL_OFFSET) |
+			  XILINX_DMA_XR_IRQ_ALL_MASK);
+
+		/* Update tail ptr register and start the transfer */
+		dma_write(chan, XILINX_DMA_TDESC_OFFSET, desct->async_tx.phys);
+		goto out_unlock;
+	}
+
+	/* In simple mode */
+	dma_halt(chan);
+
+	if (chan->err)
+		goto out_unlock;
+
+	pr_info("xilinx_dma_start_transfer::simple DMA mode\n");
+
+	desch = list_first_entry(&chan->pending_list,
+				 struct xilinx_dma_desc_sw, node);
+
+	list_del(&desch->node);
+	list_add_tail(&desch->node, &chan->active_list);
+
+	dma_start(chan);
+
+	if (chan->err)
+		goto out_unlock;
+
+	hw = &desch->hw;
+
+	/* Enable interrupts */
+	dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+		  dma_read(chan, XILINX_DMA_CONTROL_OFFSET) |
+		  XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	dma_write(chan, XILINX_DMA_SRCADDR_OFFSET, hw->buf_addr);
+
+	/* Start the transfer */
+	dma_write(chan, XILINX_DMA_BTT_OFFSET,
+		  hw->control & XILINX_DMA_MAX_TRANS_LEN);
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static void xilinx_dma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_dma_start_transfer(chan);
+}
+
+/**
+ * xilinx_dma_update_completed_cookie - Update the completed cookie.
+ * @chan : xilinx DMA channel
+ *
+ * CONTEXT: hardirq
+ */
+static void xilinx_dma_update_completed_cookie(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_desc_sw *desc = NULL;
+	struct xilinx_dma_desc_hw *hw = NULL;
+	unsigned long flags;
+	dma_cookie_t cookie = -EBUSY;
+	int done = 0;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	if (list_empty(&chan->active_list)) {
+		dev_dbg(chan->dev, "no running descriptors\n");
+		goto out_unlock;
+	}
+
+	/* Get the last completed descriptor, update the cookie to that */
+	list_for_each_entry(desc, &chan->active_list, node) {
+		if (chan->has_sg) {
+			hw = &desc->hw;
+
+			/* If a BD has no status bits set, hw has it */
+			if (!(hw->status & XILINX_DMA_BD_STS_ALL_MASK)) {
+				break;
+			} else {
+				done = 1;
+				cookie = desc->async_tx.cookie;
+			}
+		} else {
+			/* In non-SG mode, all active entries are done */
+			done = 1;
+			cookie = desc->async_tx.cookie;
+		}
+	}
+
+	if (done)
+		chan->completed_cookie = cookie;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/* Reset hardware */
+static int dma_reset(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_RESET_LOOP;
+	u32 tmp;
+
+	dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+		  dma_read(chan, XILINX_DMA_CONTROL_OFFSET) |
+		  XILINX_DMA_CR_RESET_MASK);
+
+	tmp = dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+	      XILINX_DMA_CR_RESET_MASK;
+
+	/* Wait for the hardware to finish reset */
+	while (loop && tmp) {
+		tmp = dma_read(chan, XILINX_DMA_CONTROL_OFFSET) &
+		      XILINX_DMA_CR_RESET_MASK;
+		loop -= 1;
+	}
+
+	if (!loop) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			dma_read(chan, XILINX_DMA_CONTROL_OFFSET),
+			dma_read(chan, XILINX_DMA_STATUS_OFFSET));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static irqreturn_t dma_intr_handler(int irq, void *data)
+{
+	struct xilinx_dma_chan *chan = data;
+	int update_cookie = 0;
+	int to_transfer = 0;
+	u32 stat, reg;
+
+	reg = dma_read(chan, XILINX_DMA_CONTROL_OFFSET);
+
+	/* Disable intr */
+	dma_write(chan, XILINX_DMA_CONTROL_OFFSET,
+		  reg & ~XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	stat = dma_read(chan, XILINX_DMA_STATUS_OFFSET);
+	if (!(stat & XILINX_DMA_XR_IRQ_ALL_MASK))
+		return IRQ_NONE;
+
+	/* Ack the interrupts */
+	dma_write(chan, XILINX_DMA_STATUS_OFFSET,
+		  XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	/* Check for only the interrupts which are enabled */
+	stat &= (reg & XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	if (stat & XILINX_DMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev,
+			"Channel %x has errors %x, cdr %x tdr %x\n",
+			(unsigned int)chan,
+			(unsigned int)dma_read(chan, XILINX_DMA_STATUS_OFFSET),
+			(unsigned int)dma_read(chan, XILINX_DMA_CDESC_OFFSET),
+			(unsigned int)dma_read(chan, XILINX_DMA_TDESC_OFFSET));
+		chan->err = 1;
+	}
+
+	/*
+	 * Device takes too long to do the transfer when user requires
+	 * responsiveness
+	 */
+	if (stat & XILINX_DMA_XR_IRQ_DELAY_MASK)
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+
+	if (stat & XILINX_DMA_XR_IRQ_IOC_MASK) {
+		update_cookie = 1;
+		to_transfer = 1;
+	}
+
+	if (update_cookie)
+		xilinx_dma_update_completed_cookie(chan);
+
+	if (to_transfer)
+		chan->start_transfer(chan);
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+static void dma_do_tasklet(unsigned long data)
+{
+	struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
+
+	xilinx_chan_desc_cleanup(chan);
+}
+
+/* Append the descriptor list to the pending list */
+static void append_desc_queue(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_desc_sw *desc)
+{
+	struct xilinx_dma_desc_sw *tail =
+		container_of(chan->pending_list.prev,
+			     struct xilinx_dma_desc_sw, node);
+	struct xilinx_dma_desc_hw *hw;
+
+	if (list_empty(&chan->pending_list))
+		goto out_splice;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 */
+	hw = &(tail->hw);
+	hw->next_desc = (u32)desc->async_tx.phys;
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+out_splice:
+	list_splice_tail_init(&desc->tx_list, &chan->pending_list);
+}
+
+/*
+ * Assign cookie to each descriptor, and append the descriptors to the pending
+ * list
+ */
+static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
+	struct xilinx_dma_desc_sw *desc;
+	struct xilinx_dma_desc_sw *child;
+	unsigned long flags;
+	dma_cookie_t cookie = -EBUSY;
+
+	desc = container_of(tx, struct xilinx_dma_desc_sw, async_tx);
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		if (!dma_reset(chan))
+			chan->err = 0;
+		else
+			return cookie;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	/*
+	 * Assign cookies to all of the software descriptors
+	 * that make up this transaction
+	 */
+	cookie = chan->cookie;
+	list_for_each_entry(child, &desc->tx_list, node) {
+		cookie++;
+		if (cookie < 0)
+			cookie = DMA_MIN_COOKIE;
+
+		child->async_tx.cookie = cookie;
+	}
+
+	chan->cookie = cookie;
+
+	/* Put this transaction onto the tail of the pending queue */
+	append_desc_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+static struct
+xilinx_dma_desc_sw *xilinx_dma_alloc_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_desc_sw *desc;
+	dma_addr_t pdesc;
+
+	desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc);
+	if (!desc) {
+		dev_dbg(chan->dev, "out of memory for desc\n");
+		return NULL;
+	}
+
+	memset(desc, 0, sizeof(*desc));
+	INIT_LIST_HEAD(&desc->tx_list);
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_dma_tx_submit;
+	desc->async_tx.phys = pdesc;
+
+	return desc;
+}
+
+/**
+ * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
+ * @chan: DMA channel
+ * @sgl: scatterlist to transfer to/from
+ * @sg_len: number of entries in @scatterlist
+ * @direction: DMA direction
+ * @flags: transfer ack flags
+ */
+static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
+	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction, unsigned long flags,
+	void *context)
+{
+	struct xilinx_dma_chan *chan;
+	struct xilinx_dma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
+	struct xilinx_dma_desc_hw *hw = NULL, *prev_hw = NULL;
+
+	size_t copy;
+
+	int i;
+	struct scatterlist *sg;
+	size_t sg_used;
+	dma_addr_t dma_src;
+
+#ifdef TEST_DMA_WITH_LOOPBACK
+	int total_len;
+#endif
+	if (!dchan)
+		return NULL;
+
+	chan = to_xilinx_chan(dchan);
+
+	if (chan->direction != direction)
+		return NULL;
+
+#ifdef TEST_DMA_WITH_LOOPBACK
+	total_len = 0;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		total_len += sg_dma_len(sg);
+	}
+#endif
+	/* Build transactions using information in the scatter gather list */
+	for_each_sg(sgl, sg, sg_len, i) {
+		sg_used = 0;
+
+		/* Loop until the entire scatterlist entry is used */
+		while (sg_used < sg_dma_len(sg)) {
+
+			/* Allocate the link descriptor from DMA pool */
+			new = xilinx_dma_alloc_descriptor(chan);
+			if (!new) {
+				dev_err(chan->dev,
+					"No free memory for link descriptor\n");
+				goto fail;
+			}
+
+			/*
+			 * Calculate the maximum number of bytes to transfer,
+			 * making sure it is less than the hw limit
+			 */
+			copy = min((size_t)(sg_dma_len(sg) - sg_used),
+				   (size_t)chan->max_len);
+			hw = &(new->hw);
+
+			dma_src = sg_dma_address(sg) + sg_used;
+
+			hw->buf_addr = dma_src;
+
+			/* Fill in the descriptor */
+			hw->control = copy;
+
+			/*
+			 * If this is not the first descriptor, chain the
+			 * current descriptor after the previous descriptor
+			 *
+			 * For the first DMA_MEM_TO_DEV transfer, set SOP
+			 */
+			if (!first) {
+				first = new;
+				if (direction == DMA_MEM_TO_DEV) {
+					hw->control |= XILINX_DMA_BD_SOP;
+#ifdef TEST_DMA_WITH_LOOPBACK
+					hw->app_4 = total_len;
+#endif
+				}
+			} else {
+				prev_hw = &(prev->hw);
+				prev_hw->next_desc = new->async_tx.phys;
+			}
+
+			new->async_tx.cookie = 0;
+			async_tx_ack(&new->async_tx);
+
+			prev = new;
+			sg_used += copy;
+
+			/* Insert the link descriptor into the LD ring */
+			list_add_tail(&new->node, &first->tx_list);
+		}
+	}
+
+	/* Link the last BD with the first BD */
+	hw->next_desc = first->async_tx.phys;
+
+	if (direction == DMA_MEM_TO_DEV)
+		hw->control |= XILINX_DMA_BD_EOP;
+
+	/* All scatter gather list entries has length == 0 */
+	if (!first || !new)
+		return NULL;
+
+	new->async_tx.flags = flags;
+	new->async_tx.cookie = -EBUSY;
+
+	/* Set EOP to the last link descriptor of new list */
+	hw->control |= XILINX_DMA_BD_EOP;
+
+	return &first->async_tx;
+
+fail:
+	/*
+	 * If first was not set, then we failed to allocate the very first
+	 * descriptor, and we're done
+	 */
+	if (!first)
+		return NULL;
+
+	/*
+	 * First is set, so all of the descriptors we allocated have been added
+	 * to first->tx_list, INCLUDING "first" itself. Therefore we
+	 * must traverse the list backwards freeing each descriptor in turn
+	 */
+	xilinx_dma_free_desc_list_reverse(chan, &first->tx_list);
+
+	return NULL;
+}
+
+/* Run-time device configuration for Axi DMA */
+static int xilinx_dma_device_control(struct dma_chan *dchan,
+				     enum dma_ctrl_cmd cmd, unsigned long arg)
+{
+	struct xilinx_dma_chan *chan;
+	unsigned long flags;
+
+	if (!dchan)
+		return -EINVAL;
+
+	chan = to_xilinx_chan(dchan);
+
+	if (cmd == DMA_TERMINATE_ALL) {
+		/* Halt the DMA engine */
+		dma_halt(chan);
+
+		spin_lock_irqsave(&chan->lock, flags);
+
+		/* Remove and free all of the descriptors in the lists */
+		xilinx_dma_free_desc_list(chan, &chan->pending_list);
+		xilinx_dma_free_desc_list(chan, &chan->active_list);
+
+		spin_unlock_irqrestore(&chan->lock, flags);
+		return 0;
+	} else if (cmd == DMA_SLAVE_CONFIG) {
+		/*
+		 * Configure interrupt coalescing and delay counter
+		 * Use value XILINX_DMA_NO_CHANGE to signal no change
+		 */
+		struct xilinx_dma_config *cfg = (struct xilinx_dma_config *)arg;
+		u32 reg = dma_read(chan, XILINX_DMA_CONTROL_OFFSET);
+
+		if (cfg->coalesc <= XILINX_DMA_COALESCE_MAX) {
+			reg &= ~XILINX_DMA_XR_COALESCE_MASK;
+			reg |= cfg->coalesc << XILINX_DMA_COALESCE_SHIFT;
+
+			chan->config.coalesc = cfg->coalesc;
+		}
+
+		if (cfg->delay <= XILINX_DMA_DELAY_MAX) {
+			reg &= ~XILINX_DMA_XR_DELAY_MASK;
+			reg |= cfg->delay << XILINX_DMA_DELAY_SHIFT;
+			chan->config.delay = cfg->delay;
+		}
+
+		dma_write(chan, XILINX_DMA_CONTROL_OFFSET, reg);
+
+		return 0;
+	} else
+		return -ENXIO;
+}
+
+static void xilinx_dma_free_channels(struct xilinx_dma_device *xdev)
+{
+	int i;
+
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) {
+		list_del(&xdev->chan[i]->common.device_node);
+		tasklet_kill(&xdev->chan[i]->tasklet);
+		irq_dispose_mapping(xdev->chan[i]->irq);
+	}
+}
+
+/*
+ * Probing channels
+ *
+ * . Get channel features from the device tree entry
+ * . Initialize special channel handling routines
+ */
+static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
+				 struct device_node *node, u32 feature)
+{
+	struct xilinx_dma_chan *chan;
+	int err;
+	u32 device_id, value, width = 0;
+
+	/* alloc channel */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->feature = feature;
+	chan->max_len = XILINX_DMA_MAX_TRANS_LEN;
+
+	chan->has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (err) {
+		dev_err(xdev->dev, "unable to read datawidth property");
+		return err;
+	} else {
+		width = value >> 3; /* convert bits to bytes */
+
+		/* If data width is greater than 8 bytes, DRE is not in hw */
+		if (width > 8)
+			chan->has_dre = 0;
+
+		chan->feature |= width - 1;
+	}
+
+	err = of_property_read_u32(node, "xlnx,device-id", &device_id);
+	if (err) {
+		dev_err(xdev->dev, "unable to read device id property");
+		return err;
+	}
+
+	chan->has_sg = (xdev->feature & XILINX_DMA_FTR_HAS_SG) >>
+		       XILINX_DMA_FTR_HAS_SG_SHIFT;
+
+	chan->start_transfer = xilinx_dma_start_transfer;
+
+	if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel"))
+		chan->direction = DMA_MEM_TO_DEV;
+
+	if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel"))
+		chan->direction = DMA_DEV_TO_MEM;
+
+	chan->regs = xdev->regs;
+
+	if (chan->direction == DMA_DEV_TO_MEM) {
+		chan->regs = (xdev->regs + XILINX_DMA_RX_CHANNEL_OFFSET);
+		chan->id = 1;
+	}
+
+	/*
+	 * Used by dmatest channel matching in slave transfers
+	 * Can change it to be a structure to have more matching information
+	 */
+	chan->private = (chan->direction & 0xFF) | XILINX_DMA_IP_DMA |
+			(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
+	chan->common.private = (void *)&(chan->private);
+
+	if (!chan->has_dre)
+		xdev->common.copy_align = fls(width - 1);
+
+	chan->dev = xdev->dev;
+	xdev->chan[chan->id] = chan;
+
+	/* Initialize the channel */
+	err = dma_reset(chan);
+	if (err) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->active_list);
+
+	chan->common.device = &xdev->common;
+
+	/* find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = devm_request_irq(xdev->dev, chan->irq, dma_intr_handler,
+			       IRQF_SHARED,
+			       "xilinx-dma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ\n");
+		return err;
+	}
+
+	tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan);
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+
+	return 0;
+}
+
+static int xilinx_dma_probe(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev;
+	struct device_node *child, *node;
+	struct resource *res;
+	int ret;
+	u32 value;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &(pdev->dev);
+	INIT_LIST_HEAD(&xdev->common.channels);
+
+	node = pdev->dev.of_node;
+
+	/* iomap registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Check if SG is enabled */
+	value = of_property_read_bool(node, "xlnx,include-sg");
+	if (value)
+		xdev->feature |= XILINX_DMA_FTR_HAS_SG;
+
+	/* Check if status control streams are enabled */
+	value = of_property_read_bool(node,
+				      "xlnx,sg-include-stscntrl-strm");
+	if (value)
+		xdev->feature |= XILINX_DMA_FTR_STSCNTRL_STRM;
+
+	/* Axi DMA only do slave transfers */
+	dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
+	xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
+	xdev->common.device_control = xilinx_dma_device_control;
+	xdev->common.device_issue_pending = xilinx_dma_issue_pending;
+	xdev->common.device_alloc_chan_resources =
+		xilinx_dma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+		xilinx_dma_free_chan_resources;
+	xdev->common.device_tx_status = xilinx_tx_status;
+	xdev->common.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, xdev);
+
+	for_each_child_of_node(node, child) {
+		ret = xilinx_dma_chan_probe(xdev, child, xdev->feature);
+		if (ret) {
+			dev_err(&pdev->dev, "Probing channels failed\n");
+			goto free_chan_resources;
+		}
+	}
+
+	ret = dma_async_device_register(&xdev->common);
+	if (ret) {
+		dev_err(&pdev->dev, "DMA device registration failed\n");
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "Probing xilinx axi dma engine...Successful\n");
+
+	return 0;
+
+free_chan_resources:
+	xilinx_dma_free_channels(xdev);
+
+	return ret;
+}
+
+static int xilinx_dma_remove(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev;
+
+	xdev = platform_get_drvdata(pdev);
+	dma_async_device_unregister(&xdev->common);
+
+	xilinx_dma_free_channels(xdev);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_dma_of_match[] = {
+	{ .compatible = "xlnx,axi-dma", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
+
+static struct platform_driver xilinx_dma_driver = {
+	.driver = {
+		.name = "xilinx-dma",
+		.owner = THIS_MODULE,
+		.of_match_table = xilinx_dma_of_match,
+	},
+	.probe = xilinx_dma_probe,
+	.remove = xilinx_dma_remove,
+};
+
+module_platform_driver(xilinx_dma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx DMA driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axivdma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/dma/xilinx/xilinx_axivdma.c	2014-07-20 22:06:35.817314609 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * DMA driver for Xilinx Video DMA Engine
+ *
+ * Copyright (C) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ * The AXI Video Direct Memory Access (AXI VDMA) core is a soft Xilinx IP
+ * core that provides high-bandwidth direct memory access between memory
+ * and AXI4-Stream type video target peripherals. The core provides efficient
+ * two dimensional DMA operations with independent asynchronous read (S2MM)
+ * and write (MM2S) channel operation. It can be configured to have either
+ * one channel or two channels. If configured as two channels, one is to
+ * transmit to the video device (MM2S) and another is to receive from the
+ * video device (S2MM). Initialization, status, interrupt and management
+ * registers are accessed through an AXI4-Lite slave interface.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/bitops.h>
+#include <linux/dmapool.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+
+/* Register/Descriptor Offsets */
+#define XILINX_VDMA_MM2S_CTRL_OFFSET		0x0000
+#define XILINX_VDMA_S2MM_CTRL_OFFSET		0x0030
+#define XILINX_VDMA_MM2S_DESC_OFFSET		0x0050
+#define XILINX_VDMA_S2MM_DESC_OFFSET		0x00a0
+
+/* Control Registers */
+#define XILINX_VDMA_REG_DMACR			0x0000
+#define XILINX_VDMA_DMACR_DELAY_MAX		0xff
+#define XILINX_VDMA_DMACR_DELAY_SHIFT		24
+#define XILINX_VDMA_DMACR_FRAME_COUNT_MAX	0xff
+#define XILINX_VDMA_DMACR_FRAME_COUNT_SHIFT	16
+#define XILINX_VDMA_DMACR_ERR_IRQ		(1 << 14)
+#define XILINX_VDMA_DMACR_DLY_CNT_IRQ		(1 << 13)
+#define XILINX_VDMA_DMACR_FRM_CNT_IRQ		(1 << 12)
+#define XILINX_VDMA_DMACR_MASTER_SHIFT		8
+#define XILINX_VDMA_DMACR_FSYNCSRC_SHIFT	5
+#define XILINX_VDMA_DMACR_FRAMECNT_EN		(1 << 4)
+#define XILINX_VDMA_DMACR_GENLOCK_EN		(1 << 3)
+#define XILINX_VDMA_DMACR_RESET			(1 << 2)
+#define XILINX_VDMA_DMACR_CIRC_EN		(1 << 1)
+#define XILINX_VDMA_DMACR_RUNSTOP		(1 << 0)
+#define XILINX_VDMA_DMACR_DELAY_MASK		\
+				(XILINX_VDMA_DMACR_DELAY_MAX << \
+				XILINX_VDMA_DMACR_DELAY_SHIFT)
+#define XILINX_VDMA_DMACR_FRAME_COUNT_MASK	\
+				(XILINX_VDMA_DMACR_FRAME_COUNT_MAX << \
+				XILINX_VDMA_DMACR_FRAME_COUNT_SHIFT)
+#define XILINX_VDMA_DMACR_MASTER_MASK		\
+				(0xf << XILINX_VDMA_DMACR_MASTER_SHIFT)
+#define XILINX_VDMA_DMACR_FSYNCSRC_MASK		\
+				(3 << XILINX_VDMA_DMACR_FSYNCSRC_SHIFT)
+
+#define XILINX_VDMA_REG_DMASR			0x0004
+#define XILINX_VDMA_DMASR_DELAY_SHIFT		24
+#define XILINX_VDMA_DMASR_FRAME_COUNT_SHIFT	16
+#define XILINX_VDMA_DMASR_EOL_LATE_ERR		(1 << 15)
+#define XILINX_VDMA_DMASR_ERR_IRQ		(1 << 14)
+#define XILINX_VDMA_DMASR_DLY_CNT_IRQ		(1 << 13)
+#define XILINX_VDMA_DMASR_FRM_CNT_IRQ		(1 << 12)
+#define XILINX_VDMA_DMASR_SOF_LATE_ERR		(1 << 11)
+#define XILINX_VDMA_DMASR_SG_DEC_ERR		(1 << 10)
+#define XILINX_VDMA_DMASR_SG_SLV_ERR		(1 << 9)
+#define XILINX_VDMA_DMASR_EOF_EARLY_ERR		(1 << 8)
+#define XILINX_VDMA_DMASR_SOF_EARLY_ERR		(1 << 7)
+#define XILINX_VDMA_DMASR_DMA_DEC_ERR		(1 << 6)
+#define XILINX_VDMA_DMASR_DMA_SLAVE_ERR		(1 << 5)
+#define XILINX_VDMA_DMASR_DMA_INT_ERR		(1 << 4)
+#define XILINX_VDMA_DMASR_IDLE			(1 << 1)
+#define XILINX_VDMA_DMASR_HALTED		(1 << 0)
+#define XILINX_VDMA_DMASR_DELAY_MASK		\
+				(0xff << XILINX_VDMA_DMASR_DELAY_SHIFT)
+#define XILINX_VDMA_DMASR_FRAME_COUNT_MASK	\
+				(0xff << XILINX_VDMA_DMASR_FRAME_COUNT_SHIFT)
+
+#define XILINX_VDMA_REG_CURDESC			0x0008
+#define XILINX_VDMA_REG_TAILDESC		0x0010
+#define XILINX_VDMA_REG_REG_INDEX		0x0014
+#define XILINX_VDMA_REG_FRMSTORE		0x0018
+#define XILINX_VDMA_REG_THRESHOLD		0x001c
+#define XILINX_VDMA_REG_FRMPTR_STS		0x0024
+#define XILINX_VDMA_REG_PARK_PTR		0x0028
+#define XILINX_VDMA_PARK_PTR_WR_REF_SHIFT	8
+#define XILINX_VDMA_PARK_PTR_RD_REF_SHIFT	0
+#define XILINX_VDMA_REG_VDMA_VERSION		0x002c
+
+/* Register Direct Mode Registers */
+#define XILINX_VDMA_REG_VSIZE			0x0000
+#define XILINX_VDMA_REG_HSIZE			0x0004
+
+#define XILINX_VDMA_REG_FRMDLY_STRIDE		0x0008
+#define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
+#define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
+#define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_MASK	\
+				(0x1f <<	\
+				XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT)
+#define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_MASK	\
+				(0xffff <<	\
+				XILINX_VDMA_FRMDLY_STRIDE_STRIDE_MASK)
+
+#define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
+
+/* Hw specific definitions */
+#define XILINX_VDMA_MAX_CHANS_PER_DEVICE	0x2
+
+#define XILINX_VDMA_DMAXR_ALL_IRQ_MASK	(XILINX_VDMA_DMASR_FRM_CNT_IRQ | \
+					 XILINX_VDMA_DMASR_DLY_CNT_IRQ | \
+					 XILINX_VDMA_DMASR_ERR_IRQ)
+
+#define XILINX_VDMA_DMASR_ALL_ERR_MASK	(XILINX_VDMA_DMASR_EOL_LATE_ERR | \
+					 XILINX_VDMA_DMASR_SOF_LATE_ERR | \
+					 XILINX_VDMA_DMASR_SG_DEC_ERR | \
+					 XILINX_VDMA_DMASR_SG_SLV_ERR | \
+					 XILINX_VDMA_DMASR_EOF_EARLY_ERR | \
+					 XILINX_VDMA_DMASR_SOF_EARLY_ERR | \
+					 XILINX_VDMA_DMASR_DMA_DEC_ERR | \
+					 XILINX_VDMA_DMASR_DMA_SLAVE_ERR | \
+					 XILINX_VDMA_DMASR_DMA_INT_ERR)
+
+/*
+ * Recoverable errors are DMA Internal error, SOF Early, EOF Early and SOF Late.
+ * They are only recoverable when C_FLUSH_ON_FSYNC is enabled in the h/w system.
+ */
+#define XILINX_VDMA_DMASR_ERR_RECOVER_MASK	\
+					(XILINX_VDMA_DMASR_SOF_LATE_ERR | \
+					 XILINX_VDMA_DMASR_EOF_EARLY_ERR | \
+					 XILINX_VDMA_DMASR_SOF_EARLY_ERR | \
+					 XILINX_VDMA_DMASR_DMA_INT_ERR)
+
+/* Axi VDMA Flush on Fsync bits */
+#define XILINX_VDMA_FLUSH_S2MM			3
+#define XILINX_VDMA_FLUSH_MM2S			2
+#define XILINX_VDMA_FLUSH_BOTH			1
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_VDMA_LOOP_COUNT			1000000
+
+/**
+ * struct xilinx_vdma_desc_hw - Hardware Descriptor
+ * @next_desc: Next Descriptor Pointer @0x00
+ * @pad1: Reserved @0x04
+ * @buf_addr: Buffer address @0x08
+ * @pad2: Reserved @0x0C
+ * @vsize: Vertical Size @0x10
+ * @hsize: Horizontal Size @0x14
+ * @stride: Number of bytes between the first
+ *	    pixels of each horizontal line @0x18
+ */
+struct xilinx_vdma_desc_hw {
+	u32 next_desc;
+	u32 pad1;
+	u32 buf_addr;
+	u32 pad2;
+	u32 vsize;
+	u32 hsize;
+	u32 stride;
+} __aligned(64);
+
+/**
+ * struct xilinx_vdma_tx_segment - Descriptor segment
+ * @hw: Hardware descriptor
+ * @node: Node in the descriptor segments list
+ * @cookie: Segment cookie
+ * @phys: Physical address of segment
+ */
+struct xilinx_vdma_tx_segment {
+	struct xilinx_vdma_desc_hw hw;
+	struct list_head node;
+	dma_cookie_t cookie;
+	dma_addr_t phys;
+} __aligned(64);
+
+/**
+ * struct xilinx_vdma_tx_descriptor - Per Transaction structure
+ * @async_tx: Async transaction descriptor
+ * @segments: TX segments list
+ * @node: Node in the channel descriptors list
+ */
+struct xilinx_vdma_tx_descriptor {
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head segments;
+	struct list_head node;
+};
+
+#define to_vdma_tx_descriptor(tx) \
+	container_of(tx, struct xilinx_vdma_tx_descriptor, async_tx)
+
+/**
+ * struct xilinx_vdma_chan - Driver specific VDMA channel structure
+ * @xdev: Driver specific device structure
+ * @ctrl_offset: Control registers offset
+ * @desc_offset: TX descriptor registers offset
+ * @completed_cookie: Maximum cookie completed
+ * @cookie: The current cookie
+ * @lock: Descriptor operation lock
+ * @pending_list: Descriptors waiting
+ * @active_desc: Active descriptor
+ * @done_list: Complete descriptors
+ * @common: DMA common channel
+ * @desc_pool: Descriptors pool
+ * @dev: The dma device
+ * @irq: Channel IRQ
+ * @id: Channel ID
+ * @direction: Transfer direction
+ * @num_frms: Number of frames
+ * @has_sg: Support scatter transfers
+ * @genlock: Support genlock mode
+ * @err: Channel has errors
+ * @tasklet: Cleanup work after irq
+ * @private: Match info for channel request
+ * @config: Device configuration info
+ * @flush_on_fsync: Flush on Frame sync
+ */
+struct xilinx_vdma_chan {
+	struct xilinx_vdma_device *xdev;
+	u32 ctrl_offset;
+	u32 desc_offset;
+	dma_cookie_t completed_cookie;
+	dma_cookie_t cookie;
+	spinlock_t lock;
+	struct list_head pending_list;
+	struct xilinx_vdma_tx_descriptor *active_desc;
+	struct list_head done_list;
+	struct dma_chan common;
+	struct dma_pool *desc_pool;
+	struct device *dev;
+	int irq;
+	int id;
+	enum dma_transfer_direction direction;
+	int num_frms;
+	bool has_sg;
+	bool genlock;
+	bool err;
+	struct tasklet_struct tasklet;
+	u32 private;
+	struct xilinx_vdma_config config;
+	bool flush_on_fsync;
+};
+
+/**
+ * struct xilinx_vdma_device - VDMA device structure
+ * @regs: I/O mapped base address
+ * @dev: Device Structure
+ * @common: DMA device structure
+ * @chan: Driver specific VDMA channel
+ * @has_sg: Specifies whether Scatter-Gather is present or not
+ * @flush_on_fsync: Flush on frame sync
+ */
+struct xilinx_vdma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_vdma_chan *chan[XILINX_VDMA_MAX_CHANS_PER_DEVICE];
+	bool has_sg;
+	u32 flush_on_fsync;
+};
+
+#define to_xilinx_chan(chan) \
+			container_of(chan, struct xilinx_vdma_chan, common)
+
+/* IO accessors */
+static inline u32 vdma_read(struct xilinx_vdma_chan *chan, u32 reg)
+{
+	return ioread32(chan->xdev->regs + reg);
+}
+
+static inline void vdma_write(struct xilinx_vdma_chan *chan, u32 reg, u32 value)
+{
+	iowrite32(value, chan->xdev->regs + reg);
+}
+
+static inline void vdma_desc_write(struct xilinx_vdma_chan *chan, u32 reg,
+				   u32 value)
+{
+	vdma_write(chan, chan->desc_offset + reg, value);
+}
+
+static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32 reg)
+{
+	return vdma_read(chan, chan->ctrl_offset + reg);
+}
+
+static inline void vdma_ctrl_write(struct xilinx_vdma_chan *chan, u32 reg,
+				   u32 value)
+{
+	vdma_write(chan, chan->ctrl_offset + reg, value);
+}
+
+static inline void vdma_ctrl_clr(struct xilinx_vdma_chan *chan, u32 reg,
+				 u32 clr)
+{
+	vdma_ctrl_write(chan, reg, vdma_ctrl_read(chan, reg) & ~clr);
+}
+
+static inline void vdma_ctrl_set(struct xilinx_vdma_chan *chan, u32 reg,
+				 u32 set)
+{
+	vdma_ctrl_write(chan, reg, vdma_ctrl_read(chan, reg) | set);
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors and segments alloc and free
+ */
+
+/**
+ * xilinx_vdma_alloc_tx_segment - Allocate transaction segment
+ * @chan: Driver specific VDMA channel
+ *
+ * Return the allocated segment on success and NULL on failure.
+ */
+static struct xilinx_vdma_tx_segment *
+xilinx_vdma_alloc_tx_segment(struct xilinx_vdma_chan *chan)
+{
+	struct xilinx_vdma_tx_segment *segment;
+	dma_addr_t phys;
+
+	segment = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &phys);
+	if (!segment)
+		return NULL;
+
+	memset(segment, 0, sizeof(*segment));
+	segment->phys = phys;
+
+	return segment;
+}
+
+/**
+ * xilinx_vdma_free_tx_segment - Free transaction segment
+ * @chan: Driver specific VDMA channel
+ * @segment: VDMA transaction segment
+ */
+static void xilinx_vdma_free_tx_segment(struct xilinx_vdma_chan *chan,
+					struct xilinx_vdma_tx_segment *segment)
+{
+	dma_pool_free(chan->desc_pool, segment, segment->phys);
+}
+
+/**
+ * xilinx_vdma_tx_descriptor - Allocate transaction descriptor
+ * @chan: Driver specific VDMA channel
+ *
+ * Return the allocated descriptor on success and NULL on failure.
+ */
+static struct xilinx_vdma_tx_descriptor *
+xilinx_vdma_alloc_tx_descriptor(struct xilinx_vdma_chan *chan)
+{
+	struct xilinx_vdma_tx_descriptor *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return NULL;
+
+	INIT_LIST_HEAD(&desc->segments);
+
+	return desc;
+}
+
+/**
+ * xilinx_vdma_free_tx_descriptor - Free transaction descriptor
+ * @chan: Driver specific VDMA channel
+ * @desc: VDMA transaction descriptor
+ */
+static void
+xilinx_vdma_free_tx_descriptor(struct xilinx_vdma_chan *chan,
+			       struct xilinx_vdma_tx_descriptor *desc)
+{
+	struct xilinx_vdma_tx_segment *segment, *next;
+
+	if (!desc)
+		return;
+
+	list_for_each_entry_safe(segment, next, &desc->segments, node) {
+		list_del(&segment->node);
+		xilinx_vdma_free_tx_segment(chan, segment);
+	}
+
+	kfree(desc);
+}
+
+/* Required functions */
+
+/**
+ * xilinx_vdma_free_descriptors - Free descriptors list
+ * @chan: Driver specific VDMA channel
+ * @list: List to parse and delete the descriptor
+ */
+static void xilinx_vdma_free_desc_list(struct xilinx_vdma_chan *chan,
+					struct list_head *list)
+{
+	struct xilinx_vdma_tx_descriptor *desc, *next;
+
+	list_for_each_entry_safe(desc, next, list, node) {
+		list_del(&desc->node);
+		xilinx_vdma_free_tx_descriptor(chan, desc);
+	}
+}
+
+/**
+ * xilinx_vdma_free_descriptors - Free channel descriptors
+ * @chan: Driver specific VDMA channel
+ */
+static void xilinx_vdma_free_descriptors(struct xilinx_vdma_chan *chan)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	xilinx_vdma_free_desc_list(chan, &chan->pending_list);
+	xilinx_vdma_free_desc_list(chan, &chan->done_list);
+
+	xilinx_vdma_free_tx_descriptor(chan, chan->active_desc);
+	chan->active_desc = NULL;
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_vdma_free_chan_resources - Free channel resources
+ * @dchan: DMA channel
+ */
+static void xilinx_vdma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+
+	dev_dbg(chan->dev, "Free all channel resources.\n");
+
+	tasklet_kill(&chan->tasklet);
+	xilinx_vdma_free_descriptors(chan);
+	dma_pool_destroy(chan->desc_pool);
+	chan->desc_pool = NULL;
+}
+
+/**
+ * xilinx_vdma_chan_desc_cleanup - Clean channel descriptors
+ * @chan: Driver specific VDMA channel
+ */
+static void xilinx_vdma_chan_desc_cleanup(struct xilinx_vdma_chan *chan)
+{
+	struct xilinx_vdma_tx_descriptor *desc, *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	list_for_each_entry_safe(desc, next, &chan->done_list, node) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		xilinx_vdma_free_tx_descriptor(chan, desc);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_vdma_do_tasklet - Schedule completion tasklet
+ * @data: Pointer to the Xilinx VDMA channel structure
+ */
+static void xilinx_vdma_do_tasklet(unsigned long data)
+{
+	struct xilinx_vdma_chan *chan = (struct xilinx_vdma_chan *)data;
+
+	xilinx_vdma_chan_desc_cleanup(chan);
+}
+
+/**
+ * xilinx_vdma_alloc_chan_resources - Allocate channel resources
+ * @dchan: DMA channel
+ *
+ * Returns '1' on success and failure value on error
+ */
+static int xilinx_vdma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Has this channel already been allocated? */
+	if (chan->desc_pool)
+		return 1;
+
+	/*
+	 * We need the descriptor to be aligned to 64bytes
+	 * for meeting Xilinx VDMA specification requirement.
+	 */
+	chan->desc_pool = dma_pool_create("xilinx_vdma_desc_pool",
+				chan->dev,
+				sizeof(struct xilinx_vdma_tx_segment),
+				__alignof__(struct xilinx_vdma_tx_segment), 0);
+	if (!chan->desc_pool) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptor pool\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	tasklet_init(&chan->tasklet, xilinx_vdma_do_tasklet,
+			(unsigned long)chan);
+
+	chan->completed_cookie = DMA_MIN_COOKIE;
+	chan->cookie = DMA_MIN_COOKIE;
+
+	/* There is at least one descriptor free to be allocated */
+	return 1;
+}
+
+/**
+ * xilinx_vdma_tx_status - Get VDMA transaction status
+ * @dchan: DMA channel
+ * @cookie: Transaction identifier
+ * @txstate: Transaction state
+ *
+ * Returns DMA transaction status
+ */
+static enum dma_status xilinx_vdma_tx_status(struct dma_chan *dchan,
+					dma_cookie_t cookie,
+					struct dma_tx_state *txstate)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+
+	xilinx_vdma_chan_desc_cleanup(chan);
+
+	last_used = dchan->cookie;
+	last_complete = chan->completed_cookie;
+
+	dma_set_tx_state(txstate, last_complete, last_used, 0);
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/**
+ * xilinx_vdma_is_running - Check if VDMA channel is running
+ * @chan: Driver specific VDMA channel
+ *
+ * Returns '1' if running, '0' if not.
+ */
+static int xilinx_vdma_is_running(struct xilinx_vdma_chan *chan)
+{
+	return !(vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) &
+		 XILINX_VDMA_DMASR_HALTED) &&
+		(vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR) &
+		 XILINX_VDMA_DMACR_RUNSTOP);
+}
+
+/**
+ * xilinx_vdma_is_idle - Check if VDMA channel is idle
+ * @chan: Driver specific VDMA channel
+ *
+ * Returns '1' if idle, '0' if not.
+ */
+static int xilinx_vdma_is_idle(struct xilinx_vdma_chan *chan)
+{
+	return vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) &
+		XILINX_VDMA_DMASR_IDLE;
+}
+
+/**
+ * xilinx_vdma_halt - Halt VDMA channel
+ * @chan: Driver specific VDMA channel
+ */
+static void xilinx_vdma_halt(struct xilinx_vdma_chan *chan)
+{
+	int loop = XILINX_VDMA_LOOP_COUNT + 1;
+
+	vdma_ctrl_clr(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP);
+
+	/* Wait for the hardware to halt */
+	while (loop--)
+		if (vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) &
+		    XILINX_VDMA_DMASR_HALTED)
+			break;
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot stop channel %p: %x\n",
+			chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR));
+		chan->err = true;
+	}
+
+	return;
+}
+
+/**
+ * xilinx_vdma_start - Start VDMA channel
+ * @chan: Driver specific VDMA channel
+ */
+static void xilinx_vdma_start(struct xilinx_vdma_chan *chan)
+{
+	int loop = XILINX_VDMA_LOOP_COUNT + 1;
+
+	vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP);
+
+	/* Wait for the hardware to start */
+	while (loop)
+		if (!(vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) &
+		      XILINX_VDMA_DMASR_HALTED))
+			break;
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot start channel %p: %x\n",
+			chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR));
+
+		chan->err = true;
+	}
+
+	return;
+}
+
+/**
+ * xilinx_vdma_start_transfer - Starts VDMA transfer
+ * @chan: Driver specific channel struct pointer
+ */
+static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan)
+{
+	struct xilinx_vdma_config *config = &chan->config;
+	struct xilinx_vdma_tx_descriptor *desc;
+	unsigned long flags;
+	u32 reg;
+	struct xilinx_vdma_tx_segment *head, *tail = NULL;
+
+	if (chan->err)
+		return;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	/* There's already an active descriptor, bail out. */
+	if (chan->active_desc)
+		goto out_unlock;
+
+	if (list_empty(&chan->pending_list))
+		goto out_unlock;
+
+	desc = list_first_entry(&chan->pending_list,
+				struct xilinx_vdma_tx_descriptor, node);
+
+	/* If it is SG mode and hardware is busy, cannot submit */
+	if (chan->has_sg && xilinx_vdma_is_running(chan) &&
+	    !xilinx_vdma_is_idle(chan)) {
+		dev_dbg(chan->dev, "DMA controller still busy\n");
+		goto out_unlock;
+	}
+
+	if (chan->err)
+		goto out_unlock;
+
+	/*
+	 * If hardware is idle, then all descriptors on the running lists are
+	 * done, start new transfers
+	 */
+	if (chan->has_sg) {
+		head = list_first_entry(&desc->segments,
+					struct xilinx_vdma_tx_segment, node);
+		tail = list_entry(desc->segments.prev,
+				  struct xilinx_vdma_tx_segment, node);
+
+		vdma_ctrl_write(chan, XILINX_VDMA_REG_CURDESC, head->phys);
+	}
+
+	/* Configure the hardware using info in the config structure */
+	reg = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR);
+
+	if (config->frm_cnt_en)
+		reg |= XILINX_VDMA_DMACR_FRAMECNT_EN;
+	else
+		reg &= ~XILINX_VDMA_DMACR_FRAMECNT_EN;
+
+	/*
+	 * With SG, start with circular mode, so that BDs can be fetched.
+	 * In direct register mode, if not parking, enable circular mode
+	 */
+	if (chan->has_sg || !config->park)
+		reg |= XILINX_VDMA_DMACR_CIRC_EN;
+
+	if (config->park)
+		reg &= ~XILINX_VDMA_DMACR_CIRC_EN;
+
+	vdma_ctrl_write(chan, XILINX_VDMA_REG_DMACR, reg);
+
+	if (config->park && (config->park_frm >= 0) &&
+			(config->park_frm < chan->num_frms)) {
+		if (chan->direction == DMA_MEM_TO_DEV)
+			vdma_write(chan, XILINX_VDMA_REG_PARK_PTR,
+				config->park_frm <<
+					XILINX_VDMA_PARK_PTR_RD_REF_SHIFT);
+		else
+			vdma_write(chan, XILINX_VDMA_REG_PARK_PTR,
+				config->park_frm <<
+					XILINX_VDMA_PARK_PTR_WR_REF_SHIFT);
+	}
+
+	/* Start the hardware */
+	xilinx_vdma_start(chan);
+
+	if (chan->err)
+		goto out_unlock;
+
+	/* Start the transfer */
+	if (chan->has_sg) {
+		vdma_ctrl_write(chan, XILINX_VDMA_REG_TAILDESC, tail->phys);
+	} else {
+		struct xilinx_vdma_tx_segment *segment;
+		int i = 0;
+
+		list_for_each_entry(segment, &desc->segments, node)
+			vdma_desc_write(chan,
+					XILINX_VDMA_REG_START_ADDRESS(i++),
+					segment->hw.buf_addr);
+
+		vdma_desc_write(chan, XILINX_VDMA_REG_HSIZE, config->hsize);
+		vdma_desc_write(chan, XILINX_VDMA_REG_FRMDLY_STRIDE,
+				(config->frm_dly <<
+				 XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT) |
+				(config->stride <<
+				 XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT));
+		vdma_desc_write(chan, XILINX_VDMA_REG_VSIZE, config->vsize);
+	}
+
+	list_del(&desc->node);
+	chan->active_desc = desc;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_vdma_issue_pending - Issue pending transactions
+ * @dchan: DMA channel
+ */
+static void xilinx_vdma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_vdma_start_transfer(chan);
+}
+
+/**
+ * xilinx_vdma_complete_descriptor - Mark the active descriptor as complete
+ * @chan : xilinx DMA channel
+ *
+ * CONTEXT: hardirq
+ */
+static void xilinx_vdma_complete_descriptor(struct xilinx_vdma_chan *chan)
+{
+	struct xilinx_vdma_tx_descriptor *desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	desc = chan->active_desc;
+	if (!desc) {
+		dev_dbg(chan->dev, "no running descriptors\n");
+		goto out_unlock;
+	}
+
+	list_add_tail(&desc->node, &chan->done_list);
+
+	/* Update the completed cookie and reset the active descriptor. */
+	chan->completed_cookie = desc->async_tx.cookie;
+	chan->active_desc = NULL;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_vdma_reset - Reset VDMA channel
+ * @chan: Driver specific VDMA channel
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_reset(struct xilinx_vdma_chan *chan)
+{
+	int loop = XILINX_VDMA_LOOP_COUNT + 1;
+	u32 tmp;
+
+	vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RESET);
+
+	tmp = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR) &
+		XILINX_VDMA_DMACR_RESET;
+
+	/* Wait for the hardware to finish reset */
+	while (loop-- && tmp)
+		tmp = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR) &
+			XILINX_VDMA_DMACR_RESET;
+
+	if (!loop) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR),
+			vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR));
+		return -ETIMEDOUT;
+	}
+
+	chan->err = false;
+
+	return 0;
+}
+
+/**
+ * xilinx_vdma_chan_reset - Reset VDMA channel and enable interrupts
+ * @chan: Driver specific VDMA channel
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_chan_reset(struct xilinx_vdma_chan *chan)
+{
+	int err;
+
+	/* Reset VDMA */
+	err = xilinx_vdma_reset(chan);
+	if (err)
+		return err;
+
+	/* Enable interrupts */
+	vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR,
+		      XILINX_VDMA_DMAXR_ALL_IRQ_MASK);
+
+	return 0;
+}
+
+/**
+ * xilinx_vdma_irq_handler - VDMA Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the Xilinx VDMA channel structure
+ *
+ * Returns IRQ_HANDLED/IRQ_NONE
+ */
+static irqreturn_t xilinx_vdma_irq_handler(int irq, void *data)
+{
+	struct xilinx_vdma_chan *chan = data;
+	u32 status;
+
+	/* Read the status and ack the interrupts. */
+	status = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR);
+	if (!(status & XILINX_VDMA_DMAXR_ALL_IRQ_MASK))
+		return IRQ_NONE;
+
+	vdma_ctrl_write(chan, XILINX_VDMA_REG_DMASR,
+			status & XILINX_VDMA_DMAXR_ALL_IRQ_MASK);
+
+	if (status & XILINX_VDMA_DMASR_ERR_IRQ) {
+		/*
+		 * An error occurred. If C_FLUSH_ON_FSYNC is enabled and the
+		 * error is recoverable, ignore it. Otherwise flag the error.
+		 *
+		 * Only recoverable errors can be cleared in the DMASR register,
+		 * make sure not to write to other error bits to 1.
+		 */
+		u32 errors = status & XILINX_VDMA_DMASR_ALL_ERR_MASK;
+		vdma_ctrl_write(chan, XILINX_VDMA_REG_DMASR,
+				errors & XILINX_VDMA_DMASR_ERR_RECOVER_MASK);
+
+		if (!chan->flush_on_fsync ||
+		    (errors & ~XILINX_VDMA_DMASR_ERR_RECOVER_MASK)) {
+			dev_err(chan->dev,
+				"Channel %p has errors %x, cdr %x tdr %x\n",
+				chan, errors,
+				vdma_ctrl_read(chan, XILINX_VDMA_REG_CURDESC),
+				vdma_ctrl_read(chan, XILINX_VDMA_REG_TAILDESC));
+			chan->err = 1;
+		}
+	}
+
+	if (status & XILINX_VDMA_DMASR_DLY_CNT_IRQ) {
+		/*
+		 * Device takes too long to do the transfer when user requires
+		 * responsiveness.
+		 */
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+	}
+
+	if (status & XILINX_VDMA_DMASR_FRM_CNT_IRQ) {
+		xilinx_vdma_complete_descriptor(chan);
+		xilinx_vdma_start_transfer(chan);
+	}
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xilinx_vdma_tx_submit - Submit DMA transaction
+ * @tx: Async transaction descriptor
+ *
+ * Returns cookie value on success and failure value on error
+ */
+static dma_cookie_t xilinx_vdma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_vdma_tx_descriptor *desc = to_vdma_tx_descriptor(tx);
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(tx->chan);
+	struct xilinx_vdma_tx_segment *segment;
+	dma_cookie_t cookie;
+	unsigned long flags;
+	int err;
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		err = xilinx_vdma_chan_reset(chan);
+		if (err < 0)
+			return err;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	/* Assign cookies to all of the segments that make up this transaction.
+	 * Use the cookie of the last segment as the transaction cookie.
+	 */
+	cookie = chan->cookie;
+
+	list_for_each_entry(segment, &desc->segments, node) {
+		if (cookie < DMA_MAX_COOKIE)
+			cookie++;
+		else
+			cookie = DMA_MIN_COOKIE;
+
+		segment->cookie = cookie;
+	}
+
+	tx->cookie = cookie;
+	chan->cookie = cookie;
+
+	/* Append the transaction to the pending transactions queue. */
+	list_add_tail(&desc->node, &chan->pending_list);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+/**
+ * xilinx_vdma_prep_slave_sg - prepare a descriptor for a DMA_SLAVE transaction
+ * @dchan: DMA channel
+ * @sgl: scatterlist to transfer to/from
+ * @sg_len: number of entries in @sgl
+ * @dir: DMA direction
+ * @flags: transfer ack flags
+ * @context: unused
+ */
+static struct dma_async_tx_descriptor *
+xilinx_vdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
+			  unsigned int sg_len, enum dma_transfer_direction dir,
+			  unsigned long flags, void *context)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_vdma_tx_descriptor *desc;
+	struct xilinx_vdma_tx_segment *segment;
+	struct xilinx_vdma_tx_segment *prev = NULL;
+	struct scatterlist *sg;
+	int i;
+
+	if (chan->direction != dir || sg_len == 0)
+		return NULL;
+
+	/* Enforce one sg entry for one frame. */
+	if (sg_len != chan->num_frms) {
+		dev_err(chan->dev,
+		"number of entries %d not the same as num stores %d\n",
+			sg_len, chan->num_frms);
+		return NULL;
+	}
+
+	/* Allocate a transaction descriptor. */
+	desc = xilinx_vdma_alloc_tx_descriptor(chan);
+	if (!desc)
+		return NULL;
+
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_vdma_tx_submit;
+	desc->async_tx.cookie = 0;
+	async_tx_ack(&desc->async_tx);
+
+	/* Build the list of transaction segments. */
+	for_each_sg(sgl, sg, sg_len, i) {
+		struct xilinx_vdma_desc_hw *hw;
+
+		/* Allocate the link descriptor from DMA pool */
+		segment = xilinx_vdma_alloc_tx_segment(chan);
+		if (!segment)
+			goto error;
+
+		/* Fill in the hardware descriptor */
+		hw = &segment->hw;
+		hw->buf_addr = sg_dma_address(sg);
+		hw->vsize = chan->config.vsize;
+		hw->hsize = chan->config.hsize;
+		hw->stride = (chan->config.frm_dly <<
+			      XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT) |
+			     (chan->config.stride <<
+			      XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT);
+		if (prev)
+			prev->hw.next_desc = segment->phys;
+
+		/* Insert the segment into the descriptor segments list. */
+		list_add_tail(&segment->node, &desc->segments);
+
+		prev = segment;
+	}
+
+	/* Link the last hardware descriptor with the first. */
+	segment = list_first_entry(&desc->segments,
+				   struct xilinx_vdma_tx_segment, node);
+	prev->hw.next_desc = segment->phys;
+
+	return &desc->async_tx;
+
+error:
+	xilinx_vdma_free_tx_descriptor(chan, desc);
+	return NULL;
+}
+
+/**
+ * xilinx_vdma_terminate_all - Halt the channel and free descriptors
+ * @chan: Driver specific VDMA Channel pointer
+ */
+static void xilinx_vdma_terminate_all(struct xilinx_vdma_chan *chan)
+{
+	/* Halt the DMA engine */
+	xilinx_vdma_halt(chan);
+
+	/* Remove and free all of the descriptors in the lists */
+	xilinx_vdma_free_descriptors(chan);
+}
+
+/**
+ * xilinx_vdma_slave_config - Configure VDMA channel
+ * Run-time configuration for Axi VDMA, supports:
+ * . halt the channel
+ * . configure interrupt coalescing and inter-packet delay threshold
+ * . start/stop parking
+ * . enable genlock
+ * . set transfer information using config struct
+ *
+ * @chan: Driver specific VDMA Channel pointer
+ * @cfg: Channel configuration pointer
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_slave_config(struct xilinx_vdma_chan *chan,
+				    struct xilinx_vdma_config *cfg)
+{
+	u32 dmacr;
+
+	if (cfg->reset)
+		return xilinx_vdma_chan_reset(chan);
+
+	dmacr = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR);
+
+	/* If vsize is -1, it is park-related operations */
+	if (cfg->vsize == -1) {
+		if (cfg->park)
+			dmacr &= ~XILINX_VDMA_DMACR_CIRC_EN;
+		else
+			dmacr |= XILINX_VDMA_DMACR_CIRC_EN;
+
+		vdma_ctrl_write(chan, XILINX_VDMA_REG_DMACR, dmacr);
+		return 0;
+	}
+
+	/* If hsize is -1, it is interrupt threshold settings */
+	if (cfg->hsize == -1) {
+		if (cfg->coalesc <= XILINX_VDMA_DMACR_FRAME_COUNT_MAX) {
+			dmacr &= ~XILINX_VDMA_DMACR_FRAME_COUNT_MASK;
+			dmacr |= cfg->coalesc <<
+				 XILINX_VDMA_DMACR_FRAME_COUNT_SHIFT;
+			chan->config.coalesc = cfg->coalesc;
+		}
+
+		if (cfg->delay <= XILINX_VDMA_DMACR_DELAY_MAX) {
+			dmacr &= ~XILINX_VDMA_DMACR_DELAY_MASK;
+			dmacr |= cfg->delay << XILINX_VDMA_DMACR_DELAY_SHIFT;
+			chan->config.delay = cfg->delay;
+		}
+
+		vdma_ctrl_write(chan, XILINX_VDMA_REG_DMACR, dmacr);
+		return 0;
+	}
+
+	/* Transfer information */
+	chan->config.vsize = cfg->vsize;
+	chan->config.hsize = cfg->hsize;
+	chan->config.stride = cfg->stride;
+	chan->config.frm_dly = cfg->frm_dly;
+	chan->config.park = cfg->park;
+
+	/* genlock settings */
+	chan->config.gen_lock = cfg->gen_lock;
+	chan->config.master = cfg->master;
+
+	if (cfg->gen_lock && chan->genlock) {
+		dmacr |= XILINX_VDMA_DMACR_GENLOCK_EN;
+		dmacr |= cfg->master << XILINX_VDMA_DMACR_MASTER_SHIFT;
+	}
+
+	chan->config.frm_cnt_en = cfg->frm_cnt_en;
+	if (cfg->park)
+		chan->config.park_frm = cfg->park_frm;
+	else
+		chan->config.park_frm = -1;
+
+	chan->config.coalesc = cfg->coalesc;
+	chan->config.delay = cfg->delay;
+	if (cfg->coalesc <= XILINX_VDMA_DMACR_FRAME_COUNT_MAX) {
+		dmacr |= cfg->coalesc << XILINX_VDMA_DMACR_FRAME_COUNT_SHIFT;
+		chan->config.coalesc = cfg->coalesc;
+	}
+
+	if (cfg->delay <= XILINX_VDMA_DMACR_DELAY_MAX) {
+		dmacr |= cfg->delay << XILINX_VDMA_DMACR_DELAY_SHIFT;
+		chan->config.delay = cfg->delay;
+	}
+
+	/* FSync Source selection */
+	dmacr &= ~XILINX_VDMA_DMACR_FSYNCSRC_MASK;
+	dmacr |= cfg->ext_fsync << XILINX_VDMA_DMACR_FSYNCSRC_SHIFT;
+
+	vdma_ctrl_write(chan, XILINX_VDMA_REG_DMACR, dmacr);
+	return 0;
+}
+
+/**
+ * xilinx_vdma_device_control - Configure DMA channel of the device
+ * @dchan: DMA Channel pointer
+ * @cmd: DMA control command
+ * @arg: Channel configuration
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_device_control(struct dma_chan *dchan,
+				      enum dma_ctrl_cmd cmd, unsigned long arg)
+{
+	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		xilinx_vdma_terminate_all(chan);
+		return 0;
+	case DMA_SLAVE_CONFIG:
+		return xilinx_vdma_slave_config(chan,
+					(struct xilinx_vdma_config *)arg);
+	default:
+		return -ENXIO;
+	}
+}
+
+/* -----------------------------------------------------------------------------
+ * Probe and remove
+ */
+
+/**
+ * xilinx_vdma_chan_remove - Per Channel remove function
+ * @chan: Driver specific VDMA channel
+ */
+static void xilinx_vdma_chan_remove(struct xilinx_vdma_chan *chan)
+{
+	/* Disable all interrupts */
+	vdma_ctrl_clr(chan, XILINX_VDMA_REG_DMACR,
+		      XILINX_VDMA_DMAXR_ALL_IRQ_MASK);
+
+	list_del(&chan->common.device_node);
+}
+
+/**
+ * xilinx_vdma_chan_probe - Per Channel Probing
+ * It get channel features from the device tree entry and
+ * initialize special channel handling routines
+ *
+ * @xdev: Driver specific device structure
+ * @node: Device node
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_chan_probe(struct xilinx_vdma_device *xdev,
+				  struct device_node *node)
+{
+	struct xilinx_vdma_chan *chan;
+	bool has_dre = false;
+	u32 device_id;
+	u32 value;
+	int err;
+
+	/* Allocate and initialize the channel structure */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->dev = xdev->dev;
+	chan->xdev = xdev;
+	chan->has_sg = xdev->has_sg;
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->done_list);
+
+	/* Retrieve the channel properties from the device tree */
+	has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (!err) {
+		u32 width = value >> 3; /* Convert bits to bytes */
+
+		/* If data width is greater than 8 bytes, DRE is not in hw */
+		if (width > 8)
+			has_dre = false;
+
+		if (!has_dre)
+			xdev->common.copy_align = fls(width - 1);
+	}
+
+	err = of_property_read_u32(node, "xlnx,device-id", &device_id);
+	if (err < 0) {
+		dev_err(xdev->dev, "missing xlnx,device-id property\n");
+		return err;
+	}
+
+	if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel")) {
+		chan->direction = DMA_MEM_TO_DEV;
+		chan->id = 0;
+
+		chan->ctrl_offset = XILINX_VDMA_MM2S_CTRL_OFFSET;
+		chan->desc_offset = XILINX_VDMA_MM2S_DESC_OFFSET;
+
+		if (xdev->flush_on_fsync == XILINX_VDMA_FLUSH_BOTH ||
+		    xdev->flush_on_fsync == XILINX_VDMA_FLUSH_MM2S)
+			chan->flush_on_fsync = true;
+	} else if (of_device_is_compatible(node,
+					    "xlnx,axi-vdma-s2mm-channel")) {
+		chan->direction = DMA_DEV_TO_MEM;
+		chan->id = 1;
+
+		chan->ctrl_offset = XILINX_VDMA_S2MM_CTRL_OFFSET;
+		chan->desc_offset = XILINX_VDMA_S2MM_DESC_OFFSET;
+
+		if (xdev->flush_on_fsync == XILINX_VDMA_FLUSH_BOTH ||
+		    xdev->flush_on_fsync == XILINX_VDMA_FLUSH_S2MM)
+			chan->flush_on_fsync = true;
+	} else {
+		dev_err(xdev->dev, "Invalid channel compatible node\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Used by DMA clients who doesnt have a device node and can request
+	 * the channel by passing this as a filter to 'dma_request_channel()'.
+	 */
+	chan->private = (chan->direction & 0xff) |
+			XILINX_DMA_IP_VDMA |
+			(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
+
+	/* Request the interrupt */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = devm_request_irq(xdev->dev, chan->irq, xilinx_vdma_irq_handler,
+			       IRQF_SHARED, "xilinx-vdma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ\n");
+		return err;
+	}
+
+	/* Initialize the DMA channel and add it to the DMA engine channels
+	 * list.
+	 */
+	chan->common.device = &xdev->common;
+	chan->common.private = (void *)&(chan->private);
+
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+	xdev->chan[chan->id] = chan;
+
+	/* Reset the channel */
+	err = xilinx_vdma_chan_reset(chan);
+	if (err < 0) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	return 0;
+}
+
+/**
+ * struct of_dma_filter_xilinx_args - Channel filter args
+ * @dev: DMA device structure
+ * @chan_id: Channel id
+ */
+struct of_dma_filter_xilinx_args {
+	struct dma_device *dev;
+	u32 chan_id;
+};
+
+/**
+ * xilinx_vdma_dt_filter - VDMA channel filter function
+ * @chan: DMA channel pointer
+ * @param: Filter match value
+ *
+ * Returns true/false based on the result
+ */
+static bool xilinx_vdma_dt_filter(struct dma_chan *chan, void *param)
+{
+	struct of_dma_filter_xilinx_args *args = param;
+
+	return chan->device == args->dev && chan->chan_id == args->chan_id;
+}
+
+/**
+ * of_dma_xilinx_xlate - Translation function
+ * @dma_spec: Pointer to DMA specifier as found in the device tree
+ * @ofdma: Pointer to DMA controller data
+ *
+ * Returns DMA channel pointer on success and NULL on error
+ */
+static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
+						struct of_dma *ofdma)
+{
+	struct of_dma_filter_xilinx_args args;
+	dma_cap_mask_t cap;
+
+	args.dev = ofdma->of_dma_data;
+	if (!args.dev)
+		return NULL;
+
+	if (dma_spec->args_count != 1)
+		return NULL;
+
+	dma_cap_zero(cap);
+	dma_cap_set(DMA_SLAVE, cap);
+
+	args.chan_id = dma_spec->args[0];
+
+	return dma_request_channel(cap, xilinx_vdma_dt_filter, &args);
+}
+
+/**
+ * xilinx_vdma_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xilinx_vdma_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct xilinx_vdma_device *xdev;
+	struct device_node *child;
+	struct resource *io;
+	int num_frames, i, err;
+
+	dev_info(&pdev->dev, "Probing xilinx axi vdma engine\n");
+
+	/* Allocate and initialize the DMA engine structure */
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &pdev->dev;
+
+	/* Request and map I/O memory */
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, io);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Retrieve the DMA engine properties from the device tree */
+	xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
+
+	err = of_property_read_u32(node, "xlnx,num-fstores", &num_frames);
+	if (err < 0) {
+		dev_err(xdev->dev, "missing xlnx,num-fstores property\n");
+		return err;
+	}
+
+	of_property_read_u32(node, "xlnx,flush-fsync", &xdev->flush_on_fsync);
+
+	/* Initialize the DMA engine */
+	xdev->common.dev = &pdev->dev;
+
+	INIT_LIST_HEAD(&xdev->common.channels);
+	dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
+
+	xdev->common.device_alloc_chan_resources =
+				xilinx_vdma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+				xilinx_vdma_free_chan_resources;
+	xdev->common.device_prep_slave_sg = xilinx_vdma_prep_slave_sg;
+	xdev->common.device_control = xilinx_vdma_device_control;
+	xdev->common.device_tx_status = xilinx_vdma_tx_status;
+	xdev->common.device_issue_pending = xilinx_vdma_issue_pending;
+
+	platform_set_drvdata(pdev, xdev);
+
+	/* Initialize the channels */
+	for_each_child_of_node(node, child) {
+		err = xilinx_vdma_chan_probe(xdev, child);
+		if (err < 0)
+			goto error;
+	}
+
+	for (i = 0; i < XILINX_VDMA_MAX_CHANS_PER_DEVICE; i++) {
+		if (xdev->chan[i])
+			xdev->chan[i]->num_frms = num_frames;
+	}
+
+	/* Register the DMA engine with the core */
+	dma_async_device_register(&xdev->common);
+
+	err = of_dma_controller_register(node, of_dma_xilinx_xlate,
+					 &xdev->common);
+	if (err < 0)
+		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+
+	return 0;
+
+error:
+	for (i = 0; i < XILINX_VDMA_MAX_CHANS_PER_DEVICE; i++) {
+		if (xdev->chan[i])
+			xilinx_vdma_chan_remove(xdev->chan[i]);
+	}
+
+	return err;
+}
+
+/**
+ * xilinx_vdma_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Always returns '0'
+ */
+static int xilinx_vdma_remove(struct platform_device *pdev)
+{
+	struct xilinx_vdma_device *xdev;
+	int i;
+
+	of_dma_controller_free(pdev->dev.of_node);
+
+	xdev = platform_get_drvdata(pdev);
+	dma_async_device_unregister(&xdev->common);
+
+	for (i = 0; i < XILINX_VDMA_MAX_CHANS_PER_DEVICE; i++) {
+		if (xdev->chan[i])
+			xilinx_vdma_chan_remove(xdev->chan[i]);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_vdma_of_ids[] = {
+	{ .compatible = "xlnx,axi-vdma",},
+	{}
+};
+
+static struct platform_driver xilinx_vdma_driver = {
+	.driver = {
+		.name = "xilinx-vdma",
+		.owner = THIS_MODULE,
+		.of_match_table = xilinx_vdma_of_ids,
+	},
+	.probe = xilinx_vdma_probe,
+	.remove = xilinx_vdma_remove,
+};
+
+module_platform_driver(xilinx_vdma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx VDMA driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/edac/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/edac/Kconfig	2014-07-20 22:05:50.172067677 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/edac/Kconfig	2014-07-20 22:06:35.830314394 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:329 @
 	  Support for error detection and correction on the
 	  Tilera memory controller.
 
+config EDAC_ZYNQ
+	tristate "ZYNQ DDR Memory Controller"
+	depends on EDAC_MM_EDAC && ARCH_ZYNQ
+	help
+	  This enables support for EDAC on the ECC memory used
+	  with the ZYNQ DDR memory controller.
+
 config EDAC_HIGHBANK_MC
 	tristate "Highbank Memory Controller"
 	depends on EDAC_MM_EDAC && ARCH_HIGHBANK
Index: linux-3.12.24-rt38-xilinx/drivers/edac/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/edac/Makefile	2014-07-20 22:05:50.171067694 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/edac/Makefile	2014-07-20 22:06:35.840314229 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:67 @
 obj-$(CONFIG_EDAC_OCTEON_L2C)		+= octeon_edac-l2c.o
 obj-$(CONFIG_EDAC_OCTEON_LMC)		+= octeon_edac-lmc.o
 obj-$(CONFIG_EDAC_OCTEON_PCI)		+= octeon_edac-pci.o
+obj-$(CONFIG_EDAC_ZYNQ)			+= zynq_edac.o
Index: linux-3.12.24-rt38-xilinx/drivers/edac/zynq_edac.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/edac/zynq_edac.c	2014-07-20 22:06:35.853314015 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq DDR ECC Driver
+ * This driver is based on ppc4xx_edac.c drivers
+ *
+ * Copyright (C) 2012 - 2013 Xilinx, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/edac.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "edac_core.h"
+
+/* Number of cs_rows needed per memory controller */
+#define ZYNQ_EDAC_NR_CSROWS	1
+
+/* Number of channels per memory controller */
+#define ZYNQ_EDAC_NR_CHANS	1
+
+/* Granularity of reported error in bytes */
+#define ZYNQ_EDAC_ERROR_GRAIN	1
+
+#define ZYNQ_EDAC_MESSAGE_SIZE	256
+
+/* Zynq DDR memory controller registers that are relevant to ECC */
+#define ZYNQ_DDRC_CONTROL_REG_OFFSET	0x0 /* Control regsieter */
+#define ZYNQ_DDRC_T_ZQ_REG_OFFSET	0xA4 /* ZQ register */
+
+/* ECC control register */
+#define ZYNQ_DDRC_ECC_CONTROL_REG_OFFSET	0xC4
+/* ECC log register */
+#define ZYNQ_DDRC_ECC_CE_LOG_REG_OFFSET		0xC8
+/* ECC address register */
+#define ZYNQ_DDRC_ECC_CE_ADDR_REG_OFFSET	0xCC
+/* ECC data[31:0] register */
+#define ZYNQ_DDRC_ECC_CE_DATA_31_0_REG_OFFSET	0xD0
+
+/* Uncorrectable error info regsisters */
+#define ZYNQ_DDRC_ECC_UE_LOG_REG_OFFSET		0xDC /* ECC control register */
+#define ZYNQ_DDRC_ECC_UE_ADDR_REG_OFFSET	0xE0 /* ECC log register */
+#define ZYNQ_DDRC_ECC_UE_DATA_31_0_REG_OFFSET	0xE4 /* ECC address register */
+
+#define ZYNQ_DDRC_ECC_STAT_REG_OFFSET	0xF0 /* ECC statistics register */
+#define ZYNQ_DDRC_ECC_SCRUB_REG_OFFSET	0xF4 /* ECC scrub register */
+
+/* Control regsiter bitfield definitions */
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK		0xC
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT	2
+
+#define ZYNQ_DDRCTL_WDTH_16	1
+#define ZYNQ_DDRCTL_WDTH_32	0
+
+/* ZQ register bitfield definitions */
+#define ZYNQ_DDRC_T_ZQ_REG_DDRMODE_MASK		0x2
+
+/* ECC control register bitfield definitions */
+#define ZYNQ_DDRC_ECCCTRL_CLR_CE_ERR	0x2
+#define ZYNQ_DDRC_ECCCTRL_CLR_UE_ERR	0x1
+
+/* ECC correctable/uncorrectable error log register definitions */
+#define ZYNQ_DDRC_ECC_CE_LOGREG_VALID		0x1
+#define ZYNQ_DDRC_ECC_CE_LOGREG_BITPOS_MASK	0xFE
+#define ZYNQ_DDRC_ECC_CE_LOGREG_BITPOS_SHIFT	1
+
+/* ECC correctable/uncorrectable error address register definitions */
+#define ZYNQ_DDRC_ECC_ADDRREG_COL_MASK		0xFFF
+#define ZYNQ_DDRC_ECC_ADDRREG_ROW_MASK		0xFFFF000
+#define ZYNQ_DDRC_ECC_ADDRREG_ROW_SHIFT		12
+#define ZYNQ_DDRC_ECC_ADDRREG_BANK_MASK		0x70000000
+#define ZYNQ_DDRC_ECC_ADDRREG_BANK_SHIFT	28
+
+/* ECC statistic regsiter definitions */
+#define ZYNQ_DDRC_ECC_STATREG_UECOUNT_MASK	0xFF
+#define ZYNQ_DDRC_ECC_STATREG_CECOUNT_MASK	0xFF00
+#define ZYNQ_DDRC_ECC_STATREG_CECOUNT_SHIFT	8
+
+/* ECC scrub regsiter definitions */
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK	0x7
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED	0x4
+
+/**
+ * struct ecc_error_info - ECC error log information
+ * @row:	Row number
+ * @col:	Column number
+ * @bank:	Bank number
+ * @bitpos:	Bit position
+ * @data:	Data causing the error
+ */
+struct ecc_error_info {
+	u32 row;
+	u32 col;
+	u32 bank;
+	u32 bitpos;
+	u32 data;
+};
+
+/**
+ * struct zynq_ecc_status - ECC status information to report
+ * @ce_count:	Correctable error count
+ * @ue_count:	Uncorrectable error count
+ * @ceinfo:	Correctable error log information
+ * @ueinfo:	Uncorrectable error log information
+ */
+struct zynq_ecc_status {
+	u32 ce_count;
+	u32 ue_count;
+	struct ecc_error_info ceinfo;
+	struct ecc_error_info ueinfo;
+};
+
+/**
+ * struct zynq_edac_priv - Zynq DDR memory controller private instance data
+ * @baseaddr:		Base address of the DDR controller
+ * @ce_count:		Correctable Error count
+ * @ue_count:		Uncorrectable Error count
+ */
+struct zynq_edac_priv {
+	void __iomem *baseaddr;
+	u32 ce_count;
+	u32 ue_count;
+};
+
+/**
+ * zynq_edac_geterror_info - Get the current ecc error info
+ * @base:	Pointer to the base address of the ddr memory controller
+ * @perrstatus:	Pointer to the zynq ecc status structure
+ *
+ * This routine determines there is any ecc error or not
+ *
+ * Returns zero if there is no error otherwise returns 1
+ */
+static int zynq_edac_geterror_info(void __iomem *base,
+		struct zynq_ecc_status *perrstatus)
+{
+	u32 regval;
+	u32 clearval = 0;
+
+	regval = readl(base + ZYNQ_DDRC_ECC_STAT_REG_OFFSET) &
+			(ZYNQ_DDRC_ECC_STATREG_UECOUNT_MASK |
+			ZYNQ_DDRC_ECC_STATREG_CECOUNT_MASK);
+
+	if (regval == 0)
+		return 0;
+
+	memset(perrstatus, 0, sizeof(struct zynq_ecc_status));
+
+	perrstatus->ce_count = (regval & ZYNQ_DDRC_ECC_STATREG_CECOUNT_MASK) >>
+				ZYNQ_DDRC_ECC_STATREG_CECOUNT_SHIFT;
+	perrstatus->ue_count = (regval & ZYNQ_DDRC_ECC_STATREG_UECOUNT_MASK);
+
+	if (perrstatus->ce_count) {
+		regval = readl(base + ZYNQ_DDRC_ECC_CE_LOG_REG_OFFSET);
+		if (regval & ZYNQ_DDRC_ECC_CE_LOGREG_VALID) {
+			perrstatus->ceinfo.bitpos = (regval &
+				ZYNQ_DDRC_ECC_CE_LOGREG_BITPOS_MASK) >>
+				ZYNQ_DDRC_ECC_CE_LOGREG_BITPOS_SHIFT;
+			regval = readl(base +
+					ZYNQ_DDRC_ECC_CE_ADDR_REG_OFFSET);
+			perrstatus->ceinfo.row = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_ROW_MASK) >>
+					ZYNQ_DDRC_ECC_ADDRREG_ROW_SHIFT;
+			perrstatus->ceinfo.col = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_COL_MASK);
+			perrstatus->ceinfo.bank = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_BANK_MASK) >>
+					ZYNQ_DDRC_ECC_ADDRREG_BANK_SHIFT;
+			perrstatus->ceinfo.data = readl(base +
+					ZYNQ_DDRC_ECC_CE_DATA_31_0_REG_OFFSET);
+			edac_dbg(3, "ce bitposition: %d data: %d\n",
+					perrstatus->ceinfo.bitpos,
+					perrstatus->ceinfo.data);
+		}
+		clearval = ZYNQ_DDRC_ECCCTRL_CLR_CE_ERR;
+	}
+
+	if (perrstatus->ue_count) {
+		regval = readl(base + ZYNQ_DDRC_ECC_UE_LOG_REG_OFFSET);
+		if (regval & ZYNQ_DDRC_ECC_CE_LOGREG_VALID) {
+			regval = readl(base +
+					ZYNQ_DDRC_ECC_UE_ADDR_REG_OFFSET);
+			perrstatus->ueinfo.row = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_ROW_MASK) >>
+					ZYNQ_DDRC_ECC_ADDRREG_ROW_SHIFT;
+			perrstatus->ueinfo.col = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_COL_MASK);
+			perrstatus->ueinfo.bank = (regval &
+					ZYNQ_DDRC_ECC_ADDRREG_BANK_MASK) >>
+					ZYNQ_DDRC_ECC_ADDRREG_BANK_SHIFT;
+			perrstatus->ueinfo.data = readl(base +
+					ZYNQ_DDRC_ECC_UE_DATA_31_0_REG_OFFSET);
+		}
+		clearval |= ZYNQ_DDRC_ECCCTRL_CLR_UE_ERR;
+	}
+
+	writel(clearval, base + ZYNQ_DDRC_ECC_CONTROL_REG_OFFSET);
+	writel(0x0, base + ZYNQ_DDRC_ECC_CONTROL_REG_OFFSET);
+
+	return 1;
+}
+
+/**
+ * zynq_edac_generate_message - Generate interpreted ECC status message
+ * @mci:	Pointer to the edac memory controller instance
+ * @perrstatus:	Pointer to the zynq ecc status structure
+ * @buffer:	Pointer to the buffer in which to generate the
+ *		message
+ * @size:	The size, in bytes, of space available in buffer
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECC register of
+ * the specified ECC status.
+ */
+static void zynq_edac_generate_message(const struct mem_ctl_info *mci,
+			struct zynq_ecc_status *perrstatus, char *buffer,
+			size_t size)
+{
+	struct ecc_error_info *pinfo = NULL;
+
+	if (perrstatus->ce_count > 0)
+		pinfo = &perrstatus->ceinfo;
+	else
+		pinfo = &perrstatus->ueinfo;
+
+	snprintf(buffer, ZYNQ_EDAC_MESSAGE_SIZE,
+		 "DDR ECC error type :%s Row %d Bank %d Col %d ",
+		 (perrstatus->ce_count > 0) ? "CE" : "UE", pinfo->row,
+		 pinfo->bank, pinfo->col);
+}
+
+/**
+ * zynq_edac_handle_error - Handle controller error types CE and UE
+ * @mci:	Pointer to the edac memory controller instance
+ * @perrstatus:	Pointer to the zynq ecc status structure
+ *
+ * This routine handles an xilinx,ps7-ddrc controller ECC correctable error.
+ */
+static void zynq_edac_handle_error(struct mem_ctl_info *mci,
+			struct zynq_ecc_status *perrstatus)
+{
+	char message[ZYNQ_EDAC_MESSAGE_SIZE];
+
+	zynq_edac_generate_message(mci, perrstatus, &message[0],
+				   ZYNQ_EDAC_MESSAGE_SIZE);
+
+	if (perrstatus->ce_count)
+		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+				     perrstatus->ce_count, 0, 0, 0, 0, 0, -1,
+				     &message[0], "");
+	else
+		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+				     perrstatus->ue_count, 0, 0, 0, 0, 0, -1,
+				     &message[0], "");
+}
+
+/**
+ * zynq_edac_check - Check controller for ECC errors
+ * @mci:	Pointer to the edac memory controller instance
+ *
+ * This routine is used to check and post ECC errors and is called by
+ * the EDAC polling thread
+ */
+static void zynq_edac_check(struct mem_ctl_info *mci)
+{
+	struct zynq_edac_priv *priv = mci->pvt_info;
+	struct zynq_ecc_status errstatus;
+	int status;
+
+	status = zynq_edac_geterror_info(priv->baseaddr, &errstatus);
+	if (status) {
+		priv->ce_count += errstatus.ce_count;
+		priv->ue_count += errstatus.ue_count;
+
+		if (errstatus.ce_count) {
+			zynq_edac_handle_error(mci, &errstatus);
+			errstatus.ce_count = 0;
+		}
+		if (errstatus.ue_count) {
+			zynq_edac_handle_error(mci, &errstatus);
+			errstatus.ue_count = 0;
+		}
+		edac_dbg(3, "total error count ce %d ue %d\n",
+			 priv->ce_count, priv->ue_count);
+	}
+}
+
+/**
+ * zynq_edac_get_dtype - Return the controller memory width
+ * @base:	Pointer to the ddr memory contoller base address
+ *
+ * This routine returns the EDAC device type width appropriate for the
+ * current controller configuration.
+ *
+ * Returns a device type width enumeration.
+ */
+static enum dev_type zynq_edac_get_dtype(void __iomem *base)
+{
+	enum dev_type dt;
+	u32 width;
+
+	width = readl(base + ZYNQ_DDRC_CONTROL_REG_OFFSET);
+	width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >>
+			ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT;
+
+	switch (width) {
+	case ZYNQ_DDRCTL_WDTH_16:
+		dt = DEV_X2;
+		break;
+	case ZYNQ_DDRCTL_WDTH_32:
+		dt = DEV_X4;
+		break;
+	default:
+		dt = DEV_UNKNOWN;
+	}
+
+	return dt;
+}
+
+/**
+ * zynq_edac_get_eccstate - Return the controller ecc enable/disable status
+ * @base:	Pointer to the ddr memory contoller base address
+ *
+ * This routine returns the ECC enable/diable status for the xlnx,ps7-ddrc
+ * controller
+ *
+ * Returns a ecc status boolean i.e true/false - enabled/disabled.
+ */
+static bool zynq_edac_get_eccstate(void __iomem *base)
+{
+	enum dev_type dt;
+	u32 ecctype;
+	bool state = false;
+
+	dt = zynq_edac_get_dtype(base);
+
+	ecctype = (readl(base + ZYNQ_DDRC_ECC_SCRUB_REG_OFFSET) &
+			ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK);
+
+	if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED)
+			&& (dt == DEV_X2)) {
+		state = true;
+		writel(0x0, base + ZYNQ_DDRC_ECC_CONTROL_REG_OFFSET);
+	} else {
+		state = false;
+	}
+
+	return state;
+}
+
+/**
+ * zynq_edac_get_memsize - Return the size of the attched mmeory device
+ *
+ * This routine returns the size of the system memory by reading the sysinfo
+ * information
+ *
+ * Returns the memory size in bytes
+ */
+static u32 zynq_edac_get_memsize(void)
+{
+	struct sysinfo inf;
+
+	/* Reading the system memory size from the global meminfo structure */
+	si_meminfo(&inf);
+
+	return inf.totalram * inf.mem_unit;
+}
+
+/**
+ * zynq_edac_get_mtype - Returns controller memory type
+ * @base:	pointer to the zynq ecc status structure
+ *
+ * This routine returns the EDAC memory type appropriate for the
+ * current controller configuration.
+ *
+ * Returns a memory type enumeration.
+ */
+static enum mem_type zynq_edac_get_mtype(void __iomem *base)
+{
+	enum mem_type mt;
+	u32 memtype;
+
+	memtype = readl(base + ZYNQ_DDRC_T_ZQ_REG_OFFSET);
+
+	if (memtype & ZYNQ_DDRC_T_ZQ_REG_DDRMODE_MASK)
+		mt = MEM_DDR3;
+	else
+		mt = MEM_DDR2;
+
+	return mt;
+}
+
+/**
+ * zynq_edac_init_csrows - Initialize the cs row data
+ * @mci:	Pointer to the edac memory controller instance
+ *
+ * This routine initializes the chip select rows associated
+ * with the EDAC memory controller instance
+ *
+ * Returns 0 if OK; otherwise, -EINVAL if the memory bank size
+ * configuration cannot be determined.
+ */
+static int zynq_edac_init_csrows(struct mem_ctl_info *mci)
+{
+	struct csrow_info *csi;
+	struct dimm_info *dimm;
+	struct zynq_edac_priv *priv = mci->pvt_info;
+	u32 size;
+	int row, j;
+
+	for (row = 0; row < mci->nr_csrows; row++) {
+		csi = mci->csrows[row];
+		size = zynq_edac_get_memsize();
+
+		for (j = 0; j < csi->nr_channels; j++) {
+			dimm = csi->channels[j]->dimm;
+			dimm->edac_mode = EDAC_FLAG_SECDED;
+			dimm->mtype = zynq_edac_get_mtype(priv->baseaddr);
+			dimm->nr_pages =
+			    (size >> PAGE_SHIFT) / csi->nr_channels;
+			dimm->grain = ZYNQ_EDAC_ERROR_GRAIN;
+			dimm->dtype = zynq_edac_get_dtype(priv->baseaddr);
+		}
+
+	}
+
+	return 0;
+}
+
+/**
+ * zynq_edac_mc_init - Initialize driver instance
+ * @mci:	Pointer to the edac memory controller instance
+ * @pdev:	Pointer to the platform_device struct
+ *
+ * This routine performs initialization of the EDAC memory controller
+ * instance and related driver-private data associated with the
+ * xlnx,ps7-ddrc memory controller the instance is bound to.
+ *
+ * Returns 0 if OK; otherwise, < 0 on error.
+ */
+static int zynq_edac_mc_init(struct mem_ctl_info *mci,
+			struct platform_device *pdev)
+{
+	int status;
+	struct zynq_edac_priv *priv;
+
+	/* Initial driver pointers and private data */
+	mci->pdev = &pdev->dev;
+	priv = mci->pvt_info;
+	platform_set_drvdata(pdev, mci);
+
+	/* Initialize controller capabilities and configuration */
+	mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
+	mci->scrub_cap = SCRUB_HW_SRC;
+	/* Check the scrub setting from the controller */
+	mci->scrub_mode = SCRUB_NONE;
+
+	mci->edac_cap = EDAC_FLAG_SECDED;
+	/* Initialize strings */
+	mci->ctl_name = "zynq_ddr_controller";
+	mci->dev_name = dev_name(&pdev->dev);
+	mci->mod_name = "zynq_edac";
+	mci->mod_ver = "1";
+
+	/* Initialize callbacks */
+	edac_op_state = EDAC_OPSTATE_POLL;
+	mci->edac_check = zynq_edac_check;
+	mci->ctl_page_to_phys = NULL;
+
+	/*
+	 * Initialize the MC control structure 'csrows' table
+	 * with the mapping and control information.
+	 */
+	status = zynq_edac_init_csrows(mci);
+	if (status)
+		pr_err("Failed to initialize rows!\n");
+
+	return status;
+}
+
+/**
+ * zynq_edac_mc_probe - Check controller and bind driver
+ * @pdev:	Pointer to the platform_device struct
+ *
+ * This routine probes a specific xilinx,ps7-ddrc controller
+ * instance for binding with the driver.
+ *
+ * Returns 0 if the controller instance was successfully bound to the
+ * driver; otherwise, < 0 on error.
+ */
+static int zynq_edac_mc_probe(struct platform_device *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct edac_mc_layer layers[2];
+	struct zynq_edac_priv *priv;
+	int rc;
+	struct resource *res;
+	void __iomem *baseaddr;
+
+	/* Get the data from the platform device */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	baseaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(baseaddr))
+		return PTR_ERR(baseaddr);
+
+	/* Check for the ecc enable status */
+	if (zynq_edac_get_eccstate(baseaddr) == false) {
+		dev_err(&pdev->dev, "ecc not enabled\n");
+		return -ENXIO;
+	}
+
+	/*
+	 * At this point, we know ECC is enabled, allocate an EDAC
+	 * controller instance and perform the appropriate
+	 * initialization.
+	 */
+	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
+	layers[0].size = ZYNQ_EDAC_NR_CSROWS;
+	layers[0].is_virt_csrow = true;
+	layers[1].type = EDAC_MC_LAYER_CHANNEL;
+	layers[1].size = ZYNQ_EDAC_NR_CHANS;
+	layers[1].is_virt_csrow = false;
+
+	mci = edac_mc_alloc(pdev->id, ARRAY_SIZE(layers), layers,
+			    sizeof(struct zynq_edac_priv));
+	if (mci == NULL) {
+		pr_err("Failed memory allocation for mci instance!\n");
+		return -ENOMEM;
+	}
+
+	priv = mci->pvt_info;
+	priv->baseaddr = baseaddr;
+	rc = zynq_edac_mc_init(mci, pdev);
+	if (rc) {
+		pr_err("Failed to initialize instance!\n");
+		goto free_edac_mc;
+	}
+
+	/*
+	 * We have a valid, initialized EDAC instance bound to the
+	 * controller. Attempt to register it with the EDAC subsystem
+	 */
+	rc = edac_mc_add_mc(mci);
+	if (rc) {
+		dev_err(&pdev->dev, "failed to register with EDAC core\n");
+		goto del_edac_mc;
+	}
+
+	return rc;
+
+del_edac_mc:
+	edac_mc_del_mc(&pdev->dev);
+free_edac_mc:
+	edac_mc_free(mci);
+
+	return rc;
+}
+
+/**
+ * zynq_edac_mc_remove - Unbind driver from controller
+ * @pdev:	Pointer to the platform_device struct
+ *
+ * This routine unbinds the EDAC memory controller instance associated
+ * with the specified xilinx,ps7-ddrc controller described by the
+ * OpenFirmware device tree node passed as a parameter.
+ *
+ * Unconditionally returns 0.
+ */
+static int zynq_edac_mc_remove(struct platform_device *pdev)
+{
+	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
+
+	edac_mc_del_mc(&pdev->dev);
+	edac_mc_free(mci);
+
+	return 0;
+}
+
+/* Device tree node type and compatible tuples this driver can match on */
+static struct of_device_id zynq_edac_match[] = {
+	{ .compatible = "xlnx,ps7-ddrc-1.00.a", },
+	{ /* end of table */ }
+};
+
+MODULE_DEVICE_TABLE(of, zynq_edac_match);
+
+static struct platform_driver zynq_edac_mc_driver = {
+	.driver = {
+		   .name = "zynq-edac",
+		   .owner = THIS_MODULE,
+		   .of_match_table = zynq_edac_match,
+		   },
+	.probe = zynq_edac_mc_probe,
+	.remove = zynq_edac_mc_remove,
+};
+
+module_platform_driver(zynq_edac_mc_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Zynq DDR ECC driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/gpio/gpio-xilinx.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpio/gpio-xilinx.c	2014-07-20 22:05:50.185067463 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpio/gpio-xilinx.c	2014-07-20 22:06:35.868313767 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:20 @
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
 /* Register Offset Definitions */
-#define XGPIO_DATA_OFFSET   (0x0)	/* Data register  */
-#define XGPIO_TRI_OFFSET    (0x4)	/* I/O direction register  */
+#define XGPIO_DATA_OFFSET	0x0 /* Data register */
+#define XGPIO_TRI_OFFSET	0x4 /* I/O direction register */
+#define XGPIO_GIER_OFFSET	0x11c /* Global Interrupt Enable */
+#define XGPIO_GIER_IE		BIT(31)
+
+#define XGPIO_IPISR_OFFSET	0x120 /* IP Interrupt Status */
+#define XGPIO_IPIER_OFFSET	0x128 /* IP Interrupt Enable */
 
 #define XGPIO_CHANNEL_OFFSET	0x8
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:53 @
 
 /**
  * struct xgpio_instance - Stores information about GPIO device
- * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
- * gpio_state: GPIO state shadow register
- * gpio_dir: GPIO direction shadow register
- * offset: GPIO channel offset
- * gpio_lock: Lock used for synchronization
+ * @mmchip: OF GPIO chip for memory mapped banks
+ * @gpio_state: GPIO state shadow register
+ * @gpio_dir: GPIO direction shadow register
+ * @offset: GPIO channel offset
+ * @irq_base: GPIO channel irq base address
+ * @irq_enable: GPIO irq enable/disable bitfield
+ * @gpio_lock: Lock used for synchronization
+ * @irq_domain: irq_domain of the controller
  */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
 	u32 gpio_state;
 	u32 gpio_dir;
 	u32 offset;
+	int irq_base;
+	u32 irq_enable;
 	spinlock_t gpio_lock;
+	struct irq_domain *irq_domain;
 };
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:78 @
  * @gc:     Pointer to gpio_chip device structure.
  * @gpio:   GPIO signal number.
  *
- * This function reads the specified signal of the GPIO device. It returns 0 if
- * the signal clear, 1 if signal is set or negative value on error.
+ * This function reads the specified signal of the GPIO device.
+ *
+ * Return:
+ * 0 if direction of GPIO signals is set as input otherwise it
+ * returns negative error value.
  */
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:132 @
  * @gpio:   GPIO signal number.
  *
  * This function sets the direction of specified GPIO signal as input.
- * It returns 0 if direction of GPIO signals is set as input otherwise it
- * returns negative error value.
+ *
+ * Return:
+ * 0 - if direction of GPIO signals is set as input
+ * otherwise it returns negative error value.
  */
 static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:162 @
  * @gpio:   GPIO signal number.
  * @val:    Value to be written to specified signal.
  *
- * This function sets the direction of specified GPIO signal as output. If all
- * GPIO signals of GPIO chip is configured as input then it returns
+ * This function sets the direction of specified GPIO signal as output.
+ *
+ * Return:
+ * If all GPIO signals of GPIO chip is configured as input then it returns
  * error otherwise it returns 0.
  */
 static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:197 @
 
 /**
  * xgpio_save_regs - Set initial values of GPIO pins
- * @mm_gc: pointer to memory mapped GPIO chip structure
+ * @mm_gc: Pointer to memory mapped GPIO chip structure
  */
 static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:211 @
 }
 
 /**
+ * xgpio_xlate - Set initial values of GPIO pins
+ * @gc: Pointer to gpio_chip device structure.
+ * @gpiospec:  gpio specifier as found in the device tree
+ * @flags: A flags pointer based on binding
+ *
+ * Return:
+ * irq number otherwise -EINVAL
+ */
+static int xgpio_xlate(struct gpio_chip *gc,
+		       const struct of_phandle_args *gpiospec, u32 *flags)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct xgpio_instance *chip = container_of(mm_gc, struct xgpio_instance,
+						   mmchip);
+
+	if (gpiospec->args[1] == chip->offset)
+		return gpiospec->args[0];
+
+	return -EINVAL;
+}
+
+/**
+ * xgpio_irq_mask - Write the specified signal of the GPIO device.
+ * @irq_data: per irq and chip data passed down to chip functions
+ */
+static void xgpio_irq_mask(struct irq_data *irq_data)
+{
+	unsigned long flags;
+	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
+	struct of_mm_gpio_chip *mm_gc = &chip->mmchip;
+	u32 offset = irq_data->irq - chip->irq_base;
+	u32 temp;
+
+	pr_debug("%s: Disable %d irq, irq_enable_mask 0x%x\n",
+		__func__, offset, chip->irq_enable);
+
+	spin_lock_irqsave(&chip->gpio_lock, flags);
+
+	chip->irq_enable &= ~BIT(offset);
+
+	if (!chip->irq_enable) {
+		/* Enable per channel interrupt */
+		temp = xgpio_readreg(mm_gc->regs + XGPIO_IPIER_OFFSET);
+		temp &= chip->offset / XGPIO_CHANNEL_OFFSET + 1;
+		xgpio_writereg(mm_gc->regs + XGPIO_IPIER_OFFSET, temp);
+
+		/* Disable global interrupt if channel interrupts are unused */
+		temp = xgpio_readreg(mm_gc->regs + XGPIO_IPIER_OFFSET);
+		if (!temp)
+			xgpio_writereg(mm_gc->regs + XGPIO_GIER_OFFSET,
+				       ~XGPIO_GIER_IE);
+
+	}
+	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+}
+
+/**
+ * xgpio_irq_unmask - Write the specified signal of the GPIO device.
+ * @irq_data: per irq and chip data passed down to chip functions
+ */
+static void xgpio_irq_unmask(struct irq_data *irq_data)
+{
+	unsigned long flags;
+	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
+	struct of_mm_gpio_chip *mm_gc = &chip->mmchip;
+	u32 offset = irq_data->irq - chip->irq_base;
+	u32 temp;
+
+	pr_debug("%s: Enable %d irq, irq_enable_mask 0x%x\n",
+		__func__, offset, chip->irq_enable);
+
+	/* Setup pin as input */
+	xgpio_dir_in(&mm_gc->gc, offset);
+
+	spin_lock_irqsave(&chip->gpio_lock, flags);
+
+	chip->irq_enable |= BIT(offset);
+
+	if (chip->irq_enable) {
+
+		/* Enable per channel interrupt */
+		temp = xgpio_readreg(mm_gc->regs + XGPIO_IPIER_OFFSET);
+		temp |= chip->offset / XGPIO_CHANNEL_OFFSET + 1;
+		xgpio_writereg(mm_gc->regs + XGPIO_IPIER_OFFSET, temp);
+
+		/* Enable global interrupts */
+		xgpio_writereg(mm_gc->regs + XGPIO_GIER_OFFSET, XGPIO_GIER_IE);
+	}
+
+	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+}
+
+/**
+ * xgpio_set_irq_type - Write the specified signal of the GPIO device.
+ * @irq_data: Per irq and chip data passed down to chip functions
+ * @type: Interrupt type that is to be set for the gpio pin
+ *
+ * Return:
+ * 0 if interrupt type is supported otherwise otherwise -EINVAL
+ */
+static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
+{
+	/* Only rising edge case is supported now */
+	if (type == IRQ_TYPE_EDGE_RISING)
+		return 0;
+
+	return -EINVAL;
+}
+
+/* irq chip descriptor */
+static struct irq_chip xgpio_irqchip = {
+	.name		= "xgpio",
+	.irq_mask	= xgpio_irq_mask,
+	.irq_unmask	= xgpio_irq_unmask,
+	.irq_set_type	= xgpio_set_irq_type,
+};
+
+/**
+ * xgpio_to_irq - Find out gpio to Linux irq mapping
+ * @gc: Pointer to gpio_chip device structure.
+ * @offset: Gpio pin offset
+ *
+ * Return:
+ * irq number otherwise -EINVAL
+ */
+static int xgpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct xgpio_instance *chip = container_of(mm_gc, struct xgpio_instance,
+						   mmchip);
+
+	return irq_find_mapping(chip->irq_domain, offset);
+}
+
+/**
+ * xgpio_irqhandler - Gpio interrupt service routine
+ * @irq: gpio irq number
+ * @desc: Pointer to interrupt description
+ */
+static void xgpio_irqhandler(unsigned int irq, struct irq_desc *desc)
+{
+	struct xgpio_instance *chip = (struct xgpio_instance *)
+						irq_get_handler_data(irq);
+	struct of_mm_gpio_chip *mm_gc = &chip->mmchip;
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	int offset;
+	unsigned long val;
+
+	chained_irq_enter(irqchip, desc);
+
+	val = xgpio_readreg(mm_gc->regs + chip->offset);
+	/* Only rising edge is supported */
+	val &= chip->irq_enable;
+
+	for_each_set_bit(offset, &val, chip->mmchip.gc.ngpio) {
+		generic_handle_irq(chip->irq_base + offset);
+	}
+
+	xgpio_writereg(mm_gc->regs + XGPIO_IPISR_OFFSET,
+		       chip->offset / XGPIO_CHANNEL_OFFSET + 1);
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static struct lock_class_key gpio_lock_class;
+
+/**
+ * xgpio_irq_setup - Allocate irq for gpio and setup appropriate functions
+ * @np: Device node of the GPIO chip
+ * @chip: Pointer to private gpio channel structure
+ *
+ * Return:
+ * 0 if success, otherwise -1
+ */
+static int xgpio_irq_setup(struct device_node *np, struct xgpio_instance *chip)
+{
+	u32 pin_num;
+	struct resource res;
+
+	int ret = of_irq_to_resource(np, 0, &res);
+	if (!ret) {
+		pr_info("GPIO IRQ not connected\n");
+		return 0;
+	}
+
+	chip->mmchip.gc.of_xlate = xgpio_xlate;
+	chip->mmchip.gc.of_gpio_n_cells = 2;
+	chip->mmchip.gc.to_irq = xgpio_to_irq;
+
+	chip->irq_base = irq_alloc_descs(-1, 0, chip->mmchip.gc.ngpio, 0);
+	if (chip->irq_base < 0) {
+		pr_err("Couldn't allocate IRQ numbers\n");
+		return -1;
+	}
+	chip->irq_domain = irq_domain_add_legacy(np, chip->mmchip.gc.ngpio,
+						 chip->irq_base, 0,
+						 &irq_domain_simple_ops, NULL);
+
+	/*
+	 * set the irq chip, handler and irq chip data for callbacks for
+	 * each pin
+	 */
+	for (pin_num = 0; pin_num < chip->mmchip.gc.ngpio; pin_num++) {
+		u32 gpio_irq = irq_find_mapping(chip->irq_domain, pin_num);
+		irq_set_lockdep_class(gpio_irq, &gpio_lock_class);
+		pr_debug("IRQ Base: %d, Pin %d = IRQ %d\n",
+			chip->irq_base,	pin_num, gpio_irq);
+		irq_set_chip_and_handler(gpio_irq, &xgpio_irqchip,
+					 handle_simple_irq);
+		irq_set_chip_data(gpio_irq, (void *)chip);
+#ifdef CONFIG_ARCH_ZYNQ
+		set_irq_flags(gpio_irq, IRQF_VALID);
+#endif
+	}
+	irq_set_handler_data(res.start, (void *)chip);
+	irq_set_chained_handler(res.start, xgpio_irqhandler);
+
+	return 0;
+}
+
+/**
  * xgpio_of_probe - Probe method for the GPIO device.
  * @np: pointer to device tree node
  *
  * This function probes the GPIO device in the device tree. It initializes the
- * driver data structure. It returns 0, if the driver is bound to the GPIO
- * device, or a negative value if there is an error.
+ * driver data structure.
+ *
+ * Return:
+ * It returns 0, if the driver is bound to the GPIO device, or
+ * a negative value if there is an error.
  */
-static int xgpio_of_probe(struct device_node *np)
+static int xgpio_of_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct xgpio_instance *chip;
 	int status = 0;
 	const u32 *tree_info;
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:481 @
 	/* Call the OF gpio helper to setup and register the GPIO device */
 	status = of_mm_gpiochip_add(np, &chip->mmchip);
 	if (status) {
-		kfree(chip);
 		pr_err("%s: error in probe function with status %d\n",
 		       np->full_name, status);
 		return status;
 	}
 
+	status = xgpio_irq_setup(np, chip);
+	if (status) {
+		pr_err("%s: GPIO IRQ initialization failed %d\n",
+		       np->full_name, status);
+		return status;
+	}
+
 	pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
 							chip->mmchip.gc.base);
 
 	tree_info = of_get_property(np, "xlnx,is-dual", NULL);
 	if (tree_info && be32_to_cpup(tree_info)) {
-		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+		chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 		if (!chip)
 			return -ENOMEM;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:531 @
 
 		chip->mmchip.save_regs = xgpio_save_regs;
 
+		status = xgpio_irq_setup(np, chip);
+		if (status) {
+			pr_err("%s: GPIO IRQ initialization failed %d\n",
+			      np->full_name, status);
+			return status;
+		}
+
 		/* Call the OF gpio helper to setup and register the GPIO dev */
 		status = of_mm_gpiochip_add(np, &chip->mmchip);
 		if (status) {
-			kfree(chip);
 			pr_err("%s: error in probe function with status %d\n",
-			np->full_name, status);
+			       np->full_name, status);
 			return status;
 		}
 		pr_info("XGpio: %s: dual channel registered, base is %d\n",
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:556 @
 	{ .compatible = "xlnx,xps-gpio-1.00.a", },
 	{ /* end of list */ },
 };
+MODULE_DEVICE_TABLE(of, xgpio_of_match);
+
+static struct platform_driver xilinx_gpio_driver = {
+	.probe = xgpio_of_probe,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xilinx-gpio",
+		.of_match_table = xgpio_of_match,
+	},
+};
 
 static int __init xgpio_init(void)
 {
-	struct device_node *np;
-
-	for_each_matching_node(np, xgpio_of_match)
-		xgpio_of_probe(np);
-
-	return 0;
+	return platform_driver_register(&xilinx_gpio_driver);
 }
 
 /* Make sure we get initialized before anyone else tries to use us */
Index: linux-3.12.24-rt38-xilinx/drivers/gpio/gpio-zynq.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpio/gpio-zynq.c	2014-07-20 22:06:35.883313520 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS GPIO device driver
+ *
+ * 2009-2011 (c) Xilinx, 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <asm/mach/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+
+#define DRIVER_NAME "zynq_gpio"
+#define ZYNQ_GPIO_NR_GPIOS	118
+
+static struct irq_domain *irq_domain;
+
+/* Register offsets for the GPIO device */
+
+#define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK)	(0x000 + (8 * BANK)) /* LSW Mask &
+								Data -WO */
+#define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK)	(0x004 + (8 * BANK)) /* MSW Mask &
+								Data -WO */
+#define ZYNQ_GPIO_DATA_OFFSET(BANK)	(0x040 + (4 * BANK)) /* Data Register
+								-RW */
+#define ZYNQ_GPIO_DIRM_OFFSET(BANK)	(0x204 + (0x40 * BANK)) /* Direction
+								mode reg-RW */
+#define ZYNQ_GPIO_OUTEN_OFFSET(BANK)	(0x208 + (0x40 * BANK)) /* Output
+								enable reg-RW
+								 */
+#define ZYNQ_GPIO_INTMASK_OFFSET(BANK)	(0x20C + (0x40 * BANK)) /* Interrupt
+								mask reg-RO */
+#define ZYNQ_GPIO_INTEN_OFFSET(BANK)	(0x210 + (0x40 * BANK)) /* Interrupt
+								enable reg-WO
+								 */
+#define ZYNQ_GPIO_INTDIS_OFFSET(BANK)	(0x214 + (0x40 * BANK)) /* Interrupt
+								disable reg-WO
+								 */
+#define ZYNQ_GPIO_INTSTS_OFFSET(BANK)	(0x218 + (0x40 * BANK)) /* Interrupt
+								status reg-RO
+								 */
+#define ZYNQ_GPIO_INTTYPE_OFFSET(BANK)	(0x21C + (0x40 * BANK)) /* Interrupt
+								type reg-RW
+								 */
+#define ZYNQ_GPIO_INTPOL_OFFSET(BANK)	(0x220 + (0x40 * BANK)) /* Interrupt
+								polarity reg
+								-RW */
+#define ZYNQ_GPIO_INTANY_OFFSET(BANK)	(0x224 + (0x40 * BANK)) /* Interrupt on
+								any, reg-RW */
+
+/* Read/Write access to the GPIO PS registers */
+#define zynq_gpio_readreg(offset)		__raw_readl(offset)
+#define zynq_gpio_writereg(val, offset)	__raw_writel(val, offset)
+
+static unsigned int zynq_gpio_pin_table[] = {
+	31, /* 0 - 31 */
+	53, /* 32 - 53 */
+	85, /* 54 - 85 */
+	117 /* 86 - 117 */
+};
+
+/**
+ * struct zynq_gpio - gpio device private data structure
+ * @chip:	instance of the gpio_chip
+ * @base_addr:	base address of the GPIO device
+ * @gpio_lock:	lock used for synchronization
+ */
+struct zynq_gpio {
+	struct gpio_chip chip;
+	void __iomem *base_addr;
+	unsigned int irq;
+	unsigned int irq_base;
+	struct clk *clk;
+	spinlock_t gpio_lock;
+};
+
+/**
+ * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
+ * for a given pin in the GPIO device
+ * @pin_num:	gpio pin number within the device
+ * @bank_num:	an output parameter used to return the bank number of the gpio
+ *		pin
+ * @bank_pin_num: an output parameter used to return pin number within a bank
+ *		  for the given gpio pin
+ *
+ * Returns the bank number.
+ */
+static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
+					 unsigned int *bank_num,
+					 unsigned int *bank_pin_num)
+{
+	for (*bank_num = 0; *bank_num < 4; (*bank_num)++)
+		if (pin_num <= zynq_gpio_pin_table[*bank_num])
+			break;
+
+	if (*bank_num == 0)
+		*bank_pin_num = pin_num;
+	else
+		*bank_pin_num = pin_num % (zynq_gpio_pin_table[*bank_num - 1] +
+				1);
+}
+
+/**
+ * zynq_gpio_get_value - Get the state of the specified pin of GPIO device
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * This function reads the state of the specified pin of the GPIO device.
+ * It returns 0 if the pin is low, 1 if pin is high.
+ */
+static int zynq_gpio_get_value(struct gpio_chip *chip, unsigned int pin)
+{
+	unsigned int bank_num, bank_pin_num;
+	struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip);
+
+	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num);
+
+	return (zynq_gpio_readreg(gpio->base_addr +
+				 ZYNQ_GPIO_DATA_OFFSET(bank_num)) >>
+		bank_pin_num) & 1;
+}
+
+/**
+ * zynq_gpio_set_value - Modify the state of the pin with specified value
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value used to modify the state of the specified pin
+ *
+ * This function calculates the register offset (i.e to lower 16 bits or
+ * upper 16 bits) based on the given pin number and sets the state of a
+ * gpio pin to the specified value. The state is either 0 or non-zero.
+ */
+static void zynq_gpio_set_value(struct gpio_chip *chip, unsigned int pin,
+			       int state)
+{
+	unsigned long flags;
+	unsigned int reg_offset;
+	unsigned int bank_num, bank_pin_num;
+	struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip);
+
+	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num);
+
+	if (bank_pin_num >= 16) {
+		bank_pin_num -= 16; /* only 16 data bits in bit maskable reg */
+		reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
+	} else {
+		reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
+	}
+
+	/*
+	 * get the 32 bit value to be written to the mask/data register where
+	 * the upper 16 bits is the mask and lower 16 bits is the data
+	 */
+	if (state)
+		state = 1;
+	state = ~(1 << (bank_pin_num + 16)) & ((state << bank_pin_num) |
+					       0xFFFF0000);
+
+	spin_lock_irqsave(&gpio->gpio_lock, flags);
+	zynq_gpio_writereg(state, gpio->base_addr + reg_offset);
+	spin_unlock_irqrestore(&gpio->gpio_lock, flags);
+}
+
+/**
+ * zynq_gpio_dir_in - Set the direction of the specified GPIO pin as input
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * This function uses the read-modify-write sequence to set the direction of
+ * the gpio pin as input. Returns 0 always.
+ */
+static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
+{
+	unsigned int reg, bank_num, bank_pin_num;
+	struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip);
+
+	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num);
+	/* clear the bit in direction mode reg to set the pin as input */
+	reg = zynq_gpio_readreg(gpio->base_addr +
+				ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+	reg &= ~(1 << bank_pin_num);
+	zynq_gpio_writereg(reg, gpio->base_addr +
+			   ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+
+	return 0;
+}
+
+/**
+ * zynq_gpio_dir_out - Set the direction of the specified GPIO pin as output
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value to be written to specified pin
+ *
+ * This function sets the direction of specified GPIO pin as output, configures
+ * the Output Enable register for the pin and uses zynq_gpio_set to set
+ * the state of the pin to the value specified. Returns 0 always.
+ */
+static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
+			     int state)
+{
+	struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip);
+	unsigned int reg, bank_num, bank_pin_num;
+
+	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num);
+
+	/* set the GPIO pin as output */
+	reg = zynq_gpio_readreg(gpio->base_addr +
+				ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+	reg |= 1 << bank_pin_num;
+	zynq_gpio_writereg(reg, gpio->base_addr +
+				ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+
+	/* configure the output enable reg for the pin */
+	reg = zynq_gpio_readreg(gpio->base_addr +
+				ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
+	reg |= 1 << bank_pin_num;
+	zynq_gpio_writereg(reg, gpio->base_addr +
+				ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
+
+	/* set the state of the pin */
+	zynq_gpio_set_value(chip, pin, state);
+	return 0;
+}
+
+static int zynq_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return irq_find_mapping(irq_domain, offset);
+}
+
+/**
+ * zynq_gpio_irq_ack - Acknowledge the interrupt of a gpio pin
+ * @irq_data:	irq data containing irq number of gpio pin for the interrupt
+ *		to ack
+ *
+ * This function calculates gpio pin number from irq number and sets the bit
+ * in the Interrupt Status Register of the corresponding bank, to ACK the irq.
+ */
+static void zynq_gpio_irq_ack(struct irq_data *irq_data)
+{
+	struct zynq_gpio *gpio = (struct zynq_gpio *)
+				 irq_data_get_irq_chip_data(irq_data);
+	unsigned int device_pin_num, bank_num, bank_pin_num;
+
+	device_pin_num = irq_data->hwirq;
+	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num);
+	zynq_gpio_writereg(1 << bank_pin_num, gpio->base_addr +
+			(ZYNQ_GPIO_INTSTS_OFFSET(bank_num)));
+}
+
+/**
+ * zynq_gpio_irq_mask - Disable the interrupts for a gpio pin
+ * @irq:	irq number of gpio pin for which interrupt is to be disabled
+ *
+ * This function calculates gpio pin number from irq number and sets the
+ * bit in the Interrupt Disable register of the corresponding bank to disable
+ * interrupts for that pin.
+ */
+static void zynq_gpio_irq_mask(struct irq_data *irq_data)
+{
+	struct zynq_gpio *gpio = (struct zynq_gpio *)
+				 irq_data_get_irq_chip_data(irq_data);
+	unsigned int device_pin_num, bank_num, bank_pin_num;
+
+	device_pin_num = irq_data->hwirq;
+	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num);
+	zynq_gpio_writereg(1 << bank_pin_num,
+			  gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
+}
+
+/**
+ * zynq_gpio_irq_unmask - Enable the interrupts for a gpio pin
+ * @irq_data:	irq data containing irq number of gpio pin for the interrupt
+ *		to enable
+ *
+ * This function calculates the gpio pin number from irq number and sets the
+ * bit in the Interrupt Enable register of the corresponding bank to enable
+ * interrupts for that pin.
+ */
+static void zynq_gpio_irq_unmask(struct irq_data *irq_data)
+{
+	struct zynq_gpio *gpio = irq_data_get_irq_chip_data(irq_data);
+	unsigned int device_pin_num, bank_num, bank_pin_num;
+
+	device_pin_num = irq_data->hwirq;
+	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num);
+	zynq_gpio_writereg(1 << bank_pin_num,
+			  gpio->base_addr + ZYNQ_GPIO_INTEN_OFFSET(bank_num));
+}
+
+/**
+ * zynq_gpio_set_irq_type - Set the irq type for a gpio pin
+ * @irq_data:	irq data containing irq number of gpio pin
+ * @type:	interrupt type that is to be set for the gpio pin
+ *
+ * This function gets the gpio pin number and its bank from the gpio pin number
+ * and configures the INT_TYPE, INT_POLARITY and INT_ANY registers. Returns 0,
+ * negative error otherwise.
+ * TYPE-EDGE_RISING,  INT_TYPE - 1, INT_POLARITY - 1,  INT_ANY - 0;
+ * TYPE-EDGE_FALLING, INT_TYPE - 1, INT_POLARITY - 0,  INT_ANY - 0;
+ * TYPE-EDGE_BOTH,    INT_TYPE - 1, INT_POLARITY - NA, INT_ANY - 1;
+ * TYPE-LEVEL_HIGH,   INT_TYPE - 0, INT_POLARITY - 1,  INT_ANY - NA;
+ * TYPE-LEVEL_LOW,    INT_TYPE - 0, INT_POLARITY - 0,  INT_ANY - NA
+ */
+static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
+{
+	struct zynq_gpio *gpio = irq_data_get_irq_chip_data(irq_data);
+	unsigned int device_pin_num, bank_num, bank_pin_num;
+	unsigned int int_type, int_pol, int_any;
+
+	device_pin_num = irq_data->hwirq;
+	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num);
+
+	int_type = zynq_gpio_readreg(gpio->base_addr +
+				    ZYNQ_GPIO_INTTYPE_OFFSET(bank_num));
+	int_pol = zynq_gpio_readreg(gpio->base_addr +
+				   ZYNQ_GPIO_INTPOL_OFFSET(bank_num));
+	int_any = zynq_gpio_readreg(gpio->base_addr +
+				   ZYNQ_GPIO_INTANY_OFFSET(bank_num));
+
+	/*
+	 * based on the type requested, configure the INT_TYPE, INT_POLARITY
+	 * and INT_ANY registers
+	 */
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		int_type |= (1 << bank_pin_num);
+		int_pol |= (1 << bank_pin_num);
+		int_any &= ~(1 << bank_pin_num);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		int_type |= (1 << bank_pin_num);
+		int_pol &= ~(1 << bank_pin_num);
+		int_any &= ~(1 << bank_pin_num);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		int_type |= (1 << bank_pin_num);
+		int_any |= (1 << bank_pin_num);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		int_type &= ~(1 << bank_pin_num);
+		int_pol |= (1 << bank_pin_num);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		int_type &= ~(1 << bank_pin_num);
+		int_pol &= ~(1 << bank_pin_num);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	zynq_gpio_writereg(int_type,
+			  gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num));
+	zynq_gpio_writereg(int_pol,
+			  gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num));
+	zynq_gpio_writereg(int_any,
+			  gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num));
+	return 0;
+}
+
+static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on)
+{
+	if (on)
+		zynq_gpio_irq_unmask(data);
+	else
+		zynq_gpio_irq_mask(data);
+
+	return 0;
+}
+
+/* irq chip descriptor */
+static struct irq_chip zynq_gpio_irqchip = {
+	.name		= DRIVER_NAME,
+	.irq_ack	= zynq_gpio_irq_ack,
+	.irq_mask	= zynq_gpio_irq_mask,
+	.irq_unmask	= zynq_gpio_irq_unmask,
+	.irq_set_type	= zynq_gpio_set_irq_type,
+	.irq_set_wake	= zynq_gpio_set_wake,
+};
+
+/**
+ * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device
+ * @irq:	irq number of the gpio bank where interrupt has occurred
+ * @desc:	irq descriptor instance of the 'irq'
+ *
+ * This function reads the Interrupt Status Register of each bank to get the
+ * gpio pin number which has triggered an interrupt. It then acks the triggered
+ * interrupt and calls the pin specific handler set by the higher layer
+ * application for that pin.
+ * Note: A bug is reported if no handler is set for the gpio pin.
+ */
+static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc)
+{
+	struct zynq_gpio *gpio = (struct zynq_gpio *)irq_get_handler_data(irq);
+	int gpio_irq = gpio->irq_base;
+	unsigned int int_sts, int_enb, bank_num;
+	struct irq_desc *gpio_irq_desc;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+
+	chained_irq_enter(chip, desc);
+
+	for (bank_num = 0; bank_num < 4; bank_num++) {
+		int_sts = zynq_gpio_readreg(gpio->base_addr +
+					   ZYNQ_GPIO_INTSTS_OFFSET(bank_num));
+		int_enb = zynq_gpio_readreg(gpio->base_addr +
+					   ZYNQ_GPIO_INTMASK_OFFSET(bank_num));
+		int_sts &= ~int_enb;
+
+		for (; int_sts != 0; int_sts >>= 1, gpio_irq++) {
+			if ((int_sts & 1) == 0)
+				continue;
+			gpio_irq_desc = irq_to_desc(gpio_irq);
+			BUG_ON(!gpio_irq_desc);
+			chip = irq_desc_get_chip(gpio_irq_desc);
+			BUG_ON(!chip);
+			chip->irq_ack(&gpio_irq_desc->irq_data);
+
+			/* call the pin specific handler */
+			generic_handle_irq(gpio_irq);
+		}
+		/* shift to first virtual irq of next bank */
+		gpio_irq = gpio->irq_base + zynq_gpio_pin_table[bank_num] + 1;
+	}
+
+	chip = irq_desc_get_chip(desc);
+	chained_irq_exit(chip, desc);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int zynq_gpio_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	if (!device_may_wakeup(dev)) {
+		if (!pm_runtime_suspended(dev))
+			clk_disable(gpio->clk);
+		return 0;
+	}
+
+	return 0;
+}
+
+static int zynq_gpio_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	if (!device_may_wakeup(dev)) {
+		if (!pm_runtime_suspended(dev))
+			return clk_enable(gpio->clk);
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int zynq_gpio_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	clk_disable(gpio->clk);
+
+	return 0;
+}
+
+static int zynq_gpio_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	return clk_enable(gpio->clk);
+}
+
+static int zynq_gpio_idle(struct device *dev)
+{
+	return pm_schedule_suspend(dev, 1);
+}
+
+static int zynq_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	int ret;
+
+	ret = pm_runtime_get_sync(chip->dev);
+
+	/*
+	 * If the device is already active pm_runtime_get() will return 1 on
+	 * success, but gpio_request still needs to return 0.
+	 */
+	return ret < 0 ? ret : 0;
+}
+
+static void zynq_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pm_runtime_put_sync(chip->dev);
+}
+
+static void zynq_gpio_pm_runtime_init(struct platform_device *pdev)
+{
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	clk_disable(gpio->clk);
+	pm_runtime_enable(&pdev->dev);
+}
+
+#else /* ! CONFIG_PM_RUNTIME */
+#define zynq_gpio_request	NULL
+#define zynq_gpio_free	NULL
+static void zynq_gpio_pm_runtime_init(struct platform_device *pdev) {}
+#endif /* ! CONFIG_PM_RUNTIME */
+
+#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
+static const struct dev_pm_ops zynq_gpio_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(zynq_gpio_suspend, zynq_gpio_resume)
+	SET_RUNTIME_PM_OPS(zynq_gpio_runtime_suspend, zynq_gpio_runtime_resume,
+			zynq_gpio_idle)
+};
+#define ZYNQ_GPIO_PM	(&zynq_gpio_dev_pm_ops)
+
+#else /*! CONFIG_PM_RUNTIME || ! CONFIG_PM_SLEEP */
+#define ZYNQ_GPIO_PM	NULL
+#endif /*! CONFIG_PM_RUNTIME */
+
+/**
+ * zynq_gpio_probe - Initialization method for a zynq_gpio device
+ * @pdev:	platform device instance
+ *
+ * This function allocates memory resources for the gpio device and registers
+ * all the banks of the device. It will also set up interrupts for the gpio
+ * pins.
+ * Note: Interrupts are disabled for all the banks during initialization.
+ * Returns 0 on success, negative error otherwise.
+ */
+static int zynq_gpio_probe(struct platform_device *pdev)
+{
+	int ret;
+	unsigned int irq_num;
+	struct zynq_gpio *gpio;
+	struct gpio_chip *chip;
+	struct resource *res;
+	int pin_num, bank_num, gpio_irq;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	spin_lock_init(&gpio->gpio_lock);
+
+	platform_set_drvdata(pdev, gpio);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	gpio->base_addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gpio->base_addr))
+		return PTR_ERR(gpio->base_addr);
+
+	irq_num = platform_get_irq(pdev, 0);
+	gpio->irq = irq_num;
+
+	/* configure the gpio chip */
+	chip = &gpio->chip;
+	chip->label = "zynq_gpio";
+	chip->owner = THIS_MODULE;
+	chip->dev = &pdev->dev;
+	chip->get = zynq_gpio_get_value;
+	chip->set = zynq_gpio_set_value;
+	chip->request = zynq_gpio_request;
+	chip->free = zynq_gpio_free;
+	chip->direction_input = zynq_gpio_dir_in;
+	chip->direction_output = zynq_gpio_dir_out;
+	chip->to_irq = zynq_gpio_to_irq;
+	chip->dbg_show = NULL;
+	chip->base = 0;		/* default pin base */
+	chip->ngpio = ZYNQ_GPIO_NR_GPIOS;
+	chip->can_sleep = 0;
+
+	gpio->irq_base = irq_alloc_descs(-1, 0, chip->ngpio, 0);
+	if (gpio->irq_base < 0) {
+		dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
+					   chip->ngpio, gpio->irq_base, 0,
+					   &irq_domain_simple_ops, NULL);
+
+	/* report a bug if gpio chip registration fails */
+	ret = gpiochip_add(chip);
+	if (ret < 0)
+		return ret;
+
+	dev_info(&pdev->dev, "gpio at 0x%08lx mapped to 0x%08lx\n",
+		 (unsigned long)res->start, (unsigned long)gpio->base_addr);
+
+	/* Enable GPIO clock */
+	gpio->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(gpio->clk)) {
+		dev_err(&pdev->dev, "input clock not found.\n");
+		gpiochip_remove(chip);
+		return PTR_ERR(gpio->clk);
+	}
+	ret = clk_prepare_enable(gpio->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable clock.\n");
+		gpiochip_remove(chip);
+		return ret;
+	}
+
+	/* disable interrupts for all banks */
+	for (bank_num = 0; bank_num < 4; bank_num++) {
+		zynq_gpio_writereg(0xffffffff, gpio->base_addr +
+				  ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
+	}
+
+	/*
+	 * set the irq chip, handler and irq chip data for callbacks for
+	 * each pin
+	 */
+	for (pin_num = 0; pin_num < min_t(int, ZYNQ_GPIO_NR_GPIOS,
+						(int)chip->ngpio); pin_num++) {
+		gpio_irq = irq_find_mapping(irq_domain, pin_num);
+		irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip,
+							handle_simple_irq);
+		irq_set_chip_data(gpio_irq, (void *)gpio);
+		set_irq_flags(gpio_irq, IRQF_VALID);
+	}
+
+	irq_set_handler_data(irq_num, (void *)gpio);
+	irq_set_chained_handler(irq_num, zynq_gpio_irqhandler);
+
+	zynq_gpio_pm_runtime_init(pdev);
+
+	device_set_wakeup_capable(&pdev->dev, 1);
+
+	return 0;
+
+
+	return ret;
+}
+
+static int zynq_gpio_remove(struct platform_device *pdev)
+{
+	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(gpio->clk);
+	device_set_wakeup_capable(&pdev->dev, 0);
+	return 0;
+}
+
+static struct of_device_id zynq_gpio_of_match[] = {
+	{ .compatible = "xlnx,ps7-gpio-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, zynq_gpio_of_match);
+
+static struct platform_driver zynq_gpio_driver = {
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= ZYNQ_GPIO_PM,
+		.of_match_table = zynq_gpio_of_match,
+	},
+	.probe		= zynq_gpio_probe,
+	.remove		= zynq_gpio_remove,
+};
+
+/**
+ * zynq_gpio_init - Initial driver registration call
+ */
+static int __init zynq_gpio_init(void)
+{
+	return platform_driver_register(&zynq_gpio_driver);
+}
+
+postcore_initcall(zynq_gpio_init);
Index: linux-3.12.24-rt38-xilinx/drivers/gpio/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpio/Kconfig	2014-07-20 22:05:50.183067495 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpio/Kconfig	2014-07-20 22:06:35.893313355 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:281 @
 config GPIO_XILINX
 	bool "Xilinx GPIO support"
 	depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
+	select GENERIC_IRQ_CHIP
 	help
-	  Say yes here to support the Xilinx FPGA GPIO device
+	  Say yes here to support the Xilinx AXI/XPS GPIO device
+
+config GPIO_ZYNQ
+	tristate "Xilinx ZYNQ GPIO support"
+	depends on ARCH_ZYNQ
+	select GENERIC_IRQ_CHIP
+	help
+	  Say yes here to support Xilinx ZYNQ GPIO controller.
 
 config GPIO_VR41XX
 	tristate "NEC VR4100 series General-purpose I/O Uint support"
Index: linux-3.12.24-rt38-xilinx/drivers/gpio/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpio/Makefile	2014-07-20 22:05:50.182067512 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpio/Makefile	2014-07-20 22:06:35.974312019 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:95 @
 obj-$(CONFIG_GPIO_WM8350)	+= gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)	+= gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)	+= gpio-xilinx.o
+obj-$(CONFIG_GPIO_ZYNQ)		+= gpio-zynq.o
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/drm_edid.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpu/drm/drm_edid.c	2014-07-20 22:05:50.197067264 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/drm_edid.c	2014-07-20 22:06:36.004311524 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1100 @
  * Try to fetch EDID information by calling i2c driver function.
  */
 static int
-drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
+drm_do_probe_ddc_edid(void *data, unsigned char *buf,
 		      int block, int len)
 {
+	struct i2c_adapter *adapter = data;
 	unsigned char start = block * EDID_LENGTH;
 	unsigned char segment = block >> 1;
 	unsigned char xfers = segment ? 3 : 2;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1159 @
 	return true;
 }
 
-static u8 *
-drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
+struct edid *drm_do_get_edid(struct drm_connector *connector,
+	int (*get_edid_block)(void *, unsigned char *buf, int, int), void *data)
 {
 	int i, j = 0, valid_extensions = 0;
 	u8 *block, *new;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1171 @
 
 	/* base block fetch */
 	for (i = 0; i < 4; i++) {
-		if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
+		if (get_edid_block(data, block, 0, EDID_LENGTH))
 			goto out;
 		if (drm_edid_block_valid(block, 0, print_bad_edid))
 			break;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1185 @
 
 	/* if there's no extensions, we're done */
 	if (block[0x7e] == 0)
-		return block;
+		return (struct edid *)block;
 
 	new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
 	if (!new)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1194 @
 
 	for (j = 1; j <= block[0x7e]; j++) {
 		for (i = 0; i < 4; i++) {
-			if (drm_do_probe_ddc_edid(adapter,
+			if (get_edid_block(data,
 				  block + (valid_extensions + 1) * EDID_LENGTH,
 				  j, EDID_LENGTH))
 				goto out;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1222 @
 		block = new;
 	}
 
-	return block;
+	return (struct edid *)block;
 
 carp:
 	if (print_bad_edid) {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1235 @
 	kfree(block);
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(drm_do_get_edid);
 
 /**
  * Probe DDC presence.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1268 @
 	struct edid *edid = NULL;
 
 	if (drm_probe_ddc(adapter))
-		edid = (struct edid *)drm_do_get_edid(connector, adapter);
+		edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid,
+				adapter);
 
 	return edid;
 }
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/adv7511_audio.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/adv7511_audio.c	2014-07-20 22:06:36.020311260 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include <drm/i2c/adv7511.h>
+
+static const struct snd_soc_dapm_widget adv7511_dapm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("TMDS"),
+	SND_SOC_DAPM_AIF_IN("AIFIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
+};
+
+static const struct snd_soc_dapm_route adv7511_routes[] = {
+	{ "TMDS", NULL, "AIFIN" },
+};
+
+static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
+			       unsigned int *cts, unsigned int *n)
+{
+	switch (fs) {
+	case 32000:
+		*n = 4096;
+		break;
+	case 44100:
+		*n = 6272;
+		break;
+	case 48000:
+		*n = 6144;
+		break;
+	}
+
+	*cts = ((f_tmds * *n) / (128 * fs)) * 1000;
+}
+
+static int adv7511_update_cts_n(struct adv7511 *adv7511)
+{
+	unsigned int cts = 0;
+	unsigned int n = 0;
+
+	adv7511_calc_cts_n(adv7511->f_tmds, adv7511->f_audio, &cts, &n);
+
+	regmap_write(adv7511->regmap, ADV7511_REG_N0, (n >> 16) & 0xf);
+	regmap_write(adv7511->regmap, ADV7511_REG_N1, (n >> 8) & 0xff);
+	regmap_write(adv7511->regmap, ADV7511_REG_N2, n & 0xff);
+
+	regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL0,
+		     (cts >> 16) & 0xf);
+	regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL1,
+		     (cts >> 8) & 0xff);
+	regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL2,
+		     cts & 0xff);
+
+	return 0;
+}
+
+static int adv7511_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params,
+			     struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec);
+	unsigned int rate;
+	unsigned int len;
+
+	switch (params_rate(params)) {
+	case 32000:
+		rate = ADV7511_SAMPLE_FREQ_32000;
+		break;
+	case 44100:
+		rate = ADV7511_SAMPLE_FREQ_44100;
+		break;
+	case 48000:
+		rate = ADV7511_SAMPLE_FREQ_48000;
+		break;
+	case 88200:
+		rate = ADV7511_SAMPLE_FREQ_88200;
+		break;
+	case 96000:
+		rate = ADV7511_SAMPLE_FREQ_96000;
+		break;
+	case 176400:
+		rate = ADV7511_SAMPLE_FREQ_176400;
+		break;
+	case 192000:
+		rate = ADV7511_SAMPLE_FREQ_192000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		len = ADV7511_I2S_SAMPLE_LEN_16;
+		break;
+	case SNDRV_PCM_FORMAT_S18_3LE:
+		len = ADV7511_I2S_SAMPLE_LEN_18;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		len = ADV7511_I2S_SAMPLE_LEN_20;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		len = ADV7511_I2S_SAMPLE_LEN_24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	adv7511->f_audio = params_rate(params);
+
+	adv7511_update_cts_n(adv7511);
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CFG3,
+			   ADV7511_AUDIO_CFG3_LEN_MASK, len);
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG,
+			   ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4);
+
+	return 0;
+}
+
+static int adv7511_set_dai_fmt(struct snd_soc_dai *codec_dai,
+			       unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec);
+	unsigned int audio_source, i2s_format = 0;
+	unsigned int invert_clock;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		audio_source = ADV7511_AUDIO_SOURCE_I2S;
+		i2s_format = ADV7511_I2S_FORMAT_I2S;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		audio_source = ADV7511_AUDIO_SOURCE_I2S;
+		i2s_format = ADV7511_I2S_FORMAT_RIGHT_J;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		audio_source = ADV7511_AUDIO_SOURCE_I2S;
+		i2s_format = ADV7511_I2S_FORMAT_LEFT_J;
+		break;
+	case SND_SOC_DAIFMT_SPDIF:
+		audio_source = ADV7511_AUDIO_SOURCE_SPDIF;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		invert_clock = 0;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		invert_clock = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_SOURCE, 0x70,
+			   audio_source << 4);
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, BIT(6),
+			   invert_clock << 6);
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_I2S_CONFIG, 0x03,
+			   i2s_format);
+
+	adv7511->audio_source = audio_source;
+
+	return 0;
+}
+
+static int adv7511_set_bias_level(struct snd_soc_codec *codec,
+				  enum snd_soc_bias_level level)
+{
+	struct adv7511 *adv7511 = snd_soc_codec_get_drvdata(codec);
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		switch (adv7511->audio_source) {
+		case ADV7511_AUDIO_SOURCE_I2S:
+			break;
+		case ADV7511_AUDIO_SOURCE_SPDIF:
+			regmap_update_bits(adv7511->regmap,
+					   ADV7511_REG_AUDIO_CONFIG, BIT(7),
+					   BIT(7));
+			break;
+		}
+		break;
+	case SND_SOC_BIAS_PREPARE:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
+			adv7511_packet_enable(adv7511,
+					ADV7511_PACKET_ENABLE_AUDIO_SAMPLE);
+			adv7511_packet_enable(adv7511,
+					ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME);
+			adv7511_packet_enable(adv7511,
+					ADV7511_PACKET_ENABLE_N_CTS);
+		} else {
+			adv7511_packet_disable(adv7511,
+					ADV7511_PACKET_ENABLE_AUDIO_SAMPLE);
+			adv7511_packet_disable(adv7511,
+					ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME);
+			adv7511_packet_disable(adv7511,
+					ADV7511_PACKET_ENABLE_N_CTS);
+		}
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
+				   BIT(7), 0);
+		break;
+	case SND_SOC_BIAS_OFF:
+		break;
+	}
+	codec->dapm.bias_level = level;
+	return 0;
+}
+
+#define ADV7511_RATES (SNDRV_PCM_RATE_32000 |\
+		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+		SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\
+		SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
+
+#define ADV7511_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\
+		SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops adv7511_dai_ops = {
+	.hw_params	= adv7511_hw_params,
+	/*.set_sysclk	= adv7511_set_dai_sysclk,*/
+	.set_fmt	= adv7511_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver adv7511_dai = {
+	.name = "adv7511",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = ADV7511_RATES,
+		.formats = ADV7511_FORMATS,
+	},
+	.ops = &adv7511_dai_ops,
+};
+
+static int adv7511_suspend(struct snd_soc_codec *codec)
+{
+	return adv7511_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static int adv7511_resume(struct snd_soc_codec *codec)
+{
+	return adv7511_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+}
+
+static int adv7511_probe(struct snd_soc_codec *codec)
+{
+	int ret;
+
+	ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+	if (ret < 0) {
+		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+		return ret;
+	}
+
+	return adv7511_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+}
+
+static int adv7511_remove(struct snd_soc_codec *codec)
+{
+	adv7511_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	return 0;
+}
+
+static struct snd_soc_codec_driver adv7511_codec_driver = {
+	.probe		    = adv7511_probe,
+	.remove		    = adv7511_remove,
+	.suspend	    = adv7511_suspend,
+	.resume		    = adv7511_resume,
+	.set_bias_level	    = adv7511_set_bias_level,
+
+	.dapm_widgets	    = adv7511_dapm_widgets,
+	.num_dapm_widgets   = ARRAY_SIZE(adv7511_dapm_widgets),
+	.dapm_routes	    = adv7511_routes,
+	.num_dapm_routes    = ARRAY_SIZE(adv7511_routes),
+};
+
+int adv7511_audio_init(struct device *dev)
+{
+	return snd_soc_register_codec(dev, &adv7511_codec_driver,
+				      &adv7511_dai, 1);
+}
+
+void adv7511_audio_exit(struct device *dev)
+{
+	snd_soc_unregister_codec(dev);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/adv7511_core.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/adv7511_core.c	2014-07-20 22:06:36.034311029 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+
+#include <drm/i2c/adv7511.h>
+
+static const uint8_t adv7511_register_defaults[] = {
+	0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */
+	0x00, 0x00, 0x01, 0x0e, 0xbc, 0x18, 0x01, 0x13,
+	0x25, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */
+	0x46, 0x62, 0x04, 0xa8, 0x00, 0x00, 0x1c, 0x84,
+	0x1c, 0xbf, 0x04, 0xa8, 0x1e, 0x70, 0x02, 0x1e, /* 20 */
+	0x00, 0x00, 0x04, 0xa8, 0x08, 0x12, 0x1b, 0xac,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */
+	0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,
+	0x00, 0x50, 0x90, 0x7e, 0x79, 0x70, 0x00, 0x00, /* 40 */
+	0x00, 0xa8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, /* 50 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 90 */
+	0x0b, 0x02, 0x00, 0x18, 0x5a, 0x60, 0x00, 0x00,
+	0x00, 0x00, 0x80, 0x80, 0x08, 0x04, 0x00, 0x00, /* a0 */
+	0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x14,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0 */
+	0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x01, 0x04,
+	0x30, 0xff, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* d0 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
+	0x80, 0x75, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* e0 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, /* f0 */
+	0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+/* ADI recommanded values for proper operation. */
+static const struct reg_default adv7511_fixed_registers[] = {
+	{ 0x98, 0x03 },
+	{ 0x9a, 0xe0 },
+	{ 0x9c, 0x30 },
+	{ 0x9d, 0x61 },
+	{ 0xa2, 0xa4 },
+	{ 0xa3, 0xa4 },
+	{ 0xe0, 0xd0 },
+	{ 0xf9, 0x00 },
+	{ 0x55, 0x02 },
+};
+
+static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
+{
+	return to_encoder_slave(encoder)->slave_priv;
+}
+
+static void adv7511_set_colormap(struct adv7511 *adv7511, bool enable,
+				 const uint16_t *coeff,
+				 unsigned int scaling_factor)
+{
+	unsigned int i;
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1),
+			   ADV7511_CSC_UPDATE_MODE, ADV7511_CSC_UPDATE_MODE);
+
+	if (enable) {
+		for (i = 0; i < 12; ++i) {
+			regmap_update_bits(adv7511->regmap,
+					   ADV7511_REG_CSC_UPPER(i),
+					   0x1f, coeff[i] >> 8);
+			regmap_write(adv7511->regmap,
+				     ADV7511_REG_CSC_LOWER(i),
+				     coeff[i] & 0xff);
+		}
+	}
+
+	if (enable)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(0),
+				   0xe0, 0x80 | (scaling_factor << 5));
+	else
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(0),
+				   0x80, 0x00);
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1),
+			   ADV7511_CSC_UPDATE_MODE, 0);
+}
+
+#define ADV7511_HDMI_CFG_MODE_MASK 0x2
+#define ADV7511_HDMI_CFG_MODE_DVI 0x0
+#define ADV7511_HDMI_CFG_MODE_HDMI 0x2
+
+#define ADV7511_PACKET_MEM_SPD		0
+#define ADV7511_PACKET_MEM_MPEG		1
+#define ADV7511_PACKET_MEM_ACP		2
+#define ADV7511_PACKET_MEM_ISRC1	3
+#define ADV7511_PACKET_MEM_ISRC2	4
+#define ADV7511_PACKET_MEM_GM		5
+#define ADV7511_PACKET_MEM_SPARE1	6
+#define ADV7511_PACKET_MEM_SPARE2	7
+
+#define ADV7511_PACKET_MEM_DATA_REG(x) ((x) * 0x20)
+#define ADV7511_PACKET_MEM_UPDATE_REG(x) ((x) * 0x20 + 0x1f)
+#define ADV7511_PACKET_MEM_UPDATE_ENABLE BIT(7)
+
+static void adv7511_set_config(struct drm_encoder *encoder, void *c)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+	struct adv7511_video_config *config = c;
+	bool output_format_422, output_format_ycbcr;
+	unsigned int mode;
+	uint8_t infoframe[17];
+
+	if (config->hdmi_mode) {
+		mode = ADV7511_HDMI_CFG_MODE_HDMI;
+
+		switch (config->avi_infoframe.colorspace) {
+		case HDMI_COLORSPACE_YUV444:
+			output_format_422 = false;
+			output_format_ycbcr = true;
+			break;
+		case HDMI_COLORSPACE_YUV422:
+			output_format_422 = true;
+			output_format_ycbcr = true;
+			break;
+		default:
+			output_format_422 = false;
+			output_format_ycbcr = false;
+			break;
+		}
+	} else {
+		mode = ADV7511_HDMI_CFG_MODE_DVI;
+		output_format_422 = false;
+		output_format_ycbcr = false;
+	}
+
+	adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME);
+
+	adv7511_set_colormap(adv7511, config->csc_enable,
+			     config->csc_coefficents,
+			     config->csc_scaling_factor);
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG1, 0x81,
+			   (output_format_422 << 7) | output_format_ycbcr);
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_HDCP_HDMI_CFG,
+			   ADV7511_HDMI_CFG_MODE_MASK, mode);
+
+	hdmi_avi_infoframe_pack(&config->avi_infoframe, infoframe,
+				sizeof(infoframe));
+
+	/* The AVI infoframe id is not configurable */
+	regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION,
+			  infoframe + 1, sizeof(infoframe) - 1);
+
+	adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME);
+}
+
+static void adv7511_set_link_config(struct adv7511 *adv7511,
+				    const struct adv7511_link_config *config)
+{
+	enum adv7511_input_sync_pulse sync_pulse;
+
+	switch (config->id) {
+	case ADV7511_INPUT_ID_12_15_16BIT_RGB444_YCbCr444:
+		sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE;
+		break;
+	default:
+		sync_pulse = config->sync_pulse;
+		break;
+	}
+
+	switch (config->id) {
+	case ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC:
+	case ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_EMBEDDED_SYNC:
+		adv7511->embedded_sync = true;
+		break;
+	default:
+		adv7511->embedded_sync = false;
+		break;
+	}
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, 0xf,
+			   config->id);
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG1, 0x7e,
+			   (config->input_color_depth << 4) |
+			   (config->input_style << 2));
+	regmap_write(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG2,
+		     (config->reverse_bitorder << 6) |
+		     (config->bit_justification << 3));
+	regmap_write(adv7511->regmap, ADV7511_REG_TIMING_GEN_SEQ,
+		     (sync_pulse << 2) | (config->timing_gen_seq << 1));
+	regmap_write(adv7511->regmap, 0xba, (config->clock_delay << 5));
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_TMDS_CLOCK_INV, 0x08,
+			   config->tmds_clock_inversion << 3);
+
+	adv7511->hsync_polarity = config->hsync_polarity;
+	adv7511->vsync_polarity = config->vsync_polarity;
+}
+
+int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet)
+{
+	if (packet & 0xff)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,
+				   packet, 0xff);
+
+	if (packet & 0xff00) {
+		packet >>= 8;
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1,
+				   packet, 0xff);
+	}
+
+	return 0;
+}
+
+int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet)
+{
+	if (packet & 0xff)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,
+				   packet, 0x00);
+
+	if (packet & 0xff00) {
+		packet >>= 8;
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1,
+				   packet, 0x00);
+	}
+
+	return 0;
+}
+
+static bool adv7511_register_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case ADV7511_REG_SPDIF_FREQ:
+	case ADV7511_REG_CTS_AUTOMATIC1:
+	case ADV7511_REG_CTS_AUTOMATIC2:
+	case ADV7511_REG_VIC_DETECTED:
+	case ADV7511_REG_VIC_SEND:
+	case ADV7511_REG_AUX_VIC_DETECTED:
+	case ADV7511_REG_STATUS:
+	case ADV7511_REG_GC(1):
+	case ADV7511_REG_INT(0):
+	case ADV7511_REG_INT(1):
+	case ADV7511_REG_PLL_STATUS:
+	case ADV7511_REG_AN(0):
+	case ADV7511_REG_AN(1):
+	case ADV7511_REG_AN(2):
+	case ADV7511_REG_AN(3):
+	case ADV7511_REG_AN(4):
+	case ADV7511_REG_AN(5):
+	case ADV7511_REG_AN(6):
+	case ADV7511_REG_AN(7):
+	case ADV7511_REG_HDCP_STATUS:
+	case ADV7511_REG_BCAPS:
+	case ADV7511_REG_BKSV(0):
+	case ADV7511_REG_BKSV(1):
+	case ADV7511_REG_BKSV(2):
+	case ADV7511_REG_BKSV(3):
+	case ADV7511_REG_BKSV(4):
+	case ADV7511_REG_DDC_STATUS:
+	case ADV7511_REG_BSTATUS(0):
+	case ADV7511_REG_BSTATUS(1):
+	case ADV7511_REG_CHIP_ID_HIGH:
+	case ADV7511_REG_CHIP_ID_LOW:
+		return true;
+	}
+
+	return false;
+}
+
+static bool adv7511_hpd(struct adv7511 *adv7511)
+{
+	unsigned int irq0;
+	int ret;
+
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);
+	if (ret < 0)
+		return false;
+
+	if (irq0 & ADV7511_INT0_HDP) {
+		regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+			     ADV7511_INT0_HDP);
+		return true;
+	}
+
+	return false;
+}
+
+static irqreturn_t adv7511_irq_handler(int irq, void *devid)
+{
+	struct adv7511 *adv7511 = devid;
+
+	if (adv7511_hpd(adv7511))
+		drm_helper_hpd_irq_event(adv7511->encoder->dev);
+
+	wake_up_all(&adv7511->wq);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned int adv7511_is_interrupt_pending(struct adv7511 *adv7511,
+						 unsigned int irq)
+{
+	unsigned int irq0, irq1;
+	unsigned int pending;
+	int ret;
+
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);
+	if (ret < 0)
+		return 0;
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1);
+	if (ret < 0)
+		return 0;
+
+	pending = (irq1 << 8) | irq0;
+
+	return pending & irq;
+}
+
+static int adv7511_wait_for_interrupt(struct adv7511 *adv7511, int irq,
+				      int timeout)
+{
+	unsigned int pending = 0;
+	int ret;
+
+	if (adv7511->i2c_main->irq) {
+		ret = wait_event_interruptible_timeout(adv7511->wq,
+				adv7511_is_interrupt_pending(adv7511, irq),
+				msecs_to_jiffies(timeout));
+		if (ret <= 0)
+			return 0;
+		pending = adv7511_is_interrupt_pending(adv7511, irq);
+	} else {
+		if (timeout < 25)
+			timeout = 25;
+		do {
+			pending = adv7511_is_interrupt_pending(adv7511, irq);
+			if (pending)
+				break;
+			msleep(25);
+			timeout -= 25;
+		} while (timeout >= 25);
+	}
+
+	return pending;
+}
+
+static int adv7511_get_edid_block(void *data, unsigned char *buf, int block,
+				  int len)
+{
+	struct drm_encoder *encoder = data;
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+	struct i2c_msg xfer[2];
+	uint8_t offset;
+	int i;
+	int ret;
+
+	if (len > 128)
+		return -EINVAL;
+
+	if (adv7511->current_edid_segment != block / 2) {
+		unsigned int status;
+
+		ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS,
+				  &status);
+		if (ret < 0)
+			return ret;
+
+		if (status != 2) {
+			regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
+				     block);
+			ret = adv7511_wait_for_interrupt(adv7511,
+					ADV7511_INT0_EDID_READY |
+					ADV7511_INT1_DDC_ERROR, 200);
+
+			if (!(ret & ADV7511_INT0_EDID_READY))
+				return -EIO;
+		}
+
+		regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+			     ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR);
+
+		/* Break this apart, hopefully more I2C controllers will
+		 * support 64 byte transfers than 256 byte transfers
+		 */
+
+		xfer[0].addr = adv7511->i2c_edid->addr;
+		xfer[0].flags = 0;
+		xfer[0].len = 1;
+		xfer[0].buf = &offset;
+		xfer[1].addr = adv7511->i2c_edid->addr;
+		xfer[1].flags = I2C_M_RD;
+		xfer[1].len = 64;
+		xfer[1].buf = adv7511->edid_buf;
+
+		offset = 0;
+
+		for (i = 0; i < 4; ++i) {
+			ret = i2c_transfer(adv7511->i2c_edid->adapter, xfer,
+					   ARRAY_SIZE(xfer));
+			if (ret < 0)
+				return ret;
+			else if (ret != 2)
+				return -EIO;
+
+			xfer[1].buf += 64;
+			offset += 64;
+		}
+
+		adv7511->current_edid_segment = block / 2;
+	}
+
+	if (block % 2 == 0)
+		memcpy(buf, adv7511->edid_buf, len);
+	else
+		memcpy(buf, adv7511->edid_buf + 128, len);
+
+	return 0;
+}
+
+static int adv7511_get_modes(struct drm_encoder *encoder,
+			     struct drm_connector *connector)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+	struct edid *edid;
+	unsigned int count;
+
+	/* Reading the EDID only works if the device is powered */
+	if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) {
+		regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+			     ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR);
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+				   ADV7511_POWER_POWER_DOWN, 0);
+		adv7511->current_edid_segment = -1;
+	}
+
+	edid = drm_do_get_edid(connector, adv7511_get_edid_block, encoder);
+
+	if (adv7511->dpms_mode != DRM_MODE_DPMS_ON)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+				   ADV7511_POWER_POWER_DOWN,
+				   ADV7511_POWER_POWER_DOWN);
+
+	adv7511->edid = edid;
+	if (!edid)
+		return 0;
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	count = drm_add_edid_modes(connector, edid);
+
+	kfree(adv7511->edid);
+
+	return count;
+}
+
+struct edid *adv7511_get_edid(struct drm_encoder *encoder)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+
+	if (!adv7511->edid)
+		return NULL;
+
+	return kmemdup(adv7511->edid, sizeof(*adv7511->edid) +
+		       adv7511->edid->extensions * 128, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(adv7511_get_edid);
+
+static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+		adv7511->current_edid_segment = -1;
+
+		regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+			     ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR);
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+				   ADV7511_POWER_POWER_DOWN, 0);
+		/*
+		 * Per spec it is allowed to pulse the HDP signal to indicate
+		 * that the EDID information has changed. Some monitors do this
+		 * when they wakeup from standby or are enabled. When the HDP
+		 * goes low the adv7511 is reset and the outputs are disabled
+		 * which might cause the monitor to go to standby again. To
+		 * avoid this we ignore the HDP pin for the first few seconds
+		 * after enabeling the output.
+		 */
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
+				   ADV7511_REG_POWER2_HDP_SRC_MASK,
+				   ADV7511_REG_POWER2_HDP_SRC_NONE);
+		/* Most of the registers are reset during power down or
+		 * when HPD is low
+		 */
+		regcache_sync(adv7511->regmap);
+		break;
+	default:
+		/* TODO: setup additional power down modes */
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+				   ADV7511_POWER_POWER_DOWN,
+				   ADV7511_POWER_POWER_DOWN);
+		regcache_mark_dirty(adv7511->regmap);
+		break;
+	}
+
+	adv7511->dpms_mode = mode;
+}
+
+static enum drm_connector_status
+adv7511_encoder_detect(struct drm_encoder *encoder,
+		       struct drm_connector *connector)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+	enum drm_connector_status status;
+	unsigned int val;
+	bool hpd;
+	int ret;
+
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
+	if (ret < 0)
+		return connector_status_disconnected;
+
+	if (val & ADV7511_STATUS_HPD)
+		status = connector_status_connected;
+	else
+		status = connector_status_disconnected;
+
+	hpd = adv7511_hpd(adv7511);
+
+	/* The chip resets itself when the cable is disconnected, so in case
+	 * there is a pending HPD interrupt and the cable is connected there was
+	 * at least on transition from disconnected to connected and the chip
+	 * has to be reinitialized. */
+	if (status == connector_status_connected && hpd &&
+	    adv7511->dpms_mode == DRM_MODE_DPMS_ON) {
+		regcache_mark_dirty(adv7511->regmap);
+		adv7511_encoder_dpms(encoder, adv7511->dpms_mode);
+		adv7511_get_modes(encoder, connector);
+		status = connector_status_disconnected;
+	} else {
+		/* Renable HDP sensing */
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
+				   ADV7511_REG_POWER2_HDP_SRC_MASK,
+				   ADV7511_REG_POWER2_HDP_SRC_BOTH);
+	}
+
+	adv7511->status = status;
+	return status;
+}
+
+static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adj_mode)
+{
+	struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+	unsigned int low_refresh_rate;
+	unsigned int hsync_polarity = 0;
+	unsigned int vsync_polarity = 0;
+
+	if (adv7511->embedded_sync) {
+		unsigned int hsync_offset, hsync_len;
+		unsigned int vsync_offset, vsync_len;
+
+		hsync_offset = adj_mode->crtc_hsync_start -
+			       adj_mode->crtc_hdisplay;
+		vsync_offset = adj_mode->crtc_vsync_start -
+			       adj_mode->crtc_vdisplay;
+		hsync_len = adj_mode->crtc_hsync_end -
+			    adj_mode->crtc_hsync_start;
+		vsync_len = adj_mode->crtc_vsync_end -
+			    adj_mode->crtc_vsync_start;
+
+		/* The hardware vsync generator has a off-by-one bug */
+		vsync_offset += 1;
+
+		regmap_write(adv7511->regmap, ADV7511_REG_HSYNC_PLACEMENT_MSB,
+			     ((hsync_offset >> 10) & 0x7) << 5);
+		regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(0),
+			     (hsync_offset >> 2) & 0xff);
+		regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(1),
+			     ((hsync_offset & 0x3) << 6) |
+			     ((hsync_len >> 4) & 0x3f));
+		regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(2),
+			     ((hsync_len & 0xf) << 4) |
+			     ((vsync_offset >> 6) & 0xf));
+		regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(3),
+			     ((vsync_offset & 0x3f) << 2) |
+			     ((vsync_len >> 8) & 0x3));
+		regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(4),
+			     vsync_len & 0xff);
+
+		hsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PHSYNC);
+		vsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PVSYNC);
+	} else {
+		enum adv7511_sync_polarity mode_hsync_polarity;
+		enum adv7511_sync_polarity mode_vsync_polarity;
+
+		/**
+		 * If the input signal is always low or always high we want to
+		 * invert or let it passthrough depending on the polarity of the
+		 * current mode.
+		 **/
+		if (adj_mode->flags & DRM_MODE_FLAG_NHSYNC)
+			mode_hsync_polarity = ADV7511_SYNC_POLARITY_LOW;
+		else
+			mode_hsync_polarity = ADV7511_SYNC_POLARITY_HIGH;
+
+		if (adj_mode->flags & DRM_MODE_FLAG_NVSYNC)
+			mode_vsync_polarity = ADV7511_SYNC_POLARITY_LOW;
+		else
+			mode_vsync_polarity = ADV7511_SYNC_POLARITY_HIGH;
+
+		if (adv7511->hsync_polarity != mode_hsync_polarity &&
+		    adv7511->hsync_polarity !=
+		    ADV7511_SYNC_POLARITY_PASSTHROUGH)
+			hsync_polarity = 1;
+
+		if (adv7511->vsync_polarity != mode_vsync_polarity &&
+		    adv7511->vsync_polarity !=
+		    ADV7511_SYNC_POLARITY_PASSTHROUGH)
+			vsync_polarity = 1;
+	}
+
+	if (mode->vrefresh <= 24000)
+		low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ;
+	else if (mode->vrefresh <= 25000)
+		low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ;
+	else if (mode->vrefresh <= 30000)
+		low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ;
+	else
+		low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
+
+	regmap_update_bits(adv7511->regmap, 0xfb,
+		0x6, low_refresh_rate << 1);
+	regmap_update_bits(adv7511->regmap, 0x17,
+		0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+
+	adv7511->f_tmds = mode->clock;
+}
+
+static struct drm_encoder_slave_funcs adv7511_encoder_funcs = {
+	.set_config = adv7511_set_config,
+	.dpms = adv7511_encoder_dpms,
+	/* .destroy = adv7511_encoder_destroy,*/
+	.mode_set = adv7511_encoder_mode_set,
+	.detect = adv7511_encoder_detect,
+	.get_modes = adv7511_get_modes,
+};
+
+static const struct regmap_config adv7511_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = 0xff,
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults_raw = adv7511_register_defaults,
+	.num_reg_defaults_raw = ARRAY_SIZE(adv7511_register_defaults),
+
+	.volatile_reg = adv7511_register_volatile,
+};
+
+/*
+	adi,input-id -
+		0x00:
+		0x01:
+		0x02:
+		0x03:
+		0x04:
+		0x05:
+	adi,sync-pulse - Selects the sync pulse
+		0x00: Use the DE signal as sync pulse
+		0x01: Use the HSYNC signal as sync pulse
+		0x02: Use the VSYNC signal as sync pulse
+		0x03: No external sync pulse
+	adi,bit-justification -
+		0x00: Evently
+		0x01: Right
+		0x02: Left
+	adi,up-conversion -
+		0x00: zero-order up conversion
+		0x01: first-order up conversion
+	adi,timing-generation-sequence -
+		0x00: Sync adjustment first, then DE generation
+		0x01: DE generation first then sync adjustment
+	adi,vsync-polarity - Polarity of the vsync signal
+		0x00: Passthrough
+		0x01: Active low
+		0x02: Active high
+	adi,hsync-polarity - Polarity of the hsync signal
+		0x00: Passthrough
+		0x01: Active low
+		0x02: Active high
+	adi,reverse-bitorder - If set the bitorder is reveresed
+	adi,tmds-clock-inversion - If set use tdms clock inversion
+	adi,clock-delay - Clock delay for the video data clock
+		0x00: -1200 ps
+		0x01:  -800 ps
+		0x02:  -400 ps
+		0x03: no dealy
+		0x04:   400 ps
+		0x05:   800 ps
+		0x06:  1200 ps
+		0x07:  1600 ps
+	adi,input-style - Specifies the input style used
+		0x02: Use input style 1
+		0x01: Use input style 2
+		0x03: Use Input style 3
+	adi,input-color-depth - Selects the input format color depth
+		0x03: 8-bit per channel
+		0x01: 10-bit per channel
+		0x02: 12-bit per channel
+*/
+
+static int adv7511_parse_dt(struct device_node *np,
+			    struct adv7511_link_config *config)
+{
+	int ret;
+
+	ret = of_property_read_u32(np, "adi,input-id", &config->id);
+	if (ret < 0)
+		return ret;
+
+	config->sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE;
+	of_property_read_u32(np, "adi,sync-pulse", &config->sync_pulse);
+
+	ret = of_property_read_u32(np, "adi,bit-justification",
+				   &config->bit_justification);
+	if (ret < 0)
+		return ret;
+
+	config->up_conversion = ADV7511_UP_CONVERSION_ZERO_ORDER;
+	of_property_read_u32(np, "adi,up-conversion", &config->up_conversion);
+
+	ret = of_property_read_u32(np, "adi,timing-generation-sequence",
+				   &config->timing_gen_seq);
+	if (ret < 0)
+		return ret;
+
+	ret = of_property_read_u32(np, "adi,vsync-polarity",
+				   &config->vsync_polarity);
+	if (ret < 0)
+		return ret;
+
+	ret = of_property_read_u32(np, "adi,hsync-polarity",
+				   &config->hsync_polarity);
+	if (ret < 0)
+		return ret;
+
+	config->reverse_bitorder = of_property_read_bool(np,
+		"adi,reverse-bitorder");
+	config->tmds_clock_inversion = of_property_read_bool(np,
+		"adi,tmds-clock-inversion");
+
+	ret = of_property_read_u32(np, "adi,clock-delay",
+				   &config->clock_delay);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32(np, "adi,input-style",
+				   &config->input_style);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32(np, "adi,input-color-depth",
+				   &config->input_color_depth);
+	if (ret)
+		return ret;
+
+	config->gpio_pd = of_get_gpio(np, 0);
+	if (config->gpio_pd == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	return 0;
+}
+
+static const int edid_i2c_addr = 0x7e;
+static const int packet_i2c_addr = 0x70;
+static const int cec_i2c_addr = 0x78;
+
+static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+	struct adv7511_link_config link_config;
+	struct adv7511 *adv7511;
+	struct device *dev = &i2c->dev;
+	unsigned int val;
+	int ret;
+
+	if (dev->of_node) {
+		ret = adv7511_parse_dt(dev->of_node, &link_config);
+		if (ret)
+			return ret;
+	} else {
+		if (!dev->platform_data)
+			return -EINVAL;
+		link_config = *(struct adv7511_link_config *)dev->platform_data;
+	}
+
+	adv7511 = devm_kzalloc(dev, sizeof(*adv7511), GFP_KERNEL);
+	if (!adv7511)
+		return -ENOMEM;
+
+	adv7511->gpio_pd = link_config.gpio_pd;
+
+	if (gpio_is_valid(adv7511->gpio_pd)) {
+		ret = devm_gpio_request_one(dev, adv7511->gpio_pd,
+					    GPIOF_OUT_INIT_HIGH, "PD");
+		if (ret)
+			return ret;
+		mdelay(5);
+		gpio_set_value_cansleep(adv7511->gpio_pd, 0);
+	}
+
+	adv7511->regmap = devm_regmap_init_i2c(i2c, &adv7511_regmap_config);
+	if (IS_ERR(adv7511->regmap))
+		return PTR_ERR(adv7511->regmap);
+
+	ret = regmap_read(adv7511->regmap, ADV7511_REG_CHIP_REVISION, &val);
+	if (ret)
+		return ret;
+	dev_dbg(dev, "Rev. %d\n", val);
+
+	ret = regmap_register_patch(adv7511->regmap, adv7511_fixed_registers,
+				    ARRAY_SIZE(adv7511_fixed_registers));
+	if (ret)
+		return ret;
+
+	regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);
+	regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
+		     packet_i2c_addr);
+	regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, cec_i2c_addr);
+	adv7511_packet_disable(adv7511, 0xffff);
+
+	adv7511->i2c_main = i2c;
+	adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);
+	adv7511->i2c_packet = i2c_new_dummy(i2c->adapter, packet_i2c_addr >> 1);
+	if (!adv7511->i2c_edid)
+		return -ENOMEM;
+
+	if (i2c->irq) {
+		ret = request_threaded_irq(i2c->irq, NULL, adv7511_irq_handler,
+					   IRQF_ONESHOT, dev_name(dev),
+					   adv7511);
+		if (ret)
+			goto err_i2c_unregister_device;
+
+		init_waitqueue_head(&adv7511->wq);
+	}
+
+	/* CEC is unused for now */
+	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
+		     ADV7511_CEC_CTRL_POWER_DOWN);
+
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+			   ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN);
+
+	adv7511->current_edid_segment = -1;
+
+	i2c_set_clientdata(i2c, adv7511);
+	adv7511_audio_init(dev);
+
+	adv7511_set_link_config(adv7511, &link_config);
+
+	return 0;
+
+err_i2c_unregister_device:
+	i2c_unregister_device(adv7511->i2c_edid);
+
+	return ret;
+}
+
+static int adv7511_remove(struct i2c_client *i2c)
+{
+	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+
+	i2c_unregister_device(adv7511->i2c_edid);
+
+	if (i2c->irq)
+		free_irq(i2c->irq, adv7511);
+	kfree(adv7511->edid);
+
+	return 0;
+}
+
+static int adv7511_encoder_init(struct i2c_client *i2c, struct drm_device *dev,
+				struct drm_encoder_slave *encoder)
+{
+
+	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+
+	encoder->slave_priv = adv7511;
+	encoder->slave_funcs = &adv7511_encoder_funcs;
+
+	adv7511->encoder = &encoder->base;
+
+	return 0;
+}
+
+static const struct i2c_device_id adv7511_ids[] = {
+	{ "adv7511", 0 },
+	{}
+};
+
+static struct drm_i2c_encoder_driver adv7511_driver = {
+	.i2c_driver = {
+		.driver = {
+			.name = "adv7511",
+		},
+		.id_table = adv7511_ids,
+		.probe = adv7511_probe,
+		.remove = adv7511_remove,
+	},
+
+	.encoder_init = adv7511_encoder_init,
+};
+
+static int adv7511_init(void)
+{
+	return drm_i2c_encoder_register(THIS_MODULE, &adv7511_driver);
+}
+module_init(adv7511_init);
+
+static void adv7511_exit(void)
+{
+	drm_i2c_encoder_unregister(&adv7511_driver);
+}
+module_exit(adv7511_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpu/drm/i2c/Kconfig	2014-07-20 22:05:50.199067232 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/Kconfig	2014-07-20 22:06:36.042310897 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:28 @
 	help
 	  Support for NXP Semiconductors TDA998X HDMI encoders.
 
+config DRM_ENCODER_ADV7511
+	tristate "ADV7511 encoder"
+	depends on SOUND
+	depends on SND
+	depends on SND_SOC
+	select REGMAP_I2C
+	select HDMI
+
 endmenu
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpu/drm/i2c/Makefile	2014-07-20 22:05:50.198067248 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/i2c/Makefile	2014-07-20 22:06:36.052310732 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:11 @
 
 tda998x-y := tda998x_drv.o
 obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o
+
+adv7511-y := adv7511_core.o adv7511_audio.o
+obj-$(CONFIG_DRM_ENCODER_ADV7511) += adv7511.o
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpu/drm/Kconfig	2014-07-20 22:05:50.196067281 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/Kconfig	2014-07-20 22:06:36.062310567 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:239 @
 source "drivers/gpu/drm/qxl/Kconfig"
 
 source "drivers/gpu/drm/msm/Kconfig"
+
+source "drivers/gpu/drm/xilinx/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/gpu/drm/Makefile	2014-07-20 22:05:50.195067298 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/Makefile	2014-07-20 22:06:36.071310419 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:58 @
 obj-$(CONFIG_DRM_TILCDC)	+= tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_MSM) += msm/
+obj-$(CONFIG_DRM_XILINX)	+= xilinx/
 obj-y			+= i2c/
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/Kconfig	2014-07-20 22:06:36.084310204 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+config DRM_XILINX
+	tristate "Xilinx DRM"
+	depends on DRM && ARCH_ZYNQ && HAVE_CLK
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_GEM_CMA_HELPER
+	select DRM_ENCODER_ADV7511
+	select XILINX_AXIVDMA
+	help
+	  DRM display driver for Xilinx IP based pipelines.
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/Makefile	2014-07-20 22:06:36.089310122 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+xilinx_drm-y := xilinx_drm_drv.o xilinx_drm_crtc.o xilinx_drm_plane.o \
+	      xilinx_drm_encoder.o xilinx_drm_connector.o
+xilinx_drm-y += xilinx_cresample.o xilinx_rgb2yuv.o xilinx_osd.o xilinx_vtc.o
+
+obj-$(CONFIG_DRM_XILINX) += xilinx_drm.o
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_cresample.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_cresample.c	2014-07-20 22:06:36.096310006 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Chroma Resampler support for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "xilinx_drm_drv.h"
+
+/* registers */
+/* general control registers */
+#define CRESAMPLE_CONTROL		0x0000
+
+/* horizontal and vertical active frame size */
+#define CRESAMPLE_ACTIVE_SIZE		0x0020
+
+/* control register bit definition */
+#define CRESAMPLE_CTL_EN		(1 << 0)	/* enable */
+#define CRESAMPLE_CTL_RU		(1 << 1)	/* reg update */
+#define CRESAMPLE_CTL_RESET		(1 << 31)	/* instant reset */
+
+struct xilinx_cresample {
+	void __iomem *base;
+	const char *input_format_name;
+	const char *output_format_name;
+};
+
+/* enable cresample */
+void xilinx_cresample_enable(struct xilinx_cresample *cresample)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
+	xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
+			  reg | CRESAMPLE_CTL_EN);
+}
+
+/* disable cresample */
+void xilinx_cresample_disable(struct xilinx_cresample *cresample)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
+	xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
+			  reg & ~CRESAMPLE_CTL_EN);
+}
+
+/* configure cresample */
+void xilinx_cresample_configure(struct xilinx_cresample *cresample,
+				int hactive, int vactive)
+{
+	/* configure hsize and vsize */
+	xilinx_drm_writel(cresample->base, CRESAMPLE_ACTIVE_SIZE,
+			  (vactive << 16) | hactive);
+}
+
+/* reset cresample */
+void xilinx_cresample_reset(struct xilinx_cresample *cresample)
+{
+	u32 reg;
+
+	xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
+			  CRESAMPLE_CTL_RESET);
+
+	/* enable register update */
+	reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
+	xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
+			  reg | CRESAMPLE_CTL_RU);
+}
+
+/* get an input format */
+const char *
+xilinx_cresample_get_input_format_name(struct xilinx_cresample *cresample)
+{
+	return cresample->input_format_name;
+}
+
+/* get an output format */
+const char *
+xilinx_cresample_get_output_format_name(struct xilinx_cresample *cresample)
+{
+	return cresample->output_format_name;
+}
+
+struct xilinx_cresample *xilinx_cresample_probe(struct device *dev,
+						struct device_node *node)
+{
+	struct xilinx_cresample *cresample;
+	struct resource res;
+	int ret;
+
+	cresample = devm_kzalloc(dev, sizeof(*cresample), GFP_KERNEL);
+	if (!cresample)
+		return ERR_PTR(-ENOMEM);
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to of_address_to_resource\n");
+		return ERR_PTR(ret);
+	}
+
+	cresample->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(cresample->base))
+		return ERR_CAST(cresample->base);
+
+	ret = of_property_read_string(node, "xlnx,input-format",
+				      &cresample->input_format_name);
+	if (ret) {
+		dev_warn(dev, "failed to get an input format prop\n");
+		return ERR_PTR(ret);
+	}
+
+	ret = of_property_read_string(node, "xlnx,output-format",
+				      &cresample->output_format_name);
+	if (ret) {
+		dev_warn(dev, "failed to get an output format prop\n");
+		return ERR_PTR(ret);
+	}
+
+	xilinx_cresample_reset(cresample);
+
+	return cresample;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_cresample.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_cresample.h	2014-07-20 22:06:36.102309908 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Chroma Resampler Header for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_CRESAMPLE_H_
+#define _XILINX_CRESAMPLE_H_
+
+struct xilinx_cresample;
+
+void xilinx_cresample_configure(struct xilinx_cresample *cresample,
+				int hactive, int vactive);
+void xilinx_cresample_reset(struct xilinx_cresample *cresample);
+void xilinx_cresample_enable(struct xilinx_cresample *cresample);
+void xilinx_cresample_disable(struct xilinx_cresample *cresample);
+
+const char *
+xilinx_cresample_get_input_format_name(struct xilinx_cresample *cresample);
+const char *
+xilinx_cresample_get_output_format_name(struct xilinx_cresample *cresample);
+
+struct device;
+struct device_node;
+
+struct xilinx_cresample *xilinx_cresample_probe(struct device *dev,
+						struct device_node *node);
+
+#endif /* _XILINX_CRESAMPLE_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_connector.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_connector.c	2014-07-20 22:06:36.179308638 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM connector driver for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/i2c/adv7511.h>
+
+#include <linux/device.h>
+
+#include "xilinx_drm_drv.h"
+
+struct xilinx_drm_connector {
+	struct drm_connector base;
+	struct drm_encoder *encoder;
+};
+
+#define to_xilinx_connector(x)	\
+	container_of(x, struct xilinx_drm_connector, base)
+
+/* get mode list */
+static int xilinx_drm_connector_get_modes(struct drm_connector *base_connector)
+{
+	struct xilinx_drm_connector *connector =
+		to_xilinx_connector(base_connector);
+	struct drm_encoder *encoder = connector->encoder;
+	struct drm_encoder_slave *encoder_slave = to_encoder_slave(encoder);
+	struct drm_encoder_slave_funcs *encoder_sfuncs =
+		encoder_slave->slave_funcs;
+	int count = 0;
+
+	if (encoder_sfuncs->get_modes)
+		count = encoder_sfuncs->get_modes(encoder, base_connector);
+
+	return count;
+}
+
+/* check if mode is valid */
+static int xilinx_drm_connector_mode_valid(struct drm_connector *base_connector,
+					   struct drm_display_mode *mode)
+{
+	if (mode->clock > 165000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_NO_INTERLACE;
+
+	return MODE_OK;
+}
+
+/* find best encoder: return stored encoder */
+static struct drm_encoder *
+xilinx_drm_connector_best_encoder(struct drm_connector *base_connector)
+{
+	struct xilinx_drm_connector *connector =
+		to_xilinx_connector(base_connector);
+
+	return connector->encoder;
+}
+
+static struct drm_connector_helper_funcs xilinx_drm_connector_helper_funcs = {
+	.get_modes	= xilinx_drm_connector_get_modes,
+	.mode_valid	= xilinx_drm_connector_mode_valid,
+	.best_encoder	= xilinx_drm_connector_best_encoder,
+};
+
+static enum drm_connector_status
+xilinx_drm_connector_detect(struct drm_connector *base_connector, bool force)
+{
+	struct xilinx_drm_connector *connector =
+		to_xilinx_connector(base_connector);
+	enum drm_connector_status status = connector_status_unknown;
+	struct drm_encoder *encoder = connector->encoder;
+	struct drm_encoder_slave *encoder_slave = to_encoder_slave(encoder);
+	struct drm_encoder_slave_funcs *encoder_sfuncs =
+		encoder_slave->slave_funcs;
+
+	if (encoder_sfuncs->detect)
+		status = encoder_sfuncs->detect(encoder, base_connector);
+
+	/* some connector ignores the first hpd, so try again if forced */
+	if (force && (status != connector_status_connected))
+		status = encoder_sfuncs->detect(encoder, base_connector);
+
+	DRM_DEBUG_KMS("status: %d\n", status);
+
+	return status;
+}
+
+/* destroy connector */
+void xilinx_drm_connector_destroy(struct drm_connector *base_connector)
+{
+	drm_sysfs_connector_remove(base_connector);
+	drm_connector_cleanup(base_connector);
+}
+
+static struct drm_connector_funcs xilinx_drm_connector_funcs = {
+	.dpms		= drm_helper_connector_dpms,
+	.fill_modes	= drm_helper_probe_single_connector_modes,
+	.detect		= xilinx_drm_connector_detect,
+	.destroy	= xilinx_drm_connector_destroy,
+};
+
+/* create connector */
+struct drm_connector *
+xilinx_drm_connector_create(struct drm_device *drm,
+			    struct drm_encoder *base_encoder)
+{
+	struct xilinx_drm_connector *connector;
+	int ret;
+
+	connector = devm_kzalloc(drm->dev, sizeof(*connector), GFP_KERNEL);
+	if (!connector)
+		return ERR_PTR(-ENOMEM);
+
+	connector->base.polled = DRM_CONNECTOR_POLL_CONNECT |
+				 DRM_CONNECTOR_POLL_DISCONNECT;
+
+	ret = drm_connector_init(drm, &connector->base,
+				 &xilinx_drm_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
+	if (ret) {
+		DRM_ERROR("failed to initialize connector\n");
+		return ERR_PTR(ret);
+	}
+
+	drm_connector_helper_add(&connector->base,
+				 &xilinx_drm_connector_helper_funcs);
+
+	/* add sysfs entry for connector */
+	ret = drm_sysfs_connector_add(&connector->base);
+	if (ret) {
+		DRM_ERROR("failed to add to sysfs\n");
+		goto err_sysfs;
+	}
+
+	/* connect connector and encoder */
+	connector->base.encoder = base_encoder;
+	ret = drm_mode_connector_attach_encoder(&connector->base, base_encoder);
+	if (ret) {
+		DRM_ERROR("failed to attach connector to encoder\n");
+		goto err_attach;
+	}
+	connector->encoder = base_encoder;
+
+	return &connector->base;
+
+err_attach:
+	drm_sysfs_connector_remove(&connector->base);
+err_sysfs:
+	drm_connector_cleanup(&connector->base);
+	return ERR_PTR(ret);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_connector.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_connector.h	2014-07-20 22:06:36.185308539 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM connector header for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_DRM_CONNECTOR_H_
+#define _XILINX_DRM_CONNECTOR_H_
+
+struct drm_device;
+struct drm_connector;
+
+struct drm_connector *
+xilinx_drm_connector_create(struct drm_device *drm,
+			    struct drm_encoder *base_encoder);
+void xilinx_drm_connector_destroy(struct drm_connector *base_connector);
+
+#endif /* _XILINX_DRM_CONNECTOR_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_crtc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_crtc.c	2014-07-20 22:06:36.195308374 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM crtc driver for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+#include <video/videomode.h>
+
+#include "xilinx_drm_drv.h"
+#include "xilinx_drm_plane.h"
+
+#include "xilinx_cresample.h"
+#include "xilinx_rgb2yuv.h"
+#include "xilinx_vtc.h"
+
+struct xilinx_drm_crtc {
+	struct drm_crtc base;
+	struct drm_plane *priv_plane;
+	struct xilinx_cresample *cresample;
+	struct xilinx_rgb2yuv *rgb2yuv;
+	struct clk *pixel_clock;
+	struct xilinx_vtc *vtc;
+	struct xilinx_drm_plane_manager *plane_manager;
+	int dpms;
+	struct drm_pending_vblank_event *event;
+};
+
+#define to_xilinx_crtc(x)	container_of(x, struct xilinx_drm_crtc, base)
+
+/* set crtc dpms */
+static void xilinx_drm_crtc_dpms(struct drm_crtc *base_crtc, int dpms)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	DRM_DEBUG_KMS("dpms: %d -> %d\n", crtc->dpms, dpms);
+
+	if (crtc->dpms == dpms)
+		return;
+
+	crtc->dpms = dpms;
+
+	switch (dpms) {
+	case DRM_MODE_DPMS_ON:
+		xilinx_drm_plane_dpms(crtc->priv_plane, dpms);
+		if (crtc->rgb2yuv)
+			xilinx_rgb2yuv_enable(crtc->rgb2yuv);
+		if (crtc->cresample)
+			xilinx_cresample_enable(crtc->cresample);
+		xilinx_vtc_enable(crtc->vtc);
+		break;
+	default:
+		xilinx_vtc_disable(crtc->vtc);
+		xilinx_vtc_reset(crtc->vtc);
+		if (crtc->cresample) {
+			xilinx_cresample_disable(crtc->cresample);
+			xilinx_cresample_reset(crtc->cresample);
+		}
+		if (crtc->rgb2yuv) {
+			xilinx_rgb2yuv_disable(crtc->rgb2yuv);
+			xilinx_rgb2yuv_reset(crtc->rgb2yuv);
+		}
+		xilinx_drm_plane_dpms(crtc->priv_plane, dpms);
+		break;
+	}
+}
+
+/* prepare crtc */
+static void xilinx_drm_crtc_prepare(struct drm_crtc *base_crtc)
+{
+	xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_OFF);
+}
+
+/* apply mode to crtc pipe */
+static void xilinx_drm_crtc_commit(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_ON);
+	xilinx_drm_plane_commit(crtc->priv_plane);
+}
+
+/* fix mode */
+static bool xilinx_drm_crtc_mode_fixup(struct drm_crtc *base_crtc,
+				       const struct drm_display_mode *mode,
+				       struct drm_display_mode *adjusted_mode)
+{
+	/* no op */
+	return true;
+}
+
+/* set new mode in crtc pipe */
+static int xilinx_drm_crtc_mode_set(struct drm_crtc *base_crtc,
+				    struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode,
+				    int x, int y,
+				    struct drm_framebuffer *old_fb)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+	struct videomode vm;
+	long diff;
+	int ret;
+
+	/* set pixel clock */
+	ret = clk_set_rate(crtc->pixel_clock, adjusted_mode->clock * 1000);
+	if (ret) {
+		DRM_ERROR("failed to set a pixel clock\n");
+		return ret;
+	}
+
+	diff = clk_get_rate(crtc->pixel_clock) - adjusted_mode->clock * 1000;
+	if (abs(diff) > (adjusted_mode->clock * 1000) / 20)
+		DRM_INFO("actual pixel clock rate(%d) is off by %ld\n",
+				adjusted_mode->clock, diff);
+
+	/* set video timing */
+	vm.hactive = adjusted_mode->hdisplay;
+	vm.hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
+	vm.hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end;
+	vm.hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
+
+	vm.vactive = adjusted_mode->vdisplay;
+	vm.vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
+	vm.vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end;
+	vm.vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
+
+	xilinx_vtc_config_sig(crtc->vtc, &vm);
+
+	/* configure cresample and rgb2yuv */
+	if (crtc->cresample)
+		xilinx_cresample_configure(crtc->cresample,
+					   adjusted_mode->hdisplay,
+					   adjusted_mode->vdisplay);
+	if (crtc->rgb2yuv)
+		xilinx_rgb2yuv_configure(crtc->rgb2yuv,
+					 adjusted_mode->hdisplay,
+					 adjusted_mode->vdisplay);
+
+	/* configure a plane: vdma and osd layer */
+	ret = xilinx_drm_plane_mode_set(crtc->priv_plane, base_crtc,
+					base_crtc->fb, 0, 0,
+					adjusted_mode->hdisplay,
+					adjusted_mode->vdisplay,
+					x, y,
+					adjusted_mode->hdisplay,
+					adjusted_mode->vdisplay);
+	if (ret) {
+		DRM_ERROR("failed to mode set a plane\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int _xilinx_drm_crtc_mode_set_base(struct drm_crtc *base_crtc,
+					  struct drm_framebuffer *fb,
+					  int x, int y)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+	int ret;
+
+	/* configure a plane */
+	ret = xilinx_drm_plane_mode_set(crtc->priv_plane, base_crtc,
+					fb, 0, 0,
+					base_crtc->hwmode.hdisplay,
+					base_crtc->hwmode.vdisplay,
+					x, y,
+					base_crtc->hwmode.hdisplay,
+					base_crtc->hwmode.vdisplay);
+	if (ret) {
+		DRM_ERROR("failed to mode set a plane\n");
+		return ret;
+	}
+
+	/* apply the new fb addr */
+	xilinx_drm_crtc_commit(base_crtc);
+
+	return 0;
+}
+
+/* update address and information from fb */
+static int xilinx_drm_crtc_mode_set_base(struct drm_crtc *base_crtc,
+					 int x, int y,
+					 struct drm_framebuffer *old_fb)
+{
+	/* configure a plane */
+	return _xilinx_drm_crtc_mode_set_base(base_crtc, base_crtc->fb, x, y);
+}
+
+/* load rgb LUT for crtc */
+static void xilinx_drm_crtc_load_lut(struct drm_crtc *base_crtc)
+{
+	/* no op */
+}
+
+static struct drm_crtc_helper_funcs xilinx_drm_crtc_helper_funcs = {
+	.dpms		= xilinx_drm_crtc_dpms,
+	.prepare	= xilinx_drm_crtc_prepare,
+	.commit		= xilinx_drm_crtc_commit,
+	.mode_fixup	= xilinx_drm_crtc_mode_fixup,
+	.mode_set	= xilinx_drm_crtc_mode_set,
+	.mode_set_base	= xilinx_drm_crtc_mode_set_base,
+	.load_lut	= xilinx_drm_crtc_load_lut,
+};
+
+/* destroy crtc */
+void xilinx_drm_crtc_destroy(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	/* make sure crtc is off */
+	xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_OFF);
+
+	drm_crtc_cleanup(base_crtc);
+
+	clk_disable_unprepare(crtc->pixel_clock);
+
+	xilinx_drm_plane_destroy_planes(crtc->plane_manager);
+	xilinx_drm_plane_destroy_private(crtc->plane_manager, crtc->priv_plane);
+	xilinx_drm_plane_remove_manager(crtc->plane_manager);
+}
+
+/* cancel page flip functions */
+void xilinx_drm_crtc_cancel_page_flip(struct drm_crtc *base_crtc,
+				      struct drm_file *file)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+	struct drm_device *drm = base_crtc->dev;
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&drm->event_lock, flags);
+	event = crtc->event;
+	if (event && (event->base.file_priv == file)) {
+		crtc->event = NULL;
+		event->base.destroy(&event->base);
+		drm_vblank_put(drm, 0);
+	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
+/* finish page flip functions */
+static void xilinx_drm_crtc_finish_page_flip(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+	struct drm_device *drm = base_crtc->dev;
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&drm->event_lock, flags);
+	event = crtc->event;
+	crtc->event = NULL;
+	if (event) {
+		drm_send_vblank_event(drm, 0, event);
+		drm_vblank_put(drm, 0);
+	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
+/* page flip functions */
+static int xilinx_drm_crtc_page_flip(struct drm_crtc *base_crtc,
+				     struct drm_framebuffer *fb,
+				     struct drm_pending_vblank_event *event,
+				     uint32_t page_flip_flags)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+	struct drm_device *drm = base_crtc->dev;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&drm->event_lock, flags);
+	if (crtc->event != NULL) {
+		spin_unlock_irqrestore(&drm->event_lock, flags);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+
+	/* configure a plane */
+	ret = _xilinx_drm_crtc_mode_set_base(base_crtc, fb,
+					     base_crtc->x, base_crtc->y);
+	if (ret) {
+		DRM_ERROR("failed to mode set a plane\n");
+		return ret;
+	}
+
+	base_crtc->fb = fb;
+
+	if (event) {
+		event->pipe = 0;
+		drm_vblank_get(drm, 0);
+		spin_lock_irqsave(&drm->event_lock, flags);
+		crtc->event = event;
+		spin_unlock_irqrestore(&drm->event_lock, flags);
+	}
+
+	return 0;
+}
+
+/* vblank interrupt handler */
+static void xilinx_drm_crtc_vblank_handler(void *data)
+{
+	struct drm_crtc *base_crtc = data;
+	struct drm_device *drm;
+
+	if (!base_crtc)
+		return;
+
+	drm = base_crtc->dev;
+
+	drm_handle_vblank(drm, 0);
+	xilinx_drm_crtc_finish_page_flip(base_crtc);
+}
+
+/* enable vblank interrupt */
+void xilinx_drm_crtc_enable_vblank(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	xilinx_vtc_enable_vblank_intr(crtc->vtc, xilinx_drm_crtc_vblank_handler,
+				      base_crtc);
+}
+
+/* disable vblank interrupt */
+void xilinx_drm_crtc_disable_vblank(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	xilinx_vtc_disable_vblank_intr(crtc->vtc);
+}
+
+/* check max width */
+unsigned int xilinx_drm_crtc_get_max_width(struct drm_crtc *base_crtc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	return xilinx_drm_plane_get_max_width(crtc->priv_plane);
+}
+
+/* check format */
+bool xilinx_drm_crtc_check_format(struct drm_crtc *base_crtc, uint32_t fourcc)
+{
+	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
+
+	return xilinx_drm_plane_check_format(crtc->plane_manager);
+}
+
+static struct drm_crtc_funcs xilinx_drm_crtc_funcs = {
+	.destroy	= xilinx_drm_crtc_destroy,
+	.set_config	= drm_crtc_helper_set_config,
+	.page_flip	= xilinx_drm_crtc_page_flip,
+};
+
+/* create crtc */
+struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
+{
+	struct xilinx_drm_crtc *crtc;
+	struct device_node *sub_node;
+	int possible_crtcs = 1;
+	int ret;
+
+	crtc = devm_kzalloc(drm->dev, sizeof(*crtc), GFP_KERNEL);
+	if (!crtc)
+		return ERR_PTR(-ENOMEM);
+
+	/* probe chroma resampler and enable */
+	sub_node = of_parse_phandle(drm->dev->of_node, "cresample", 0);
+	if (sub_node) {
+		crtc->cresample = xilinx_cresample_probe(drm->dev, sub_node);
+		of_node_put(sub_node);
+		if (IS_ERR(crtc->cresample)) {
+			DRM_ERROR("failed to probe a cresample\n");
+			return ERR_CAST(crtc->cresample);
+		}
+	}
+
+	/* probe color space converter and enable */
+	sub_node = of_parse_phandle(drm->dev->of_node, "rgb2yuv", 0);
+	if (sub_node) {
+		crtc->rgb2yuv = xilinx_rgb2yuv_probe(drm->dev, sub_node);
+		of_node_put(sub_node);
+		if (IS_ERR(crtc->rgb2yuv)) {
+			DRM_ERROR("failed to probe a rgb2yuv\n");
+			return ERR_CAST(crtc->rgb2yuv);
+		}
+	}
+
+	/* probe a plane manager */
+	crtc->plane_manager = xilinx_drm_plane_probe_manager(drm);
+	if (IS_ERR(crtc->plane_manager)) {
+		DRM_ERROR("failed to probe a plane manager\n");
+		return ERR_CAST(crtc->plane_manager);
+	}
+
+	/* create a private plane. there's only one crtc now */
+	crtc->priv_plane = xilinx_drm_plane_create_private(crtc->plane_manager,
+							   possible_crtcs);
+	if (IS_ERR(crtc->priv_plane)) {
+		DRM_ERROR("failed to create a private plane for crtc\n");
+		ret = PTR_ERR(crtc->priv_plane);
+		goto err_plane;
+	}
+
+	/* create extra planes */
+	xilinx_drm_plane_create_planes(crtc->plane_manager, possible_crtcs);
+
+	crtc->pixel_clock = devm_clk_get(drm->dev, 0);
+	if (IS_ERR(crtc->pixel_clock)) {
+		DRM_DEBUG_KMS("failed to get pixel clock\n");
+		ret = -EPROBE_DEFER;
+		goto err_out;
+	}
+
+	ret = clk_prepare_enable(crtc->pixel_clock);
+	if (ret) {
+		DRM_DEBUG_KMS("failed to prepare/enable clock\n");
+		goto err_out;
+	}
+
+	sub_node = of_parse_phandle(drm->dev->of_node, "vtc", 0);
+	if (!sub_node) {
+		DRM_ERROR("failed to get a video timing controller node\n");
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	crtc->vtc = xilinx_vtc_probe(drm->dev, sub_node);
+	of_node_put(sub_node);
+	if (IS_ERR(crtc->vtc)) {
+		DRM_ERROR("failed to probe video timing controller\n");
+		ret = PTR_ERR(crtc->vtc);
+		goto err_out;
+	}
+
+	crtc->dpms = DRM_MODE_DPMS_OFF;
+
+	/* initialize drm crtc */
+	ret = drm_crtc_init(drm, &crtc->base, &xilinx_drm_crtc_funcs);
+	if (ret) {
+		DRM_ERROR("failed to initialize crtc\n");
+		goto err_out;
+	}
+	drm_crtc_helper_add(&crtc->base, &xilinx_drm_crtc_helper_funcs);
+
+	return &crtc->base;
+
+err_out:
+	xilinx_drm_plane_destroy_planes(crtc->plane_manager);
+	xilinx_drm_plane_destroy_private(crtc->plane_manager, crtc->priv_plane);
+err_plane:
+	xilinx_drm_plane_remove_manager(crtc->plane_manager);
+	return ERR_PTR(ret);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_crtc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_crtc.h	2014-07-20 22:06:36.201308275 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM crtc header for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_DRM_CRTC_H_
+#define _XILINX_DRM_CRTC_H_
+
+struct drm_device;
+struct drm_crtc;
+
+void xilinx_drm_crtc_enable_vblank(struct drm_crtc *base_crtc);
+void xilinx_drm_crtc_disable_vblank(struct drm_crtc *base_crtc);
+void xilinx_drm_crtc_cancel_page_flip(struct drm_crtc *base_crtc,
+				      struct drm_file *file);
+
+unsigned int xilinx_drm_crtc_get_max_width(struct drm_crtc *base_crtc);
+bool xilinx_drm_crtc_check_format(struct drm_crtc *base_crtc, uint32_t fourcc);
+
+struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm);
+void xilinx_drm_crtc_destroy(struct drm_crtc *base_crtc);
+
+#endif /* _XILINX_DRM_CRTC_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_drv.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_drv.c	2014-07-20 22:06:36.210308126 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM KMS support for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "xilinx_drm_connector.h"
+#include "xilinx_drm_crtc.h"
+#include "xilinx_drm_drv.h"
+#include "xilinx_drm_encoder.h"
+
+#define DRIVER_NAME	"xilinx_drm"
+#define DRIVER_DESC	"Xilinx DRM KMS support for Xilinx"
+#define DRIVER_DATE	"20130509"
+#define DRIVER_MAJOR	1
+#define DRIVER_MINOR	0
+
+/*
+ * TODO: The possible pipeline configurations are numerous with Xilinx soft IPs.
+ * It's not too bad for now, but the more proper way(Common Display Framework,
+ * or some internal abstraction) should be considered, when it reaches a point
+ * that such thing is required.
+ */
+
+struct xilinx_drm_private {
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
+	struct drm_fbdev_cma *fbdev;
+	struct platform_device *pdev;
+};
+
+/**
+ * struct xilinx_video_format_desc - Xilinx Video IP video format description
+ * @name: Xilinx video format name
+ * @xilinx_format: xilinx format code
+ * @drm_format: drm format code
+ */
+struct xilinx_video_format_desc {
+	const char *name;
+	unsigned int xilinx_format;
+	uint32_t drm_format;
+};
+
+static const struct xilinx_video_format_desc xilinx_video_formats[] = {
+	{ "yuv422", XILINX_VIDEO_FORMAT_YUV422, DRM_FORMAT_YUV422 },
+	{ "yuv444", XILINX_VIDEO_FORMAT_YUV444, DRM_FORMAT_YUV444 },
+	{ "xrgb888", XILINX_VIDEO_FORMAT_RGB, DRM_FORMAT_XRGB8888 },
+	{ "yuv420", XILINX_VIDEO_FORMAT_YUV420, DRM_FORMAT_YUV420 },
+};
+
+/* create a fb */
+static struct drm_framebuffer *
+xilinx_drm_fb_create(struct drm_device *drm, struct drm_file *file_priv,
+		     struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+	bool res;
+
+	res = xilinx_drm_crtc_check_format(private->crtc,
+					   mode_cmd->pixel_format);
+	if (!res) {
+		DRM_ERROR("unsupported pixel format %08x\n",
+			  mode_cmd->pixel_format);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return drm_fb_cma_create(drm, file_priv, mode_cmd);
+}
+
+/* poll changed handler */
+static void xilinx_drm_output_poll_changed(struct drm_device *drm)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	drm_fbdev_cma_hotplug_event(private->fbdev);
+}
+
+static const struct drm_mode_config_funcs xilinx_drm_mode_config_funcs = {
+	.fb_create		= xilinx_drm_fb_create,
+	.output_poll_changed	= xilinx_drm_output_poll_changed,
+};
+
+/* enable vblank */
+static int xilinx_drm_enable_vblank(struct drm_device *drm, int crtc)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	xilinx_drm_crtc_enable_vblank(private->crtc);
+
+	return 0;
+}
+
+/* disable vblank */
+static void xilinx_drm_disable_vblank(struct drm_device *drm, int crtc)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	xilinx_drm_crtc_disable_vblank(private->crtc);
+}
+
+/* initialize mode config */
+static void xilinx_drm_mode_config_init(struct drm_device *drm)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	drm->mode_config.min_width = 0;
+	drm->mode_config.min_height = 0;
+
+	drm->mode_config.max_width =
+		xilinx_drm_crtc_get_max_width(private->crtc);
+	drm->mode_config.max_height = 4096;
+
+	drm->mode_config.funcs = &xilinx_drm_mode_config_funcs;
+}
+
+/* convert xilinx format to drm format by code */
+int xilinx_drm_format_by_code(unsigned int xilinx_format, uint32_t *drm_format)
+{
+	const struct xilinx_video_format_desc *format;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xilinx_video_formats); i++) {
+		format = &xilinx_video_formats[i];
+		if (format->xilinx_format == xilinx_format) {
+			*drm_format = format->drm_format;
+			return 0;
+		}
+	}
+
+	DRM_ERROR("Unknown Xilinx video format: %d\n", xilinx_format);
+
+	return -EINVAL;
+}
+
+/* convert xilinx format to drm format by name */
+int xilinx_drm_format_by_name(const char *name, uint32_t *drm_format)
+{
+	const struct xilinx_video_format_desc *format;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xilinx_video_formats); i++) {
+		format = &xilinx_video_formats[i];
+		if (strcmp(format->name, name) == 0) {
+			*drm_format = format->drm_format;
+			return 0;
+		}
+	}
+
+	DRM_ERROR("Unknown Xilinx video format: %s\n", name);
+
+	return -EINVAL;
+}
+
+/* load xilinx drm */
+static int xilinx_drm_load(struct drm_device *drm, unsigned long flags)
+{
+	struct xilinx_drm_private *private;
+	struct platform_device *pdev = drm->platformdev;
+	int ret;
+
+	private = devm_kzalloc(drm->dev, sizeof(*private), GFP_KERNEL);
+	if (!private)
+		return -ENOMEM;
+
+	drm_mode_config_init(drm);
+
+	/* create a xilinx crtc */
+	private->crtc = xilinx_drm_crtc_create(drm);
+	if (IS_ERR(private->crtc)) {
+		DRM_DEBUG_DRIVER("failed to create xilinx crtc\n");
+		ret = PTR_ERR(private->crtc);
+		goto err_crtc;
+	}
+
+	/* create a xilinx encoder */
+	private->encoder = xilinx_drm_encoder_create(drm);
+	if (IS_ERR(private->encoder)) {
+		DRM_DEBUG_DRIVER("failed to create xilinx encoder\n");
+		ret = PTR_ERR(private->encoder);
+		goto err_encoder;
+	}
+
+	/* create a xilinx connector */
+	private->connector = xilinx_drm_connector_create(drm, private->encoder);
+	if (IS_ERR(private->connector)) {
+		DRM_DEBUG_DRIVER("failed to create xilinx connector\n");
+		ret = PTR_ERR(private->connector);
+		goto err_connector;
+	}
+
+	ret = drm_vblank_init(drm, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize vblank\n");
+		goto err_vblank;
+	}
+
+	/* enable irq to enable vblank feature */
+	drm->irq_enabled = 1;
+
+	/* allow disable vblank */
+	drm->vblank_disable_allowed = 1;
+
+	/* initialize xilinx cma framebuffer */
+	private->fbdev = drm_fbdev_cma_init(drm, 32, 1, 1);
+	if (IS_ERR(private->fbdev)) {
+		DRM_ERROR("failed to initialize drm cma fbdev\n");
+		ret = PTR_ERR(private->fbdev);
+		goto err_fbdev;
+	}
+
+	drm->dev_private = private;
+	private->drm = drm;
+
+	drm_kms_helper_poll_init(drm);
+
+	/* set up mode config for xilinx */
+	xilinx_drm_mode_config_init(drm);
+
+	drm_helper_disable_unused_functions(drm);
+
+	platform_set_drvdata(pdev, private);
+
+	return 0;
+
+err_fbdev:
+	drm_vblank_cleanup(drm);
+err_vblank:
+	xilinx_drm_connector_destroy(private->connector);
+err_connector:
+	xilinx_drm_encoder_destroy(private->encoder);
+err_encoder:
+	xilinx_drm_crtc_destroy(private->crtc);
+err_crtc:
+	drm_mode_config_cleanup(drm);
+	if (ret == -EPROBE_DEFER)
+		DRM_INFO("load() is defered & will be called again\n");
+	return ret;
+}
+
+/* unload xilinx drm */
+static int xilinx_drm_unload(struct drm_device *drm)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	drm_vblank_cleanup(drm);
+
+	drm_kms_helper_poll_fini(drm);
+
+	drm_fbdev_cma_fini(private->fbdev);
+
+	drm_mode_config_cleanup(drm);
+
+	return 0;
+}
+
+/* preclose */
+static void xilinx_drm_preclose(struct drm_device *drm, struct drm_file *file)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	/* cancel pending page flip request */
+	xilinx_drm_crtc_cancel_page_flip(private->crtc, file);
+}
+
+/* restore the default mode when xilinx drm is released */
+static void xilinx_drm_lastclose(struct drm_device *drm)
+{
+	struct xilinx_drm_private *private = drm->dev_private;
+
+	drm_fbdev_cma_restore_mode(private->fbdev);
+}
+
+static const struct file_operations xilinx_drm_fops = {
+	.owner		= THIS_MODULE,
+	.open		= drm_open,
+	.release	= drm_release,
+	.unlocked_ioctl	= drm_ioctl,
+	.mmap		= drm_gem_cma_mmap,
+	.poll		= drm_poll,
+	.read		= drm_read,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= drm_compat_ioctl,
+#endif
+	.llseek		= noop_llseek,
+};
+
+static struct drm_driver xilinx_drm_driver = {
+	.driver_features		= DRIVER_MODESET | DRIVER_GEM |
+					  DRIVER_PRIME,
+	.load				= xilinx_drm_load,
+	.unload				= xilinx_drm_unload,
+	.preclose			= xilinx_drm_preclose,
+	.lastclose			= xilinx_drm_lastclose,
+
+	.get_vblank_counter		= drm_vblank_count,
+	.enable_vblank			= xilinx_drm_enable_vblank,
+	.disable_vblank			= xilinx_drm_disable_vblank,
+
+	.prime_handle_to_fd		= drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle		= drm_gem_prime_fd_to_handle,
+	.gem_prime_export		= drm_gem_prime_export,
+	.gem_prime_import		= drm_gem_prime_import,
+	.gem_prime_get_sg_table		= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_import_sg_table	= drm_gem_cma_prime_import_sg_table,
+	.gem_prime_vmap			= drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap		= drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap			= drm_gem_cma_prime_mmap,
+	.gem_free_object		= drm_gem_cma_free_object,
+	.gem_vm_ops			= &drm_gem_cma_vm_ops,
+	.dumb_create			= drm_gem_cma_dumb_create,
+	.dumb_map_offset		= drm_gem_cma_dumb_map_offset,
+	.dumb_destroy			= drm_gem_dumb_destroy,
+
+	.fops				= &xilinx_drm_fops,
+
+	.name				= DRIVER_NAME,
+	.desc				= DRIVER_DESC,
+	.date				= DRIVER_DATE,
+	.major				= DRIVER_MAJOR,
+	.minor				= DRIVER_MINOR,
+};
+
+#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
+/* suspend xilinx drm */
+static int xilinx_drm_pm_suspend(struct device *dev)
+{
+	struct xilinx_drm_private *private = dev_get_drvdata(dev);
+
+	drm_kms_helper_poll_disable(private->drm);
+	drm_helper_connector_dpms(private->connector, DRM_MODE_DPMS_SUSPEND);
+
+	return 0;
+}
+
+/* resume xilinx drm */
+static int xilinx_drm_pm_resume(struct device *dev)
+{
+	struct xilinx_drm_private *private = dev_get_drvdata(dev);
+
+	drm_helper_connector_dpms(private->connector, DRM_MODE_DPMS_ON);
+	drm_kms_helper_poll_enable(private->drm);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops xilinx_drm_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xilinx_drm_pm_suspend, xilinx_drm_pm_resume)
+	SET_RUNTIME_PM_OPS(xilinx_drm_pm_suspend, xilinx_drm_pm_resume, NULL)
+};
+
+/* init xilinx drm platform */
+static int xilinx_drm_platform_probe(struct platform_device *pdev)
+{
+	return drm_platform_init(&xilinx_drm_driver, pdev);
+}
+
+/* exit xilinx drm platform */
+static int xilinx_drm_platform_remove(struct platform_device *pdev)
+{
+	drm_platform_exit(&xilinx_drm_driver, pdev);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_drm_of_match[] = {
+	{ .compatible = "xlnx,drm", },
+	{ /* end of table */ },
+};
+MODULE_DEVICE_TABLE(of, xilinx_drm_of_match);
+
+static struct platform_driver xilinx_drm_private_driver = {
+	.probe			= xilinx_drm_platform_probe,
+	.remove			= xilinx_drm_platform_remove,
+	.driver			= {
+		.owner		= THIS_MODULE,
+		.name		= "xilinx-drm",
+		.pm		= &xilinx_drm_pm_ops,
+		.of_match_table	= xilinx_drm_of_match,
+	},
+};
+
+module_platform_driver(xilinx_drm_private_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx DRM KMS Driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_drv.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_drv.h	2014-07-20 22:06:36.216308027 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM KMS Header for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_DRM_H_
+#define _XILINX_DRM_H_
+
+enum xilinx_video_format {
+	XILINX_VIDEO_FORMAT_YUV422 = 0,
+	XILINX_VIDEO_FORMAT_YUV444 = 1,
+	XILINX_VIDEO_FORMAT_RGB = 2,
+	XILINX_VIDEO_FORMAT_YUV420 = 3,
+};
+
+/* convert the xilinx format to the drm format */
+int xilinx_drm_format_by_code(unsigned int xilinx_format, uint32_t *drm_format);
+int xilinx_drm_format_by_name(const char *name, uint32_t *drm_format);
+
+/* io write operations */
+static inline void xilinx_drm_writel(void __iomem *base, int offset, u32 val)
+{
+	writel(val, base + offset);
+}
+
+/* io read operations */
+static inline u32 xilinx_drm_readl(void __iomem *base, int offset)
+{
+	return readl(base + offset);
+}
+
+#endif /* _XILINX_DRM_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_encoder.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_encoder.c	2014-07-20 22:06:36.224307895 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM encoder driver for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/i2c/adv7511.h>
+
+#include <linux/hdmi.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "xilinx_drm_drv.h"
+
+struct xilinx_drm_encoder {
+	struct drm_encoder_slave slave;
+	struct i2c_client *i2c_slave;
+	bool rgb;
+	int dpms;
+};
+
+#define to_xilinx_encoder(x)	\
+	container_of(x, struct xilinx_drm_encoder, slave)
+
+/* coefficients for adv7511 color space conversion */
+static const uint16_t adv7511_csc_ycbcr_to_rgb[] = {
+	0x0734, 0x04ad, 0x0000, 0x1c1b,
+	0x1ddc, 0x04ad, 0x1f24, 0x0135,
+	0x0000, 0x04ad, 0x087c, 0x1b77,
+};
+
+/* set encoder dpms */
+static void xilinx_drm_encoder_dpms(struct drm_encoder *base_encoder, int dpms)
+{
+	struct xilinx_drm_encoder *encoder;
+	struct drm_encoder_slave *encoder_slave;
+	struct drm_encoder_slave_funcs *encoder_sfuncs;
+
+	encoder_slave = to_encoder_slave(base_encoder);
+	encoder_sfuncs = encoder_slave->slave_funcs;
+	encoder = to_xilinx_encoder(encoder_slave);
+
+	DRM_DEBUG_KMS("dpms: %d -> %d\n", encoder->dpms, dpms);
+
+	if (encoder->dpms == dpms)
+		return;
+
+	encoder->dpms = dpms;
+	if (encoder_sfuncs->dpms)
+		encoder_sfuncs->dpms(base_encoder, dpms);
+}
+
+/* adjust a mode if needed */
+static bool
+xilinx_drm_encoder_mode_fixup(struct drm_encoder *base_encoder,
+			      const struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct drm_encoder_slave *encoder_slave;
+	struct drm_encoder_slave_funcs *encoder_sfuncs = NULL;
+	bool ret = true;
+
+	encoder_slave = to_encoder_slave(base_encoder);
+	encoder_sfuncs = encoder_slave->slave_funcs;
+	if (encoder_sfuncs->mode_fixup)
+		ret = encoder_sfuncs->mode_fixup(base_encoder, mode,
+						 adjusted_mode);
+
+	return ret;
+}
+
+/* set mode to xilinx encoder */
+static void xilinx_drm_encoder_mode_set(struct drm_encoder *base_encoder,
+					struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	struct xilinx_drm_encoder *encoder;
+	struct drm_device *dev = base_encoder->dev;
+	struct drm_encoder_slave *encoder_slave;
+	struct drm_encoder_slave_funcs *encoder_sfuncs;
+	struct drm_connector *iter;
+	struct drm_connector *connector = NULL;
+	struct adv7511_video_config config;
+	struct edid *edid;
+
+	DRM_DEBUG_KMS("h: %d, v: %d\n",
+		      adjusted_mode->hdisplay, adjusted_mode->vdisplay);
+	DRM_DEBUG_KMS("refresh: %d, pclock: %d khz\n",
+		      adjusted_mode->vrefresh, adjusted_mode->clock);
+
+	encoder_slave = to_encoder_slave(base_encoder);
+	encoder = to_xilinx_encoder(encoder_slave);
+
+	/* search for a connector for this encoder.
+	 * assume there's only one connector for this encoder
+	 */
+	list_for_each_entry(iter, &dev->mode_config.connector_list, head) {
+		if (iter->encoder == base_encoder) {
+			connector = iter;
+			break;
+		}
+	}
+	if (!connector) {
+		DRM_ERROR("failed to find a connector\n");
+		return;
+	}
+
+	edid = adv7511_get_edid(base_encoder);
+	if (edid) {
+		config.hdmi_mode = drm_detect_hdmi_monitor(edid);
+		kfree(edid);
+	} else
+		config.hdmi_mode = false;
+
+	hdmi_avi_infoframe_init(&config.avi_infoframe);
+
+	config.avi_infoframe.scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
+
+	if (encoder->rgb) {
+		config.csc_enable = false;
+		config.avi_infoframe.colorspace = HDMI_COLORSPACE_RGB;
+	} else {
+		config.csc_scaling_factor = ADV7511_CSC_SCALING_4;
+		config.csc_coefficents = adv7511_csc_ycbcr_to_rgb;
+
+		if ((connector->display_info.color_formats &
+		     DRM_COLOR_FORMAT_YCRCB422) &&
+		    config.hdmi_mode) {
+			config.csc_enable = false;
+			config.avi_infoframe.colorspace =
+				HDMI_COLORSPACE_YUV422;
+		} else {
+			config.csc_enable = true;
+			config.avi_infoframe.colorspace = HDMI_COLORSPACE_RGB;
+		}
+	}
+
+	encoder_sfuncs = encoder_slave->slave_funcs;
+	if (encoder_sfuncs->set_config)
+		encoder_sfuncs->set_config(base_encoder, &config);
+
+	if (encoder_sfuncs->mode_set)
+		encoder_sfuncs->mode_set(base_encoder, mode, adjusted_mode);
+}
+
+/* apply mode to encoder pipe */
+static void xilinx_drm_encoder_commit(struct drm_encoder *base_encoder)
+{
+	/* start encoder with new mode */
+	xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_ON);
+}
+
+/* prepare encoder */
+static void xilinx_drm_encoder_prepare(struct drm_encoder *base_encoder)
+{
+	xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_OFF);
+}
+
+/* get crtc */
+static struct drm_crtc *
+xilinx_drm_encoder_get_crtc(struct drm_encoder *base_encoder)
+{
+	return base_encoder->crtc;
+}
+
+static struct drm_encoder_helper_funcs xilinx_drm_encoder_helper_funcs = {
+	.dpms		= xilinx_drm_encoder_dpms,
+	.mode_fixup	= xilinx_drm_encoder_mode_fixup,
+	.mode_set	= xilinx_drm_encoder_mode_set,
+	.prepare	= xilinx_drm_encoder_prepare,
+	.commit		= xilinx_drm_encoder_commit,
+	.get_crtc	= xilinx_drm_encoder_get_crtc,
+};
+
+/* destroy encoder */
+void xilinx_drm_encoder_destroy(struct drm_encoder *base_encoder)
+{
+	struct xilinx_drm_encoder *encoder;
+	struct drm_encoder_slave *encoder_slave;
+
+	encoder_slave = to_encoder_slave(base_encoder);
+	encoder = to_xilinx_encoder(encoder_slave);
+
+	/* make sure encoder is off */
+	xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_OFF);
+
+	drm_encoder_cleanup(base_encoder);
+	put_device(&encoder->i2c_slave->dev);
+}
+
+static struct drm_encoder_funcs xilinx_drm_encoder_funcs = {
+	.destroy	= xilinx_drm_encoder_destroy,
+};
+
+/* create encoder */
+struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm)
+{
+	struct xilinx_drm_encoder *encoder;
+	struct device_node *sub_node;
+	struct drm_i2c_encoder_driver *i2c_driver;
+	int ret;
+
+	encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL);
+	if (!encoder)
+		return ERR_PTR(-ENOMEM);
+
+	encoder->dpms = DRM_MODE_DPMS_OFF;
+
+	/* get slave encoder */
+	sub_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0);
+	if (!sub_node) {
+		DRM_ERROR("failed to get an encoder slave node\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	encoder->i2c_slave = of_find_i2c_device_by_node(sub_node);
+	of_node_put(sub_node);
+	if (!encoder->i2c_slave) {
+		DRM_DEBUG_KMS("failed to get an encoder slv\n");
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	/* initialize slave encoder */
+	i2c_driver = to_drm_i2c_encoder_driver(encoder->i2c_slave->driver);
+	if (!i2c_driver) {
+		DRM_ERROR("failed to initialize encoder slave\n");
+		ret = -EPROBE_DEFER;
+		goto err_out;
+	}
+
+	ret = i2c_driver->encoder_init(encoder->i2c_slave, drm,
+				       &encoder->slave);
+	if (ret) {
+		DRM_ERROR("failed to initialize encoder slave\n");
+		goto err_out;
+	}
+
+	if (!encoder->slave.slave_funcs) {
+		DRM_ERROR("there's no encoder slave function\n");
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	encoder->rgb = of_property_read_bool(drm->dev->of_node, "adi,is-rgb");
+
+	/* initialize encoder */
+	encoder->slave.base.possible_crtcs = 1;
+	ret = drm_encoder_init(drm, &encoder->slave.base,
+			       &xilinx_drm_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret) {
+		DRM_ERROR("failed to initialize drm encoder\n");
+		goto err_out;
+	}
+
+	drm_encoder_helper_add(&encoder->slave.base,
+			       &xilinx_drm_encoder_helper_funcs);
+
+	return &encoder->slave.base;
+
+err_out:
+	put_device(&encoder->i2c_slave->dev);
+	return ERR_PTR(ret);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_encoder.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_encoder.h	2014-07-20 22:06:36.230307796 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM encoder header for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_DRM_ENCODER_H_
+#define _XILINX_DRM_ENCODER_H_
+
+struct drm_device;
+struct drm_encoder;
+
+struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm);
+void xilinx_drm_encoder_destroy(struct drm_encoder *base_encoder);
+
+#endif /* _XILINX_DRM_ENCODER_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_plane.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_plane.c	2014-07-20 22:06:36.241307615 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM plane driver for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+
+#include "xilinx_drm_drv.h"
+
+#include "xilinx_cresample.h"
+#include "xilinx_osd.h"
+#include "xilinx_rgb2yuv.h"
+
+/**
+ * struct xilinx_drm_plane_vdma: Xilinx drm plane VDMA object
+ *
+ * @chan: dma channel
+ * @dma_config: vdma config
+ */
+struct xilinx_drm_plane_vdma {
+	struct dma_chan *chan;
+	struct xilinx_vdma_config dma_config;
+};
+
+/**
+ * struct xilinx_drm_plane: Xilinx drm plane object
+ *
+ * @base: base drm plane object
+ * @id: plane id
+ * @dpms: current dpms level
+ * @priv: flag for private plane
+ * @x: x position
+ * @y: y position
+ * @paddr: physical address of current plane buffer
+ * @bpp: bytes per pixel
+ * @format: pixel format
+ * @vdma: vdma object
+ * @rgb2yuv: rgb2yuv instance
+ * @cresample: cresample instance
+ * @osd_layer: osd layer
+ * @manager: plane manager
+ */
+struct xilinx_drm_plane {
+	struct drm_plane base;
+	int id;
+	int dpms;
+	bool priv;
+	uint32_t x;
+	uint32_t y;
+	dma_addr_t paddr;
+	int bpp;
+	uint32_t format;
+	struct xilinx_drm_plane_vdma vdma;
+	struct xilinx_rgb2yuv *rgb2yuv;
+	struct xilinx_cresample *cresample;
+	struct xilinx_osd_layer *osd_layer;
+	struct xilinx_drm_plane_manager *manager;
+};
+
+#define MAX_PLANES 8
+
+/**
+ * struct xilinx_drm_plane_manager: Xilinx drm plane manager object
+ *
+ * @drm: drm device
+ * @node: plane device node
+ * @osd: osd instance
+ * @num_planes: number of available planes
+ * @format: video format
+ * @max_width: maximum width
+ * @planes: xilinx drm planes
+ */
+struct xilinx_drm_plane_manager {
+	struct drm_device *drm;
+	struct device_node *node;
+	struct xilinx_osd *osd;
+	int num_planes;
+	uint32_t format;
+	int max_width;
+	struct xilinx_drm_plane *planes[MAX_PLANES];
+};
+
+#define to_xilinx_plane(x)	container_of(x, struct xilinx_drm_plane, base)
+
+/* set plane dpms */
+void xilinx_drm_plane_dpms(struct drm_plane *base_plane, int dpms)
+{
+	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
+	struct xilinx_drm_plane_manager *manager = plane->manager;
+	struct xilinx_vdma_config dma_config;
+
+	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);
+	DRM_DEBUG_KMS("dpms: %d -> %d\n", plane->dpms, dpms);
+
+	if (plane->dpms == dpms)
+		return;
+
+	plane->dpms = dpms;
+	switch (dpms) {
+	case DRM_MODE_DPMS_ON:
+		/* start vdma engine */
+		dma_async_issue_pending(plane->vdma.chan);
+
+		if (plane->rgb2yuv)
+			xilinx_rgb2yuv_enable(plane->rgb2yuv);
+
+		if (plane->cresample)
+			xilinx_cresample_enable(plane->cresample);
+
+		/* enable osd */
+		if (manager->osd) {
+			xilinx_osd_disable_rue(manager->osd);
+
+			/* set zorder(= id for now) */
+			xilinx_osd_layer_set_priority(plane->osd_layer,
+						      plane->id);
+			/* FIXME: use global alpha for now */
+			xilinx_osd_layer_set_alpha(plane->osd_layer, 1, 0xff);
+			xilinx_osd_layer_enable(plane->osd_layer);
+			if (plane->priv) {
+				/* set background color as black */
+				xilinx_osd_set_color(manager->osd, 0x0, 0x0,
+						     0x0);
+				xilinx_osd_enable(manager->osd);
+			}
+
+			xilinx_osd_enable_rue(manager->osd);
+		}
+
+		break;
+	default:
+		/* disable/reset osd */
+		if (manager->osd) {
+			xilinx_osd_disable_rue(manager->osd);
+
+			xilinx_osd_layer_set_dimension(plane->osd_layer,
+						       0, 0, 0, 0);
+			xilinx_osd_layer_disable(plane->osd_layer);
+			if (plane->priv)
+				xilinx_osd_reset(manager->osd);
+
+			xilinx_osd_enable_rue(manager->osd);
+		}
+
+		if (plane->cresample) {
+			xilinx_cresample_disable(plane->cresample);
+			xilinx_cresample_reset(plane->cresample);
+		}
+
+		if (plane->rgb2yuv) {
+			xilinx_rgb2yuv_disable(plane->rgb2yuv);
+			xilinx_rgb2yuv_reset(plane->rgb2yuv);
+		}
+
+		/* reset vdma */
+		dma_config.reset = 1;
+		dmaengine_device_control(plane->vdma.chan, DMA_SLAVE_CONFIG,
+					 (unsigned long)&dma_config);
+
+		/* stop vdma engine and release descriptors */
+		dmaengine_terminate_all(plane->vdma.chan);
+		break;
+	}
+}
+
+/* apply mode to plane pipe */
+void xilinx_drm_plane_commit(struct drm_plane *base_plane)
+{
+	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
+	struct dma_async_tx_descriptor *desc;
+	uint32_t height = plane->vdma.dma_config.hsize;
+	int pitch = plane->vdma.dma_config.stride;
+	size_t offset;
+
+	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);
+
+	offset = plane->x * plane->bpp + plane->y * pitch;
+	desc = dmaengine_prep_slave_single(plane->vdma.chan,
+					   plane->paddr + offset,
+					   height * pitch, DMA_MEM_TO_DEV, 0);
+	if (!desc) {
+		DRM_ERROR("failed to prepare DMA descriptor\n");
+		return;
+	}
+
+	/* submit vdma desc */
+	dmaengine_submit(desc);
+
+	/* start vdma with new mode */
+	dma_async_issue_pending(plane->vdma.chan);
+}
+
+/* mode set a plane */
+int xilinx_drm_plane_mode_set(struct drm_plane *base_plane,
+			      struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			      int crtc_x, int crtc_y,
+			      unsigned int crtc_w, unsigned int crtc_h,
+			      uint32_t src_x, uint32_t src_y,
+			      uint32_t src_w, uint32_t src_h)
+{
+	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
+	struct drm_gem_cma_object *obj;
+
+	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);
+
+	if (fb->pixel_format != plane->format) {
+		DRM_ERROR("unsupported pixel format %08x\n", fb->pixel_format);
+		return -EINVAL;
+	}
+
+	/* configure cresample */
+	if (plane->cresample)
+		xilinx_cresample_configure(plane->cresample, crtc_w, crtc_h);
+
+	/* configure rgb2yuv */
+	if (plane->rgb2yuv)
+		xilinx_rgb2yuv_configure(plane->rgb2yuv, crtc_w, crtc_h);
+
+	obj = drm_fb_cma_get_gem_obj(fb, 0);
+	if (!obj) {
+		DRM_ERROR("failed to get a gem obj for fb\n");
+		return -EINVAL;
+	}
+
+	plane->x = src_x;
+	plane->y = src_y;
+	plane->bpp = fb->bits_per_pixel / 8;
+	plane->paddr = obj->paddr;
+
+	DRM_DEBUG_KMS("h: %d(%d), v: %d(%d), paddr: %p\n",
+		      src_w, crtc_x, src_h, crtc_y, (void *)obj->paddr);
+	DRM_DEBUG_KMS("bpp: %d\n", plane->bpp);
+
+	/* configure vdma desc */
+	plane->vdma.dma_config.hsize = src_w * plane->bpp;
+	plane->vdma.dma_config.vsize = src_h;
+	plane->vdma.dma_config.stride = fb->pitches[0];
+	plane->vdma.dma_config.park = 1;
+	plane->vdma.dma_config.park_frm = 0;
+
+	dmaengine_device_control(plane->vdma.chan, DMA_SLAVE_CONFIG,
+				 (unsigned long)&plane->vdma.dma_config);
+
+	/* set OSD dimensions */
+	if (plane->manager->osd) {
+		xilinx_osd_disable_rue(plane->manager->osd);
+
+		/* if a plane is private, it's for crtc */
+		if (plane->priv)
+			xilinx_osd_set_dimension(plane->manager->osd,
+						 crtc_w, crtc_h);
+
+		xilinx_osd_layer_set_dimension(plane->osd_layer, crtc_x, crtc_y,
+					       src_w, src_h);
+
+		xilinx_osd_enable_rue(plane->manager->osd);
+	}
+
+	return 0;
+}
+
+/* update a plane. just call mode_set() with bit-shifted values */
+static int xilinx_drm_plane_update(struct drm_plane *base_plane,
+				   struct drm_crtc *crtc,
+				   struct drm_framebuffer *fb,
+				   int crtc_x, int crtc_y,
+				   unsigned int crtc_w, unsigned int crtc_h,
+				   uint32_t src_x, uint32_t src_y,
+				   uint32_t src_w, uint32_t src_h)
+{
+	int ret;
+
+	ret = xilinx_drm_plane_mode_set(base_plane, crtc, fb,
+					crtc_x, crtc_y, crtc_w, crtc_h,
+					src_x >> 16, src_y >> 16,
+					src_w >> 16, src_h >> 16);
+	if (ret) {
+		DRM_ERROR("failed to mode-set a plane\n");
+		return ret;
+	}
+
+	/* make sure a plane is on */
+	xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_ON);
+	/* apply the new fb addr */
+	xilinx_drm_plane_commit(base_plane);
+
+	return 0;
+}
+
+/* disable a plane */
+static int xilinx_drm_plane_disable(struct drm_plane *base_plane)
+{
+	xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_OFF);
+
+	return 0;
+}
+
+/* destroy a plane */
+static void xilinx_drm_plane_destroy(struct drm_plane *base_plane)
+{
+	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
+
+	xilinx_drm_plane_dpms(base_plane, DRM_MODE_DPMS_OFF);
+
+	plane->manager->planes[plane->id] = NULL;
+
+	drm_plane_cleanup(base_plane);
+
+	dma_release_channel(plane->vdma.chan);
+
+	if (plane->manager->osd) {
+		xilinx_osd_layer_disable(plane->osd_layer);
+		xilinx_osd_layer_put(plane->osd_layer);
+	}
+}
+
+/* set property of a plane */
+static int xilinx_drm_plane_set_property(struct drm_plane *base_plane,
+					 struct drm_property *property,
+					 uint64_t val)
+{
+	/* TODO: set zorder, etc */
+	return -EINVAL;
+}
+
+static struct drm_plane_funcs xilinx_drm_plane_funcs = {
+	.update_plane	= xilinx_drm_plane_update,
+	.disable_plane	= xilinx_drm_plane_disable,
+	.destroy	= xilinx_drm_plane_destroy,
+	.set_property	= xilinx_drm_plane_set_property,
+};
+
+/* get a plane max width */
+int xilinx_drm_plane_get_max_width(struct drm_plane *base_plane)
+{
+	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
+
+	return plane->manager->max_width;
+}
+
+/* check if format is supported */
+bool xilinx_drm_plane_check_format(struct xilinx_drm_plane_manager *manager,
+				   uint32_t format)
+{
+	int i;
+
+	for (i = 0; i < MAX_PLANES; i++)
+		if (manager->planes[i] &&
+		    (manager->planes[i]->format == format))
+			return true;
+
+	return false;
+}
+
+/* create a plane */
+static struct xilinx_drm_plane *
+xilinx_drm_plane_create(struct xilinx_drm_plane_manager *manager,
+			unsigned int possible_crtcs, bool priv)
+{
+	struct xilinx_drm_plane *plane;
+	struct device *dev = manager->drm->dev;
+	char plane_name[16];
+	struct device_node *plane_node;
+	struct device_node *sub_node;
+	uint32_t fmt_in = -1;
+	uint32_t fmt_out = -1;
+	const char *fmt;
+	int i;
+	int ret;
+
+	for (i = 0; i < manager->num_planes; i++)
+		if (!manager->planes[i])
+			break;
+
+	if (i >= manager->num_planes) {
+		DRM_ERROR("failed to allocate plane\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	snprintf(plane_name, sizeof(plane_name), "plane%d", i);
+	plane_node = of_get_child_by_name(manager->node, plane_name);
+	if (!plane_node) {
+		DRM_ERROR("failed to find a plane node\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
+	if (!plane) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	plane->priv = priv;
+	plane->id = i;
+	plane->dpms = DRM_MODE_DPMS_OFF;
+	plane->format = -1;
+	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);
+
+	plane->vdma.chan = of_dma_request_slave_channel(plane_node, "vdma");
+	if (!plane->vdma.chan) {
+		DRM_ERROR("failed to request dma channel\n");
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	/* probe color space converter */
+	sub_node = of_parse_phandle(plane_node, "rgb2yuv", i);
+	if (sub_node) {
+		plane->rgb2yuv = xilinx_rgb2yuv_probe(dev, sub_node);
+		of_node_put(sub_node);
+		if (IS_ERR(plane->rgb2yuv)) {
+			DRM_ERROR("failed to probe a rgb2yuv\n");
+			ret = PTR_ERR(plane->rgb2yuv);
+			goto err_dma;
+		}
+
+		/* rgb2yuv input format */
+		plane->format = DRM_FORMAT_XRGB8888;
+
+		/* rgb2yuv output format */
+		fmt_out = DRM_FORMAT_YUV444;
+	}
+
+	/* probe chroma resampler */
+	sub_node = of_parse_phandle(plane_node, "cresample", i);
+	if (sub_node) {
+		plane->cresample = xilinx_cresample_probe(dev, sub_node);
+		of_node_put(sub_node);
+		if (IS_ERR(plane->cresample)) {
+			DRM_ERROR("failed to probe a cresample\n");
+			ret = PTR_ERR(plane->cresample);
+			goto err_dma;
+		}
+
+		/* cresample input format */
+		fmt = xilinx_cresample_get_input_format_name(plane->cresample);
+		ret = xilinx_drm_format_by_name(fmt, &fmt_in);
+		if (ret)
+			goto err_dma;
+
+		/* format sanity check */
+		if ((fmt_out != -1) && (fmt_out != fmt_in)) {
+			DRM_ERROR("input/output format mismatch\n");
+			ret = -EINVAL;
+			goto err_dma;
+		}
+
+		if (plane->format == -1)
+			plane->format = fmt_in;
+
+		/* cresample output format */
+		fmt = xilinx_cresample_get_output_format_name(plane->cresample);
+		ret = xilinx_drm_format_by_name(fmt, &fmt_out);
+		if (ret)
+			goto err_dma;
+	}
+
+	/* create an OSD layer when OSD is available */
+	if (manager->osd) {
+		/* format sanity check */
+		if ((fmt_out != -1) && (fmt_out != manager->format)) {
+			DRM_ERROR("input/output format mismatch\n");
+			ret = -EINVAL;
+			goto err_dma;
+		}
+
+		/* create an osd layer */
+		plane->osd_layer = xilinx_osd_layer_get(manager->osd);
+		if (IS_ERR(plane->osd_layer)) {
+			DRM_ERROR("failed to create a osd layer\n");
+			ret = PTR_ERR(plane->osd_layer);
+			plane->osd_layer = NULL;
+			goto err_dma;
+		}
+
+		if (plane->format == -1)
+			plane->format = manager->format;
+	}
+
+	/* If there's no IP other than VDMA, choose XRGB8888 */
+	if (plane->format == -1)
+		plane->format = DRM_FORMAT_XRGB8888;
+
+	/* initialize drm plane */
+	ret = drm_plane_init(manager->drm, &plane->base, possible_crtcs,
+			     &xilinx_drm_plane_funcs, &plane->format, 1, priv);
+	if (ret) {
+		DRM_ERROR("failed to initialize plane\n");
+		goto err_init;
+	}
+	plane->manager = manager;
+	manager->planes[i] = plane;
+
+	of_node_put(plane_node);
+
+	return plane;
+
+err_init:
+	if (manager->osd) {
+		xilinx_osd_layer_disable(plane->osd_layer);
+		xilinx_osd_layer_put(plane->osd_layer);
+	}
+err_dma:
+	dma_release_channel(plane->vdma.chan);
+err_out:
+	of_node_put(plane_node);
+	return ERR_PTR(ret);
+}
+
+/* create a private plane */
+struct drm_plane *
+xilinx_drm_plane_create_private(struct xilinx_drm_plane_manager *manager,
+				unsigned int possible_crtcs)
+{
+	struct xilinx_drm_plane *plane;
+
+	plane = xilinx_drm_plane_create(manager, possible_crtcs, true);
+	if (IS_ERR(plane)) {
+		DRM_ERROR("failed to allocate a private plane\n");
+		return ERR_CAST(plane);
+	}
+
+	return &plane->base;
+}
+
+void xilinx_drm_plane_destroy_private(struct xilinx_drm_plane_manager *manager,
+				      struct drm_plane *base_plane)
+{
+	xilinx_drm_plane_destroy(base_plane);
+}
+
+/* destroy planes */
+void xilinx_drm_plane_destroy_planes(struct xilinx_drm_plane_manager *manager)
+{
+	struct xilinx_drm_plane *plane;
+	int i;
+
+	for (i = 0; i < manager->num_planes; i++) {
+		plane = manager->planes[i];
+		if (plane && !plane->priv) {
+			xilinx_drm_plane_destroy(&plane->base);
+			manager->planes[i] = NULL;
+		}
+	}
+}
+
+/* create extra planes */
+int xilinx_drm_plane_create_planes(struct xilinx_drm_plane_manager *manager,
+				   unsigned int possible_crtcs)
+{
+	int i;
+	int err_ret;
+
+	/* find if there any available plane, and create if available */
+	for (i = 0; i < manager->num_planes; i++) {
+		if (manager->planes[i])
+			continue;
+		manager->planes[i] = xilinx_drm_plane_create(manager,
+							     possible_crtcs,
+							     false);
+		if (IS_ERR(manager->planes[i])) {
+			DRM_ERROR("failed to allocate a plane\n");
+			err_ret = PTR_ERR(manager->planes[i]);
+			manager->planes[i] = NULL;
+			goto err_out;
+		}
+	}
+
+	return 0;
+
+err_out:
+	xilinx_drm_plane_destroy_planes(manager);
+	return err_ret;
+}
+
+/* initialize a plane manager: num_planes, format, max_width */
+static int
+xilinx_drm_plane_init_manager(struct xilinx_drm_plane_manager *manager)
+{
+	unsigned int format;
+	int ret = 0;
+
+	if (manager->osd) {
+		manager->num_planes = xilinx_osd_get_num_layers(manager->osd);
+		manager->max_width = xilinx_osd_get_max_width(manager->osd);
+
+		format = xilinx_osd_get_format(manager->osd);
+		ret = xilinx_drm_format_by_code(format, &manager->format);
+	} else {
+		/* without osd, only one plane is supported */
+		manager->num_planes = 1;
+		/* XRGB based on the current pipeline design without osd */
+		manager->format = DRM_FORMAT_XRGB8888;
+		manager->max_width = 4096;
+	}
+
+	return ret;
+}
+
+struct xilinx_drm_plane_manager *
+xilinx_drm_plane_probe_manager(struct drm_device *drm)
+{
+	struct xilinx_drm_plane_manager *manager;
+	struct device *dev = drm->dev;
+	struct device_node *sub_node;
+	int ret;
+
+	manager = devm_kzalloc(dev, sizeof(*manager), GFP_KERNEL);
+	if (!manager)
+		return ERR_PTR(-ENOMEM);
+
+	/* this node is used to create a plane */
+	manager->node = of_get_child_by_name(dev->of_node, "planes");
+	if (!manager->node) {
+		DRM_ERROR("failed to get a planes node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	manager->drm = drm;
+
+	/* probe an OSD. proceed even if there's no OSD */
+	sub_node = of_parse_phandle(dev->of_node, "osd", 0);
+	if (sub_node) {
+		manager->osd = xilinx_osd_probe(dev, sub_node);
+		of_node_put(sub_node);
+		if (IS_ERR(manager->osd)) {
+			of_node_put(manager->node);
+			DRM_ERROR("failed to probe an osd\n");
+			return ERR_CAST(manager->osd);
+		}
+	}
+
+	ret = xilinx_drm_plane_init_manager(manager);
+	if (ret) {
+		DRM_ERROR("failed to init a plane manager\n");
+		return ERR_PTR(ret);
+	}
+
+	return manager;
+}
+
+void xilinx_drm_plane_remove_manager(struct xilinx_drm_plane_manager *manager)
+{
+	int i;
+
+	for (i = 0; i < manager->num_planes; i++) {
+		if (manager->planes[i] && !manager->planes[i]->priv) {
+			xilinx_drm_plane_dpms(&manager->planes[i]->base,
+					      DRM_MODE_DPMS_OFF);
+			xilinx_drm_plane_destroy(&manager->planes[i]->base);
+			manager->planes[i] = NULL;
+		}
+	}
+
+	of_node_put(manager->node);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_plane.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_drm_plane.h	2014-07-20 22:06:36.248307499 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DRM plane header for Xilinx
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_DRM_PLANE_H_
+#define _XILINX_DRM_PLANE_H_
+
+struct drm_crtc;
+struct drm_plane;
+
+/* plane operations */
+void xilinx_drm_plane_dpms(struct drm_plane *base_plane, int dpms);
+void xilinx_drm_plane_commit(struct drm_plane *base_plane);
+int xilinx_drm_plane_mode_set(struct drm_plane *base_plane,
+			      struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			      int crtc_x, int crtc_y,
+			      unsigned int crtc_w, unsigned int crtc_h,
+			      uint32_t src_x, uint32_t src_y,
+			      uint32_t src_w, uint32_t src_h);
+int xilinx_drm_plane_get_max_width(struct drm_plane *base_plane);
+
+/* plane manager operations */
+struct xilinx_drm_plane_manager;
+
+struct drm_plane *
+xilinx_drm_plane_create_private(struct xilinx_drm_plane_manager *manager,
+				unsigned int possible_crtcs);
+void xilinx_drm_plane_destroy_private(struct xilinx_drm_plane_manager *manager,
+				      struct drm_plane *base_plane);
+int xilinx_drm_plane_create_planes(struct xilinx_drm_plane_manager *manager,
+				   unsigned int possible_crtcs);
+void xilinx_drm_plane_destroy_planes(struct xilinx_drm_plane_manager *manager);
+
+bool xilinx_drm_plane_check_format(struct xilinx_drm_plane_manager *manager);
+
+struct xilinx_drm_plane_manager *
+xilinx_drm_plane_probe_manager(struct drm_device *drm);
+void xilinx_drm_plane_remove_manager(struct xilinx_drm_plane_manager *manager);
+
+#endif /* _XILINX_DRM_PLANE_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_osd.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_osd.c	2014-07-20 22:06:36.256307367 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx OSD support
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+
+#include "xilinx_drm_drv.h"
+
+/* registers */
+#define OSD_CTL	0x000	/* control */
+#define OSD_SS	0x020	/* screen size */
+#define OSD_ENC	0x028	/* encoding register */
+#define OSD_BC0	0x100	/* background color channel 0 */
+#define OSD_BC1	0x104	/* background color channel 1 */
+#define OSD_BC2	0x108	/* background color channel 2 */
+
+#define OSD_L0C	0x110	/* layer 0 control */
+
+/* register offset of layers */
+#define OSD_LAYER_SIZE	0x10
+#define OSD_LXC		0x00	/* layer control */
+#define OSD_LXP		0x04	/* layer position */
+#define OSD_LXS		0x08	/* layer size */
+
+/*osd control register bit definition */
+#define OSD_CTL_RUE		(1 << 1)	/* osd reg update enable */
+#define OSD_CTL_EN		(1 << 0)	/* osd enable */
+
+/* osd screen size register bit definition */
+#define OSD_SS_YSIZE_MASK   0x0fff0000	/* vertical height of OSD output */
+#define OSD_SS_YSIZE_SHIFT  16		/* bit shift of OSD_SS_YSIZE_MASK */
+#define OSD_SS_XSIZE_MASK   0x00000fff	/* horizontal width of OSD output */
+
+/* osd vidoe format mask */
+#define OSD_VIDEO_FORMAT_MASK	0x0000000f	/* video format */
+
+/* osd background color channel 0 */
+#define OSD_BC0_YG_MASK		0x000000ff	/* Y (luma) or Green */
+
+/* osd background color channel 1 */
+#define OSD_BC1_UCBB_MASK	0x000000ff	/* U (Cb) or Blue */
+
+/* osd background color channel 2 */
+#define OSD_BC2_VCRR_MASK	0x000000ff	/* V(Cr) or Red */
+
+/* maximum number of the layers */
+#define OSD_MAX_NUM_OF_LAYERS	8
+
+/* osd layer control (layer 0 through (OSD_MAX_NUM_OF_LAYERS - 1)) */
+#define OSD_LXC_ALPHA_MASK	0x0fff0000	/* global alpha value */
+#define OSD_LXC_ALPHA_SHIFT	16		/* bit shift of alpha value */
+#define OSD_LXC_PRIORITY_MASK	0x00000700	/* layer priority */
+#define OSD_LXC_PRIORITY_SHIFT	8		/* bit shift of priority */
+#define OSD_LXC_GALPHAEN	(1 << 1)	/* global alpha enable */
+#define OSD_LXC_EN		(1 << 0)	/* layer enable */
+
+/* osd layer position (layer 0 through (OSD_MAX_NUM_OF_LAYERS - 1)) */
+#define OSD_LXP_YSTART_MASK	0x0fff0000	/* vert start line */
+#define OSD_LXP_YSTART_SHIFT	16		/* vert start line bit shift */
+#define OSD_LXP_XSTART_MASK	0x00000fff	/* horizontal start pixel */
+
+/* osd layer size (layer 0 through (OSD_MAX_NUM_OF_LAYERS - 1)) */
+#define OSD_LXS_YSIZE_MASK	0x0fff0000	/* vert size */
+#define OSD_LXS_YSIZE_SHIFT	16		/* vertical size bit shift */
+#define OSD_LXS_XSIZE_MASK	0x00000fff	/* horizontal size of layer */
+
+/* osd software reset */
+#define OSD_RST_RESET	(1 << 31)
+
+/**
+ * struct xilinx_osd_layer: Xilinx OSD layer object
+ *
+ * @base: base address
+ * @id: id
+ * @avail: available flag
+ * @osd: osd
+ */
+struct xilinx_osd_layer {
+	void __iomem *base;
+	int id;
+	bool avail;
+	struct xilinx_osd *osd;
+};
+
+/**
+ * struct xilinx_osd: Xilinx OSD object
+ *
+ * @base: base address
+ * @layers: layers
+ * @num_layers: number of layers
+ * @max_width: maximum width
+ * @format: video format
+ */
+struct xilinx_osd {
+	void __iomem *base;
+	struct xilinx_osd_layer *layers[OSD_MAX_NUM_OF_LAYERS];
+	unsigned int num_layers;
+	unsigned int max_width;
+	unsigned int format;
+};
+
+/* osd layer operation */
+/* set layer alpha */
+void xilinx_osd_layer_set_alpha(struct xilinx_osd_layer *layer, u32 enable,
+				u32 alpha)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("layer->id: %d\n", layer->id);
+	DRM_DEBUG_DRIVER("alpha: 0x%08x\n", alpha);
+
+	value = xilinx_drm_readl(layer->base, OSD_LXC);
+	value = enable ? (value | OSD_LXC_GALPHAEN) :
+		(value & ~OSD_LXC_GALPHAEN);
+	value &= ~OSD_LXC_ALPHA_MASK;
+	value |= (alpha << OSD_LXC_ALPHA_SHIFT) & OSD_LXC_ALPHA_MASK;
+	xilinx_drm_writel(layer->base, OSD_LXC, value);
+}
+
+/* set layer priority */
+void xilinx_osd_layer_set_priority(struct xilinx_osd_layer *layer, u32 prio)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("layer->id: %d\n", layer->id);
+	DRM_DEBUG_DRIVER("prio: %d\n", prio);
+
+	value = xilinx_drm_readl(layer->base, OSD_LXC);
+	value &= ~OSD_LXC_PRIORITY_MASK;
+	value |= (prio << OSD_LXC_PRIORITY_SHIFT) & OSD_LXC_PRIORITY_MASK;
+	xilinx_drm_writel(layer->base, OSD_LXC, value);
+}
+
+/* set layer dimension */
+void xilinx_osd_layer_set_dimension(struct xilinx_osd_layer *layer,
+				    u16 xstart, u16 ystart,
+				    u16 xsize, u16 ysize)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("layer->id: %d\n", layer->id);
+	DRM_DEBUG_DRIVER("w: %d(%d), h: %d(%d)\n",
+			 xsize, xstart, ysize, ystart);
+
+	value = xstart & OSD_LXP_XSTART_MASK;
+	value |= (ystart << OSD_LXP_YSTART_SHIFT) & OSD_LXP_YSTART_MASK;
+
+	xilinx_drm_writel(layer->base, OSD_LXP, value);
+
+	value = xsize & OSD_LXS_XSIZE_MASK;
+	value |= (ysize << OSD_LXS_YSIZE_SHIFT) & OSD_LXS_YSIZE_MASK;
+
+	xilinx_drm_writel(layer->base, OSD_LXS, value);
+}
+
+/* enable layer */
+void xilinx_osd_layer_enable(struct xilinx_osd_layer *layer)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("layer->id: %d\n", layer->id);
+
+	value = xilinx_drm_readl(layer->base, OSD_LXC);
+	value |= OSD_LXC_EN;
+	xilinx_drm_writel(layer->base, OSD_LXC, value);
+}
+
+/* disable layer */
+void xilinx_osd_layer_disable(struct xilinx_osd_layer *layer)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("layer->id: %d\n", layer->id);
+
+	value = xilinx_drm_readl(layer->base, OSD_LXC);
+	value &= ~OSD_LXC_EN;
+	xilinx_drm_writel(layer->base, OSD_LXC, value);
+}
+
+/* get an available layer */
+struct xilinx_osd_layer *xilinx_osd_layer_get(struct xilinx_osd *osd)
+{
+	struct xilinx_osd_layer *layer = NULL;
+	int i;
+
+	for (i = 0; i < osd->num_layers; i++) {
+		if (osd->layers[i]->avail) {
+			layer = osd->layers[i];
+			layer->avail = false;
+			break;
+		}
+	}
+
+	if (!layer)
+		return ERR_PTR(-ENODEV);
+
+	DRM_DEBUG_DRIVER("layer id: %d\n", i);
+
+	return layer;
+}
+
+/* put a layer */
+void xilinx_osd_layer_put(struct xilinx_osd_layer *layer)
+{
+	layer->avail = true;
+}
+
+/* osd operations */
+/* set osd color */
+void xilinx_osd_set_color(struct xilinx_osd *osd, u8 r, u8 g, u8 b)
+{
+	u32 value;
+
+	value = g;
+	xilinx_drm_writel(osd->base, OSD_BC0, value);
+	value = b;
+	xilinx_drm_writel(osd->base, OSD_BC1, value);
+	value = r;
+	xilinx_drm_writel(osd->base, OSD_BC2, value);
+}
+
+/* set osd dimension */
+void xilinx_osd_set_dimension(struct xilinx_osd *osd, u32 width, u32 height)
+{
+	u32 value;
+
+	DRM_DEBUG_DRIVER("w: %d, h: %d\n", width, height);
+
+	value = width | ((height << OSD_SS_YSIZE_SHIFT) & OSD_SS_YSIZE_MASK);
+	xilinx_drm_writel(osd->base, OSD_SS, value);
+}
+
+/* get osd number of layers */
+unsigned int xilinx_osd_get_num_layers(struct xilinx_osd *osd)
+{
+	return osd->num_layers;
+}
+
+/* get osd max width */
+unsigned int xilinx_osd_get_max_width(struct xilinx_osd *osd)
+{
+	return osd->max_width;
+}
+
+/* get osd color format */
+unsigned int xilinx_osd_get_format(struct xilinx_osd *osd)
+{
+	return osd->format;
+}
+
+/* reset osd */
+void xilinx_osd_reset(struct xilinx_osd *osd)
+{
+	xilinx_drm_writel(osd->base, OSD_CTL, OSD_RST_RESET);
+}
+
+/* enable osd */
+void xilinx_osd_enable(struct xilinx_osd *osd)
+{
+	xilinx_drm_writel(osd->base, OSD_CTL,
+			  xilinx_drm_readl(osd->base, OSD_CTL) | OSD_CTL_EN);
+}
+
+/* disable osd */
+void xilinx_osd_disable(struct xilinx_osd *osd)
+{
+	xilinx_drm_writel(osd->base, OSD_CTL,
+			  xilinx_drm_readl(osd->base, OSD_CTL) & ~OSD_CTL_EN);
+}
+
+/* register-update-enable osd */
+void xilinx_osd_enable_rue(struct xilinx_osd *osd)
+{
+	xilinx_drm_writel(osd->base, OSD_CTL,
+			  xilinx_drm_readl(osd->base, OSD_CTL) | OSD_CTL_RUE);
+}
+
+/* register-update-enable osd */
+void xilinx_osd_disable_rue(struct xilinx_osd *osd)
+{
+	xilinx_drm_writel(osd->base, OSD_CTL,
+			  xilinx_drm_readl(osd->base, OSD_CTL) & ~OSD_CTL_RUE);
+}
+
+struct xilinx_osd *xilinx_osd_probe(struct device *dev,
+				    struct device_node *node)
+{
+	struct xilinx_osd *osd;
+	struct xilinx_osd_layer *layer;
+	struct resource res;
+	int i;
+	int ret;
+
+	osd = devm_kzalloc(dev, sizeof(*osd), GFP_KERNEL);
+	if (!osd)
+		return ERR_PTR(-ENOMEM);
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to of_address_to_resource\n");
+		return ERR_PTR(ret);
+	}
+
+	osd->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(osd->base))
+		return ERR_CAST(osd->base);
+
+	ret = of_property_read_u32(node, "xlnx,num-layers", &osd->num_layers);
+	if (ret) {
+		dev_warn(dev, "failed to get num of layers prop\n");
+		return ERR_PTR(ret);
+	}
+
+	ret = of_property_read_u32(node, "xlnx,screen-width", &osd->max_width);
+	if (ret) {
+		dev_warn(dev, "failed to get screen width prop\n");
+		return ERR_PTR(ret);
+	}
+
+	/* read the video format set by a user */
+	osd->format = xilinx_drm_readl(osd->base, OSD_ENC) &
+		      OSD_VIDEO_FORMAT_MASK;
+
+	for (i = 0; i < osd->num_layers; i++) {
+		layer = devm_kzalloc(dev, sizeof(*layer), GFP_KERNEL);
+		if (!layer)
+			return ERR_PTR(-ENOMEM);
+
+		layer->base = osd->base + OSD_L0C + OSD_LAYER_SIZE * i;
+		layer->id = i;
+		layer->osd = osd;
+		layer->avail = true;
+		osd->layers[i] = layer;
+	}
+
+	return osd;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_osd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_osd.h	2014-07-20 22:06:36.263307252 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx OSD Header for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_OSD_H_
+#define _XILINX_OSD_H_
+
+struct xilinx_osd;
+struct xilinx_osd_layer;
+
+/* osd layer configuration */
+void xilinx_osd_layer_set_alpha(struct xilinx_osd_layer *layer, u32 enable,
+				u32 alpha);
+void xilinx_osd_layer_set_priority(struct xilinx_osd_layer *layer, u32 prio);
+void xilinx_osd_layer_set_dimension(struct xilinx_osd_layer *layer,
+				    u16 xstart, u16 ystart,
+				    u16 xsize, u16 ysize);
+
+/* osd layer operation */
+void xilinx_osd_layer_enable(struct xilinx_osd_layer *layer);
+void xilinx_osd_layer_disable(struct xilinx_osd_layer *layer);
+struct xilinx_osd_layer *xilinx_osd_layer_get(struct xilinx_osd *osd);
+void xilinx_osd_layer_put(struct xilinx_osd_layer *layer);
+
+/* osd configuration */
+void xilinx_osd_set_color(struct xilinx_osd *osd, u8 r, u8 g, u8 b);
+void xilinx_osd_set_dimension(struct xilinx_osd *osd, u32 width, u32 height);
+
+unsigned int xilinx_osd_get_num_layers(struct xilinx_osd *osd);
+unsigned int xilinx_osd_get_max_width(struct xilinx_osd *osd);
+unsigned int xilinx_osd_get_format(struct xilinx_osd *osd);
+
+/* osd operation */
+void xilinx_osd_reset(struct xilinx_osd *osd);
+void xilinx_osd_enable(struct xilinx_osd *osd);
+void xilinx_osd_disable(struct xilinx_osd *osd);
+void xilinx_osd_enable_rue(struct xilinx_osd *osd);
+void xilinx_osd_disable_rue(struct xilinx_osd *osd);
+
+struct device;
+struct device_node;
+
+struct xilinx_osd *xilinx_osd_probe(struct device *dev,
+				    struct device_node *node);
+
+#endif /* _XILINX_OSD_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_rgb2yuv.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_rgb2yuv.c	2014-07-20 22:06:36.269307153 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx rgb to yuv converter support for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "xilinx_drm_drv.h"
+
+/* registers */
+/* control register */
+#define RGB_CONTROL	0x000
+/* active size v,h */
+#define RGB_ACTIVE_SIZE	0x020
+
+/* control register bit definition */
+#define RGB_CTL_EN	(1 << 0)	/* enable */
+#define RGB_CTL_RUE	(1 << 1)	/* register update enable */
+#define RGB_RST_RESET	(1 << 31)	/* instant reset */
+
+struct xilinx_rgb2yuv {
+	void __iomem *base;
+};
+
+/* enable rgb2yuv */
+void xilinx_rgb2yuv_enable(struct xilinx_rgb2yuv *rgb2yuv)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
+	xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg | RGB_CTL_EN);
+}
+
+/* disable rgb2yuv */
+void xilinx_rgb2yuv_disable(struct xilinx_rgb2yuv *rgb2yuv)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
+	xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg & ~RGB_CTL_EN);
+}
+
+/* configure rgb2yuv */
+void xilinx_rgb2yuv_configure(struct xilinx_rgb2yuv *rgb2yuv,
+			      int hactive, int vactive)
+{
+	xilinx_drm_writel(rgb2yuv->base, RGB_ACTIVE_SIZE,
+			  (vactive << 16) | hactive);
+}
+
+/* reset rgb2yuv */
+void xilinx_rgb2yuv_reset(struct xilinx_rgb2yuv *rgb2yuv)
+{
+	u32 reg;
+
+	xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, RGB_RST_RESET);
+
+	/* enable register update */
+	reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
+	xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg | RGB_CTL_RUE);
+}
+
+/* probe rgb2yuv */
+struct xilinx_rgb2yuv *xilinx_rgb2yuv_probe(struct device *dev,
+					    struct device_node *node)
+{
+	struct xilinx_rgb2yuv *rgb2yuv;
+	struct resource res;
+	int ret;
+
+	rgb2yuv = devm_kzalloc(dev, sizeof(*rgb2yuv), GFP_KERNEL);
+	if (!rgb2yuv)
+		return ERR_PTR(-ENOMEM);
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to of_address_to_resource\n");
+		return ERR_PTR(ret);
+	}
+
+	rgb2yuv->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(rgb2yuv->base))
+		return ERR_CAST(rgb2yuv->base);
+
+	xilinx_rgb2yuv_reset(rgb2yuv);
+
+	return rgb2yuv;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_rgb2yuv.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_rgb2yuv.h	2014-07-20 22:06:36.275307054 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Color Space Converter Header for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_RGB2YUV_H_
+#define _XILINX_RGB2YUV_H_
+
+struct xilinx_rgb2yuv;
+
+void xilinx_rgb2yuv_configure(struct xilinx_rgb2yuv *rgb2yuv,
+			      int hactive, int vactive);
+void xilinx_rgb2yuv_reset(struct xilinx_rgb2yuv *rgb2yuv);
+void xilinx_rgb2yuv_enable(struct xilinx_rgb2yuv *rgb2yuv);
+void xilinx_rgb2yuv_disable(struct xilinx_rgb2yuv *rgb2yuv);
+
+struct device;
+struct device_node;
+
+struct xilinx_rgb2yuv *xilinx_rgb2yuv_probe(struct device *dev,
+					    struct device_node *node);
+
+#endif /* _XILINX_RGB2YUV_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_vtc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_vtc.c	2014-07-20 22:06:36.355305734 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Video Timing Controller support for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+
+#include <video/videomode.h>
+
+#include "xilinx_drm_drv.h"
+#include "xilinx_vtc.h"
+
+/* register offsets */
+#define VTC_CTL		0x000	/* control */
+#define VTC_STATS	0x004	/* status */
+#define VTC_ERROR	0x008	/* error */
+
+#define VTC_GASIZE	0x060	/* generator active size */
+#define VTC_GPOL	0x06c	/* generator polarity */
+#define VTC_GHSIZE	0x070	/* generator frame horizontal size */
+#define VTC_GVSIZE	0x074	/* generator frame vertical size */
+#define VTC_GHSYNC	0x078	/* generator horizontal sync */
+#define VTC_GVBHOFF	0x07c	/* generator vblank horizontal offset */
+#define VTC_GVSYNC	0x080	/* generator vertical sync */
+#define VTC_GVSHOFF	0x084	/* generator vsync horizontal offset */
+
+#define VTC_RESET	0x000	/* reset register */
+#define VTC_ISR		0x004	/* interrupt status register */
+#define VTC_IER		0x00c	/* interrupt enable register */
+
+/* control register bit */
+#define VTC_CTL_FIP	(1 << 6)	/* field id output polarity */
+#define VTC_CTL_ACP	(1 << 5)	/* active chroma output polarity */
+#define VTC_CTL_AVP	(1 << 4)	/* active video output polarity */
+#define VTC_CTL_HSP	(1 << 3)	/* hori sync output polarity */
+#define VTC_CTL_VSP	(1 << 2)	/* vert sync output polarity */
+#define VTC_CTL_HBP	(1 << 1)	/* hori blank output polarity */
+#define VTC_CTL_VBP	(1 << 0)	/* vert blank output polarity */
+
+#define VTC_CTL_FIPSS	(1 << 26)	/* field id output polarity source */
+#define VTC_CTL_ACPSS	(1 << 25)	/* active chroma out polarity source */
+#define VTC_CTL_AVPSS	(1 << 24)	/* active video out polarity source */
+#define VTC_CTL_HSPSS	(1 << 23)	/* hori sync out polarity source */
+#define VTC_CTL_VSPSS	(1 << 22)	/* vert sync out polarity source */
+#define VTC_CTL_HBPSS	(1 << 21)	/* hori blank out polarity source */
+#define VTC_CTL_VBPSS	(1 << 20)	/* vert blank out polarity source */
+
+#define VTC_CTL_VCSS	(1 << 18)	/* chroma source select */
+#define VTC_CTL_VASS	(1 << 17)	/* vertical offset source select */
+#define VTC_CTL_VBSS	(1 << 16)	/* vertical sync end source select */
+#define VTC_CTL_VSSS	(1 << 15)	/* vertical sync start source select */
+#define VTC_CTL_VFSS	(1 << 14)	/* vertical active size source select */
+#define VTC_CTL_VTSS	(1 << 13)	/* vertical frame size source select */
+
+#define VTC_CTL_HBSS	(1 << 11)	/* horiz sync end source select */
+#define VTC_CTL_HSSS	(1 << 10)	/* horiz sync start source select */
+#define VTC_CTL_HFSS	(1 << 9)	/* horiz active size source select */
+#define VTC_CTL_HTSS	(1 << 8)	/* horiz frame size source select */
+
+#define VTC_CTL_GE	(1 << 2)	/* vtc generator enable */
+#define VTC_CTL_RU	(1 << 1)	/* vtc register update */
+
+/* vtc generator horizontal 1 */
+#define VTC_GH1_BPSTART_MASK   0x1fff0000	/* horiz back porch start */
+#define VTC_GH1_BPSTART_SHIFT  16
+#define VTC_GH1_SYNCSTART_MASK 0x00001fff
+
+/* vtc generator vertical 1 (filed 0) */
+#define VTC_GV1_BPSTART_MASK   0x1fff0000	/* vertical back porch start */
+#define VTC_GV1_BPSTART_SHIFT  16
+#define VTC_GV1_SYNCSTART_MASK 0x00001fff
+
+/* vtc generator/detector vblank/vsync horizontal offset registers */
+#define VTC_XVXHOX_HEND_MASK	0x1fff0000	/* horizontal offset end */
+#define VTC_XVXHOX_HEND_SHIFT	16		/* horizontal offset end
+						   shift */
+#define VTC_XVXHOX_HSTART_MASK	0x00001fff	/* horizontal offset start */
+
+/* reset register bit definition */
+#define VTC_RESET_RESET		(1 << 31)	/* Software Reset */
+
+/* interrupt status/enable register bit definition */
+#define VTC_IXR_FSYNC15		(1 << 31)	/* frame sync interrupt 15 */
+#define VTC_IXR_FSYNC14		(1 << 30)	/* frame sync interrupt 14 */
+#define VTC_IXR_FSYNC13		(1 << 29)	/* frame sync interrupt 13 */
+#define VTC_IXR_FSYNC12		(1 << 28)	/* frame sync interrupt 12 */
+#define VTC_IXR_FSYNC11		(1 << 27)	/* frame sync interrupt 11 */
+#define VTC_IXR_FSYNC10		(1 << 26)	/* frame sync interrupt 10 */
+#define VTC_IXR_FSYNC09		(1 << 25)	/* frame sync interrupt 09 */
+#define VTC_IXR_FSYNC08		(1 << 24)	/* frame sync interrupt 08 */
+#define VTC_IXR_FSYNC07		(1 << 23)	/* frame sync interrupt 07 */
+#define VTC_IXR_FSYNC06		(1 << 22)	/* frame sync interrupt 06 */
+#define VTC_IXR_FSYNC05		(1 << 21)	/* frame sync interrupt 05 */
+#define VTC_IXR_FSYNC04		(1 << 20)	/* frame sync interrupt 04 */
+#define VTC_IXR_FSYNC03		(1 << 19)	/* frame sync interrupt 03 */
+#define VTC_IXR_FSYNC02		(1 << 18)	/* frame sync interrupt 02 */
+#define VTC_IXR_FSYNC01		(1 << 17)	/* frame sync interrupt 01 */
+#define VTC_IXR_FSYNC00		(1 << 16)	/* frame sync interrupt 00 */
+#define VTC_IXR_FSYNCALL_MASK	(VTC_IXR_FSYNC00 |	\
+				VTC_IXR_FSYNC01 |	\
+				VTC_IXR_FSYNC02 |	\
+				VTC_IXR_FSYNC03 |	\
+				VTC_IXR_FSYNC04 |	\
+				VTC_IXR_FSYNC05 |	\
+				VTC_IXR_FSYNC06 |	\
+				VTC_IXR_FSYNC07 |	\
+				VTC_IXR_FSYNC08 |	\
+				VTC_IXR_FSYNC09 |	\
+				VTC_IXR_FSYNC10 |	\
+				VTC_IXR_FSYNC11 |	\
+				VTC_IXR_FSYNC12 |	\
+				VTC_IXR_FSYNC13 |	\
+				VTC_IXR_FSYNC14 |	\
+				VTC_IXR_FSYNC15)
+
+#define VTC_IXR_G_AV		(1 << 13)	/* generator actv video intr */
+#define VTC_IXR_G_VBLANK	(1 << 12)	/* generator vblank interrupt */
+#define VTC_IXR_G_ALL_MASK	(VTC_IXR_G_AV |	\
+				 VTC_IXR_G_VBLANK)	/* all generator intr */
+
+#define VTC_IXR_D_AV		(1 << 11)	/* detector active video intr */
+#define VTC_IXR_D_VBLANK	(1 << 10)	/* detector vblank interrupt */
+#define VTC_IXR_D_ALL_MASK	(VTC_IXR_D_AV |	\
+				VTC_IXR_D_VBLANK)	/* all detector intr */
+
+#define VTC_IXR_LOL		(1 << 9)	/* lock loss */
+#define VTC_IXR_LO		(1 << 8)	/* lock  */
+#define VTC_IXR_LOCKALL_MASK	(VTC_IXR_LOL |	\
+				VTC_IXR_LO)	/* all signal lock intr */
+
+#define VTC_IXR_ACL	(1 << 21)	/* active chroma signal lock */
+#define VTC_IXR_AVL	(1 << 20)	/* active video signal lock */
+#define VTC_IXR_HSL	(1 << 19)	/* horizontal sync signal
+						   lock */
+#define VTC_IXR_VSL	(1 << 18)	/* vertical sync signal lock */
+#define VTC_IXR_HBL	(1 << 17)	/* horizontal blank signal
+						   lock */
+#define VTC_IXR_VBL	(1 << 16)	/* vertical blank signal lock */
+
+/* mask for all interrupts */
+#define VTC_IXR_ALLINTR_MASK	(VTC_IXR_FSYNCALL_MASK |	\
+				VTC_IXR_G_ALL_MASK |		\
+				VTC_IXR_D_ALL_MASK |		\
+				VTC_IXR_LOCKALL_MASK)
+/**
+ * struct xilinx_vtc: Xilinx VTC object
+ *
+ * @base: base addr
+ * @irq: irq
+ * @vblank_fn: vblank handler func
+ * @vblank_data: vblank handler private data
+ */
+struct xilinx_vtc {
+	void __iomem *base;
+	int irq;
+	void (*vblank_fn)(void *);
+	void *vblank_data;
+};
+
+/**
+ * struct xilinx_vtc_polarity: vtc polarity config
+ *
+ * @active_chroma: active chroma polarity
+ * @active_video: active video polarity
+ * @field_id: field ID polarity
+ * @vblank: vblank polarity
+ * @vsync: vsync polarity
+ * @hblank: hblank polarity
+ * @hsync: hsync polarity
+ */
+struct xilinx_vtc_polarity {
+	u8 active_chroma;
+	u8 active_video;
+	u8 field_id;
+	u8 vblank;
+	u8 vsync;
+	u8 hblank;
+	u8 hsync;
+};
+
+/**
+ * struct xilinx_vtc_hori_offset: vtc horizontal offset config
+ *
+ * @vblank_hori_start: vblank horizontal start
+ * @vblank_hori_end: vblank horizontal end
+ * @vsync_hori_start: vsync horizontal start
+ * @vsync_hori_end: vsync horizontal end
+ */
+struct xilinx_vtc_hori_offset {
+	u16 vblank_hori_start;
+	u16 vblank_hori_end;
+	u16 vsync_hori_start;
+	u16 vsync_hori_end;
+};
+
+/**
+ * struct xilinx_vtc_src_config: vtc source config
+ *
+ * @field_id_pol: filed id polarity source
+ * @active_chroma_pol: active chroma polarity source
+ * @active_video_pol: active video polarity source
+ * @hsync_pol: hsync polarity source
+ * @vsync_pol: vsync polarity source
+ * @hblank_pol: hblnak polarity source
+ * @vblank_pol: vblank polarity source
+ * @vchroma: vchroma polarity start source
+ * @vactive: vactive size source
+ * @vbackporch: vbackporch start source
+ * @vsync: vsync start source
+ * @vfrontporch: vfrontporch start source
+ * @vtotal: vtotal size source
+ * @hactive: hactive start source
+ * @hbackporch: hbackporch start source
+ * @hsync: hsync start source
+ * @hfrontporch: hfrontporch start source
+ * @htotal: htotal size source
+ */
+struct xilinx_vtc_src_config {
+	u8 field_id_pol;
+	u8 active_chroma_pol;
+	u8 active_video_pol;
+	u8 hsync_pol;
+	u8 vsync_pol;
+	u8 hblank_pol;
+	u8 vblank_pol;
+
+	u8 vchroma;
+	u8 vactive;
+	u8 vbackporch;
+	u8 vsync;
+	u8 vfrontporch;
+	u8 vtotal;
+
+	u8 hactive;
+	u8 hbackporch;
+	u8 hsync;
+	u8 hfrontporch;
+	u8 htotal;
+};
+
+/* configure polarity of signals */
+static void xilinx_vtc_config_polarity(struct xilinx_vtc *vtc,
+				       struct xilinx_vtc_polarity *polarity)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(vtc->base, VTC_GPOL);
+
+	if (polarity->active_chroma)
+		reg |= VTC_CTL_ACP;
+	if (polarity->active_video)
+		reg |= VTC_CTL_AVP;
+	if (polarity->field_id)
+		reg |= VTC_CTL_FIP;
+	if (polarity->vblank)
+		reg |= VTC_CTL_VBP;
+	if (polarity->vsync)
+		reg |= VTC_CTL_VSP;
+	if (polarity->hblank)
+		reg |= VTC_CTL_HBP;
+	if (polarity->hsync)
+		reg |= VTC_CTL_HSP;
+
+	xilinx_drm_writel(vtc->base, VTC_GPOL, reg);
+}
+
+/* configure horizontal offset */
+static void
+xilinx_vtc_config_hori_offset(struct xilinx_vtc *vtc,
+			      struct xilinx_vtc_hori_offset *hori_offset)
+{
+	u32 reg;
+
+	reg = hori_offset->vblank_hori_start & VTC_XVXHOX_HSTART_MASK;
+	reg |= (hori_offset->vblank_hori_end << VTC_XVXHOX_HEND_SHIFT) &
+	       VTC_XVXHOX_HEND_MASK;
+	xilinx_drm_writel(vtc->base, VTC_GVBHOFF, reg);
+
+	reg = hori_offset->vsync_hori_start & VTC_XVXHOX_HSTART_MASK;
+	reg |= (hori_offset->vsync_hori_end << VTC_XVXHOX_HEND_SHIFT) &
+	       VTC_XVXHOX_HEND_MASK;
+	xilinx_drm_writel(vtc->base, VTC_GVSHOFF, reg);
+}
+
+/* configure source */
+static void xilinx_vtc_config_src(struct xilinx_vtc *vtc,
+				  struct xilinx_vtc_src_config *src_config)
+{
+	u32 reg;
+
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+
+	if (src_config->field_id_pol)
+		reg |= VTC_CTL_FIPSS;
+	if (src_config->active_chroma_pol)
+		reg |= VTC_CTL_ACPSS;
+	if (src_config->active_video_pol)
+		reg |= VTC_CTL_AVPSS;
+	if (src_config->hsync_pol)
+		reg |= VTC_CTL_HSPSS;
+	if (src_config->vsync_pol)
+		reg |= VTC_CTL_VSPSS;
+	if (src_config->hblank_pol)
+		reg |= VTC_CTL_HBPSS;
+	if (src_config->vblank_pol)
+		reg |= VTC_CTL_VBPSS;
+
+	if (src_config->vchroma)
+		reg |= VTC_CTL_VCSS;
+	if (src_config->vactive)
+		reg |= VTC_CTL_VASS;
+	if (src_config->vbackporch)
+		reg |= VTC_CTL_VBSS;
+	if (src_config->vsync)
+		reg |= VTC_CTL_VSSS;
+	if (src_config->vfrontporch)
+		reg |= VTC_CTL_VFSS;
+	if (src_config->vtotal)
+		reg |= VTC_CTL_VTSS;
+
+	if (src_config->hbackporch)
+		reg |= VTC_CTL_HBSS;
+	if (src_config->hsync)
+		reg |= VTC_CTL_HSSS;
+	if (src_config->hfrontporch)
+		reg |= VTC_CTL_HFSS;
+	if (src_config->htotal)
+		reg |= VTC_CTL_HTSS;
+
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg);
+}
+
+/* enable vtc */
+void xilinx_vtc_enable(struct xilinx_vtc *vtc)
+{
+	u32 reg;
+
+	/* enable a generator only for now */
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg | VTC_CTL_GE);
+}
+
+/* disable vtc */
+void xilinx_vtc_disable(struct xilinx_vtc *vtc)
+{
+	u32 reg;
+
+	/* disable a generator only for now */
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg & ~VTC_CTL_GE);
+}
+
+/* configure vtc signals */
+void xilinx_vtc_config_sig(struct xilinx_vtc *vtc,
+			   struct videomode *vm)
+{
+	u32 reg;
+	u32 htotal, hactive, hsync_start, hbackporch_start;
+	u32 vtotal, vactive, vsync_start, vbackporch_start;
+	struct xilinx_vtc_hori_offset hori_offset;
+	struct xilinx_vtc_polarity polarity;
+	struct xilinx_vtc_src_config src;
+
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg & ~VTC_CTL_RU);
+
+	htotal = vm->hactive + vm->hfront_porch + vm->hsync_len +
+		 vm->hback_porch;
+	vtotal = vm->vactive + vm->vfront_porch + vm->vsync_len +
+		 vm->vback_porch;
+
+	hactive = vm->hactive;
+	vactive = vm->vactive;
+
+	hsync_start = vm->hactive + vm->hfront_porch;
+	vsync_start = vm->vactive + vm->vfront_porch;
+
+	hbackporch_start = hsync_start + vm->hsync_len;
+	vbackporch_start = vsync_start + vm->vsync_len;
+
+	reg = htotal & 0x1fff;
+	xilinx_drm_writel(vtc->base, VTC_GHSIZE, reg);
+
+	reg = vtotal & 0x1fff;
+	xilinx_drm_writel(vtc->base, VTC_GVSIZE, reg);
+
+	DRM_DEBUG_DRIVER("ht: %d, vt: %d\n", htotal, vtotal);
+
+	reg = hactive & 0x1fff;
+	reg |= (vactive & 0x1fff) << 16;
+	xilinx_drm_writel(vtc->base, VTC_GASIZE, reg);
+
+	DRM_DEBUG_DRIVER("ha: %d, va: %d\n", hactive, vactive);
+
+	reg = hsync_start & VTC_GH1_SYNCSTART_MASK;
+	reg |= (hbackporch_start << VTC_GH1_BPSTART_SHIFT) &
+	       VTC_GH1_BPSTART_MASK;
+	xilinx_drm_writel(vtc->base, VTC_GHSYNC, reg);
+
+	DRM_DEBUG_DRIVER("hs: %d, hb: %d\n", hsync_start, hbackporch_start);
+
+	reg = vsync_start & VTC_GV1_SYNCSTART_MASK;
+	reg |= (vbackporch_start << VTC_GV1_BPSTART_SHIFT) &
+	       VTC_GV1_BPSTART_MASK;
+	xilinx_drm_writel(vtc->base, VTC_GVSYNC, reg);
+
+	DRM_DEBUG_DRIVER("vs: %d, vb: %d\n", vsync_start, vbackporch_start);
+
+	hori_offset.vblank_hori_start = hactive;
+	hori_offset.vblank_hori_end = hactive;
+	hori_offset.vsync_hori_start = hactive;
+	hori_offset.vsync_hori_end = hactive;
+
+	xilinx_vtc_config_hori_offset(vtc, &hori_offset);
+
+	/* set up polarity */
+	memset(&polarity, 0x0, sizeof(polarity));
+	polarity.hsync = 1;
+	polarity.vsync = 1;
+	polarity.hblank = 1;
+	polarity.vblank = 1;
+	polarity.active_video = 1;
+	polarity.active_chroma = 1;
+	polarity.field_id = 1;
+	xilinx_vtc_config_polarity(vtc, &polarity);
+
+	/* set up src config */
+	memset(&src, 0x0, sizeof(src));
+	src.vchroma = 1;
+	src.vactive = 1;
+	src.vbackporch = 1;
+	src.vsync = 1;
+	src.vfrontporch = 1;
+	src.vtotal = 1;
+	src.hactive = 1;
+	src.hbackporch = 1;
+	src.hsync = 1;
+	src.hfrontporch = 1;
+	src.htotal = 1;
+	xilinx_vtc_config_src(vtc, &src);
+
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg | VTC_CTL_RU);
+}
+
+/* reset vtc */
+void xilinx_vtc_reset(struct xilinx_vtc *vtc)
+{
+	u32 reg;
+
+	xilinx_drm_writel(vtc->base, VTC_RESET, VTC_RESET_RESET);
+
+	/* enable register update */
+	reg = xilinx_drm_readl(vtc->base, VTC_CTL);
+	xilinx_drm_writel(vtc->base, VTC_CTL, reg | VTC_CTL_RU);
+}
+
+/* enable interrupt */
+static inline void xilinx_vtc_intr_enable(struct xilinx_vtc *vtc, u32 intr)
+{
+	xilinx_drm_writel(vtc->base, VTC_IER, (intr & VTC_IXR_ALLINTR_MASK) |
+			  xilinx_drm_readl(vtc->base, VTC_IER));
+}
+
+/* disable interrupt */
+static inline void xilinx_vtc_intr_disable(struct xilinx_vtc *vtc, u32 intr)
+{
+	xilinx_drm_writel(vtc->base, VTC_IER, ~(intr & VTC_IXR_ALLINTR_MASK) &
+			  xilinx_drm_readl(vtc->base, VTC_IER));
+}
+
+/* get interrupt */
+static inline u32 xilinx_vtc_intr_get(struct xilinx_vtc *vtc)
+{
+	return xilinx_drm_readl(vtc->base, VTC_IER) &
+	       xilinx_drm_readl(vtc->base, VTC_ISR) & VTC_IXR_ALLINTR_MASK;
+}
+
+/* clear interrupt */
+static inline void xilinx_vtc_intr_clear(struct xilinx_vtc *vtc, u32 intr)
+{
+	xilinx_drm_writel(vtc->base, VTC_ISR, intr & VTC_IXR_ALLINTR_MASK);
+}
+
+/* interrupt handler */
+static irqreturn_t xilinx_vtc_intr_handler(int irq, void *data)
+{
+	struct xilinx_vtc *vtc = data;
+
+	u32 intr = xilinx_vtc_intr_get(vtc);
+
+	if ((intr & VTC_IXR_G_VBLANK) && (vtc->vblank_fn))
+		vtc->vblank_fn(vtc->vblank_data);
+
+	xilinx_vtc_intr_clear(vtc, intr);
+
+	return IRQ_HANDLED;
+}
+
+/* enable vblank interrupt */
+void xilinx_vtc_enable_vblank_intr(struct xilinx_vtc *vtc,
+				   void (*vblank_fn)(void *),
+				   void *vblank_priv)
+{
+	vtc->vblank_fn = vblank_fn;
+	vtc->vblank_data = vblank_priv;
+	xilinx_vtc_intr_enable(vtc, VTC_IXR_G_VBLANK);
+}
+
+/* disable vblank interrupt */
+void xilinx_vtc_disable_vblank_intr(struct xilinx_vtc *vtc)
+{
+	xilinx_vtc_intr_disable(vtc, VTC_IXR_G_VBLANK);
+	vtc->vblank_data = NULL;
+	vtc->vblank_fn = NULL;
+}
+
+/* probe vtc */
+struct xilinx_vtc *xilinx_vtc_probe(struct device *dev,
+				    struct device_node *node)
+{
+	struct xilinx_vtc *vtc;
+	struct resource res;
+	int ret;
+
+	vtc = devm_kzalloc(dev, sizeof(*vtc), GFP_KERNEL);
+	if (!vtc)
+		return ERR_PTR(-ENOMEM);
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to of_address_to_resource\n");
+		return ERR_PTR(ret);
+	}
+
+	vtc->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(vtc->base))
+		return ERR_CAST(vtc->base);
+
+	xilinx_vtc_intr_disable(vtc, VTC_IXR_ALLINTR_MASK);
+	vtc->irq = irq_of_parse_and_map(node, 0);
+	if (vtc->irq > 0) {
+		ret = devm_request_irq(dev, vtc->irq, xilinx_vtc_intr_handler,
+				       IRQF_SHARED, "xilinx_vtc", vtc);
+		if (ret) {
+			dev_warn(dev, "failed to requet_irq() for vtc\n");
+			return ERR_PTR(ret);
+		}
+	}
+
+	xilinx_vtc_reset(vtc);
+
+	return vtc;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_vtc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/gpu/drm/xilinx/xilinx_vtc.h	2014-07-20 22:06:36.362305619 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Video Timing Controller Header for Xilinx DRM KMS
+ *
+ *  Copyright (C) 2013 Xilinx, Inc.
+ *
+ *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
+ *
+ * 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 _XILINX_VTC_H_
+#define _XILINX_VTC_H_
+
+struct xilinx_vtc;
+
+struct videomode;
+
+void xilinx_vtc_config_sig(struct xilinx_vtc *vtc,
+			   struct videomode *vm);
+void xilinx_vtc_enable_vblank_intr(struct xilinx_vtc *vtc,
+				   void (*fn)(void *), void *data);
+void xilinx_vtc_disable_vblank_intr(struct xilinx_vtc *vtc);
+void xilinx_vtc_reset(struct xilinx_vtc *vtc);
+void xilinx_vtc_enable(struct xilinx_vtc *vtc);
+void xilinx_vtc_disable(struct xilinx_vtc *vtc);
+
+struct device;
+struct device_node;
+
+struct xilinx_vtc *xilinx_vtc_probe(struct device *dev,
+				    struct device_node *node);
+
+#endif /* _XILINX_VTC_H_ */
Index: linux-3.12.24-rt38-xilinx/drivers/hwmon/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/hwmon/Kconfig	2014-07-20 22:05:50.204067149 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/hwmon/Kconfig	2014-07-20 22:06:36.379305338 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1556 @
         help
           Support for the A/D converter on MC13783 and MC13892 PMIC.
 
+config SENSORS_XADCPS
+	tristate "Xilinx Zynq XADC"
+	depends on ARCH_ZYNQ
+	depends on SYSFS
+	help
+	  Support for the A/D converter on Xilinx Zynq.
+
 if ACPI
 
 comment "ACPI drivers"
Index: linux-3.12.24-rt38-xilinx/drivers/hwmon/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/hwmon/Makefile	2014-07-20 22:05:50.203067166 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/hwmon/Makefile	2014-07-20 22:06:36.390305157 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:145 @
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
 obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
 obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
+obj-$(CONFIG_SENSORS_XADCPS)	+= xilinx-xadcps.o
 
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
Index: linux-3.12.24-rt38-xilinx/drivers/hwmon/xilinx-xadcps.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/hwmon/xilinx-xadcps.c	2014-07-20 22:06:36.403304943 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * drivers/hwmon/xilinx-xadcps.c - Xilinx Zynq XADC support
+ *
+ * Copyright (c) 2012 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+/* XADC interface register offsets */
+#define XADC_CONFIG	0x00
+#define XADC_INTSTS	0x04
+#define XADC_INTMSK	0x08
+#define XADC_STATUS	0x0C
+#define XADC_CFIFO	0x10
+#define XADC_DFIFO	0x14
+#define XADC_CTL	0x18
+
+/* XADC interface register fields */
+#define XADC_CONFIG_ENABLE		(1 << 31)
+#define XADC_CONFIG_CFIFOTH_MSK		0xF
+#define XADC_CONFIG_CFIFOTH_SHIFT	20
+#define XADC_CONFIG_DFIFOTH_MSK		0xF
+#define XADC_CONFIG_DFIFOTH_SHIFT	16
+#define XADC_CONFIG_WEDGE		(1 << 13)
+#define XADC_CONFIG_REDGE		(1 << 12)
+#define XADC_CONFIG_TCKRATE_MSK		0x3
+#define XADC_CONFIG_TCKRATE_SHIFT	8
+#define XADC_CONFIG_IGAP_MSK		0x1F
+#define XADC_CONFIG_IGAP_SHIFT		0
+
+#define TCKRATE_DIV16			3
+
+#define XADC_INT_CFIFO_LTH		(1 << 9)
+#define XADC_INT_DFIFO_GTH		(1 << 8)
+
+#define XADC_STATUS_CFIFO_LVL_MSK	0xF
+#define XADC_STATUS_CFIFO_LVL_SHIFT	16
+#define XADC_STATUS_DFIFO_EMPTY		(1 << 8)
+
+#define XADC_FIFO_CMD_MSK		0xF
+#define XADC_FIFO_CMD_SHIFT		26
+#define XADC_FIFO_ADDR_MSK		0x3FF
+#define XADC_FIFO_ADDR_SHIFT		16
+#define XADC_FIFO_DATA_MSK		0xFFFF
+#define XADC_FIFO_DATA_SHIFT		0
+
+/* XADC commands */
+#define XADC_CMD_NOP			0
+#define XADC_CMD_READ			1
+#define XADC_CMD_WRITE			2
+
+/* XADC register offsets */
+#define REG_TEMP		0x00
+#define REG_VCCINT		0x01
+#define REG_VCCAUX		0x02
+#define REG_VPVN		0x03
+#define REG_VCCBRAM		0x06
+
+#define REG_MAX_TEMP		0x20
+#define REG_MAX_VCCINT		0x21
+#define REG_MAX_VCCAUX		0x22
+#define REG_MAX_VCCBRAM		0x23
+#define REG_MIN_TEMP		0x24
+#define REG_MIN_VCCINT		0x25
+#define REG_MIN_VCCAUX		0x26
+#define REG_MIN_VCCBRAM		0x27
+
+#define REG_FLAG		0x3F
+#define REG_CFG1		0x41
+
+#define REG_SEQ_SEL0		0x48
+#define REG_SEQ_SEL1		0x49
+#define REG_SEQ_AVG0		0x4A
+#define REG_SEQ_AVG1		0x4B
+#define REG_SEQ_BIP0		0x4C
+#define REG_SEQ_BIP1		0x4D
+#define REG_SEQ_ACQ0		0x4E
+#define REG_SEQ_ACQ1		0x4F
+
+/* XADC register fields */
+#define REG_CFG1_CAL_ADCOG	(1 << 5)	/* ADC offset & gain */
+#define REG_CFG1_CAL_SSOG	(1 << 7)	/* supply sensor offset &gain */
+
+#define REG_CFG1_SEQ_MSK	0xF
+#define REG_CFG1_SEQ_SHIFT	12
+
+#define MODE_DEF		0	/* Internal sensors, no alarms */
+#define MODE_IND		8	/* Independent:ADC A -int, ADC B -ext */
+
+#define REG_FLAG_DIS		(1 << 8)
+#define REG_FLAG_REF		(1 << 9)
+
+/* Sequencer registers 0 */
+#define REG_SEQ_V		(1 << 11)
+
+#define READ(dev, reg) readl((dev->iobase + XADC_##reg))
+#define WRITE(dev, reg, value) writel(value, dev->iobase+XADC_##reg)
+
+#define GETFIELD(reg, field, value) \
+	(((value) >> (reg##_##field##_SHIFT)) & reg##_##field##_MSK)
+
+#define SETFIELD(reg, field, value) \
+	(((value) & reg##_##field##_MSK) << reg##_##field##_SHIFT)
+
+#define CLRFIELD(reg, field, value) \
+	((value) & ~(reg##_##field##_MSK << reg##_##field##_SHIFT))
+
+#define READOP(reg) \
+		(SETFIELD(XADC_FIFO, CMD, XADC_CMD_READ) |\
+		SETFIELD(XADC_FIFO, ADDR, reg))
+
+#define WRITEOP(reg, val) \
+		(SETFIELD(XADC_FIFO, CMD, XADC_CMD_WRITE) |\
+		SETFIELD(XADC_FIFO, ADDR, reg) | SETFIELD(XADC_FIFO, DATA, val))
+
+#define NOOP (SETFIELD(XADC_FIFO, CMD, XADC_CMD_NOP))
+
+struct xadc_op {
+	u32 cmd;
+	u32 res;
+};
+
+struct xadc_batch {
+	int count;
+	int writeptr;
+	int readptr;
+	struct list_head q;
+	struct completion comp;
+	struct xadc_op *ops;
+};
+
+
+struct xadc_t {
+	struct device *dev;
+	struct device *hwmon;
+	void __iomem *iobase;
+	int irq;
+	struct clk	*clk;
+	spinlock_t slock;
+	struct list_head runq;
+	struct xadc_batch *curr;
+	u32 chanmode[17];	/* Channel 0-15 VAUX, 16 is V */
+	#define CHAN_ON		1
+	#define CHAN_BIPOLAR	2
+};
+
+
+static void run_batch(struct xadc_t *xadc)
+{
+	u32 config, rdt;
+
+	if (list_empty(&xadc->runq)) {
+		xadc->curr = NULL;
+		return;
+	}
+	xadc->curr = list_first_entry(&xadc->runq, struct xadc_batch, q);
+	list_del(&xadc->curr->q);
+
+	config = READ(xadc, CONFIG);
+	config = CLRFIELD(XADC_CONFIG, CFIFOTH, config);
+	config = CLRFIELD(XADC_CONFIG, DFIFOTH, config);
+
+	rdt = xadc->curr->count-xadc->curr->readptr;
+	if (rdt > 15) /* Trigger at half FIFO or count */
+		rdt = 8;
+	else
+		rdt--;
+
+	config |= SETFIELD(XADC_CONFIG, CFIFOTH, 0) | /* Just trigger */
+		  SETFIELD(XADC_CONFIG, DFIFOTH, rdt);
+
+	WRITE(xadc, CONFIG, config);
+
+	/* unmask CFIFO,DFIFO interrupts */
+	WRITE(xadc, INTMSK, READ(xadc, INTMSK) &
+			~(XADC_INT_CFIFO_LTH | XADC_INT_DFIFO_GTH));
+}
+
+static void add_batch(struct xadc_t *xadc, struct xadc_batch *b)
+{
+	unsigned long flags;
+
+	BUG_ON(b->count < 1);
+	b->writeptr = 0;
+	b->readptr = 0;
+	init_completion(&b->comp);
+	list_add_tail(&b->q, &xadc->runq);
+	spin_lock_irqsave(&xadc->slock, flags);
+	if (!xadc->curr)
+		run_batch(xadc);
+	spin_unlock_irqrestore(&xadc->slock, flags);
+}
+
+static inline u16 read_register(struct xadc_t *xadc, unsigned int reg)
+{
+	u16 ret;
+	struct xadc_op *ops;
+	struct xadc_batch *b = kzalloc(sizeof(*b), GFP_KERNEL);
+
+	if (!b)
+		return 0;
+	ops = kzalloc(sizeof(*ops) * 2, GFP_KERNEL);
+	if (!ops) {
+		kfree(b);
+		return 0;
+	}
+
+	b->count = 2;
+	b->ops = ops;
+	ops[0].cmd = READOP(reg);
+	ops[1].cmd = NOOP;
+	add_batch(xadc, b);
+	wait_for_completion_interruptible(&b->comp);
+	ret = GETFIELD(XADC_FIFO, DATA, b->ops[1].res);
+	kfree(ops);
+	kfree(b);
+	return ret;
+}
+
+static inline void write_register(struct xadc_t *xadc, unsigned int reg,
+		u16 val)
+{
+	struct xadc_op *ops;
+	struct xadc_batch *b = kzalloc(sizeof(*b), GFP_KERNEL);
+
+	if (!b)
+		return;
+	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
+	if (!ops) {
+		kfree(b);
+		return;
+	}
+
+	b->count = 1;
+	b->ops = ops;
+	ops[0].cmd = WRITEOP(reg, val);
+	add_batch(xadc, b);
+	wait_for_completion_interruptible(&b->comp);
+	kfree(ops);
+	kfree(b);
+}
+
+static inline int reg2temp(u16 reg)
+{
+	int val;
+
+	val = (reg >> 4) & 0xFFF; /* Use only 12 bits */
+	val = ((val * 503975) / 4096) - 273150; /* (X*503.975/4096) -273.15 */
+	val = DIV_ROUND_CLOSEST(val, 1000);
+	return val;
+}
+
+static inline unsigned reg2vcc(u16 reg)
+{
+	unsigned val;
+
+	val = (reg >> 4) & 0xFFF; /* Use only 12 bits */
+	val = ((val * 3000) / 4096); /* (X*3/4096) */
+	/* Return voltage in mV */
+	return val;
+}
+
+static inline unsigned reg2v(u16 reg)
+{
+	unsigned val;
+
+	val = (reg >> 4) & 0xFFF; /*Use only 12 bits */
+	val = (val * 1000 / 4096); /* (X/4096) */
+	/* Return voltage in mV */
+	return val;
+}
+
+static inline int reg2bv(u16 reg)
+{
+	int val;
+
+	val = (reg >> 4) & 0xFFF; /* Use only 12 bits */
+	if (val & 0x800)
+		val = val - 0x1000;
+	val = (val * 1000 / 4096); /* (X/4096) */
+	/* Return voltage in mV */
+	return val;
+}
+
+static ssize_t xadc_read_temp(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int reg = attr->index;
+	u16 regval;
+
+	clk_enable(xadc->clk);
+
+	regval = read_register(xadc, reg);
+
+	clk_disable(xadc->clk);
+
+	return sprintf(buf, "%d\n", reg2temp(regval));
+}
+
+static ssize_t xadc_read_vcc(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int reg = attr->index;
+	u16 regval;
+
+	clk_enable(xadc->clk);
+
+	regval = read_register(xadc, reg);
+
+	clk_disable(xadc->clk);
+
+	return sprintf(buf, "%u\n", reg2vcc(regval));
+}
+
+static ssize_t xadc_read_v(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	unsigned int reg = attr->index;
+	unsigned int chan = attr->nr;
+	u16 regval;
+
+	if (!(xadc->chanmode[chan] & CHAN_ON))
+		return sprintf(buf, "%d\n", 0);
+
+	clk_enable(xadc->clk);
+
+	regval = read_register(xadc, reg);
+
+	clk_disable(xadc->clk);
+
+	if ((xadc->chanmode[chan] & CHAN_BIPOLAR))
+		return sprintf(buf, "%d\n", reg2bv(regval));
+
+	return sprintf(buf, "%u\n", reg2v(regval));
+}
+
+#ifdef DEBUG
+static ssize_t xadc_read_registers(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	unsigned int i, count = 0;
+
+	clk_enable(xadc->clk);
+
+	for (i = 0; i < 0x60; i++)
+		count += sprintf(buf+count, "%02X %04x\n", i,
+				read_register(xadc, i));
+
+	clk_disable(xadc->clk);
+
+	return count;
+}
+#endif
+
+static ssize_t xadc_read_flags(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	u16 val;
+
+	clk_enable(xadc->clk);
+
+	val = read_register(xadc, REG_FLAG);
+
+	clk_disable(xadc->clk);
+
+	return sprintf(buf, "enabled:\t%s\nreference:\t%s\n",
+		val & REG_FLAG_DIS ? "no" : "yes",
+		val & REG_FLAG_REF ? "internal" : "external");
+}
+
+static ssize_t xadc_read_vmode(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	unsigned int channel = attr->nr;
+
+	return sprintf(buf, "%s\n", (xadc->chanmode[channel] & CHAN_ON) ?
+			((xadc->chanmode[channel] & CHAN_BIPOLAR) ?
+			 "bipolar" : "unipolar") : "off");
+}
+
+static ssize_t xadc_write_vmode(struct device *dev,
+		struct device_attribute *devattr,
+		const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	unsigned int channel = attr->nr;
+	unsigned int reg = attr->index;
+	u32 mode;
+	u16 val;
+
+	if (!strncmp("off", buf, 3))
+		mode = 0;
+	else if (!strncmp("unipolar", buf, 8))
+		mode = CHAN_ON;
+	else if (!strncmp("bipolar", buf, 7))
+		mode = CHAN_ON | CHAN_BIPOLAR;
+	else
+		return -EIO;
+
+	if (mode == xadc->chanmode[channel])
+		return count;
+
+	xadc->chanmode[channel] = mode;
+
+	clk_enable(xadc->clk);
+
+	if (mode & CHAN_BIPOLAR) {
+		val = read_register(xadc, reg + REG_SEQ_BIP0);
+		if (0 == reg) /* only dedicated channel there */
+			val |= REG_SEQ_V;
+		else
+			val |= 1 << channel;
+		write_register(xadc, reg + REG_SEQ_BIP0, val);
+	} else {
+		val = read_register(xadc, reg + REG_SEQ_BIP0);
+		if (0 == reg) /* only dedicated channel there */
+			val &= ~REG_SEQ_V;
+		else
+			val &= ~(1 << channel);
+		write_register(xadc, reg + REG_SEQ_BIP0, val);
+	}
+
+	if (mode & CHAN_ON) {
+		val = read_register(xadc, reg + REG_SEQ_SEL0);
+		if (0 == reg) /* only dedicated channel there */
+			val |= REG_SEQ_V;
+		else
+			val |= 1 << channel;
+		write_register(xadc, reg + REG_SEQ_SEL0, val);
+	} else {
+		val = read_register(xadc, reg + REG_SEQ_SEL0);
+		if (0 == reg) /* only dedicated channel there */
+			val &= ~REG_SEQ_V;
+		else
+			val &= ~(1 << channel);
+		write_register(xadc, reg + REG_SEQ_SEL0, val);
+	}
+
+	clk_disable(xadc->clk);
+
+	return count;
+}
+
+static ssize_t show_name(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	return sprintf(buf, "%s\n", "xadcps");
+}
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static SENSOR_DEVICE_ATTR(status, S_IRUGO, xadc_read_flags, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp, S_IRUGO, xadc_read_temp, NULL, REG_TEMP);
+static SENSOR_DEVICE_ATTR(temp_min, S_IRUGO, xadc_read_temp, NULL,
+		REG_MIN_TEMP);
+static SENSOR_DEVICE_ATTR(temp_max, S_IRUGO, xadc_read_temp, NULL,
+		REG_MAX_TEMP);
+static SENSOR_DEVICE_ATTR(vccint, S_IRUGO, xadc_read_vcc, NULL, REG_VCCINT);
+static SENSOR_DEVICE_ATTR(vccint_min, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MIN_VCCINT);
+static SENSOR_DEVICE_ATTR(vccint_max, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MAX_VCCINT);
+static SENSOR_DEVICE_ATTR(vccaux, S_IRUGO, xadc_read_vcc, NULL, REG_VCCAUX);
+static SENSOR_DEVICE_ATTR(vccaux_min, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MIN_VCCAUX);
+static SENSOR_DEVICE_ATTR(vccaux_max, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MAX_VCCAUX);
+static SENSOR_DEVICE_ATTR(vccbram, S_IRUGO, xadc_read_vcc, NULL, REG_VCCBRAM);
+static SENSOR_DEVICE_ATTR(vccbram_min, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MIN_VCCBRAM);
+static SENSOR_DEVICE_ATTR(vccbram_max, S_IRUGO, xadc_read_vcc, NULL,
+		REG_MAX_VCCBRAM);
+/*
+ * channel number, register
+ * for VPVN  = 16, REG_VPVN
+ * for VAUXi =  i, REG_VAUX0 + i
+ */
+static SENSOR_DEVICE_ATTR_2(v, S_IRUGO, xadc_read_v, NULL, 16, REG_VPVN);
+/* channel number, offset from REG_SEQ_xxx_0
+ * for VPVN  = 16, 0
+ * for VAUXi =  i, 1
+ */
+static SENSOR_DEVICE_ATTR_2(v_mode, S_IWUSR|S_IRUGO, xadc_read_vmode,
+		xadc_write_vmode, 16, 0);
+#ifdef DEBUG
+static SENSOR_DEVICE_ATTR(registers, S_IRUGO, xadc_read_registers, NULL, 0);
+#endif
+
+static struct attribute *xadc_attr[] = {
+	&dev_attr_name.attr,
+#ifdef DEBUG
+	&sensor_dev_attr_registers.dev_attr.attr,
+#endif
+	&sensor_dev_attr_status.dev_attr.attr,
+	&sensor_dev_attr_temp.dev_attr.attr,
+	&sensor_dev_attr_temp_min.dev_attr.attr,
+	&sensor_dev_attr_temp_max.dev_attr.attr,
+	&sensor_dev_attr_vccint.dev_attr.attr,
+	&sensor_dev_attr_vccint_min.dev_attr.attr,
+	&sensor_dev_attr_vccint_max.dev_attr.attr,
+	&sensor_dev_attr_vccaux.dev_attr.attr,
+	&sensor_dev_attr_vccaux_min.dev_attr.attr,
+	&sensor_dev_attr_vccaux_max.dev_attr.attr,
+	&sensor_dev_attr_vccbram.dev_attr.attr,
+	&sensor_dev_attr_vccbram_min.dev_attr.attr,
+	&sensor_dev_attr_vccbram_max.dev_attr.attr,
+	&sensor_dev_attr_v.dev_attr.attr,
+	&sensor_dev_attr_v_mode.dev_attr.attr,
+	NULL
+};
+
+
+
+static const struct attribute_group xadc_group = {
+	.attrs = xadc_attr,
+};
+
+static irqreturn_t xadc_irq(int irq, void *data)
+{
+	struct xadc_t *xadc = data;
+	u32 intsts, intmsk;
+
+
+	intsts = READ(xadc, INTSTS);
+	intmsk = READ(xadc, INTMSK);
+	dev_dbg(xadc->dev, "intsts %08x intmsk %08x\n", intsts, intmsk);
+
+	if (intsts & ~intmsk & XADC_INT_DFIFO_GTH) {
+
+		while (!(READ(xadc, STATUS) & XADC_STATUS_DFIFO_EMPTY))
+			xadc->curr->ops[xadc->curr->readptr++].res =
+				READ(xadc, DFIFO);
+		if ((xadc->curr->readptr) == xadc->curr->count) {
+			intmsk |= XADC_INT_DFIFO_GTH;
+			WRITE(xadc, INTMSK, intmsk);
+			complete(&xadc->curr->comp);
+			run_batch(xadc);
+		} else {
+			u32 config;
+			int rdt;
+
+			config = READ(xadc, CONFIG);
+			config = CLRFIELD(XADC_CONFIG, DFIFOTH, config);
+			rdt = xadc->curr->count-xadc->curr->readptr;
+			if (rdt > 15)
+				rdt = 8;
+			else
+				rdt--;
+			config |= SETFIELD(XADC_CONFIG, DFIFOTH, rdt);
+			WRITE(xadc, CONFIG, config);
+		}
+		WRITE(xadc, INTSTS, XADC_INT_DFIFO_GTH);
+	}
+
+	if (intsts & ~intmsk & XADC_INT_CFIFO_LTH) {
+		int i, towrite;
+		u32 status = READ(xadc, STATUS);
+
+		/*Don't write more than FIFO capacity*/
+		towrite = xadc->curr->count - xadc->curr->writeptr;
+		towrite = (15 - GETFIELD(XADC_STATUS, CFIFO_LVL, status));
+		towrite = min(towrite,
+			xadc->curr->count - xadc->curr->writeptr);
+
+		for (i = 0; i < towrite; i++)
+			WRITE(xadc, CFIFO,
+				xadc->curr->ops[xadc->curr->writeptr++].cmd);
+
+		if (xadc->curr->writeptr == xadc->curr->count) {
+			intmsk |= XADC_INT_CFIFO_LTH;
+			WRITE(xadc, INTMSK, intmsk);
+		} else {
+			u32 config;
+			int cmdt;
+			config = READ(xadc, CONFIG);
+			config = CLRFIELD(XADC_CONFIG, CFIFOTH, config);
+			cmdt = xadc->curr->count-xadc->curr->writeptr;
+			if (cmdt > 8) /* Half-full */
+				cmdt = 8;
+			else /* Will write all next time */
+				cmdt--;
+			config |= SETFIELD(XADC_CONFIG, CFIFOTH, cmdt);
+			WRITE(xadc, CONFIG, config);
+		}
+		WRITE(xadc, INTSTS, XADC_INT_CFIFO_LTH);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct xadc_op xadc_ops[] = {
+	{.cmd = WRITEOP(REG_CFG1, REG_CFG1_CAL_SSOG |
+			REG_CFG1_CAL_ADCOG |
+			SETFIELD(REG_CFG1, SEQ, MODE_DEF)),},
+	{.cmd = READOP(REG_FLAG),}, /* read flags */
+	{.cmd = WRITEOP(REG_SEQ_SEL0, 0)},
+	{.cmd = WRITEOP(REG_SEQ_AVG0, 0)},
+	{.cmd = WRITEOP(REG_SEQ_BIP0, 0)},
+	{.cmd = WRITEOP(REG_SEQ_ACQ0, 0)},
+	{.cmd = WRITEOP(REG_SEQ_SEL1, 0)},
+	{.cmd = WRITEOP(REG_SEQ_AVG1, 0)},
+	{.cmd = WRITEOP(REG_SEQ_BIP1, 0)},
+	{.cmd = WRITEOP(REG_SEQ_ACQ1, 0)},
+	{.cmd = WRITEOP(REG_CFG1, REG_CFG1_CAL_SSOG | REG_CFG1_CAL_ADCOG |
+			SETFIELD(REG_CFG1, SEQ, MODE_IND)),},
+};
+static struct xadc_batch setup = {
+	.count = ARRAY_SIZE(xadc_ops),
+	.ops = xadc_ops,
+};
+
+static int xadc_probe(struct platform_device *pdev)
+{
+	struct xadc_t *xadc;
+	struct resource *res;
+	u16 val;
+	int ret;
+
+	xadc = devm_kzalloc(&pdev->dev, sizeof(*xadc), GFP_KERNEL);
+	if (!xadc)
+		return -ENOMEM;
+
+	xadc->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xadc->iobase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xadc->iobase))
+		return PTR_ERR(xadc->iobase);
+
+	xadc->irq = platform_get_irq(pdev, 0);
+	ret = devm_request_irq(&pdev->dev, xadc->irq, &xadc_irq, IRQF_SHARED,
+			       dev_name(&pdev->dev), xadc);
+	if (ret) {
+		dev_err(xadc->dev, "Failed to request irq: %d\n", xadc->irq);
+		return ret;
+	}
+
+	xadc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(xadc->clk)) {
+		dev_err(&pdev->dev, "input clock not found\n");
+		return PTR_ERR(xadc->clk);
+	}
+
+	ret = clk_prepare_enable(xadc->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable clock\n");
+		return ret;
+	}
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &xadc_group);
+	if (ret)
+		goto err_clk_disable;
+
+	platform_set_drvdata(pdev, xadc);
+
+	xadc->hwmon = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(xadc->hwmon)) {
+		ret = PTR_ERR(xadc->hwmon);
+		dev_err(xadc->dev, "Failed to register hwmon device\n");
+		goto err_group;
+	}
+
+	WRITE(xadc, CONFIG, 0);
+	WRITE(xadc, CTL, 0); /* ~RESET */
+
+	WRITE(xadc, CONFIG, XADC_CONFIG_WEDGE | /* Default values */
+		XADC_CONFIG_REDGE |
+		SETFIELD(XADC_CONFIG, TCKRATE, TCKRATE_DIV16) |
+		SETFIELD(XADC_CONFIG, IGAP, 20));
+
+	WRITE(xadc, CONFIG, READ(xadc, CONFIG) | XADC_CONFIG_ENABLE);
+
+	WRITE(xadc, INTSTS, ~0); /* clear all interrupts */
+	WRITE(xadc, INTMSK, ~0); /* mask all interrupts */
+
+	INIT_LIST_HEAD(&xadc->runq);
+	spin_lock_init(&xadc->slock);
+
+	add_batch(xadc, &setup);
+	wait_for_completion_interruptible(&setup.comp);
+
+	val = setup.ops[2].res;
+	dev_info(xadc->dev, "enabled:\t%s\treference:\t%s\n",
+		val & REG_FLAG_DIS ? "no" : "yes",
+		val & REG_FLAG_REF ? "internal" : "external");
+
+	clk_disable(xadc->clk);
+
+	return 0;
+
+err_group:
+	sysfs_remove_group(&pdev->dev.kobj, &xadc_group);
+err_clk_disable:
+	clk_disable_unprepare(xadc->clk);
+
+	return ret;
+}
+
+static int xadc_remove(struct platform_device *pdev)
+{
+	struct xadc_t *xadc = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(xadc->hwmon);
+
+	sysfs_remove_group(&pdev->dev.kobj, &xadc_group);
+
+	clk_unprepare(xadc->clk);
+
+	return 0;
+}
+
+static struct of_device_id xadcps_of_match[] = {
+	{ .compatible = "xlnx,ps7-xadc-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xadcps_of_match);
+
+static struct platform_driver xadc_driver = {
+	.probe = xadc_probe,
+	.remove = xadc_remove,
+	.driver = {
+		.name = "xadcps",
+		.owner = THIS_MODULE,
+		.of_match_table = xadcps_of_match,
+	},
+};
+
+module_platform_driver(xadc_driver);
+
+MODULE_AUTHOR("Vlad Lungu <vlad.lungu@windriver.com>");
+MODULE_DESCRIPTION("Xilinx Zynq XADC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:xadcps");
Index: linux-3.12.24-rt38-xilinx/drivers/i2c/busses/i2c-xiic.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/i2c/busses/i2c-xiic.c	2014-07-20 22:05:50.248066423 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/i2c/busses/i2c-xiic.c	2014-07-20 22:06:36.420304662 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:35 @
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:72 @
 	struct i2c_adapter	adap;
 	struct i2c_msg		*tx_msg;
 	spinlock_t		lock;
-	unsigned int 		tx_pos;
+	unsigned int		tx_pos;
 	unsigned int		nmsgs;
 	enum xilinx_i2c_state	state;
 	struct i2c_msg		*rx_msg;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:275 @
 
 	bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
-		", SR: 0x%x, CR: 0x%x\n",
-		__func__, bytes_in_fifo, xiic_rx_space(i2c),
-		xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
-		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+	dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d",
+		__func__, bytes_in_fifo, xiic_rx_space(i2c));
 
 	if (bytes_in_fifo > xiic_rx_space(i2c))
 		bytes_in_fifo = xiic_rx_space(i2c);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:340 @
 	ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
 	pend = isr & ier;
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
-		"pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
-		__func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+	dev_dbg(i2c->adap.dev.parent, "%s: IER: 0x%x, ISR: 0x%x, pend: 0x%x\n",
+		__func__, ier, isr, pend);
+	dev_dbg(i2c->adap.dev.parent, "%s: SR: 0x%x, msg: %p, nmsgs: %d\n",
+		__func__, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
 		i2c->tx_msg, i2c->nmsgs);
 
 	/* Do not processes a devices interrupts if the device has no
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:543 @
 
 	xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
-		"ISR: 0x%x, CR: 0x%x\n",
-		__func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d",
+		__func__, msg, msg->len);
+	dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
+		__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
 		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
 
 	if (!(msg->flags & I2C_M_NOSTART)) {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:697 @
 	int ret, irq;
 	u8 i;
 
+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		goto resource_missing;
+	i2c->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(i2c->base)) {
+		dev_err(&pdev->dev, "Could not allocate iomem\n");
+		return PTR_ERR(i2c->base);
+	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
-		goto resource_missing;
-
-	pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev);
-
-	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
-	if (!i2c)
-		return -ENOMEM;
+		return irq;
 
-	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
-		dev_err(&pdev->dev, "Memory region busy\n");
-		ret = -EBUSY;
-		goto request_mem_failed;
+	ret = devm_request_irq(&pdev->dev, irq, xiic_isr, 0, pdev->name, i2c);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Cannot claim IRQ\n");
+		return ret;
 	}
 
-	i2c->base = ioremap(res->start, resource_size(res));
-	if (!i2c->base) {
-		dev_err(&pdev->dev, "Unable to map registers\n");
-		ret = -EIO;
-		goto map_failed;
-	}
+	pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev);
 
 	/* hook up driver to tree */
 	platform_set_drvdata(pdev, i2c);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:731 @
 
 	spin_lock_init(&i2c->lock);
 	init_waitqueue_head(&i2c->wait);
-	ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
-	if (ret) {
-		dev_err(&pdev->dev, "Cannot claim IRQ\n");
-		goto request_irq_failed;
-	}
 
 	/* add i2c adapter to i2c tree */
 	ret = i2c_add_adapter(&i2c->adap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to add adapter\n");
-		goto add_adapter_failed;
+		return ret;
 	}
 
 	if (pdata) {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:746 @
 	}
 
 	return 0;
-
-add_adapter_failed:
-	free_irq(irq, i2c);
-request_irq_failed:
-	xiic_deinit(i2c);
-	iounmap(i2c->base);
-map_failed:
-	release_mem_region(res->start, resource_size(res));
-request_mem_failed:
-	kfree(i2c);
-
-	return ret;
-resource_missing:
-	dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
-	return -ENOENT;
 }
 
 static int xiic_i2c_remove(struct platform_device *pdev)
 {
 	struct xiic_i2c *i2c = platform_get_drvdata(pdev);
-	struct resource *res;
 
 	/* remove adapter & data */
 	i2c_del_adapter(&i2c->adap);
 
 	xiic_deinit(i2c);
 
-	free_irq(platform_get_irq(pdev, 0), i2c);
-
-	iounmap(i2c->base);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res)
-		release_mem_region(res->start, resource_size(res));
-
-	kfree(i2c);
-
 	return 0;
 }
 
Index: linux-3.12.24-rt38-xilinx/drivers/i2c/busses/i2c-zynq.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/i2c/busses/i2c-zynq.c	2014-07-20 22:06:36.436304398 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx I2C bus driver for the Zynq I2C Interfaces.
+ *
+ * 2009-2011 (c) Xilinx, 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.
+ *
+ * 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.
+ *
+ *
+ * Workaround in Receive Mode
+ *	If there is only one message to be processed, then based on length of
+ *	the message we set the HOLD bit.
+ *	If the length is less than the FIFO depth, then we will directly
+ *	receive a COMP interrupt and the transaction is done.
+ *	If the length is more than the FIFO depth, then we enable the HOLD bit.
+ *	if the requested data is greater than the  max transfer size(252 bytes)
+ *	update the transfer size register with max transfer size else update
+ *	with the requested size.
+ *	We will receive the DATA interrupt, if the transfer size register value
+ *	is zero then repeat the above step for the remaining bytes (if any) and
+ *	process the data in the fifo.
+ *
+ *	The bus hold flag logic provides support for repeated start.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * Register Map
+ * Register offsets for the I2C device.
+ */
+#define XI2CPS_CR_OFFSET	0x00 /* Control Register, RW */
+#define XI2CPS_SR_OFFSET	0x04 /* Status Register, RO */
+#define XI2CPS_ADDR_OFFSET	0x08 /* I2C Address Register, RW */
+#define XI2CPS_DATA_OFFSET	0x0C /* I2C Data Register, RW */
+#define XI2CPS_ISR_OFFSET	0x10 /* Interrupt Status Register, RW */
+#define XI2CPS_XFER_SIZE_OFFSET 0x14 /* Transfer Size Register, RW */
+#define XI2CPS_SLV_PAUSE_OFFSET 0x18 /* Slave monitor pause Register, RW */
+#define XI2CPS_TIME_OUT_OFFSET	0x1C /* Time Out Register, RW */
+#define XI2CPS_IMR_OFFSET	0x20 /* Interrupt Mask Register, RO */
+#define XI2CPS_IER_OFFSET	0x24 /* Interrupt Enable Register, WO */
+#define XI2CPS_IDR_OFFSET	0x28 /* Interrupt Disable Register, WO */
+
+/*
+ * Control Register Bit mask definitions
+ * This register contains various control bits that affect the operation of the
+ * I2C controller.
+ */
+#define XI2CPS_CR_HOLD_BUS_MASK 0x00000010 /* Hold Bus bit */
+#define XI2CPS_CR_RW_MASK	0x00000001 /* Read or Write Master transfer
+					    * 0= Transmitter, 1= Receiver */
+#define XI2CPS_CR_CLR_FIFO_MASK 0x00000040 /* 1 = Auto init FIFO to zeroes */
+
+/*
+ * I2C Address Register Bit mask definitions
+ * Normal addressing mode uses [6:0] bits. Extended addressing mode uses [9:0]
+ * bits. A write access to this register always initiates a transfer if the I2C
+ * is in master mode.
+ */
+#define XI2CPS_ADDR_MASK	0x000003FF /* I2C Address Mask */
+
+/*
+ * I2C Interrupt Registers Bit mask definitions
+ * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
+ * bit definitions.
+ */
+#define XI2CPS_IXR_ALL_INTR_MASK 0x000002FF /* All ISR Mask */
+
+#define XI2CPS_FIFO_DEPTH	16		/* FIFO Depth */
+#define XI2CPS_TIMEOUT		(50 * HZ)	/* Timeout for bus busy check */
+#define XI2CPS_ENABLED_INTR	0x2EF		/* Enabled Interrupts */
+
+#define XI2CPS_DATA_INTR_DEPTH (XI2CPS_FIFO_DEPTH - 2)/* FIFO depth at which
+							 * the DATA interrupt
+							 * occurs
+							 */
+#define XI2CPS_MAX_TRANSFER_SIZE	255 /* Max transfer size */
+#define XI2CPS_TRANSFER_SIZE	(XI2CPS_MAX_TRANSFER_SIZE - 3) /* Transfer size
+					in multiples of data interrupt depth */
+
+#define DRIVER_NAME		"xi2cps"
+
+#define xi2cps_readreg(offset)		__raw_readl(id->membase + offset)
+#define xi2cps_writereg(val, offset)	__raw_writel(val, id->membase + offset)
+
+/**
+ * struct xi2cps - I2C device private data structure
+ * @membase:		Base address of the I2C device
+ * @adap:		I2C adapter instance
+ * @p_msg:		Message pointer
+ * @err_status:		Error status in Interrupt Status Register
+ * @xfer_done:		Transfer complete status
+ * @p_send_buf:		Pointer to transmit buffer
+ * @p_recv_buf:		Pointer to receive buffer
+ * @suspended:		Flag holding the device's PM status
+ * @send_count:		Number of bytes still expected to send
+ * @recv_count:		Number of bytes still expected to receive
+ * @irq:		IRQ number
+ * @cur_timeout:	The current timeout value used by the device
+ * @input_clk:		Input clock to I2C controller
+ * @i2c_clk:		Current I2C frequency
+ * @bus_hold_flag:	Flag used in repeated start for clearing HOLD bit
+ * @clk:		Pointer to struct clk
+ * @clk_rate_change_nb:	Notifier block for clock rate changes
+ */
+struct xi2cps {
+	void __iomem *membase;
+	struct i2c_adapter adap;
+	struct i2c_msg	*p_msg;
+	int err_status;
+	struct completion xfer_done;
+	unsigned char *p_send_buf;
+	unsigned char *p_recv_buf;
+	u8 suspended;
+	int send_count;
+	int recv_count;
+	int irq;
+	int cur_timeout;
+	unsigned int input_clk;
+	unsigned int i2c_clk;
+	unsigned int bus_hold_flag;
+	struct clk	*clk;
+	struct notifier_block	clk_rate_change_nb;
+};
+
+#define to_xi2cps(_nb)	container_of(_nb, struct xi2cps, clk_rate_change_nb)
+#define MAX_F_ERR 10000
+
+/**
+ * xi2cps_isr - Interrupt handler for the I2C device
+ * @irq:	irq number for the I2C device
+ * @ptr:	void pointer to xi2cps structure
+ *
+ * Returns IRQ_HANDLED always
+ *
+ * This function handles the data interrupt, transfer complete interrupt and
+ * the error interrupts of the I2C device.
+ */
+static irqreturn_t xi2cps_isr(int irq, void *ptr)
+{
+	unsigned int isr_status, avail_bytes;
+	unsigned int bytes_to_recv, bytes_to_send;
+	unsigned int ctrl_reg = 0;
+	struct xi2cps *id = ptr;
+
+	isr_status = xi2cps_readreg(XI2CPS_ISR_OFFSET);
+
+	/* Handling Nack interrupt */
+	if (isr_status & 0x00000004)
+		complete(&id->xfer_done);
+
+	/* Handling Arbitration lost interrupt */
+	if (isr_status & 0x00000200)
+		complete(&id->xfer_done);
+
+	/* Handling Data interrupt */
+	if (isr_status & 0x00000002) {
+		if (id->recv_count >= XI2CPS_DATA_INTR_DEPTH) {
+			/* Always read data interrupt threshold bytes */
+			bytes_to_recv = XI2CPS_DATA_INTR_DEPTH;
+			id->recv_count = id->recv_count -
+						XI2CPS_DATA_INTR_DEPTH;
+			avail_bytes = xi2cps_readreg(XI2CPS_XFER_SIZE_OFFSET);
+			/*
+			 * if the tranfer size register value is zero, then
+			 * check for the remaining bytes and update the
+			 * transfer size register.
+			 */
+			if (avail_bytes == 0) {
+				if (id->recv_count  > XI2CPS_TRANSFER_SIZE)
+					xi2cps_writereg(XI2CPS_TRANSFER_SIZE,
+						XI2CPS_XFER_SIZE_OFFSET);
+				else
+					xi2cps_writereg(id->recv_count,
+						XI2CPS_XFER_SIZE_OFFSET);
+			}
+			/* Process the data received */
+			while (bytes_to_recv) {
+				*(id->p_recv_buf)++ =
+					xi2cps_readreg(XI2CPS_DATA_OFFSET);
+				bytes_to_recv = bytes_to_recv - 1;
+			}
+
+			if ((id->bus_hold_flag == 0) &&
+				(id->recv_count <= XI2CPS_FIFO_DEPTH)) {
+				/* Clear the hold bus bit */
+				xi2cps_writereg(
+					(xi2cps_readreg(XI2CPS_CR_OFFSET) &
+					(~XI2CPS_CR_HOLD_BUS_MASK)),
+					XI2CPS_CR_OFFSET);
+			}
+		}
+	}
+
+	/* Handling Transfer Complete interrupt */
+	if (isr_status & 0x00000001) {
+		if ((id->p_recv_buf) == NULL) {
+			/*
+			 * If the device is sending data If there is further
+			 * data to be sent. Calculate the available space
+			 * in FIFO and fill the FIFO with that many bytes.
+			 */
+			if (id->send_count > 0) {
+				avail_bytes = XI2CPS_FIFO_DEPTH -
+				xi2cps_readreg(XI2CPS_XFER_SIZE_OFFSET);
+				if (id->send_count > avail_bytes)
+					bytes_to_send = avail_bytes;
+				else
+					bytes_to_send = id->send_count;
+
+				while (bytes_to_send--) {
+					xi2cps_writereg(
+						(*(id->p_send_buf)++),
+						 XI2CPS_DATA_OFFSET);
+					id->send_count--;
+				}
+			} else {
+				/*
+				 * Signal the completion of transaction and
+				 * clear the hold bus bit if there are no
+				 * further messages to be processed.
+				 */
+				complete(&id->xfer_done);
+			}
+			if (id->send_count == 0) {
+				if (id->bus_hold_flag == 0) {
+					/* Clear the hold bus bit */
+					ctrl_reg =
+					xi2cps_readreg(XI2CPS_CR_OFFSET);
+					if ((ctrl_reg & XI2CPS_CR_HOLD_BUS_MASK)
+						== XI2CPS_CR_HOLD_BUS_MASK)
+						xi2cps_writereg(
+						(ctrl_reg &
+						(~XI2CPS_CR_HOLD_BUS_MASK)),
+						XI2CPS_CR_OFFSET);
+				}
+			}
+		} else {
+			if (id->bus_hold_flag == 0) {
+				/* Clear the hold bus bit */
+				ctrl_reg =
+				xi2cps_readreg(XI2CPS_CR_OFFSET);
+				if ((ctrl_reg & XI2CPS_CR_HOLD_BUS_MASK)
+					== XI2CPS_CR_HOLD_BUS_MASK)
+					xi2cps_writereg(
+					(ctrl_reg &
+					(~XI2CPS_CR_HOLD_BUS_MASK)),
+					XI2CPS_CR_OFFSET);
+			}
+			/*
+			 * If the device is receiving data, then signal
+			 * the completion of transaction and read the data
+			 * present in the FIFO. Signal the completion of
+			 * transaction.
+			 */
+			while (xi2cps_readreg(XI2CPS_SR_OFFSET)
+							& 0x00000020) {
+				*(id->p_recv_buf)++ =
+					xi2cps_readreg(XI2CPS_DATA_OFFSET);
+				id->recv_count--;
+			}
+			complete(&id->xfer_done);
+		}
+	}
+
+	/* Update the status for errors */
+	id->err_status = isr_status & 0x000002EC;
+	xi2cps_writereg(isr_status, XI2CPS_ISR_OFFSET);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xi2cps_mrecv - Prepare and start a master receive operation
+ * @id:		pointer to the i2c device structure
+ *
+ */
+static void xi2cps_mrecv(struct xi2cps *id)
+{
+	unsigned int ctrl_reg;
+	unsigned int isr_status;
+
+	id->p_recv_buf = id->p_msg->buf;
+	id->recv_count = id->p_msg->len;
+
+	/*
+	 * Set the controller in master receive mode and clear the FIFO.
+	 * Set the slave address in address register.
+	 * Check for the message size against FIFO depth and set the
+	 * HOLD bus bit if it is more than FIFO depth.
+	 * Clear the interrupts in interrupt status register.
+	 */
+	ctrl_reg = xi2cps_readreg(XI2CPS_CR_OFFSET);
+	ctrl_reg |= (XI2CPS_CR_RW_MASK | XI2CPS_CR_CLR_FIFO_MASK);
+
+	if ((id->p_msg->flags & I2C_M_RECV_LEN) == I2C_M_RECV_LEN)
+		id->recv_count = I2C_SMBUS_BLOCK_MAX + 1;
+
+	if (id->recv_count > XI2CPS_FIFO_DEPTH)
+		ctrl_reg |= XI2CPS_CR_HOLD_BUS_MASK;
+
+	xi2cps_writereg(ctrl_reg, XI2CPS_CR_OFFSET);
+
+	isr_status = xi2cps_readreg(XI2CPS_ISR_OFFSET);
+	xi2cps_writereg(isr_status, XI2CPS_ISR_OFFSET);
+
+	xi2cps_writereg((id->p_msg->addr & XI2CPS_ADDR_MASK),
+						XI2CPS_ADDR_OFFSET);
+	/*
+	 * The no. of bytes to receive is checked against the limit of
+	 * max transfer size. Set transfer size register with no of bytes
+	 * receive if it is less than transfer size and transfer size if
+	 * it is more. Enable the interrupts.
+	 */
+	if (id->recv_count > XI2CPS_TRANSFER_SIZE)
+		xi2cps_writereg(XI2CPS_TRANSFER_SIZE, XI2CPS_XFER_SIZE_OFFSET);
+	else
+		xi2cps_writereg(id->recv_count, XI2CPS_XFER_SIZE_OFFSET);
+	/*
+	 * Clear the bus hold flag if bytes to receive is less than FIFO size.
+	 */
+	if (id->bus_hold_flag == 0 &&
+		((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
+		(id->recv_count <= XI2CPS_FIFO_DEPTH)) {
+			/* Clear the hold bus bit */
+			ctrl_reg = xi2cps_readreg(XI2CPS_CR_OFFSET);
+			if ((ctrl_reg & XI2CPS_CR_HOLD_BUS_MASK) ==
+					XI2CPS_CR_HOLD_BUS_MASK)
+				xi2cps_writereg(
+					(ctrl_reg & (~XI2CPS_CR_HOLD_BUS_MASK)),
+					XI2CPS_CR_OFFSET);
+	}
+	xi2cps_writereg(XI2CPS_ENABLED_INTR, XI2CPS_IER_OFFSET);
+}
+
+/**
+ * xi2cps_msend - Prepare and start a master send operation
+ * @id:		pointer to the i2c device
+ */
+static void xi2cps_msend(struct xi2cps *id)
+{
+	unsigned int avail_bytes;
+	unsigned int bytes_to_send;
+	unsigned int ctrl_reg;
+	unsigned int isr_status;
+
+	id->p_recv_buf = NULL;
+	id->p_send_buf = id->p_msg->buf;
+	id->send_count = id->p_msg->len;
+
+	/*
+	 * Set the controller in Master transmit mode and clear the FIFO.
+	 * Set the slave address in address register.
+	 * Check for the message size against FIFO depth and set the
+	 * HOLD bus bit if it is more than FIFO depth.
+	 * Clear the interrupts in interrupt status register.
+	 */
+	ctrl_reg = xi2cps_readreg(XI2CPS_CR_OFFSET);
+	ctrl_reg &= ~XI2CPS_CR_RW_MASK;
+	ctrl_reg |= XI2CPS_CR_CLR_FIFO_MASK;
+
+	if ((id->send_count) > XI2CPS_FIFO_DEPTH)
+		ctrl_reg |= XI2CPS_CR_HOLD_BUS_MASK;
+	xi2cps_writereg(ctrl_reg, XI2CPS_CR_OFFSET);
+
+	isr_status = xi2cps_readreg(XI2CPS_ISR_OFFSET);
+	xi2cps_writereg(isr_status, XI2CPS_ISR_OFFSET);
+
+	/*
+	 * Calculate the space available in FIFO. Check the message length
+	 * against the space available, and fill the FIFO accordingly.
+	 * Enable the interrupts.
+	 */
+	avail_bytes = XI2CPS_FIFO_DEPTH -
+				xi2cps_readreg(XI2CPS_XFER_SIZE_OFFSET);
+
+	if (id->send_count > avail_bytes)
+		bytes_to_send = avail_bytes;
+	else
+		bytes_to_send = id->send_count;
+
+	while (bytes_to_send--) {
+		xi2cps_writereg((*(id->p_send_buf)++), XI2CPS_DATA_OFFSET);
+		id->send_count--;
+	}
+
+	xi2cps_writereg((id->p_msg->addr & XI2CPS_ADDR_MASK),
+						XI2CPS_ADDR_OFFSET);
+
+	/*
+	 * Clear the bus hold flag if there is no more data
+	 * and if it is the last message.
+	 */
+	if (id->bus_hold_flag == 0 && id->send_count == 0) {
+		/* Clear the hold bus bit */
+		ctrl_reg = xi2cps_readreg(XI2CPS_CR_OFFSET);
+		if ((ctrl_reg & XI2CPS_CR_HOLD_BUS_MASK) ==
+				XI2CPS_CR_HOLD_BUS_MASK)
+			xi2cps_writereg(
+				(ctrl_reg & (~XI2CPS_CR_HOLD_BUS_MASK)),
+				XI2CPS_CR_OFFSET);
+	}
+	xi2cps_writereg(XI2CPS_ENABLED_INTR, XI2CPS_IER_OFFSET);
+}
+
+/**
+ * xi2cps_master_reset - Reset the interface
+ * @adap:	pointer to the i2c adapter driver instance
+ *
+ * Returns none
+ *
+ * This function cleanup the fifos, clear the hold bit and status
+ * and disable the interrupts.
+ */
+static void xi2cps_master_reset(struct i2c_adapter *adap)
+{
+	struct xi2cps *id = adap->algo_data;
+	u32 regval;
+
+	/* Disable the interrupts */
+	xi2cps_writereg(XI2CPS_IXR_ALL_INTR_MASK, XI2CPS_IDR_OFFSET);
+	/* Clear the hold bit and fifos */
+	regval = xi2cps_readreg(XI2CPS_CR_OFFSET);
+	regval &= ~XI2CPS_CR_HOLD_BUS_MASK;
+	regval |= XI2CPS_CR_CLR_FIFO_MASK;
+	xi2cps_writereg(regval, XI2CPS_CR_OFFSET);
+	/* Update the transfercount register to zero */
+	xi2cps_writereg(0x0, XI2CPS_XFER_SIZE_OFFSET);
+	/* Clear the interupt status register */
+	regval = xi2cps_readreg(XI2CPS_ISR_OFFSET);
+	xi2cps_writereg(regval, XI2CPS_ISR_OFFSET);
+	/* Clear the status register */
+	regval =  xi2cps_readreg(XI2CPS_SR_OFFSET);
+	xi2cps_writereg(regval, XI2CPS_SR_OFFSET);
+}
+
+/**
+ * xi2cps_master_xfer - The main i2c transfer function
+ * @adap:	pointer to the i2c adapter driver instance
+ * @msgs:	pointer to the i2c message structure
+ * @num:	the number of messages to transfer
+ *
+ * Returns number of msgs processed on success, negative error otherwise
+ *
+ * This function waits for the bus idle condition and updates the timeout if
+ * modified by user. Then initiates the send/recv activity based on the
+ * transfer message received.
+ */
+static int xi2cps_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+				int num)
+{
+	struct xi2cps *id = adap->algo_data;
+	unsigned int count, retries;
+	unsigned long timeout;
+	int ret;
+
+	/* Waiting for bus-ready. If bus not ready, it returns after timeout */
+	timeout = jiffies + XI2CPS_TIMEOUT;
+	while ((xi2cps_readreg(XI2CPS_SR_OFFSET)) & 0x00000100) {
+		if (time_after(jiffies, timeout)) {
+			dev_warn(id->adap.dev.parent,
+					"timedout waiting for bus ready\n");
+			xi2cps_master_reset(adap);
+			return -ETIMEDOUT;
+		}
+		schedule_timeout(1);
+	}
+
+	/* The bus is free. Set the new timeout value if updated */
+	if (id->adap.timeout != id->cur_timeout) {
+		xi2cps_writereg((id->adap.timeout & 0xFF),
+					XI2CPS_TIME_OUT_OFFSET);
+		id->cur_timeout = id->adap.timeout;
+	}
+
+	/*
+	 * Set the flag to one when multiple messages are to be
+	 * processed with a repeated start.
+	 */
+	if (num > 1) {
+		id->bus_hold_flag = 1;
+		xi2cps_writereg((xi2cps_readreg(XI2CPS_CR_OFFSET) |
+				XI2CPS_CR_HOLD_BUS_MASK), XI2CPS_CR_OFFSET);
+	} else {
+		id->bus_hold_flag = 0;
+	}
+
+	/* Process the msg one by one */
+	for (count = 0; count < num; count++, msgs++) {
+
+		if (count == (num - 1))
+			id->bus_hold_flag = 0;
+		retries = adap->retries;
+retry:
+		id->err_status = 0;
+		id->p_msg = msgs;
+		init_completion(&id->xfer_done);
+
+		/* Check for the TEN Bit mode on each msg */
+		if (msgs->flags & I2C_M_TEN) {
+			xi2cps_writereg((xi2cps_readreg(XI2CPS_CR_OFFSET) &
+					(~0x00000004)), XI2CPS_CR_OFFSET);
+		} else {
+			if ((xi2cps_readreg(XI2CPS_CR_OFFSET) & 0x00000004)
+								== 0)
+				xi2cps_writereg(
+					(xi2cps_readreg(XI2CPS_CR_OFFSET) |
+					 (0x00000004)), XI2CPS_CR_OFFSET);
+		}
+
+		/* Check for the R/W flag on each msg */
+		if (msgs->flags & I2C_M_RD)
+			xi2cps_mrecv(id);
+		else
+			xi2cps_msend(id);
+
+		/* Wait for the signal of completion */
+		ret = wait_for_completion_interruptible_timeout(
+							&id->xfer_done, HZ);
+		if (ret == 0) {
+			dev_err(id->adap.dev.parent,
+				 "timeout waiting on completion\n");
+			xi2cps_master_reset(adap);
+			return -ETIMEDOUT;
+		}
+		xi2cps_writereg(XI2CPS_IXR_ALL_INTR_MASK, XI2CPS_IDR_OFFSET);
+
+		/* If it is bus arbitration error, try again */
+		if (id->err_status & 0x00000200) {
+			dev_dbg(id->adap.dev.parent,
+				 "Lost ownership on bus, trying again\n");
+			if (retries--) {
+				mdelay(2);
+				goto retry;
+			}
+			dev_err(id->adap.dev.parent,
+					 "Retries completed, exit\n");
+			num = -EREMOTEIO;
+			break;
+		}
+		/* Report the other error interrupts to application as EIO */
+		if (id->err_status & 0x000000E4) {
+			xi2cps_master_reset(adap);
+			num = -EIO;
+			break;
+		}
+	}
+
+	id->p_msg = NULL;
+	id->err_status = 0;
+
+	return num;
+}
+
+/**
+ * xi2cps_func - Returns the supported features of the I2C driver
+ * @adap:	pointer to the i2c adapter structure
+ *
+ * Returns 32 bit value, each bit corresponding to a feature
+ */
+static u32 xi2cps_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
+		(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
+		I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm xi2cps_algo = {
+	.master_xfer	= xi2cps_master_xfer,
+	.functionality	= xi2cps_func,
+};
+
+/**
+ * xi2cps_calc_divs() - Calculate clock dividers
+ * @f:		I2C clock frequency
+ * @input_clk:	Input clock frequency
+ * @a:		First divider (return value)
+ * @b:		Second divider (return value)
+ * @err:	Frequency error
+ * Return 0 on success, negative errno otherwise.
+ *
+ * f is used as input and output variable. As input it is used as target I2C
+ * frequency. On function exit f holds the actually resulting I2C frequency.
+ */
+static int xi2cps_calc_divs(unsigned int *f, unsigned int input_clk,
+		unsigned int *a, unsigned int *b, unsigned int *err)
+{
+	unsigned int fscl = *f;
+	unsigned int div_a, div_b, calc_div_a = 0, calc_div_b = 0;
+	unsigned int last_error, current_error;
+	unsigned int best_fscl = *f, actual_fscl, temp;
+
+	/* calculate (divisor_a+1) x (divisor_b+1) */
+	temp = input_clk / (22 * fscl);
+
+	/*
+	 * If the calculated value is negative or 0, the fscl input is out of
+	 * range. Return error.
+	 */
+	if (!temp)
+		return -EINVAL;
+
+	last_error = -1;
+	for (div_b = 0; div_b < 64; div_b++) {
+		div_a = input_clk / (22 * fscl * (div_b + 1));
+
+		if (div_a != 0)
+			div_a = div_a - 1;
+
+		if (div_a > 3)
+			continue;
+
+		actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1));
+
+		current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) :
+							(fscl - actual_fscl));
+
+		if (last_error > current_error) {
+			calc_div_a = div_a;
+			calc_div_b = div_b;
+			best_fscl = actual_fscl;
+			last_error = current_error;
+		}
+	}
+
+	*err = last_error;
+	*a = calc_div_a;
+	*b = calc_div_b;
+	*f = best_fscl;
+
+	return 0;
+}
+
+/**
+ * xi2cps_setclk - This function sets the serial clock rate for the I2C device
+ * @fscl:	The clock frequency in Hz
+ * @id:		Pointer to the I2C device structure
+ *
+ * Returns zero on success, negative error otherwise
+ *
+ * The device must be idle rather than busy transferring data before setting
+ * these device options.
+ * The data rate is set by values in the control register.
+ * The formula for determining the correct register values is
+ *	Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1))
+ * See the hardware data sheet for a full explanation of setting the serial
+ * clock rate. The clock can not be faster than the input clock divide by 22.
+ * The two most common clock rates are 100KHz and 400KHz.
+ */
+static int xi2cps_setclk(unsigned int fscl, struct xi2cps *id)
+{
+	unsigned int div_a, div_b;
+	unsigned int ctrl_reg;
+	unsigned int err;
+	int ret = 0;
+
+	ret = xi2cps_calc_divs(&fscl, id->input_clk, &div_a, &div_b, &err);
+	if (ret)
+		return ret;
+
+	ctrl_reg = xi2cps_readreg(XI2CPS_CR_OFFSET);
+	ctrl_reg &= ~(0x0000C000 | 0x00003F00);
+	ctrl_reg |= ((div_a << 14) | (div_b << 8));
+	xi2cps_writereg(ctrl_reg, XI2CPS_CR_OFFSET);
+
+	return 0;
+}
+
+/**
+ * xi2cps_clk_notifier_cb - Clock rate change callback
+ * @nb:		Pointer to notifier block
+ * @event:	Notification reason
+ * @data:	Pointer to notification data object
+ * Returns NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK
+ * otherwise.
+ *
+ * This function is called when the xi2cps input clock frequency changes. In the
+ * pre-rate change notification here it is determined if the rate change may be
+ * allowed or not.
+ * In th post-change case necessary adjustments are conducted.
+ */
+static int xi2cps_clk_notifier_cb(struct notifier_block *nb, unsigned long
+		event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct xi2cps *id = to_xi2cps(nb);
+
+	if (id->suspended)
+		return NOTIFY_OK;
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+	{
+		/*
+		 * if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers. Probably we could also define an acceptable
+		 * frequency range.
+		 */
+		unsigned int input_clk = (unsigned int)ndata->new_rate;
+		unsigned int fscl = id->i2c_clk;
+		unsigned int div_a, div_b;
+		unsigned int err = 0;
+		int ret;
+
+		ret = xi2cps_calc_divs(&fscl, input_clk, &div_a, &div_b, &err);
+		if (ret)
+			return NOTIFY_STOP;
+		if (err > MAX_F_ERR)
+			return NOTIFY_STOP;
+
+		return NOTIFY_OK;
+	}
+	case POST_RATE_CHANGE:
+		id->input_clk = ndata->new_rate;
+		/* We probably need to stop the HW before this and restart
+		 * afterwards */
+		xi2cps_setclk(id->i2c_clk, id);
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xi2cps_suspend - Suspend method for the driver
+ * @_dev:	Address of the platform_device structure
+ * Returns 0 on success and error value on error
+ *
+ * Put the driver into low power mode.
+ */
+static int xi2cps_suspend(struct device *_dev)
+{
+	struct platform_device *pdev = container_of(_dev,
+			struct platform_device, dev);
+	struct xi2cps *xi2c = platform_get_drvdata(pdev);
+
+	clk_disable(xi2c->clk);
+	xi2c->suspended = 1;
+
+	return 0;
+}
+
+/**
+ * xi2cps_resume - Resume from suspend
+ * @_dev:	Address of the platform_device structure
+ * Returns 0 on success and error value on error
+ *
+ * Resume operation after suspend.
+ */
+static int xi2cps_resume(struct device *_dev)
+{
+	struct platform_device *pdev = container_of(_dev,
+			struct platform_device, dev);
+	struct xi2cps *xi2c = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = clk_enable(xi2c->clk);
+	if (ret) {
+		dev_err(_dev, "Cannot enable clock.\n");
+		return ret;
+	}
+
+	xi2c->suspended = 0;
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(xi2cps_dev_pm_ops, xi2cps_suspend, xi2cps_resume);
+
+/************************/
+/* Platform bus binding */
+/************************/
+
+/**
+ * xi2cps_probe - Platform registration call
+ * @pdev:	Handle to the platform device structure
+ *
+ * Returns zero on success, negative error otherwise
+ *
+ * This function does all the memory allocation and registration for the i2c
+ * device. User can modify the address mode to 10 bit address mode using the
+ * ioctl call with option I2C_TENBIT.
+ */
+static int xi2cps_probe(struct platform_device *pdev)
+{
+	struct resource *r_mem = NULL;
+	struct xi2cps *id;
+	int ret = 0;
+	const unsigned int *prop;
+	/*
+	 * Allocate memory for xi2cps structure.
+	 * Initialize the structure to zero and set the platform data.
+	 * Obtain the resource base address from platform data and remap it.
+	 * Get the irq resource from platform data.Initialize the adapter
+	 * structure members and also xi2cps structure.
+	 */
+	id = devm_kzalloc(&pdev->dev, sizeof(*id), GFP_KERNEL);
+	if (!id)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, id);
+
+	r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	id->membase = devm_ioremap_resource(&pdev->dev, r_mem);
+	if (IS_ERR(id->membase))
+		return PTR_ERR(id->membase);
+
+	id->irq = platform_get_irq(pdev, 0);
+
+	prop = of_get_property(pdev->dev.of_node, "bus-id", NULL);
+	if (prop) {
+		id->adap.nr = be32_to_cpup(prop);
+	} else {
+		dev_err(&pdev->dev, "couldn't determine bus-id\n");
+		return -ENXIO;
+	}
+	id->adap.dev.of_node = pdev->dev.of_node;
+	id->adap.algo = (struct i2c_algorithm *) &xi2cps_algo;
+	id->adap.timeout = 0x1F;	/* Default timeout value */
+	id->adap.retries = 3;		/* Default retry value. */
+	id->adap.algo_data = id;
+	id->adap.dev.parent = &pdev->dev;
+	snprintf(id->adap.name, sizeof(id->adap.name),
+		 "XILINX I2C at %08lx", (unsigned long)r_mem->start);
+
+	id->cur_timeout = id->adap.timeout;
+	id->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(id->clk)) {
+		dev_err(&pdev->dev, "input clock not found.\n");
+		return PTR_ERR(id->clk);
+	}
+	ret = clk_prepare_enable(id->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable clock.\n");
+		return ret;
+	}
+	id->clk_rate_change_nb.notifier_call = xi2cps_clk_notifier_cb;
+	id->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(id->clk, &id->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+	id->input_clk = (unsigned int)clk_get_rate(id->clk);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "i2c-clk", &id->i2c_clk);
+	if (ret) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "couldn't determine i2c-clk\n");
+		goto err_clk_dis;
+	}
+
+	/*
+	 * Set Master Mode,Normal addressing mode (7 bit address),
+	 * Enable Transmission of Ack in Control Register.
+	 * Set the timeout and I2C clock and request the IRQ(ISR mapped).
+	 * Call to the i2c_add_numbered_adapter registers the adapter.
+	 */
+	xi2cps_writereg(0x0000000E, XI2CPS_CR_OFFSET);
+	xi2cps_writereg(id->adap.timeout, XI2CPS_TIME_OUT_OFFSET);
+
+	ret = xi2cps_setclk(id->i2c_clk, id);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n", id->i2c_clk);
+		ret = -EINVAL;
+		goto err_clk_dis;
+	}
+
+	ret = devm_request_irq(&pdev->dev, id->irq, xi2cps_isr, 0,
+				 DRIVER_NAME, id);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
+		goto err_clk_dis;
+	}
+
+	ret = i2c_add_numbered_adapter(&id->adap);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
+		goto err_clk_dis;
+	}
+
+	dev_info(&pdev->dev, "%d kHz mmio %08lx irq %d\n",
+		 id->i2c_clk/1000, (unsigned long)r_mem->start, id->irq);
+
+	return 0;
+
+err_clk_dis:
+	clk_disable_unprepare(id->clk);
+	return ret;
+}
+
+/**
+ * xi2cps_remove - Unregister the device after releasing the resources
+ * @pdev:	Handle to the platform device structure
+ *
+ * Returns zero always
+ *
+ * This function frees all the resources allocated to the device.
+ */
+static int xi2cps_remove(struct platform_device *pdev)
+{
+	struct xi2cps *id = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&id->adap);
+	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
+	clk_disable_unprepare(id->clk);
+
+	return 0;
+}
+
+static const struct of_device_id xi2cps_of_match[] = {
+	{ .compatible = "xlnx,ps7-i2c-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xi2cps_of_match);
+
+static struct platform_driver xi2cps_drv = {
+	.driver = {
+		.name  = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = xi2cps_of_match,
+		.pm = &xi2cps_dev_pm_ops,
+	},
+	.probe  = xi2cps_probe,
+	.remove = xi2cps_remove,
+};
+
+module_platform_driver(xi2cps_drv);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx Zynq I2C bus driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
Index: linux-3.12.24-rt38-xilinx/drivers/i2c/busses/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/i2c/busses/Kconfig	2014-07-20 22:05:50.247066439 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/i2c/busses/Kconfig	2014-07-20 22:06:36.448304200 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:732 @
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-versatile.
 
+config I2C_ZYNQ
+	tristate "XILINX ZYNQ I2C Controller"
+	depends on ARCH_ZYNQ
+	help
+	  Say yes here to select Xilnx ZYNQ I2C Host Controller
+
 config I2C_WMT
 	tristate "Wondermedia WM8xxx SoC I2C bus support"
 	depends on ARCH_VT8500
Index: linux-3.12.24-rt38-xilinx/drivers/i2c/busses/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/i2c/busses/Makefile	2014-07-20 22:05:50.246066456 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/i2c/busses/Makefile	2014-07-20 22:06:36.458304035 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:79 @
 obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
 obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
+obj-$(CONFIG_I2C_ZYNQ)		+= i2c-zynq.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
Index: linux-3.12.24-rt38-xilinx/drivers/irqchip/irq-gic.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/irqchip/irq-gic.c	2014-07-20 22:05:50.208067083 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/irqchip/irq-gic.c	2014-07-20 22:06:36.474303771 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:25 @
  * As such, the enable set/clear, pending set/clear and active bit
  * registers are banked per-cpu for these sources.
  */
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:271 @
 
 	return IRQ_SET_MASK_OK;
 }
+
+void gic_set_cpu(unsigned int cpu, unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	struct cpumask mask;
+
+	cpumask_clear(&mask);
+	cpumask_set_cpu(cpu, &mask);
+	gic_set_affinity(d, &mask, true);
+}
+EXPORT_SYMBOL(gic_set_cpu);
 #endif
 
 #ifdef CONFIG_PM
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:686 @
 	/* this always happens on GIC0 */
 	writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
 }
+EXPORT_SYMBOL(gic_raise_softirq);
 #endif
 
 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
Index: linux-3.12.24-rt38-xilinx/drivers/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/Kconfig	2014-07-20 22:05:50.181067529 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/Kconfig	2014-07-20 22:06:36.488303541 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:115 @
 
 source "drivers/auxdisplay/Kconfig"
 
+source "drivers/xilinx_common/Kconfig"
+
 source "drivers/uio/Kconfig"
 
 source "drivers/vfio/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/Makefile	2014-07-20 22:05:50.173067660 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/Makefile	2014-07-20 22:06:36.498303376 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:154 @
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_IPACK_BUS)		+= ipack/
 obj-$(CONFIG_NTB)		+= ntb/
+
 obj-$(CONFIG_FMC)		+= fmc/
+
+obj-y				+= xilinx_common/
Index: linux-3.12.24-rt38-xilinx/drivers/media/i2c/adv7511.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/media/i2c/adv7511.c	2014-07-20 22:05:50.219066901 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/media/i2c/adv7511.c	2014-07-20 22:06:36.517303062 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1048 @
 	adv7511_s_audio_stream(sd, false);
 }
 
+struct v4l2_subdev *adv7511_subdev(struct v4l2_subdev *sd)
+{
+	static struct v4l2_subdev *subdev;
+
+	if (sd)
+		subdev = sd;
+
+	return subdev;
+}
+EXPORT_SYMBOL(adv7511_subdev);
+
 static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct adv7511_state *state;
Index: linux-3.12.24-rt38-xilinx/drivers/media/i2c/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/media/i2c/Makefile	2014-07-20 22:05:50.218066918 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/media/i2c/Makefile	2014-07-20 22:06:36.528302881 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:28 @
 obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
 obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
 obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
+obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
 obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
 obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
 obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/media/platform/Kconfig	2014-07-20 22:05:50.217066935 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/Kconfig	2014-07-20 22:06:36.542302650 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:127 @
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/exynos4-is/Kconfig"
 source "drivers/media/platform/s5p-tv/Kconfig"
+source "drivers/media/platform/xilinx/Kconfig"
 
 endif # V4L_PLATFORM_DRIVERS
 
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/media/platform/Makefile	2014-07-20 22:05:50.216066951 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/Makefile	2014-07-20 22:06:36.551302502 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:55 @
 
 obj-$(CONFIG_ARCH_OMAP)	+= omap/
 
+obj-$(CONFIG_VIDEO_XILINX)		+= xilinx/
+
 ccflags-y += -I$(srctree)/drivers/media/i2c
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/Kconfig	2014-07-20 22:06:36.564302287 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+config VIDEO_XILINX
+	tristate "Xilinx Video IP (EXPERIMENTAL)"
+	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+	select VIDEOBUF2_DMA_CONTIG
+	---help---
+	  Driver for Xilinx Video IP Pipelines
+
+if VIDEO_XILINX
+
+config VIDEO_XILINX_REMAPPER
+	tristate "Xilinx Video Remapper"
+	depends on VIDEO_XILINX
+	---help---
+	   Driver for the Xilinx Video Remapper
+
+config VIDEO_XILINX_TPG
+	tristate "Xilinx Video Test Pattern Generator"
+	depends on VIDEO_XILINX
+	---help---
+	   Driver for the Xilinx Video Test Pattern Generator
+
+endif #VIDEO_XILINX
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/Makefile	2014-07-20 22:06:36.569302204 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2 @
+xilinx-axi-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
+
+obj-$(CONFIG_VIDEO_XILINX) += xilinx-axi-video.o
+obj-$(CONFIG_VIDEO_XILINX_REMAPPER) += xilinx-remapper.o
+obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-dma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-dma.c	2014-07-20 22:06:36.580302023 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video DMA
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/dmaengine.h>
+#include <linux/lcm.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "xilinx-dma.h"
+#include "xilinx-vip.h"
+#include "xilinx-vipp.h"
+
+#define XVIP_DMA_DEF_FORMAT		V4L2_PIX_FMT_YUYV
+#define XVIP_DMA_DEF_WIDTH		1920
+#define XVIP_DMA_DEF_HEIGHT		1080
+
+/* Minimum and maximum widths are expressed in bytes */
+#define XVIP_DMA_MIN_WIDTH		1U
+#define XVIP_DMA_MAX_WIDTH		65535U
+#define XVIP_DMA_MIN_HEIGHT		1U
+#define XVIP_DMA_MAX_HEIGHT		8191U
+
+/* -----------------------------------------------------------------------------
+ * Helper functions
+ */
+
+static struct v4l2_subdev *
+xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
+{
+	struct media_pad *remote;
+
+	remote = media_entity_remote_pad(local);
+	if (remote == NULL ||
+	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return NULL;
+
+	if (pad)
+		*pad = remote->index;
+
+	return media_entity_to_v4l2_subdev(remote->entity);
+}
+
+static int xvip_dma_verify_format(struct xvip_dma *dma)
+{
+	struct v4l2_subdev_format fmt;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad);
+	if (subdev == NULL)
+		return -EINVAL;
+
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
+	if (ret < 0)
+		return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+
+	if (dma->fmtinfo->code != fmt.format.code ||
+	    dma->format.height != fmt.format.height ||
+	    dma->format.width != fmt.format.width)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * videobuf2 queue operations
+ */
+
+/**
+ * struct xvip_dma_buffer - Video DMA buffer
+ * @buf: vb2 buffer base object
+ * @dma: DMA channel that uses the buffer
+ * @addr: DMA bus address for the buffer memory
+ * @length: total length of the buffer in bytes
+ * @bytesused: number of bytes used in the buffer
+ */
+struct xvip_dma_buffer {
+	struct vb2_buffer buf;
+
+	struct xvip_dma *dma;
+
+	dma_addr_t addr;
+	unsigned int length;
+	unsigned int bytesused;
+};
+
+#define to_xvip_dma_buffer(vb)	container_of(vb, struct xvip_dma_buffer, buf)
+
+static void xvip_dma_complete(void *param)
+{
+	struct xvip_dma_buffer *buf = param;
+	struct xvip_dma *dma = buf->dma;
+
+	buf->buf.v4l2_buf.sequence = dma->sequence++;
+	v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp);
+	vb2_set_plane_payload(&buf->buf, 0, buf->length);
+	vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+}
+
+static int
+xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+		     unsigned int *nbuffers, unsigned int *nplanes,
+		     unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+
+	*nplanes = 1;
+
+	sizes[0] = dma->format.sizeimage;
+	alloc_ctxs[0] = dma->alloc_ctx;
+
+	return 0;
+}
+
+static int xvip_dma_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
+	struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+
+	buf->dma = dma;
+	buf->addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+	buf->length = vb2_plane_size(vb, 0);
+	buf->bytesused = 0;
+
+	return 0;
+}
+
+static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
+	struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+	struct dma_async_tx_descriptor *desc;
+	enum dma_transfer_direction dir;
+	u32 flags;
+
+	if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK
+		      | DMA_COMPL_SKIP_DEST_UNMAP;
+		dir = DMA_DEV_TO_MEM;
+	} else {
+		flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK
+		      | DMA_COMPL_SKIP_SRC_UNMAP;
+		dir = DMA_MEM_TO_DEV;
+	}
+
+	desc = dmaengine_prep_slave_single(dma->dma, buf->addr, buf->length,
+					   dir, flags);
+	desc->callback = xvip_dma_complete;
+	desc->callback_param = buf;
+
+	dmaengine_submit(desc);
+
+	if (vb2_is_streaming(&dma->queue))
+		dma_async_issue_pending(dma->dma);
+}
+
+static void xvip_dma_wait_prepare(struct vb2_queue *vq)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+
+	mutex_unlock(&dma->lock);
+}
+
+static void xvip_dma_wait_finish(struct vb2_queue *vq)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+
+	mutex_lock(&dma->lock);
+}
+
+static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+	int ret;
+
+	dma->sequence = 0;
+
+	/* Mark the pipeline as streaming. */
+	ret = media_entity_pipeline_start(&dma->video.entity,
+					  &dma->xvipp->pipe);
+	if (ret < 0)
+		return ret;
+
+	/* Verify that the configured format matches the output of the
+	 * connected subdev.
+	 */
+	ret = xvip_dma_verify_format(dma);
+	if (ret < 0) {
+		media_entity_pipeline_stop(&dma->video.entity);
+		return ret;
+	}
+
+	/* Start the DMA engine. This must be done before starting the blocks
+	 * in the pipeline to avoid DMA synchronization issues.
+	 */
+	dma_async_issue_pending(dma->dma);
+
+	/* Start the pipeline. */
+	xvip_pipeline_set_stream(dma->xvipp, true);
+
+	return 0;
+}
+
+static int xvip_dma_stop_streaming(struct vb2_queue *vq)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+	struct xilinx_vdma_config config;
+
+	/* Stop the pipeline. */
+	xvip_pipeline_set_stream(dma->xvipp, false);
+
+	/* Stop and reset the DMA engine. */
+	dmaengine_device_control(dma->dma, DMA_TERMINATE_ALL, 0);
+
+	config.reset = 1;
+
+	dmaengine_device_control(dma->dma, DMA_SLAVE_CONFIG,
+				 (unsigned long)&config);
+
+	/* Mark the pipeline as being stopped. */
+	media_entity_pipeline_stop(&dma->video.entity);
+
+	return 0;
+}
+
+static struct vb2_ops xvip_dma_queue_qops = {
+	.queue_setup = xvip_dma_queue_setup,
+	.buf_prepare = xvip_dma_buffer_prepare,
+	.buf_queue = xvip_dma_buffer_queue,
+	.wait_prepare = xvip_dma_wait_prepare,
+	.wait_finish = xvip_dma_wait_finish,
+	.start_streaming = xvip_dma_start_streaming,
+	.stop_streaming = xvip_dma_stop_streaming,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 ioctls
+ */
+
+static int
+xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	else
+		cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+
+	strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
+	strlcpy(cap->card, dma->video.name, sizeof(cap->card));
+	strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int
+xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	mutex_lock(&dma->lock);
+	format->fmt.pix = dma->format;
+	mutex_unlock(&dma->lock);
+
+	return 0;
+}
+
+static void
+__xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
+		      const struct xvip_video_format **fmtinfo)
+{
+	const struct xvip_video_format *info;
+	unsigned int min_width;
+	unsigned int max_width;
+	unsigned int min_bpl;
+	unsigned int max_bpl;
+	unsigned int width;
+	unsigned int align;
+	unsigned int bpl;
+
+	/* Retrieve format information and select the default format if the
+	 * requested format isn't supported.
+	 */
+	info = xvip_get_format_by_fourcc(pix->pixelformat);
+	if (info == NULL)
+		info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
+
+	pix->pixelformat = info->fourcc;
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	pix->field = V4L2_FIELD_NONE;
+
+	/* The transfer alignment requirements are expressed in bytes. Compute
+	 * the minimum and maximum values, clamp the requested width and convert
+	 * it back to pixels.
+	 */
+	align = lcm(dma->align, info->bpp);
+	min_width = roundup(XVIP_DMA_MIN_WIDTH, align);
+	max_width = rounddown(XVIP_DMA_MAX_WIDTH, align);
+	width = rounddown(pix->width * info->bpp, align);
+
+	pix->width = clamp(width, min_width, max_width) / info->bpp;
+	pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT,
+			    XVIP_DMA_MAX_HEIGHT);
+
+	/* Clamp the requested bytes per line value. If the maximum bytes per
+	 * line value is zero, the module doesn't support user configurable line
+	 * sizes. Override the requested value with the minimum in that case.
+	 */
+	min_bpl = pix->width * info->bpp;
+	max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
+	bpl = rounddown(pix->bytesperline, dma->align);
+
+	pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
+	pix->sizeimage = pix->bytesperline * pix->height;
+
+	if (fmtinfo)
+		*fmtinfo = info;
+}
+
+static int
+xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	__xvip_dma_try_format(dma, &format->fmt.pix, NULL);
+	return 0;
+}
+
+static int
+xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	const struct xvip_video_format *info;
+	struct xilinx_vdma_config config;
+	int ret;
+
+	__xvip_dma_try_format(dma, &format->fmt.pix, &info);
+
+	mutex_lock(&dma->lock);
+
+	if (vb2_is_streaming(&dma->queue)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	dma->format = format->fmt.pix;
+	dma->fmtinfo = info;
+
+	/* Configure the DMA engine. */
+	memset(&config, 0, sizeof(config));
+
+	config.park = 1;
+	config.park_frm = 0;
+	config.vsize = dma->format.height;
+	config.hsize = dma->format.width * info->bpp;
+	config.stride = dma->format.bytesperline;
+	config.ext_fsync = 2;
+	config.frm_cnt_en = 1;
+	config.coalesc = 1;
+
+	dmaengine_device_control(dma->dma, DMA_SLAVE_CONFIG,
+				 (unsigned long)&config);
+
+	ret = 0;
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static int
+xvip_dma_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_reqbufs(&dma->queue, rb);
+	if (ret < 0)
+		goto done;
+
+	dma->queue.owner = vfh;
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret ? ret : rb->count;
+}
+
+static int
+xvip_dma_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+	ret = vb2_querybuf(&dma->queue, buf);
+	mutex_unlock(&dma->lock);
+
+	return ret;
+}
+
+static int
+xvip_dma_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_qbuf(&dma->queue, buf);
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static int
+xvip_dma_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_dqbuf(&dma->queue, buf, file->f_flags & O_NONBLOCK);
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static int
+xvip_dma_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *eb)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_expbuf(&dma->queue, eb);
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static int
+xvip_dma_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_streamon(&dma->queue, type);
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static int
+xvip_dma_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+
+	if (dma->queue.owner && dma->queue.owner != vfh) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	ret = vb2_streamoff(&dma->queue, type);
+
+done:
+	mutex_unlock(&dma->lock);
+	return ret;
+}
+
+static const struct v4l2_ioctl_ops xvip_dma_ioctl_ops = {
+	.vidioc_querycap		= xvip_dma_querycap,
+	.vidioc_g_fmt_vid_cap		= xvip_dma_get_format,
+	.vidioc_g_fmt_vid_out		= xvip_dma_get_format,
+	.vidioc_s_fmt_vid_cap		= xvip_dma_set_format,
+	.vidioc_s_fmt_vid_out		= xvip_dma_set_format,
+	.vidioc_try_fmt_vid_cap		= xvip_dma_try_format,
+	.vidioc_try_fmt_vid_out		= xvip_dma_try_format,
+	.vidioc_reqbufs			= xvip_dma_reqbufs,
+	.vidioc_querybuf		= xvip_dma_querybuf,
+	.vidioc_qbuf			= xvip_dma_qbuf,
+	.vidioc_dqbuf			= xvip_dma_dqbuf,
+	.vidioc_expbuf			= xvip_dma_expbuf,
+	.vidioc_streamon		= xvip_dma_streamon,
+	.vidioc_streamoff		= xvip_dma_streamoff,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 file operations
+ */
+
+static int xvip_dma_open(struct file *file)
+{
+	struct xvip_dma *dma = video_drvdata(file);
+	struct v4l2_fh *vfh;
+
+	vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
+	if (vfh == NULL)
+		return -ENOMEM;
+
+	v4l2_fh_init(vfh, &dma->video);
+	v4l2_fh_add(vfh);
+
+	file->private_data = vfh;
+
+	return 0;
+}
+
+static int xvip_dma_release(struct file *file)
+{
+	struct xvip_dma *dma = video_drvdata(file);
+	struct v4l2_fh *vfh = file->private_data;
+
+	mutex_lock(&dma->lock);
+	if (dma->queue.owner == vfh) {
+		vb2_queue_release(&dma->queue);
+		dma->queue.owner = NULL;
+	}
+	mutex_unlock(&dma->lock);
+
+	v4l2_fh_release(file);
+
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static unsigned int xvip_dma_poll(struct file *file, poll_table *wait)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+	ret = vb2_poll(&dma->queue, file, wait);
+	mutex_unlock(&dma->lock);
+
+	return ret;
+}
+
+static int xvip_dma_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	int ret;
+
+	mutex_lock(&dma->lock);
+	ret = vb2_mmap(&dma->queue, vma);
+	mutex_unlock(&dma->lock);
+
+	return ret;
+}
+
+static struct v4l2_file_operations xvip_dma_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+	.open = xvip_dma_open,
+	.release = xvip_dma_release,
+	.poll = xvip_dma_poll,
+	.mmap = xvip_dma_mmap,
+};
+
+/* -----------------------------------------------------------------------------
+ * Xilinx Video DMA Core
+ */
+
+int xvip_dma_init(struct xvip_pipeline *xvipp, struct xvip_dma *dma,
+		  enum v4l2_buf_type type)
+{
+	char name[10];
+	int ret;
+
+	dma->xvipp = xvipp;
+	mutex_init(&dma->lock);
+
+	dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
+	dma->format.pixelformat = dma->fmtinfo->fourcc;
+	dma->format.colorspace = V4L2_COLORSPACE_SRGB;
+	dma->format.field = V4L2_FIELD_NONE;
+	dma->format.width = XVIP_DMA_DEF_WIDTH;
+	dma->format.height = XVIP_DMA_DEF_HEIGHT;
+	dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp;
+	dma->format.sizeimage = dma->format.bytesperline * dma->format.height;
+
+	/* Initialize the media entity... */
+	dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+		       ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
+	if (ret < 0)
+		return ret;
+
+	/* ... and the video node... */
+	dma->video.v4l2_dev = &xvipp->v4l2_dev;
+	dma->video.fops = &xvip_dma_fops;
+	snprintf(dma->video.name, sizeof(dma->video.name), "%s %s",
+		 xvipp->dev->of_node->full_name,
+		 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input");
+	dma->video.vfl_type = VFL_TYPE_GRABBER;
+	dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+			   ? VFL_DIR_RX : VFL_DIR_TX;
+	dma->video.release = video_device_release_empty;
+	dma->video.ioctl_ops = &xvip_dma_ioctl_ops;
+
+	video_set_drvdata(&dma->video, dma);
+
+	/* ... and the buffers queue... */
+	dma->alloc_ctx = vb2_dma_contig_init_ctx(dma->xvipp->dev);
+	if (IS_ERR(dma->alloc_ctx))
+		goto error;
+
+	dma->queue.type = type;
+	dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dma->queue.drv_priv = dma;
+	dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer);
+	dma->queue.ops = &xvip_dma_queue_qops;
+	dma->queue.mem_ops = &vb2_dma_contig_memops;
+	dma->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	ret = vb2_queue_init(&dma->queue);
+	if (ret < 0) {
+		dev_err(dma->xvipp->dev, "failed to initialize VB2 queue\n");
+		goto error;
+	}
+
+	/* ... and the DMA channel. */
+	sprintf(name, "vdma-%s",
+		type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "s2mm" : "mm2s");
+	dma->dma = dma_request_slave_channel(dma->xvipp->dev, name);
+	if (dma->dma == NULL) {
+		dev_err(dma->xvipp->dev, "no VDMA channel found\n");
+		ret = -ENODEV;
+		goto error;
+	}
+
+	dma->align = 1 << dma->dma->device->copy_align;
+
+	ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1);
+	if (ret < 0) {
+		dev_err(dma->xvipp->dev, "failed to register video device\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	vb2_dma_contig_cleanup_ctx(dma->alloc_ctx);
+	xvip_dma_cleanup(dma);
+	return ret;
+}
+
+void xvip_dma_cleanup(struct xvip_dma *dma)
+{
+	if (video_is_registered(&dma->video))
+		video_unregister_device(&dma->video);
+
+	if (dma->dma)
+		dma_release_channel(dma->dma);
+
+	vb2_dma_contig_cleanup_ctx(dma->alloc_ctx);
+	media_entity_cleanup(&dma->video.entity);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-dma.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-dma.h	2014-07-20 22:06:36.587301907 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video DMA
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIP_DMA_H__
+#define __XILINX_VIP_DMA_H__
+
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf2-core.h>
+
+struct dma_chan;
+struct xvip_pipeline;
+struct xvip_video_format;
+
+/**
+ * struct xvip_dma - Video pipeline DMA channel
+ * @video: V4L2 video device associated with the DMA channel
+ * @pad: media pad for the video device entity
+ * @xvipp: video pipeline that uses the DMA channel
+ * @lock: protects the @format, @fmtinfo and @queue fields
+ * @format: active V4L2 pixel format
+ * @fmtinfo: format information corresponding to the active @format
+ * @queue: vb2 buffers queue
+ * @alloc_ctx: allocation context for the vb2 @queue
+ * @sequence: V4L2 buffers sequence number
+ * @dma: DMA engine channel
+ * @align: transfer alignment required by the DMA channel (in bytes)
+ */
+struct xvip_dma {
+	struct video_device video;
+	struct media_pad pad;
+
+	struct xvip_pipeline *xvipp;
+
+	struct mutex lock;
+	struct v4l2_pix_format format;
+	const struct xvip_video_format *fmtinfo;
+
+	struct vb2_queue queue;
+	void *alloc_ctx;
+	unsigned int sequence;
+
+	struct dma_chan *dma;
+	unsigned int align;
+};
+
+#define to_xvip_dma(vdev)	container_of(vdev, struct xvip_dma, video)
+
+int xvip_dma_init(struct xvip_pipeline *xvipp, struct xvip_dma *dma,
+		  enum v4l2_buf_type type);
+void xvip_dma_cleanup(struct xvip_dma *dma);
+
+#endif /* __XILINX_VIP_DMA_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-remapper.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-remapper.c	2014-07-20 22:06:36.597301743 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video Remapper
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-subdev.h>
+
+#include "xilinx-vip.h"
+
+#define XREMAP_MIN_WIDTH			1
+#define XREMAP_DEF_WIDTH			1920
+#define XREMAP_MAX_WIDTH			65535
+#define XREMAP_MIN_HEIGHT			1
+#define XREMAP_DEF_HEIGHT			1080
+#define XREMAP_MAX_HEIGHT			65535
+
+#define XREMAP_PAD_SINK				0
+#define XREMAP_PAD_SOURCE			1
+
+/**
+ * struct xremap_mapping_output - Output format description
+ * @code: media bus pixel core after remapping
+ * @num_components: number of pixel components after remapping
+ * @component_maps: configuration array corresponding to this output
+ */
+struct xremap_mapping_output {
+	u32 code;
+	unsigned int num_components;
+	unsigned int component_maps[4];
+};
+
+/**
+ * struct xremap_mapping - Input-output remapping description
+ * @code: media bus pixel code before remapping
+ * @width: video bus width in bits
+ * @num_components: number of pixel components before remapping
+ * @outputs: array of possible output formats
+ */
+struct xremap_mapping {
+	u32 code;
+	unsigned int width;
+	unsigned int num_components;
+	const struct xremap_mapping_output *outputs;
+};
+
+/**
+ * struct xremap_device - Xilinx Test Pattern Generator device structure
+ * @xvip: Xilinx Video IP device
+ * @pads: media pads
+ * @formats: V4L2 media bus formats at the sink and source pads
+ * @config: device configuration parsed from its DT node
+ * @config.width: video bus width in bits
+ * @config.num_s_components: number of pixel components at the input
+ * @config.num_m_components: number of pixel components at the output
+ * @config.component_maps: component remapping configuration
+ * @default_mapping: Default mapping compatible with the configuration
+ * @default_output: Default output format for the default mapping
+ */
+struct xremap_device {
+	struct xvip_device xvip;
+	struct media_pad pads[2];
+	struct v4l2_mbus_framefmt formats[2];
+
+	struct {
+		unsigned int width;
+		unsigned int num_s_components;
+		unsigned int num_m_components;
+		unsigned int component_maps[4];
+	} config;
+
+	const struct xremap_mapping *default_mapping;
+	const struct xremap_mapping_output *default_output;
+};
+
+static inline struct xremap_device *to_remap(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct xremap_device, xvip.subdev);
+}
+
+/* -----------------------------------------------------------------------------
+ * Mappings
+ */
+
+static const struct xremap_mapping xremap_mappings[] = {
+	{
+		.code = V4L2_MBUS_FMT_RBG888_1X24,
+		.width = 8,
+		.num_components = 3,
+		.outputs = (const struct xremap_mapping_output[]) {
+			{ V4L2_MBUS_FMT_RGB888_1X32_PADHI, 4, { 1, 0, 2, 4 } },
+			{ },
+		},
+	},
+};
+
+static const struct xremap_mapping_output *
+xremap_match_mapping(struct xremap_device *xremap,
+		     const struct xremap_mapping *mapping)
+{
+	const struct xremap_mapping_output *output;
+
+	if (mapping->width != xremap->config.width ||
+	    mapping->num_components != xremap->config.num_s_components)
+		return NULL;
+
+	for (output = mapping->outputs; output->code; ++output) {
+		unsigned int i;
+
+		if (output->num_components != xremap->config.num_m_components)
+			continue;
+
+		for (i = 0; i < output->num_components; ++i) {
+			if (output->component_maps[i] !=
+			    xremap->config.component_maps[i])
+				break;
+		}
+
+		if (i == output->num_components)
+			return output;
+	}
+
+	return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Pad Operations
+ */
+
+static int xremap_enum_mbus_code(struct v4l2_subdev *subdev,
+				 struct v4l2_subdev_fh *fh,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct xremap_device *xremap = to_remap(subdev);
+	struct v4l2_mbus_framefmt *format;
+
+	if (code->pad == XREMAP_PAD_SINK) {
+		const struct xremap_mapping *mapping = NULL;
+		unsigned int index = code->index + 1;
+		unsigned int i;
+
+		/* Iterate through the mappings and skip the ones that don't
+		 * match the remapper configuration until we reach the requested
+		 * index.
+		 */
+		for (i = 0; i < ARRAY_SIZE(xremap_mappings) && index; ++i) {
+			mapping = &xremap_mappings[i];
+
+			if (xremap_match_mapping(xremap, mapping))
+				index--;
+		}
+
+		/* If the index was larger than the number of supported mappings
+		 * return -EINVAL.
+		 */
+		if (index > 0)
+			return -EINVAL;
+
+		code->code = mapping->code;
+	} else {
+		if (code->index)
+			return -EINVAL;
+
+		format = v4l2_subdev_get_try_format(fh, code->pad);
+		code->code = format->code;
+	}
+
+	return 0;
+}
+
+static int xremap_enum_frame_size(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_fh *fh,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_get_try_format(fh, fse->pad);
+
+	if (fse->index || fse->code != format->code)
+		return -EINVAL;
+
+	if (fse->pad == XREMAP_PAD_SINK) {
+		/* The remapper doesn't restrict the size on the sink pad. */
+		fse->min_width = XREMAP_MIN_WIDTH;
+		fse->max_width = XREMAP_MAX_WIDTH;
+		fse->min_height = XREMAP_MIN_HEIGHT;
+		fse->max_height = XREMAP_MAX_HEIGHT;
+	} else {
+		/* The size on the source pad are fixed and always identical to
+		 * the size on the sink pad.
+		 */
+		fse->min_width = format->width;
+		fse->max_width = format->width;
+		fse->min_height = format->height;
+		fse->max_height = format->height;
+	}
+
+	return 0;
+}
+
+static struct v4l2_mbus_framefmt *
+xremap_get_pad_format(struct xremap_device *xremap, struct v4l2_subdev_fh *fh,
+		      unsigned int pad, u32 which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(fh, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &xremap->formats[pad];
+	default:
+		return NULL;
+	}
+}
+
+static int xremap_get_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct xremap_device *xremap = to_remap(subdev);
+
+	fmt->format = *xremap_get_pad_format(xremap, fh, fmt->pad, fmt->which);
+
+	return 0;
+}
+
+static int xremap_set_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct xremap_device *xremap = to_remap(subdev);
+	const struct xremap_mapping_output *output;
+	const struct xremap_mapping *mapping;
+	struct v4l2_mbus_framefmt *format;
+	unsigned int i;
+
+	format = xremap_get_pad_format(xremap, fh, fmt->pad, fmt->which);
+
+	if (fmt->pad == XREMAP_PAD_SOURCE) {
+		fmt->format = *format;
+		return 0;
+	}
+
+	/* Find the mapping. If the requested format has no mapping, use the
+	 * default.
+	 */
+	for (i = 0; i < ARRAY_SIZE(xremap_mappings); ++i) {
+		mapping = &xremap_mappings[i];
+		if (mapping->code != fmt->format.code)
+			continue;
+
+		output = xremap_match_mapping(xremap, mapping);
+		if (output)
+			break;
+	}
+
+	if (!output) {
+		mapping = xremap->default_mapping;
+		output = xremap->default_output;
+	}
+
+	format->code = mapping->code;
+	format->width = clamp_t(unsigned int, fmt->format.width,
+				XREMAP_MIN_WIDTH, XREMAP_MAX_WIDTH);
+	format->height = clamp_t(unsigned int, fmt->format.height,
+				 XREMAP_MIN_HEIGHT, XREMAP_MAX_HEIGHT);
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+
+	fmt->format = *format;
+
+	/* Propagate the format to the source pad. */
+	format = xremap_get_pad_format(xremap, fh, XREMAP_PAD_SOURCE,
+				       fmt->which);
+	*format = fmt->format;
+	format->code = output->code;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Operations
+ */
+
+/*
+ * xremap_init_formats - Initialize formats on all pads
+ * @subdev: remapper V4L2 subdevice
+ * @fh: V4L2 subdev file handle
+ *
+ * Initialize all pad formats with default values. If fh is not NULL, try
+ * formats are initialized on the file handle. Otherwise active formats are
+ * initialized on the device.
+ */
+static void xremap_init_formats(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_fh *fh)
+{
+	struct xremap_device *xremap = to_remap(subdev);
+	struct v4l2_subdev_format format;
+
+	memset(&format, 0, sizeof(format));
+
+	format.pad = XREMAP_PAD_SINK;
+	format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
+	format.format.code = xremap->default_mapping->code;
+	format.format.width = XREMAP_DEF_WIDTH;
+	format.format.height = XREMAP_DEF_HEIGHT;
+
+	xremap_set_format(subdev, fh, &format);
+}
+
+static int xremap_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	xremap_init_formats(subdev, fh);
+
+	return 0;
+}
+
+static int xremap_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops xremap_core_ops = {
+};
+
+static struct v4l2_subdev_video_ops xremap_video_ops = {
+};
+
+static struct v4l2_subdev_pad_ops xremap_pad_ops = {
+	.enum_mbus_code = xremap_enum_mbus_code,
+	.enum_frame_size = xremap_enum_frame_size,
+	.get_fmt = xremap_get_format,
+	.set_fmt = xremap_set_format,
+};
+
+static struct v4l2_subdev_ops xremap_ops = {
+	.core   = &xremap_core_ops,
+	.video  = &xremap_video_ops,
+	.pad    = &xremap_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops xremap_internal_ops = {
+	.open = xremap_open,
+	.close = xremap_close,
+};
+
+/* -----------------------------------------------------------------------------
+ * Media Operations
+ */
+
+static const struct media_entity_operations xremap_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xremap_parse_of(struct xremap_device *xremap)
+{
+	struct device_node *node = xremap->xvip.dev->of_node;
+	unsigned int i;
+	int ret;
+
+	/* Parse the DT properties. */
+	ret = of_property_read_u32(node, "xlnx,axi-video-width",
+				   &xremap->config.width);
+	if (ret < 0) {
+		dev_dbg(xremap->xvip.dev, "unable to parse %s property\n",
+			"xlnx,axi-video-width");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "#xlnx,axi-s-components",
+				   &xremap->config.num_s_components);
+	if (ret < 0) {
+		dev_dbg(xremap->xvip.dev, "unable to parse %s property\n",
+			"#xlnx,axi-s-components");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "#xlnx,axi-m-components",
+				   &xremap->config.num_m_components);
+	if (ret < 0) {
+		dev_dbg(xremap->xvip.dev, "unable to parse %s property\n",
+			"#xlnx,axi-m-components");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(node, "xlnx,axi-component-maps",
+					 xremap->config.component_maps,
+					 xremap->config.num_m_components);
+	if (ret < 0) {
+		dev_dbg(xremap->xvip.dev, "unable to parse %s property\n",
+			"xlnx,axi-component-maps");
+		return -EINVAL;
+	}
+
+	/* Validate the parsed values. */
+	if (xremap->config.num_s_components > 4 ||
+	    xremap->config.num_m_components > 4) {
+		dev_dbg(xremap->xvip.dev,
+			"invalid number of components (s %u m %u)\n",
+			xremap->config.num_s_components,
+			xremap->config.num_m_components);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < xremap->config.num_m_components; ++i) {
+		if (xremap->config.component_maps[i] > 4) {
+			dev_dbg(xremap->xvip.dev, "invalid map %u @%u\n",
+				xremap->config.component_maps[i], i);
+			return -EINVAL;
+		}
+	}
+
+	/* Find the first mapping that matches the remapper configuration and
+	 * store it as the default mapping.
+	 */
+	for (i = 0; i < ARRAY_SIZE(xremap_mappings); ++i) {
+		const struct xremap_mapping_output *output;
+		const struct xremap_mapping *mapping;
+
+		mapping = &xremap_mappings[i];
+		output = xremap_match_mapping(xremap, mapping);
+
+		if (output) {
+			xremap->default_mapping = mapping;
+			xremap->default_output = output;
+			return 0;
+		}
+	}
+
+	dev_err(xremap->xvip.dev,
+		"No format compatible with device configuration\n");
+
+	return -EINVAL;
+}
+
+static int xremap_probe(struct platform_device *pdev)
+{
+	struct xremap_device *xremap;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	xremap = devm_kzalloc(&pdev->dev, sizeof(*xremap), GFP_KERNEL);
+	if (!xremap)
+		return -ENOMEM;
+
+	xremap->xvip.dev = &pdev->dev;
+
+	ret = xremap_parse_of(xremap);
+	if (ret < 0)
+		return ret;
+
+	/* Initialize V4L2 subdevice and media entity */
+	subdev = &xremap->xvip.subdev;
+	v4l2_subdev_init(subdev, &xremap_ops);
+	subdev->dev = &pdev->dev;
+	subdev->internal_ops = &xremap_internal_ops;
+	strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
+	v4l2_set_subdevdata(subdev, xremap);
+	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	xremap_init_formats(subdev, NULL);
+
+	xremap->pads[XREMAP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	xremap->pads[XREMAP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	subdev->entity.ops = &xremap_media_ops;
+	ret = media_entity_init(&subdev->entity, 2, xremap->pads, 0);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, xremap);
+
+	ret = v4l2_async_register_subdev(subdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to register subdev\n");
+		goto error;
+	}
+
+	dev_info(&pdev->dev, "device registered\n");
+
+	return 0;
+
+error:
+	media_entity_cleanup(&subdev->entity);
+	return ret;
+}
+
+static int xremap_remove(struct platform_device *pdev)
+{
+	struct xremap_device *xremap = platform_get_drvdata(pdev);
+	struct v4l2_subdev *subdev = &xremap->xvip.subdev;
+
+	v4l2_async_unregister_subdev(subdev);
+	media_entity_cleanup(&subdev->entity);
+
+	return 0;
+}
+
+static const struct of_device_id xremap_of_id_table[] = {
+	{ .compatible = "xlnx,axi-remapper" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xremap_of_id_table);
+
+static struct platform_driver xremap_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xilinx-axi-remapper",
+		.of_match_table = of_match_ptr(xremap_of_id_table),
+	},
+	.probe = xremap_probe,
+	.remove = xremap_remove,
+};
+
+module_platform_driver(xremap_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Video Remapper Driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-tpg.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-tpg.c	2014-07-20 22:06:36.607301578 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Test Pattern Generator
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-subdev.h>
+
+#include "xilinx-vip.h"
+
+#define XTPG_MIN_WIDTH				32
+#define XTPG_DEF_WIDTH				1920
+#define XTPG_MAX_WIDTH				7680
+#define XTPG_MIN_HEIGHT				32
+#define XTPG_DEF_HEIGHT				1080
+#define XTPG_MAX_HEIGHT				7680
+
+#define XTPG_CTRL_STATUS_SLAVE_ERROR		(1 << 16)
+#define XTPG_CTRL_IRQ_SLAVE_ERROR		(1 << 16)
+
+#define XTPG_PATTERN_CONTROL			0x0100
+#define XTPG_MOTION_SPEED			0x0104
+#define XTPG_CROSS_HAIRS			0x0108
+#define XTPG_ZPLATE_HOR_CONTROL			0x010c
+#define XTPG_ZPLATE_VER_CONTROL			0x0110
+#define XTPG_BOX_SIZE				0x0114
+#define XTPG_BOX_COLOR				0x0118
+#define XTPG_STUCK_PIXEL_THRESH			0x011c
+#define XTPG_NOISE_GAIN				0x0120
+
+/**
+ * struct xtpg_device - Xilinx Test Pattern Generator device structure
+ * @pad: media pad
+ * @xvip: Xilinx Video IP device
+ * @format: active V4L2 media bus format at the source pad
+ * @vip_format: format information corresponding to the active format
+ */
+struct xtpg_device {
+	struct xvip_device xvip;
+	struct media_pad pad;
+
+	struct v4l2_mbus_framefmt format;
+	const struct xvip_video_format *vip_format;
+};
+
+static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct xtpg_device, xvip.subdev);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Video Operations
+ */
+
+static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+	const u32 width = xtpg->format.width;
+	const u32 height = xtpg->format.height;
+
+	if (!enable) {
+		/* Stopping the TPG without resetting it confuses the VDMA and
+		 * results in VDMA errors the next time the stream is started.
+		 * Reset the TPG when stopping the stream for now.
+		 */
+		xvip_write(&xtpg->xvip, XVIP_CTRL_CONTROL,
+			   XVIP_CTRL_CONTROL_SW_RESET);
+		xvip_write(&xtpg->xvip, XVIP_CTRL_CONTROL, 0);
+		return 0;
+	}
+
+	xvip_write(&xtpg->xvip, XVIP_TIMING_ACTIVE_SIZE,
+		   (height << XVIP_TIMING_ACTIVE_VSIZE_SHIFT) |
+		   (width << XVIP_TIMING_ACTIVE_HSIZE_SHIFT));
+
+	xvip_write(&xtpg->xvip, XTPG_PATTERN_CONTROL, 0x00001029);
+	xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, 1);
+	xvip_write(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, (74 * 1920) / width);
+	xvip_write(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, (3 * 1080) / height);
+	xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, (112 * height) / 1080);
+	xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, 0x76543200);
+
+	xvip_write(&xtpg->xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE |
+		   XVIP_CTRL_CONTROL_REG_UPDATE);
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Pad Operations
+ */
+
+static int xtpg_enum_mbus_code(struct v4l2_subdev *subdev,
+				     struct v4l2_subdev_fh *fh,
+				     struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+
+	if (code->index)
+		return -EINVAL;
+
+	code->code = xtpg->vip_format->code;
+
+	return 0;
+}
+
+static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
+				      struct v4l2_subdev_fh *fh,
+				      struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+
+	if (fse->index || fse->code != xtpg->vip_format->code)
+		return -EINVAL;
+
+	fse->min_width = XTPG_MIN_WIDTH;
+	fse->max_width = XTPG_MAX_WIDTH;
+	fse->min_height = XTPG_MIN_HEIGHT;
+	fse->max_height = XTPG_MAX_HEIGHT;
+
+	return 0;
+}
+
+static struct v4l2_mbus_framefmt *
+__xtpg_get_pad_format(struct xtpg_device *xtpg,
+			    struct v4l2_subdev_fh *fh,
+			    unsigned int pad, u32 which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(fh, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &xtpg->format;
+	default:
+		return NULL;
+	}
+}
+
+static int xtpg_get_format(struct v4l2_subdev *subdev,
+				 struct v4l2_subdev_fh *fh,
+				 struct v4l2_subdev_format *fmt)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+
+	fmt->format =
+		*__xtpg_get_pad_format(xtpg, fh, fmt->pad, fmt->which);
+
+	return 0;
+}
+
+static int xtpg_set_format(struct v4l2_subdev *subdev,
+				 struct v4l2_subdev_fh *fh,
+				 struct v4l2_subdev_format *format)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+	struct v4l2_mbus_framefmt *__format;
+
+	__format = __xtpg_get_pad_format(xtpg, fh, format->pad,
+					       format->which);
+	__format->width = clamp_t(unsigned int, format->format.width,
+				  XTPG_MIN_WIDTH, XTPG_MAX_WIDTH);
+	__format->height = clamp_t(unsigned int, format->format.height,
+				   XTPG_MIN_HEIGHT, XTPG_MAX_HEIGHT);
+
+	format->format = *__format;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Operations
+ */
+
+static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_get_try_format(fh, 0);
+
+	format->code = xtpg->vip_format->code;
+	format->width = XTPG_DEF_WIDTH;
+	format->height = XTPG_DEF_HEIGHT;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+
+	return 0;
+}
+
+static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops xtpg_core_ops = {
+};
+
+static struct v4l2_subdev_video_ops xtpg_video_ops = {
+	.s_stream = xtpg_s_stream,
+};
+
+static struct v4l2_subdev_pad_ops xtpg_pad_ops = {
+	.enum_mbus_code = xtpg_enum_mbus_code,
+	.enum_frame_size = xtpg_enum_frame_size,
+	.get_fmt = xtpg_get_format,
+	.set_fmt = xtpg_set_format,
+};
+
+static struct v4l2_subdev_ops xtpg_ops = {
+	.core   = &xtpg_core_ops,
+	.video  = &xtpg_video_ops,
+	.pad    = &xtpg_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
+	.open = xtpg_open,
+	.close = xtpg_close,
+};
+
+/* -----------------------------------------------------------------------------
+ * Media Operations
+ */
+
+static const struct media_entity_operations xtpg_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xtpg_parse_of(struct xtpg_device *xtpg)
+{
+	struct device_node *node = xtpg->xvip.dev->of_node;
+
+	xtpg->vip_format = xvip_of_get_format(node);
+	if (xtpg->vip_format == NULL) {
+		dev_err(xtpg->xvip.dev, "invalid format in DT");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int xtpg_probe(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev;
+	struct xtpg_device *xtpg;
+	struct resource *res;
+	u32 version;
+	int ret;
+
+	xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
+	if (!xtpg)
+		return -ENOMEM;
+
+	xtpg->xvip.dev = &pdev->dev;
+
+	ret = xtpg_parse_of(xtpg);
+	if (ret < 0)
+		return ret;
+
+	xtpg->format.code = xtpg->vip_format->code;
+	xtpg->format.width = XTPG_DEF_WIDTH;
+	xtpg->format.height = XTPG_DEF_HEIGHT;
+	xtpg->format.field = V4L2_FIELD_NONE;
+	xtpg->format.colorspace = V4L2_COLORSPACE_SRGB;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xtpg->xvip.iomem = devm_ioremap_resource(&pdev->dev, res);
+	if (xtpg->xvip.iomem == NULL)
+		return -ENODEV;
+
+	/* Initialize V4L2 subdevice and media entity */
+	subdev = &xtpg->xvip.subdev;
+	v4l2_subdev_init(subdev, &xtpg_ops);
+	subdev->dev = &pdev->dev;
+	subdev->internal_ops = &xtpg_internal_ops;
+	strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
+	v4l2_set_subdevdata(subdev, xtpg);
+	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	xtpg->pad.flags = MEDIA_PAD_FL_SOURCE;
+	subdev->entity.ops = &xtpg_media_ops;
+	ret = media_entity_init(&subdev->entity, 1, &xtpg->pad, 0);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, xtpg);
+
+	version = xvip_read(&xtpg->xvip, XVIP_CTRL_VERSION);
+
+	dev_info(&pdev->dev, "device found, version %u.%02x%x\n",
+		 ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >>
+		  XVIP_CTRL_VERSION_MAJOR_SHIFT),
+		 ((version & XVIP_CTRL_VERSION_MINOR_MASK) >>
+		  XVIP_CTRL_VERSION_MINOR_SHIFT),
+		 ((version & XVIP_CTRL_VERSION_REVISION_MASK) >>
+		  XVIP_CTRL_VERSION_REVISION_SHIFT));
+
+	ret = v4l2_async_register_subdev(subdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to register subdev\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	media_entity_cleanup(&subdev->entity);
+	return ret;
+}
+
+static int xtpg_remove(struct platform_device *pdev)
+{
+	struct xtpg_device *xtpg = platform_get_drvdata(pdev);
+	struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
+
+	v4l2_async_unregister_subdev(subdev);
+	media_entity_cleanup(&subdev->entity);
+
+	return 0;
+}
+
+static const struct of_device_id xtpg_of_id_table[] = {
+	{ .compatible = "xlnx,axi-tpg" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
+
+static struct platform_driver xtpg_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xilinx-axi-tpg",
+		.of_match_table = of_match_ptr(xtpg_of_id_table),
+	},
+	.probe = xtpg_probe,
+	.remove = xtpg_remove,
+};
+
+module_platform_driver(xtpg_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vip.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vip.c	2014-07-20 22:06:36.614301462 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video IP Core
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "xilinx-vip.h"
+
+/* -----------------------------------------------------------------------------
+ * Helper functions
+ */
+
+static const struct xvip_video_format xvip_video_formats[] = {
+	{ "rbg", 8, 3, V4L2_MBUS_FMT_RBG888_1X24, 0 },
+	{ "xrgb", 8, 4, V4L2_MBUS_FMT_RGB888_1X32_PADHI, V4L2_PIX_FMT_BGR32 },
+	{ "yuv422", 8, 2, V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_YUYV },
+};
+
+/**
+ * xvip_get_format_by_code - Retrieve format information for a media bus code
+ * @code: the format media bus code
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * given V4L2 media bus format @code, or %NULL if no corresponding format can be
+ * found.
+ */
+const struct xvip_video_format *xvip_get_format_by_code(unsigned int code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (format->code == code)
+			return format;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(xvip_get_format_by_code);
+
+/**
+ * xvip_get_format_by_fourcc - Retrieve format information for a 4CC
+ * @fourcc: the format 4CC
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * given V4L2 format @fourcc, or %NULL if no corresponding format can be found.
+ */
+const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (format->fourcc == fourcc)
+			return format;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc);
+
+/**
+ * xvip_of_get_format - Parse a device tree node and return format information
+ * @node: the device tree node
+ *
+ * Read the xlnx,axi-video-format and xlnx,axi-video-width properties from the
+ * device tree @node passed as an argument and return the corresponding format
+ * information.
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * format name and width, or %NULL if no corresponding format can be found.
+ */
+const struct xvip_video_format *xvip_of_get_format(struct device_node *node)
+{
+	const char *name;
+	unsigned int i;
+	u32 width;
+	int ret;
+
+	ret = of_property_read_string(node, "xlnx,axi-video-format", &name);
+	if (ret < 0)
+		return NULL;
+
+	ret = of_property_read_u32(node, "xlnx,axi-video-width", &width);
+	if (ret < 0)
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (strcmp(format->name, name) == 0 && format->width == width)
+			return format;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(xvip_of_get_format);
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vip.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vip.h	2014-07-20 22:06:36.620301363 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video IP Core
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIP_H__
+#define __XILINX_VIP_H__
+
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+/* Xilinx Video IP Control Registers */
+#define XVIP_CTRL_CONTROL			0x0000
+#define XVIP_CTRL_CONTROL_SW_ENABLE		(1 << 0)
+#define XVIP_CTRL_CONTROL_REG_UPDATE		(1 << 1)
+#define XVIP_CTRL_CONTROL_BYPASS		(1 << 4)
+#define XVIP_CTRL_CONTROL_TEST_PATTERN		(1 << 5)
+#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET	(1 << 30)
+#define XVIP_CTRL_CONTROL_SW_RESET		(1 << 31)
+#define XVIP_CTRL_STATUS			0x0004
+#define XVIP_CTRL_STATUS_PROC_STARTED		(1 << 0)
+#define XVIP_CTRL_STATUS_EOF			(1 << 1)
+#define XVIP_CTRL_ERROR				0x0008
+#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY		(1 << 0)
+#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE		(1 << 1)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY		(1 << 2)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE		(1 << 3)
+#define XVIP_CTRL_IRQ_ENABLE			0x000c
+#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED	(1 << 0)
+#define XVIP_CTRL_IRQ_EOF			(1 << 1)
+#define XVIP_CTRL_VERSION			0x0010
+#define XVIP_CTRL_VERSION_MAJOR_MASK		(0xff << 24)
+#define XVIP_CTRL_VERSION_MAJOR_SHIFT		24
+#define XVIP_CTRL_VERSION_MINOR_MASK		(0xff << 16)
+#define XVIP_CTRL_VERSION_MINOR_SHIFT		16
+#define XVIP_CTRL_VERSION_REVISION_MASK		(0xf << 12)
+#define XVIP_CTRL_VERSION_REVISION_SHIFT	12
+#define XVIP_CTRL_VERSION_PATCH_MASK		(0xf << 8)
+#define XVIP_CTRL_VERSION_PATCH_SHIFT		8
+#define XVIP_CTRL_VERSION_INTERNAL_MASK		(0xff << 0)
+#define XVIP_CTRL_VERSION_INTERNAL_SHIFT	0
+
+/* Xilinx Video IP Timing Registers */
+#define XVIP_TIMING_ACTIVE_SIZE			0x0020
+#define XVIP_TIMING_ACTIVE_VSIZE_MASK		(0x7ff << 16)
+#define XVIP_TIMING_ACTIVE_VSIZE_SHIFT		16
+#define XVIP_TIMING_ACTIVE_HSIZE_MASK		(0x7ff << 0)
+#define XVIP_TIMING_ACTIVE_HSIZE_SHIFT		0
+#define XVIP_TIMING_OUTPUT_ENCODING		0x0028
+#define XVIP_TIMING_OUTPUT_NBITS_8		(0 << 4)
+#define XVIP_TIMING_OUTPUT_NBITS_10		(1 << 4)
+#define XVIP_TIMING_OUTPUT_NBITS_12		(2 << 4)
+#define XVIP_TIMING_OUTPUT_NBITS_16		(3 << 4)
+#define XVIP_TIMING_OUTPUT_NBITS_MASK		(3 << 4)
+#define XVIP_TIMING_OUTPUT_NBITS_SHIFT		4
+#define XVIP_TIMING_VIDEO_FORMAT_YUV422		(0 << 0)
+#define XVIP_TIMING_VIDEO_FORMAT_YUV444		(1 << 0)
+#define XVIP_TIMING_VIDEO_FORMAT_RGB		(2 << 0)
+#define XVIP_TIMING_VIDEO_FORMAT_YUV420		(3 << 0)
+#define XVIP_TIMING_VIDEO_FORMAT_MASK		(3 << 0)
+#define XVIP_TIMING_VIDEO_FORMAT_SHIFT		0
+
+/**
+ * struct xvip_device - Xilinx Video IP device structure
+ * @subdev: V4L2 subdevice
+ * @dev: (OF) device
+ * @iomem: device I/O register space remapped to kernel virtual memory
+ */
+struct xvip_device {
+	struct v4l2_subdev subdev;
+	struct device *dev;
+	void __iomem *iomem;
+};
+
+/**
+ * struct xvip_video_format - Xilinx Video IP video format description
+ * @name: AXI4 format name
+ * @width: AXI4 format width in bits per component
+ * @bpp: bytes per pixel (when stored in memory)
+ * @code: media bus format code
+ * @fourcc: V4L2 pixel format FCC identifier
+ */
+struct xvip_video_format {
+	const char *name;
+	unsigned int width;
+	unsigned int bpp;
+	unsigned int code;
+	u32 fourcc;
+};
+
+const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
+const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc);
+const struct xvip_video_format *xvip_of_get_format(struct device_node *node);
+
+static inline u32 xvip_read(struct xvip_device *xvip, u32 addr)
+{
+	return ioread32(xvip->iomem + addr);
+}
+
+static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value)
+{
+	iowrite32(value, xvip->iomem + addr);
+}
+
+#endif /* __XILINX_VIP_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vipp.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vipp.c	2014-07-20 22:06:36.630301198 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video IP Pipeline
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
+
+#include "xilinx-dma.h"
+#include "xilinx-vipp.h"
+
+#define XVIPP_DMA_S2MM				0
+#define XVIPP_DMA_MM2S				1
+
+/**
+ * struct xvip_pipeline_entity - Entity in a video pipeline
+ * @list: list entry in a pipeline entities list
+ * @node: the entity's DT node
+ * @entity: media entity, from the corresponding V4L2 subdev or video device
+ * @asd: subdev asynchronous registration information
+ * @subdev: V4L2 subdev (valid for all entities by DMA channels)
+ */
+struct xvip_pipeline_entity {
+	struct list_head list;
+	struct device_node *node;
+	struct media_entity *entity;
+
+	struct v4l2_async_subdev asd;
+	struct v4l2_subdev *subdev;
+};
+
+/* -----------------------------------------------------------------------------
+ * Pipeline Stream Management
+ */
+
+/**
+ * xvip_pipeline_start_stop - Start ot stop streaming on a pipeline
+ * @xvipp: Xilinx Video Pipeline
+ * @start: Start (when true) or stop (when false) the pipeline
+ *
+ * Walk the entities chain starting at the pipeline output video node and start
+ * or stop all of them.
+ *
+ * Return: 0 if successful, or the return value of the failed video::s_stream
+ * operation otherwise.
+ */
+static int xvip_pipeline_start_stop(struct xvip_pipeline *xvipp, bool start)
+{
+	struct media_entity *entity;
+	struct media_pad *pad;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	entity = &xvipp->dma[XVIPP_DMA_S2MM].video.entity;
+	while (1) {
+		pad = &entity->pads[0];
+		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+			break;
+
+		pad = media_entity_remote_pad(pad);
+		if (pad == NULL ||
+		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+			break;
+
+		entity = pad->entity;
+		subdev = media_entity_to_v4l2_subdev(entity);
+
+		ret = v4l2_subdev_call(subdev, video, s_stream, start);
+		if (start && ret < 0 && ret != -ENOIOCTLCMD)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * xvip_pipeline_set_stream - Enable/disable streaming on a pipeline
+ * @xvipp: Xilinx Video Pipeline
+ * @on: Turn the stream on when true or off when false
+ *
+ * The pipeline is shared between all DMA engines connect at its input and
+ * output. While the stream state of DMA engines can be controlled
+ * independently, pipelines have a shared stream state that enable or disable
+ * all entities in the pipeline. For this reason the pipeline uses a streaming
+ * counter that tracks the number of DMA engines that have requested the stream
+ * to be enabled.
+ *
+ * When called with the @on argument set to true, this function will increment
+ * the pipeline streaming count. If the streaming count reaches the number of
+ * DMA engines in the pipeline it will enable all entities that belong to the
+ * pipeline.
+ *
+ * Similarly, when called with the @on argument set to false, this function will
+ * decrement the pipeline streaming count and disable all entities in the
+ * pipeline when the streaming count reaches zero.
+ *
+ * Return: 0 if successful, or the return value of the failed video::s_stream
+ * operation otherwise. Stopping the pipeline never fails. The pipeline state is
+ * not updated when the operation fails.
+ */
+int xvip_pipeline_set_stream(struct xvip_pipeline *xvipp, bool on)
+{
+	int ret = 0;
+
+	mutex_lock(&xvipp->lock);
+
+	if (on) {
+		if (xvipp->stream_count == xvipp->num_dmas - 1) {
+			ret = xvip_pipeline_start_stop(xvipp, true);
+			if (ret < 0)
+				goto done;
+		}
+		xvipp->stream_count++;
+	} else {
+		if (--xvipp->stream_count == 0)
+			xvip_pipeline_start_stop(xvipp, false);
+	}
+
+done:
+	mutex_unlock(&xvipp->lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Pipeline Management
+ */
+
+static struct xvip_pipeline_entity *
+xvipp_pipeline_find_entity(struct xvip_pipeline *xvipp,
+			   const struct device_node *node)
+{
+	struct xvip_pipeline_entity *entity;
+
+	list_for_each_entry(entity, &xvipp->entities, list) {
+		if (entity->node == node)
+			return entity;
+	}
+
+	return NULL;
+}
+
+static int xvipp_pipeline_build_one(struct xvip_pipeline *xvipp,
+				    struct xvip_pipeline_entity *entity)
+{
+	u32 link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
+	struct media_entity *local = entity->entity;
+	struct media_entity *remote;
+	struct media_pad *local_pad;
+	struct media_pad *remote_pad;
+	struct xvip_pipeline_entity *ent;
+	struct v4l2_of_link link;
+	struct device_node *ep = NULL;
+	struct device_node *next;
+	int ret = 0;
+
+	dev_dbg(xvipp->dev, "creating links for entity %s\n", local->name);
+
+	while (1) {
+		/* Get the next endpoint and parse its link. */
+		next = v4l2_of_get_next_endpoint(entity->node, ep);
+		if (next == NULL)
+			break;
+
+		of_node_put(ep);
+		ep = next;
+
+		dev_dbg(xvipp->dev, "processing endpoint %s\n", ep->full_name);
+
+		ret = v4l2_of_parse_link(ep, &link);
+		if (ret < 0) {
+			dev_err(xvipp->dev, "failed to parse link for %s\n",
+				ep->full_name);
+			continue;
+		}
+
+		/* Skip sink ports, they will be processed from the other end of
+		 * the link.
+		 */
+		if (link.local_port >= local->num_pads) {
+			dev_err(xvipp->dev, "invalid port number %u on %s\n",
+				link.local_port, link.local_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		local_pad = &local->pads[link.local_port];
+
+		if (local_pad->flags & MEDIA_PAD_FL_SINK) {
+			dev_dbg(xvipp->dev, "skipping sink port %s:%u\n",
+				link.local_node->full_name, link.local_port);
+			v4l2_of_put_link(&link);
+			continue;
+		}
+
+		/* Find the remote entity. */
+		ent = xvipp_pipeline_find_entity(xvipp, link.remote_node);
+		if (ent == NULL) {
+			dev_err(xvipp->dev, "no entity found for %s\n",
+				link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -ENODEV;
+			break;
+		}
+
+		remote = ent->entity;
+
+		if (link.remote_port >= remote->num_pads) {
+			dev_err(xvipp->dev, "invalid port number %u on %s\n",
+				link.remote_port, link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		remote_pad = &remote->pads[link.remote_port];
+
+		v4l2_of_put_link(&link);
+
+		/* Create the media link. */
+		dev_dbg(xvipp->dev, "creating %s:%u -> %s:%u link\n",
+			local->name, local_pad->index,
+			remote->name, remote_pad->index);
+
+		ret = media_entity_create_link(local, local_pad->index,
+					       remote, remote_pad->index,
+					       link_flags);
+		if (ret < 0) {
+			dev_err(xvipp->dev,
+				"failed to create %s:%u -> %s:%u link\n",
+				local->name, local_pad->index,
+				remote->name, remote_pad->index);
+			break;
+		}
+	}
+
+	of_node_put(ep);
+	return ret;
+}
+
+static int xvipp_pipeline_notify_complete(struct v4l2_async_notifier *notifier)
+{
+	struct xvip_pipeline *xvipp =
+		container_of(notifier, struct xvip_pipeline, notifier);
+	struct xvip_pipeline_entity *entity;
+	int ret;
+
+	dev_dbg(xvipp->dev, "notify complete, all subdevs registered\n");
+
+	/* Create links for every entity. */
+	list_for_each_entry(entity, &xvipp->entities, list) {
+		ret = xvipp_pipeline_build_one(xvipp, entity);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = v4l2_device_register_subdev_nodes(&xvipp->v4l2_dev);
+	if (ret < 0)
+		dev_err(xvipp->dev, "failed to register subdev nodes\n");
+
+	return ret;
+}
+
+static int xvipp_pipeline_notify_bound(struct v4l2_async_notifier *notifier,
+				       struct v4l2_subdev *subdev,
+				       struct v4l2_async_subdev *asd)
+{
+	struct xvip_pipeline *xvipp =
+		container_of(notifier, struct xvip_pipeline, notifier);
+	struct xvip_pipeline_entity *entity;
+
+	/* Locate the entity corresponding to the bound subdev and store the
+	 * subdev pointer.
+	 */
+	list_for_each_entry(entity, &xvipp->entities, list) {
+		if (entity->node != subdev->dev->of_node)
+			continue;
+
+		if (entity->subdev) {
+			dev_err(xvipp->dev, "duplicate subdev for node %s\n",
+				entity->node->full_name);
+			return -EINVAL;
+		}
+
+		dev_dbg(xvipp->dev, "subdev %s bound\n", subdev->name);
+		entity->entity = &subdev->entity;
+		entity->subdev = subdev;
+		return 0;
+	}
+
+	dev_err(xvipp->dev, "no entity for subdev %s\n", subdev->name);
+	return -EINVAL;
+}
+
+static int xvipp_pipeline_parse_one(struct xvip_pipeline *xvipp,
+				    struct device_node *node)
+{
+	struct xvip_pipeline_entity *entity;
+	struct device_node *remote;
+	struct device_node *ep = NULL;
+	struct device_node *next;
+	int ret = 0;
+
+	dev_dbg(xvipp->dev, "parsing node %s\n", node->full_name);
+
+	while (1) {
+		next = v4l2_of_get_next_endpoint(node, ep);
+		if (next == NULL)
+			break;
+
+		of_node_put(ep);
+		ep = next;
+
+		dev_dbg(xvipp->dev, "handling endpoint %s\n", ep->full_name);
+
+		remote = v4l2_of_get_remote_port_parent(ep);
+		if (remote == NULL) {
+			ret = -EINVAL;
+			break;
+		}
+
+		/* Skip entities that we have already processed. */
+		if (xvipp_pipeline_find_entity(xvipp, remote)) {
+			of_node_put(remote);
+			continue;
+		}
+
+		entity = devm_kzalloc(xvipp->dev, sizeof(*entity), GFP_KERNEL);
+		if (entity == NULL) {
+			of_node_put(remote);
+			ret = -ENOMEM;
+			break;
+		}
+
+		entity->node = remote;
+		entity->asd.match_type = V4L2_ASYNC_MATCH_OF;
+		entity->asd.match.of.node = remote;
+		list_add_tail(&entity->list, &xvipp->entities);
+		xvipp->num_subdevs++;
+	}
+
+	of_node_put(ep);
+	return ret;
+}
+
+static int xvipp_pipeline_parse(struct xvip_pipeline *xvipp)
+{
+	struct xvip_pipeline_entity *entity;
+	int ret;
+
+	/* Walk the links to parse the full pipeline. */
+	list_for_each_entry(entity, &xvipp->entities, list) {
+		ret = xvipp_pipeline_parse_one(xvipp, entity->node);
+		if (ret < 0)
+			break;
+	}
+
+	return ret;
+}
+
+static int
+xvipp_pipeline_dma_init_one(struct xvip_pipeline *xvipp, struct xvip_dma *dma,
+			    struct device_node *node, enum v4l2_buf_type type)
+{
+	struct xvip_pipeline_entity *entity;
+	int ret;
+
+	ret = xvip_dma_init(xvipp, dma, type);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "%s initialization failed\n",
+			node->full_name);
+		return ret;
+	}
+
+	entity = devm_kzalloc(xvipp->dev, sizeof(*entity), GFP_KERNEL);
+	if (entity == NULL)
+		return -ENOMEM;
+
+	entity->node = of_node_get(node);
+	entity->entity = &dma->video.entity;
+
+	list_add_tail(&entity->list, &xvipp->entities);
+	xvipp->num_dmas++;
+
+	return 0;
+}
+
+static int xvipp_pipeline_dma_init(struct xvip_pipeline *xvipp)
+{
+	struct device_node *vdma;
+	int ret;
+
+	/* The s2mm vdma channel at the pipeline output is mandatory. */
+	vdma = of_get_child_by_name(xvipp->dev->of_node, "vdma-s2mm");
+	if (vdma == NULL) {
+		dev_err(xvipp->dev, "vdma-s2mm node not present\n");
+		return -EINVAL;
+	}
+
+	ret = xvipp_pipeline_dma_init_one(xvipp, &xvipp->dma[XVIPP_DMA_S2MM],
+					  vdma, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	of_node_put(vdma);
+
+	if (ret < 0)
+		return ret;
+
+	/* The mm2s vdma channel at the pipeline input is optional. */
+	vdma = of_get_child_by_name(xvipp->dev->of_node, "vdma-mm2s");
+	if (vdma == NULL)
+		return 0;
+
+	ret = xvipp_pipeline_dma_init_one(xvipp, &xvipp->dma[XVIPP_DMA_MM2S],
+					  vdma, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	of_node_put(vdma);
+
+	return ret;
+}
+
+static void xvipp_pipeline_cleanup(struct xvip_pipeline *xvipp)
+{
+	struct xvip_pipeline_entity *entity;
+	struct xvip_pipeline_entity *prev;
+
+	v4l2_async_notifier_unregister(&xvipp->notifier);
+
+	list_for_each_entry_safe(entity, prev, &xvipp->entities, list) {
+		of_node_put(entity->node);
+		list_del(&entity->list);
+	}
+
+	xvip_dma_cleanup(&xvipp->dma[XVIPP_DMA_S2MM]);
+	xvip_dma_cleanup(&xvipp->dma[XVIPP_DMA_MM2S]);
+}
+
+static int xvipp_pipeline_init(struct xvip_pipeline *xvipp)
+{
+	struct xvip_pipeline_entity *entity;
+	struct v4l2_async_subdev **subdevs = NULL;
+	unsigned int num_subdevs;
+	unsigned int i;
+	int ret;
+
+	/* Init the DMA channels. */
+	ret = xvipp_pipeline_dma_init(xvipp);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "DMA initialization failed\n");
+		goto done;
+	}
+
+	/* Parse the pipeline to extract a list of subdevice DT nodes. */
+	ret = xvipp_pipeline_parse(xvipp);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "pipeline parsing failed\n");
+		goto done;
+	}
+
+	if (!xvipp->num_subdevs) {
+		dev_err(xvipp->dev, "no subdev found in pipeline\n");
+		goto done;
+	}
+
+	/* Register the subdevices notifier. */
+	num_subdevs = xvipp->num_subdevs;
+	subdevs = devm_kzalloc(xvipp->dev, sizeof(*subdevs) * num_subdevs,
+			       GFP_KERNEL);
+	if (subdevs == NULL) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	i = 0;
+	list_for_each_entry(entity, &xvipp->entities, list) {
+		/* Skip entities that correspond to video nodes. */
+		if (entity->entity == NULL)
+			subdevs[i++] = &entity->asd;
+	}
+
+	xvipp->notifier.subdevs = subdevs;
+	xvipp->notifier.num_subdevs = num_subdevs;
+	xvipp->notifier.bound = xvipp_pipeline_notify_bound;
+	xvipp->notifier.complete = xvipp_pipeline_notify_complete;
+
+	ret = v4l2_async_notifier_register(&xvipp->v4l2_dev, &xvipp->notifier);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "notifier registration failed\n");
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	if (ret < 0)
+		xvipp_pipeline_cleanup(xvipp);
+
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Media Controller and V4L2
+ */
+
+static void xvipp_v4l2_cleanup(struct xvip_pipeline *xvipp)
+{
+	v4l2_device_unregister(&xvipp->v4l2_dev);
+	media_device_unregister(&xvipp->media_dev);
+}
+
+static int xvipp_v4l2_init(struct xvip_pipeline *xvipp)
+{
+	int ret;
+
+	xvipp->media_dev.dev = xvipp->dev;
+	strlcpy(xvipp->media_dev.model, "Xilinx Video Pipeline",
+		sizeof(xvipp->media_dev.model));
+	xvipp->media_dev.hw_revision = 0;
+
+	ret = media_device_register(&xvipp->media_dev);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "media device registration failed (%d)\n",
+			ret);
+		return ret;
+	}
+
+	xvipp->v4l2_dev.mdev = &xvipp->media_dev;
+	ret = v4l2_device_register(xvipp->dev, &xvipp->v4l2_dev);
+	if (ret < 0) {
+		dev_err(xvipp->dev, "V4L2 device registration failed (%d)\n",
+			ret);
+		media_device_unregister(&xvipp->media_dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xvipp_probe(struct platform_device *pdev)
+{
+	struct xvip_pipeline *xvipp;
+	int ret;
+
+	xvipp = devm_kzalloc(&pdev->dev, sizeof(*xvipp), GFP_KERNEL);
+	if (!xvipp)
+		return -ENOMEM;
+
+	xvipp->dev = &pdev->dev;
+	INIT_LIST_HEAD(&xvipp->entities);
+	mutex_init(&xvipp->lock);
+
+	ret = xvipp_v4l2_init(xvipp);
+	if (ret < 0)
+		return ret;
+
+	ret = xvipp_pipeline_init(xvipp);
+	if (ret < 0)
+		goto error;
+
+	platform_set_drvdata(pdev, xvipp);
+
+	dev_info(xvipp->dev, "device registered\n");
+
+	return 0;
+
+error:
+	xvipp_v4l2_cleanup(xvipp);
+	return ret;
+}
+
+static int xvipp_remove(struct platform_device *pdev)
+{
+	struct xvip_pipeline *xvipp = platform_get_drvdata(pdev);
+
+	xvipp_pipeline_cleanup(xvipp);
+	xvipp_v4l2_cleanup(xvipp);
+	mutex_destroy(&xvipp->lock);
+
+	return 0;
+}
+
+static const struct of_device_id xvipp_of_id_table[] = {
+	{ .compatible = "xlnx,axi-video" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xvipp_of_id_table);
+
+static struct platform_driver xvipp_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xilinx-axi-video",
+		.of_match_table = of_match_ptr(xvipp_of_id_table),
+	},
+	.probe = xvipp_probe,
+	.remove = xvipp_remove,
+};
+
+module_platform_driver(xvipp_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Video IP Pipeline Driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vipp.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/media/platform/xilinx/xilinx-vipp.h	2014-07-20 22:06:36.637301083 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Video IP Pipeline
+ *
+ * Copyright (C) 2013 Ideas on Board SPRL
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIPP_H__
+#define __XILINX_VIPP_H__
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <media/media-device.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-device.h>
+
+#include "xilinx-dma.h"
+
+/**
+ * struct xvip_pipeline - Xilinx Video IP device structure
+ * @v4l2_dev: V4L2 device
+ * @media_dev: media device
+ * @pipe: media pipeline
+ * @dev: (OF) device
+ * @notifier: V4L2 asynchronous subdevs notifier
+ * @entities: entities in the pipeline as a list of xvip_pipeline_entity
+ * @num_subdevs: number of subdevs in the pipeline
+ * @dma: DMA channels at the pipeline output and input
+ * @num_dmas: number of DMA engines in the pipeline
+ * @lock: protects the pipeline @stream_count
+ * @stream_count: number of DMA engines currently streaming
+ */
+struct xvip_pipeline {
+	struct v4l2_device v4l2_dev;
+	struct media_device media_dev;
+	struct media_pipeline pipe;
+	struct device *dev;
+
+	struct v4l2_async_notifier notifier;
+	struct list_head entities;
+	unsigned int num_subdevs;
+
+	struct xvip_dma dma[2];
+	unsigned int num_dmas;
+
+	struct mutex lock;
+	unsigned int stream_count;
+};
+
+int xvip_pipeline_set_stream(struct xvip_pipeline *xvipp, bool on);
+
+#endif /* __XILINX_VIPP_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/media/v4l2-core/v4l2-of.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/media/v4l2-core/v4l2-of.c	2014-07-20 22:05:50.215066968 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/media/v4l2-core/v4l2-of.c	2014-07-20 22:06:36.650300869 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:124 @
  * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
  * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
  * The caller should hold a reference to @node.
+ *
+ * Return: 0.
  */
-void v4l2_of_parse_endpoint(const struct device_node *node,
-			    struct v4l2_of_endpoint *endpoint)
+int v4l2_of_parse_endpoint(const struct device_node *node,
+			   struct v4l2_of_endpoint *endpoint)
 {
 	struct device_node *port_node = of_get_parent(node);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:151 @
 		v4l2_of_parse_parallel_bus(node, endpoint);
 
 	of_node_put(port_node);
+
+	return 0;
 }
 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
 
 /**
+ * v4l2_of_parse_link() - parse a link between two endpoints
+ * @node: pointer to the endpoint at the local end of the link
+ * @link: pointer to the V4L2 OF link data structure
+ *
+ * Fill the link structure with the local and remote nodes and port numbers.
+ * The local_node and remote_node fields are set to point to the local and
+ * remote port parent nodes respectively (the port parent node being the parent
+ * node of the port node if that node isn't a 'ports' node, or the grand-parent
+ * node of the port node otherwise).
+ *
+ * A reference is taken to both the local and remote nodes, the caller must use
+ * v4l2_of_put_link() to drop the references when done with the link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
+ */
+int v4l2_of_parse_link(const struct device_node *node,
+		       struct v4l2_of_link *link)
+{
+	struct device_node *np;
+
+	memset(link, 0, sizeof(*link));
+
+	np = of_get_parent(node);
+	of_property_read_u32(np, "reg", &link->local_port);
+	np = of_get_next_parent(np);
+	if (of_node_cmp(np->name, "ports") == 0)
+		np = of_get_next_parent(np);
+	link->local_node = np;
+
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!np) {
+		of_node_put(link->local_node);
+		return -ENOLINK;
+	}
+
+	np = of_get_parent(np);
+	of_property_read_u32(np, "reg", &link->remote_port);
+	np = of_get_next_parent(np);
+	if (of_node_cmp(np->name, "ports") == 0)
+		np = of_get_next_parent(np);
+	link->remote_node = np;
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_of_parse_link);
+
+/**
+ * v4l2_of_put_link() - drop references to nodes in a link
+ * @link: pointer to the V4L2 OF link data structure
+ *
+ * Drop references to the local and remote nodes in the link. This function must
+ * be called on every link parsed with v4l2_of_parse_link().
+ */
+void v4l2_of_put_link(struct v4l2_of_link *link)
+{
+	of_node_put(link->local_node);
+	of_node_put(link->remote_node);
+}
+EXPORT_SYMBOL(v4l2_of_put_link);
+
+/**
  * 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
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:330 @
 	np = of_parse_phandle(node, "remote-endpoint", 0);
 	if (!np)
 		return NULL;
-	return of_get_parent(np);
+	return of_get_next_parent(np);
 }
 EXPORT_SYMBOL(v4l2_of_get_remote_port);
Index: linux-3.12.24-rt38-xilinx/drivers/memory/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/memory/Kconfig	2014-07-20 22:05:50.190067380 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/memory/Kconfig	2014-07-20 22:06:36.663300654 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:53 @
 	  analysis, especially for IOMMU/SMMU(System Memory Management
 	  Unit) module.
 
+config ZYNQ_SMC
+	bool "Zynq Static Memory Controller(SMC) driver"
+	default y
+	depends on ARCH_ZYNQ
+	help
+	  This driver is for the Static Memory Controller(SMC) module available
+	  in Zynq SoCs.
 endif
Index: linux-3.12.24-rt38-xilinx/drivers/memory/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/memory/Makefile	2014-07-20 22:05:50.189067397 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/memory/Makefile	2014-07-20 22:06:36.672300505 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:12 @
 obj-$(CONFIG_MVEBU_DEVBUS)	+= mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o
 obj-$(CONFIG_TEGRA30_MC)	+= tegra30-mc.o
+obj-$(CONFIG_ZYNQ_SMC)		+= zynq-smc.o
Index: linux-3.12.24-rt38-xilinx/drivers/memory/zynq-smc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/memory/zynq-smc.c	2014-07-20 22:06:36.684300308 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq SMC Driver
+ *
+ * Copyright (C) 2012 - 2013 Xilinx, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Currently only a single SMC instance is supported.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/memory/zynq-smc.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Register definitions */
+#define XSMCPS_MEMC_STATUS_OFFS		0	/* Controller status reg, RO */
+#define XSMCPS_CFG_CLR_OFFS		0xC	/* Clear config reg, WO */
+#define XSMCPS_DIRECT_CMD_OFFS		0x10	/* Direct command reg, WO */
+#define XSMCPS_SET_CYCLES_OFFS		0x14	/* Set cycles register, WO */
+#define XSMCPS_SET_OPMODE_OFFS		0x18	/* Set opmode register, WO */
+#define XSMCPS_ECC_STATUS_OFFS		0x400	/* ECC status register */
+#define XSMCPS_ECC_MEMCFG_OFFS		0x404	/* ECC mem config reg */
+#define XSMCPS_ECC_MEMCMD1_OFFS		0x408	/* ECC mem cmd1 reg */
+#define XSMCPS_ECC_MEMCMD2_OFFS		0x40C	/* ECC mem cmd2 reg */
+#define XSMCPS_ECC_VALUE0_OFFS		0x418	/* ECC value 0 reg */
+
+#define XSMCPS_CFG_CLR_INT_1	0x10
+#define XSMCPS_ECC_STATUS_BUSY	(1 << 6)
+#define XSMCPS_DC_UPT_NAND_REGS	((4 << 23) |	/* CS: NAND chip */ \
+				 (2 << 21))	/* UpdateRegs operation */
+
+#define XNANDPS_ECC_CMD1	((0x80)       |	/* Write command */ \
+				 (0 << 8)     |	/* Read command */ \
+				 (0x30 << 16) |	/* Read End command */ \
+				 (1 << 24))	/* Read End command calid */
+
+#define XNANDPS_ECC_CMD2	((0x85)	      |	/* Write col change cmd */ \
+				 (5 << 8)     |	/* Read col change cmd */ \
+				 (0xE0 << 16) |	/* Read col change end cmd */ \
+				 (1 << 24)) /* Read col change end cmd valid */
+/**
+ * struct xsmcps_data
+ * @devclk:		Pointer to the peripheral clock
+ * @aperclk:		Pointer to the APER clock
+ * @clk_rate_change_nb:	Notifier block for clock frequency change callback
+ */
+struct xsmcps_data {
+	struct clk		*devclk;
+	struct clk		*aperclk;
+	struct notifier_block	clk_rate_change_nb;
+};
+
+/* SMC virtual register base */
+static void __iomem *xsmcps_base;
+static DEFINE_SPINLOCK(xsmcps_lock);
+
+/**
+ * xsmcps_set_buswidth - Set memory buswidth
+ * @bw:	Memory buswidth (8 | 16)
+ * Returns 0 on success or negative errno.
+ *
+ * Must be called with xsmcps_lock held.
+ */
+static int xsmcps_set_buswidth(unsigned int bw)
+{
+	u32 reg;
+
+	if (bw != 8 && bw != 16)
+		return -EINVAL;
+
+	reg = readl(xsmcps_base + XSMCPS_SET_OPMODE_OFFS);
+	reg &= ~3;
+	if (bw == 16)
+		reg |= 1;
+	writel(reg, xsmcps_base + XSMCPS_SET_OPMODE_OFFS);
+
+	return 0;
+}
+
+/**
+ * xsmcps_set_cycles - Set memory timing parameters
+ * @t0:	t_rc		read cycle time
+ * @t1:	t_wc		write cycle time
+ * @t2:	t_rea/t_ceoe	output enable assertion delay
+ * @t3:	t_wp		write enable deassertion delay
+ * @t4:	t_clr/t_pc	page cycle time
+ * @t5:	t_ar/t_ta	ID read time/turnaround time
+ * @t6:	t_rr		busy to RE timing
+ *
+ * Sets NAND chip specific timing parameters.
+ *
+ * Must be called with xsmcps_lock held.
+ */
+static void xsmcps_set_cycles(u32 t0, u32 t1, u32 t2, u32 t3, u32
+			      t4, u32 t5, u32 t6)
+{
+	t0 &= 0xf;
+	t1 = (t1 & 0xf) << 4;
+	t2 = (t2 & 7) << 8;
+	t3 = (t3 & 7) << 11;
+	t4 = (t4 & 7) << 14;
+	t5 = (t5 & 7) << 17;
+	t6 = (t6 & 0xf) << 20;
+
+	t0 |= t1 | t2 | t3 | t4 | t5 | t6;
+
+	writel(t0, xsmcps_base + XSMCPS_SET_CYCLES_OFFS);
+}
+
+/**
+ * xsmcps_ecc_is_busy_noirq - Read ecc busy flag
+ * Returns the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle
+ *
+ * Must be called with xsmcps_lock held.
+ */
+static int xsmcps_ecc_is_busy_noirq(void)
+{
+	return !!(readl(xsmcps_base + XSMCPS_ECC_STATUS_OFFS) &
+		  XSMCPS_ECC_STATUS_BUSY);
+}
+
+/**
+ * xsmcps_ecc_is_busy - Read ecc busy flag
+ * Returns the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle
+ */
+int xsmcps_ecc_is_busy(void)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	ret = xsmcps_ecc_is_busy_noirq();
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(xsmcps_ecc_is_busy);
+
+/**
+ * xsmcps_get_ecc_val - Read ecc_valueN registers
+ * @ecc_reg:	Index of the ecc_value reg (0..3)
+ * Returns the content of the requested ecc_value register.
+ *
+ * There are four valid ecc_value registers. The argument is truncated to stay
+ * within this valid boundary.
+ */
+u32 xsmcps_get_ecc_val(int ecc_reg)
+{
+	u32 addr, reg;
+	unsigned long flags;
+
+	ecc_reg &= 3;
+	addr = XSMCPS_ECC_VALUE0_OFFS + (ecc_reg << 2);
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	reg = readl(xsmcps_base + addr);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+
+	return reg;
+}
+EXPORT_SYMBOL_GPL(xsmcps_get_ecc_val);
+
+/**
+ * xsmcps_get_nand_int_status_raw - Get NAND interrupt status bit
+ * Returns the raw_int_status1 bit from the memc_status register
+ */
+int xsmcps_get_nand_int_status_raw(void)
+{
+	u32 reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	reg = readl(xsmcps_base + XSMCPS_MEMC_STATUS_OFFS);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+
+	reg >>= 6;
+	reg &= 1;
+
+	return reg;
+}
+EXPORT_SYMBOL_GPL(xsmcps_get_nand_int_status_raw);
+
+/**
+ * xsmcps_clr_nand_int - Clear NAND interrupt
+ */
+void xsmcps_clr_nand_int(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	writel(XSMCPS_CFG_CLR_INT_1, xsmcps_base + XSMCPS_CFG_CLR_OFFS);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+}
+EXPORT_SYMBOL_GPL(xsmcps_clr_nand_int);
+
+/**
+ * xsmcps_set_ecc_mode - Set SMC ECC mode
+ * @mode:	ECC mode (BYPASS, APB, MEM)
+ * Returns 0 on success or negative errno.
+ */
+int xsmcps_set_ecc_mode(enum xsmcps_ecc_mode mode)
+{
+	u32 reg;
+	unsigned long flags;
+	int ret = 0;
+
+	switch (mode) {
+	case XSMCPS_ECCMODE_BYPASS:
+	case XSMCPS_ECCMODE_APB:
+	case XSMCPS_ECCMODE_MEM:
+		spin_lock_irqsave(&xsmcps_lock, flags);
+
+		reg = readl(xsmcps_base + XSMCPS_ECC_MEMCFG_OFFS);
+		reg &= ~0xc;
+		reg |= mode << 2;
+		writel(reg, xsmcps_base + XSMCPS_ECC_MEMCFG_OFFS);
+
+		spin_unlock_irqrestore(&xsmcps_lock, flags);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(xsmcps_set_ecc_mode);
+
+/**
+ * xsmcps_set_ecc_pg_size - Set SMC ECC page size
+ * @pg_sz:	ECC page size
+ * Returns 0 on success or negative errno.
+ */
+int xsmcps_set_ecc_pg_size(unsigned int pg_sz)
+{
+	u32 reg, sz;
+	unsigned long flags;
+
+	switch (pg_sz) {
+	case 0:
+		sz = 0;
+		break;
+	case 512:
+		sz = 1;
+		break;
+	case 1024:
+		sz = 2;
+		break;
+	case 2048:
+		sz = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	reg = readl(xsmcps_base + XSMCPS_ECC_MEMCFG_OFFS);
+	reg &= ~3;
+	reg |= sz;
+	writel(reg, xsmcps_base + XSMCPS_ECC_MEMCFG_OFFS);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xsmcps_set_ecc_pg_size);
+
+static int xsmcps_clk_notifier_cb(struct notifier_block *nb,
+				  unsigned long event, void *data)
+{
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/*
+		 * if a rate change is announced we need to check whether we can
+		 * run under the changed conditions
+		 */
+		/* fall through */
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int xsmcps_suspend(struct device *dev)
+{
+	struct xsmcps_data *xsmcps = dev_get_drvdata(dev);
+
+	clk_disable(xsmcps->devclk);
+	clk_disable(xsmcps->aperclk);
+
+	return 0;
+}
+
+static int xsmcps_resume(struct device *dev)
+{
+	int ret;
+	struct xsmcps_data *xsmcps = dev_get_drvdata(dev);
+
+	ret = clk_enable(xsmcps->aperclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable APER clock.\n");
+		return ret;
+	}
+
+	ret = clk_enable(xsmcps->devclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable device clock.\n");
+		clk_disable(xsmcps->aperclk);
+		return ret;
+	}
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(xsmcps_dev_pm_ops, xsmcps_suspend, xsmcps_resume);
+
+/**
+ * xsmcps_init_nand_interface - Initialize the NAND interface
+ * @pdev:	Pointer to the platform_device struct
+ * @nand_node:	Pointer to the xnandps device_node struct
+ */
+static void xsmcps_init_nand_interface(struct platform_device *pdev,
+				       struct device_node *nand_node)
+{
+	u32 t_rc, t_wc, t_rea, t_wp, t_clr, t_ar, t_rr;
+	unsigned int bw;
+	int err;
+	unsigned long flags;
+
+	err = of_property_read_u32(nand_node, "xlnx,nand-width", &bw);
+	if (err) {
+		dev_warn(&pdev->dev,
+			 "xlnx,nand-width not in device tree, using 8");
+		bw = 8;
+	}
+	/* nand-cycle-<X> property is refer to the NAND flash timing
+	 * mapping between dts and the NAND flash AC timing
+	 *  X  : AC timing name
+	 *  t0 : t_rc
+	 *  t1 : t_wc
+	 *  t2 : t_rea
+	 *  t3 : t_wp
+	 *  t4 : t_clr
+	 *  t5 : t_ar
+	 *  t6 : t_rr
+	 */
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t0", &t_rc);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t0 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t1", &t_wc);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t1 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t2", &t_rea);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t2 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t3", &t_wp);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t3 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t4", &t_clr);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t4 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t5", &t_ar);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t5 not in device tree");
+		goto default_nand_timing;
+	}
+	err = of_property_read_u32(nand_node, "xlnx,nand-cycle-t6", &t_rr);
+	if (err) {
+		dev_warn(&pdev->dev, "xlnx,nand-cycle-t6 not in device tree");
+		goto default_nand_timing;
+	}
+
+default_nand_timing:
+	if (err) {
+		/* set default NAND flash timing property */
+		dev_warn(&pdev->dev, "Using default timing for");
+		dev_warn(&pdev->dev, "2Gb Numonyx MT29F2G08ABAEAWP NAND flash");
+		dev_warn(&pdev->dev, "t_wp, t_clr, t_ar are set to 4");
+		dev_warn(&pdev->dev, "t_rc, t_wc, t_rr are set to 2");
+		dev_warn(&pdev->dev, "t_rea is set to 1");
+		t_rc = t_wc = t_rr = 4;
+		t_rea = 1;
+		t_wp = t_clr = t_ar = 2;
+	}
+
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	if (xsmcps_set_buswidth(bw)) {
+		dev_warn(&pdev->dev, "xlnx,nand-width not valid, using 8");
+		xsmcps_set_buswidth(8);
+	}
+
+	/*
+	 * Default assume 50MHz clock (20ns cycle time) and 3V operation
+	 * The SET_CYCLES_REG register value depends on the flash device.
+	 * Look in to the device datasheet and change its value, This value
+	 * is for 2Gb Numonyx flash.
+	 */
+	xsmcps_set_cycles(t_rc, t_wc, t_rea, t_wp, t_clr, t_ar, t_rr);
+	writel(XSMCPS_CFG_CLR_INT_1, xsmcps_base + XSMCPS_CFG_CLR_OFFS);
+	writel(XSMCPS_DC_UPT_NAND_REGS, xsmcps_base + XSMCPS_DIRECT_CMD_OFFS);
+	/* Wait till the ECC operation is complete */
+	while (xsmcps_ecc_is_busy_noirq())
+		cpu_relax();
+	/* Set the command1 and command2 register */
+	writel(XNANDPS_ECC_CMD1, xsmcps_base + XSMCPS_ECC_MEMCMD1_OFFS);
+	writel(XNANDPS_ECC_CMD2, xsmcps_base + XSMCPS_ECC_MEMCMD2_OFFS);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+}
+
+static const struct of_device_id matches_nor[] = {
+	{ .compatible = "cfi-flash" },
+	{}
+};
+
+static const struct of_device_id matches_nand[] = {
+	{ .compatible = "xlnx,ps7-nand-1.00.a" },
+	{}
+};
+
+static int xsmcps_probe(struct platform_device *pdev)
+{
+	struct xsmcps_data *xsmcps;
+	struct device_node *child;
+	struct resource *res;
+	unsigned long flags;
+	int err;
+	struct device_node *of_node = pdev->dev.of_node;
+	const struct of_device_id *matches = NULL;
+
+	xsmcps = devm_kzalloc(&pdev->dev, sizeof(*xsmcps), GFP_KERNEL);
+	if (!xsmcps)
+		return -ENOMEM;
+
+	/* Get the NAND controller virtual address */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xsmcps_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xsmcps_base))
+		return PTR_ERR(xsmcps_base);
+
+	xsmcps->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+	if (IS_ERR(xsmcps->aperclk)) {
+		dev_err(&pdev->dev, "aper_clk clock not found.\n");
+		return PTR_ERR(xsmcps->aperclk);
+	}
+
+	xsmcps->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(xsmcps->devclk)) {
+		dev_err(&pdev->dev, "ref_clk clock not found.\n");
+		return PTR_ERR(xsmcps->devclk);
+	}
+
+	err = clk_prepare_enable(xsmcps->aperclk);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		return err;
+	}
+
+	err = clk_prepare_enable(xsmcps->devclk);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to enable device clock.\n");
+		goto out_clk_dis_aper;
+	}
+
+	platform_set_drvdata(pdev, xsmcps);
+
+	xsmcps->clk_rate_change_nb.notifier_call = xsmcps_clk_notifier_cb;
+	if (clk_notifier_register(xsmcps->devclk, &xsmcps->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+
+	/* clear interrupts */
+	spin_lock_irqsave(&xsmcps_lock, flags);
+
+	writel(0x52, xsmcps_base + XSMCPS_CFG_CLR_OFFS);
+
+	spin_unlock_irqrestore(&xsmcps_lock, flags);
+
+	/* Find compatible children. Only a single child is supported */
+	for_each_available_child_of_node(of_node, child) {
+		if (of_match_node(matches_nand, child)) {
+			xsmcps_init_nand_interface(pdev, child);
+			if (!matches) {
+				matches = matches_nand;
+			} else {
+				dev_err(&pdev->dev,
+					"incompatible configuration\n");
+				goto out_clk_disable;
+			}
+		}
+
+		if (of_match_node(matches_nor, child)) {
+			static int counts;
+			if (!matches) {
+				matches = matches_nor;
+			} else {
+				if (matches != matches_nor || counts > 1) {
+					dev_err(&pdev->dev,
+						"incompatible configuration\n");
+					goto out_clk_disable;
+				}
+			}
+			counts++;
+		}
+	}
+
+	if (matches)
+		of_platform_populate(of_node, matches, NULL, &pdev->dev);
+
+	return 0;
+
+out_clk_disable:
+	clk_disable_unprepare(xsmcps->devclk);
+out_clk_dis_aper:
+	clk_disable_unprepare(xsmcps->aperclk);
+
+	return err;
+}
+
+static int xsmcps_remove(struct platform_device *pdev)
+{
+	struct xsmcps_data *xsmcps = platform_get_drvdata(pdev);
+
+	clk_notifier_unregister(xsmcps->devclk, &xsmcps->clk_rate_change_nb);
+	clk_disable_unprepare(xsmcps->devclk);
+	clk_disable_unprepare(xsmcps->aperclk);
+
+	return 0;
+}
+
+/* Match table for device tree binding */
+static const struct of_device_id xsmcps_of_match[] = {
+	{ .compatible = "xlnx,ps7-smc" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, xsmcps_of_match);
+
+static struct platform_driver xsmcps_driver = {
+	.probe		= xsmcps_probe,
+	.remove		= xsmcps_remove,
+	.driver		= {
+		.name	= "xsmcps",
+		.owner	= THIS_MODULE,
+		.pm	= &xsmcps_dev_pm_ops,
+		.of_match_table = xsmcps_of_match,
+	},
+};
+
+module_platform_driver(xsmcps_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx PS SMC Driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/misc/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/misc/Kconfig	2014-07-20 22:05:50.242066522 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/misc/Kconfig	2014-07-20 22:06:36.701300027 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:549 @
 	  stereo and mono audio, video, microphone and UART data to use
 	  a common connector port.
 
+config SI570
+	tristate "Silicon Labs Si570 Clock Generator"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here you get support for the Silicon Labs Si570
+	  digital clock generator.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called si570
+
 config LATTICE_ECP3_CONFIG
 	tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
 	depends on SPI && SYSFS
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:579 @
 	  the genalloc API. It is supposed to be used for small on-chip SRAM
 	  areas found on many SoCs.
 
+config XILINX_TRAFGEN
+	tristate "Xilinx Traffic Generator"
+	depends on MICROBLAZE
+	help
+	  This option enables support for the Xilinx Traffic Generator driver.
+	  It is designed to generate AXI4 traffic which can be used to stress
+	  different modules/interconnect connected in the system. Different
+	  configurable options which are provided through sysfs entries allow
+	  allow the user to generate a wide variety of traffic based on their
+	  their requirements.
+
+	  If unsure, say N
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/misc/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/misc/Makefile	2014-07-20 22:05:50.241066538 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/misc/Makefile	2014-07-20 22:06:36.711299862 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:53 @
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)		+= mei/
+obj-$(CONFIG_SI570)		+= si570.o
 obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_HWLAT_DETECTOR)	+= hwlat_detector.o
+obj-$(CONFIG_XILINX_TRAFGEN)	+= xilinx_trafgen.o
Index: linux-3.12.24-rt38-xilinx/drivers/misc/si570.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/misc/si570.c	2014-07-20 22:06:36.723299664 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
+ *
+ * Copyright (C) 2010, 2011 Ericsson AB.
+ * Copyright (C) 2011 Guenter Roeck.
+ *
+ * Author: Guenter Roeck <guenter.roeck@ericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include <linux/i2c/si570.h>
+
+/* Si570 registers */
+#define SI570_REG_HS_N1		7
+#define SI570_REG_N1_RFREQ0	8
+#define SI570_REG_RFREQ1	9
+#define SI570_REG_RFREQ2	10
+#define SI570_REG_RFREQ3	11
+#define SI570_REG_RFREQ4	12
+#define SI570_REG_CONTROL	135
+#define SI570_REG_FREEZE_DCO	137
+
+#define HS_DIV_SHIFT		5
+#define HS_DIV_MASK		0xe0
+#define HS_DIV_OFFSET		4
+#define N1_6_2_MASK		0x1f
+#define N1_1_0_MASK		0xc0
+#define RFREQ_37_32_MASK	0x3f
+
+#define SI570_FOUT_FACTORY_DFLT	156250000LL
+#define SI598_FOUT_FACTORY_DFLT	10000000LL
+
+#define SI570_MIN_FREQ		10000000L
+#define SI570_MAX_FREQ		1417500000L
+#define SI598_MAX_FREQ		525000000L
+
+#define FDCO_MIN		4850000000LL
+#define FDCO_MAX		5670000000LL
+#define FDCO_CENTER		((FDCO_MIN + FDCO_MAX) / 2)
+
+#define SI570_CNTRL_RECALL	(1 << 0)
+#define SI570_CNTRL_FREEZE_ADC	(1 << 4)
+#define SI570_CNTRL_FREEZE_M	(1 << 5)
+#define SI570_CNTRL_NEWFREQ	(1 << 6)
+#define SI570_CNTRL_RESET	(1 << 7)
+
+#define SI570_FREEZE_DCO	(1 << 4)
+#define SI570_UNFREEZE_DCO	0xEF
+
+struct si570_data {
+	struct attribute_group attrs;
+	struct mutex lock;
+	u64 max_freq;
+	u64 fout;		/* Factory default frequency */
+	u64 fxtal;		/* Factory xtal frequency */
+	unsigned int n1;
+	unsigned int hs_div;
+	u64 rfreq;
+	u64 frequency;
+};
+
+
+static struct i2c_client *si570_client;
+
+
+static int si570_get_defaults(struct i2c_client *client)
+{
+	struct si570_data *data = i2c_get_clientdata(client);
+	int reg1, reg2, reg3, reg4, reg5, reg6;
+	u64 fdco;
+
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_RECALL);
+
+	reg1 = i2c_smbus_read_byte_data(client, SI570_REG_HS_N1);
+	if (reg1 < 0)
+		return reg1;
+	reg2 = i2c_smbus_read_byte_data(client, SI570_REG_N1_RFREQ0);
+	if (reg2 < 0)
+		return reg2;
+	reg3 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ1);
+	if (reg3 < 0)
+		return reg3;
+	reg4 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ2);
+	if (reg4 < 0)
+		return reg4;
+	reg5 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ3);
+	if (reg5 < 0)
+		return reg5;
+	reg6 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ4);
+	if (reg6 < 0)
+		return reg6;
+
+	data->hs_div = ((reg1 & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
+	data->n1 = ((reg1 & N1_6_2_MASK) << 2) + ((reg2 & N1_1_0_MASK) >> 6)
+	  + 1;
+	/* Handle invalid cases */
+	if (data->n1 > 1)
+		data->n1 &= ~1;
+
+	data->rfreq = reg2 & RFREQ_37_32_MASK;
+	data->rfreq = (data->rfreq << 8) + reg3;
+	data->rfreq = (data->rfreq << 8) + reg4;
+	data->rfreq = (data->rfreq << 8) + reg5;
+	data->rfreq = (data->rfreq << 8) + reg6;
+
+	/*
+	 * Accept optional precision loss to avoid arithmetic overflows.
+	 * Acceptable per Silicon Labs Application Note AN334.
+	 */
+	fdco = data->fout * data->n1 * data->hs_div;
+	if (fdco >= (1LL << 36))
+		data->fxtal = div64_u64((fdco << 24), (data->rfreq >> 4));
+	else
+		data->fxtal = div64_u64((fdco << 28), data->rfreq);
+
+	data->frequency = data->fout;
+
+	return 0;
+}
+
+/*
+ * Update rfreq registers
+ * This function must be called with update mutex lock held.
+ */
+static void si570_update_rfreq(struct i2c_client *client,
+			       struct si570_data *data)
+{
+	int status;
+	status = i2c_smbus_write_byte_data(client, SI570_REG_N1_RFREQ0,
+				  ((data->n1 - 1) << 6)
+				  | ((data->rfreq >> 32) & RFREQ_37_32_MASK));
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_N1_RFREQ0: %d\n",
+			(((data->n1 - 1) << 6) | ((data->rfreq >> 32) &
+			RFREQ_37_32_MASK)) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ1,
+				  (data->rfreq >> 24) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ1: %d\n",
+			(data->rfreq >> 24) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ2,
+				  (data->rfreq >> 16) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ2: %d\n",
+			(data->rfreq >> 16) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ3,
+				  (data->rfreq >> 8) & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ3: %d\n",
+			(data->rfreq >> 8) & 0xff, status);
+	status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ4,
+				  data->rfreq & 0xff);
+	if (status < 0)
+		dev_err(&client->dev,
+			"unable to write 0x%llX to REG_RFREQ4: %d\n",
+			data->rfreq & 0xff, status);
+}
+
+/*
+ * Update si570 frequency for small frequency changes (< 3,500 ppm)
+ * This function must be called with update mutex lock held.
+ */
+static int si570_set_frequency_small(struct i2c_client *client,
+				     struct si570_data *data,
+				     unsigned long frequency)
+{
+	data->frequency = frequency;
+	/* This is a re-implementation of DIV_ROUND_CLOSEST
+	 * using the div64_u64 function lieu of letting the compiler
+	 * insert EABI calls
+	 */
+	data->rfreq = div64_u64((data->rfreq * frequency) +
+		div64_u64(data->frequency, 2), data->frequency);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_FREEZE_M);
+	si570_update_rfreq(client, data);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL, 0);
+
+	return 0;
+}
+
+static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
+
+/*
+ * Set si570 frequency.
+ * This function must be called with update mutex lock held.
+ */
+static int si570_set_frequency(struct i2c_client *client,
+			       struct si570_data *data,
+			       unsigned long frequency)
+{
+	int i, n1, hs_div;
+	u64 fdco, best_fdco = ULLONG_MAX;
+
+	for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
+		hs_div = si570_hs_div_values[i];
+		/* Calculate lowest possible value for n1 */
+		n1 = div64_u64(div64_u64(FDCO_MIN, (u64)hs_div),
+			(u64)frequency);
+		if (!n1 || (n1 & 1))
+			n1++;
+		while (n1 <= 128) {
+			fdco = (u64)frequency * (u64)hs_div * (u64)n1;
+			if (fdco > FDCO_MAX)
+				break;
+			if (fdco >= FDCO_MIN && fdco < best_fdco) {
+				data->n1 = n1;
+				data->hs_div = hs_div;
+				data->frequency = frequency;
+				data->rfreq = div64_u64((fdco << 28),
+					data->fxtal);
+				best_fdco = fdco;
+			}
+			n1 += (n1 == 1 ? 1 : 2);
+		}
+	}
+	if (best_fdco == ULLONG_MAX) {
+		dev_err(&client->dev, "error - best FDCO is out of range\n");
+		return -EINVAL;
+	}
+
+	/* The DCO reg should be accessed with a read-modify-write operation
+	 * per AN334
+	 */
+	i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
+				  SI570_FREEZE_DCO);
+	i2c_smbus_write_byte_data(client, SI570_REG_HS_N1,
+				  ((data->hs_div - HS_DIV_OFFSET) <<
+				   HS_DIV_SHIFT)
+				  | (((data->n1 - 1) >> 2) & N1_6_2_MASK));
+	si570_update_rfreq(client, data);
+	i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
+				  0);
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_NEWFREQ);
+	return 0;
+}
+
+/*
+ * Reset chip.
+ * This function must be called with update mutex lock held.
+ */
+static int si570_reset(struct i2c_client *client, struct si570_data *data)
+{
+	i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
+				  SI570_CNTRL_RESET);
+	usleep_range(1000, 5000);
+	return si570_set_frequency(client, data, data->frequency);
+}
+
+static ssize_t show_frequency_attr(struct device *dev,
+			      struct device_attribute *devattr,
+			      char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+
+	return sprintf(buf, "%llu\n", data->frequency);
+}
+
+int get_frequency_si570(struct device *dev, unsigned long *freq)
+{
+	int err;
+	char buf[10+1];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	show_frequency_attr(dev, NULL, buf);
+
+	err = strict_strtoul(buf, 10, freq);
+	if (err)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(get_frequency_si570);
+
+static ssize_t set_frequency_attr(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (val < SI570_MIN_FREQ || val > data->max_freq) {
+		dev_err(&client->dev,
+			"requested frequency %lu Hz is out of range\n", val);
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->lock);
+
+	if (div64_u64(abs(val - data->frequency) * 10000LL,
+		data->frequency) < 35)
+		err = si570_set_frequency_small(client, data, val);
+	else
+		err = si570_set_frequency(client, data, val);
+	mutex_unlock(&data->lock);
+	if (err) {
+		dev_warn(&client->dev,
+			"unable to set output frequency %lu Hz: %d\n",
+			val, err);
+		return err;
+	}
+
+	dev_info(&client->dev,
+		"set new output frequency %lu Hz\n", val);
+
+	return count;
+}
+
+int set_frequency_si570(struct device *dev, unsigned long freq)
+{
+	char buf[10+1];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	sprintf(buf, "%lu", freq);
+
+	return set_frequency_attr(dev, NULL, buf,  0);
+}
+EXPORT_SYMBOL(set_frequency_si570);
+
+static ssize_t show_reset_attr(struct device *dev,
+			  struct device_attribute *devattr,
+			  char *buf)
+{
+	return sprintf(buf, "%d\n", 0);
+}
+
+static ssize_t set_reset_attr(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct si570_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val == 0)
+		goto done;
+
+	mutex_lock(&data->lock);
+	err = si570_reset(client, data);
+	mutex_unlock(&data->lock);
+	if (err)
+		return err;
+done:
+	return count;
+}
+
+int reset_si570(struct device *dev, int id)
+{
+	char buf[4];
+
+	if ((!dev) || (to_i2c_client(dev) != si570_client))
+		return -EINVAL;
+
+	sprintf(buf, "%lu", (unsigned long)id);
+	return set_reset_attr(dev, NULL, buf, 0);
+}
+EXPORT_SYMBOL(reset_si570);
+
+struct i2c_client *get_i2c_client_si570(void)
+{
+	return si570_client;
+}
+EXPORT_SYMBOL(get_i2c_client_si570);
+
+static DEVICE_ATTR(frequency, S_IWUSR | S_IRUGO, show_frequency_attr, set_frequency_attr);
+static DEVICE_ATTR(reset, S_IWUSR | S_IRUGO, show_reset_attr, set_reset_attr);
+
+static struct attribute *si570_attr[] = {
+	&dev_attr_frequency.attr,
+	&dev_attr_reset.attr,
+	NULL
+};
+
+static const struct i2c_device_id si570_id[] = {
+	{ "si570", 0 },
+	{ "si571", 0 },
+	{ "si598", 1 },
+	{ "si599", 1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, si570_id);
+
+static int si570_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
+{
+	struct si570_platform_data *pdata = client->dev.platform_data;
+	struct si570_data *data;
+	int err;
+	unsigned long initial_fout;
+	u32 tmp = SI570_FOUT_FACTORY_DFLT;
+
+	data = kzalloc(sizeof(struct si570_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	if (id->driver_data) {
+		data->fout = SI598_FOUT_FACTORY_DFLT;
+		data->max_freq = SI598_MAX_FREQ;
+	} else {
+		data->fout = SI570_FOUT_FACTORY_DFLT;
+		data->max_freq = SI570_MAX_FREQ;
+	}
+
+	if (pdata && pdata->factory_fout)
+		data->fout = pdata->factory_fout;
+
+	if (client->dev.of_node &&
+		(of_property_read_u32(client->dev.of_node, "factory-fout",
+			&tmp) < 0))
+		dev_warn(&client->dev,
+			"DTS does not contain factory-fout, using default\n");
+	else
+		data->fout = tmp;
+
+	i2c_set_clientdata(client, data);
+	err = si570_get_defaults(client);
+	if (err < 0)
+		goto exit_free;
+
+	mutex_init(&data->lock);
+
+	/* Register sysfs hooks */
+	data->attrs.attrs = si570_attr;
+	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+	if (err)
+		goto exit_free;
+
+	/* Display a message indicating that we've successfully registered */
+	dev_info(&client->dev,
+		"registered %s with default frequency %llu Hz\n",
+		id->name, data->fout);
+
+	/* Read the requested initial fout from either platform data or the
+	 * device tree
+	 */
+	initial_fout = 0;
+	if (pdata && pdata->initial_fout) {
+		initial_fout = pdata->initial_fout;
+	}
+	if (client->dev.of_node) {
+		of_property_read_u32(client->dev.of_node, "initial-fout",
+			(u32 *)&initial_fout);
+		if (pdata && pdata->initial_fout &&
+			(pdata->initial_fout != initial_fout)) {
+			dev_warn(&client->dev,
+				"OF initial fout %lu overrides platform data fout %lu\n",
+				initial_fout,
+				pdata->initial_fout);
+		}
+	}
+
+	if (initial_fout != 0) {
+		if (initial_fout < SI570_MIN_FREQ ||
+			initial_fout > data->max_freq) {
+			dev_err(&client->dev,
+				"requested initial frequency %lu is out of range, using default\n",
+				initial_fout);
+			return 0;
+		}
+
+		mutex_lock(&data->lock);
+
+		if (div64_u64(abs(initial_fout - data->frequency) *
+			10000LL, data->frequency) < 35)
+			err = si570_set_frequency_small(client, data,
+				initial_fout);
+		else
+			err = si570_set_frequency(client, data,
+				initial_fout);
+		mutex_unlock(&data->lock);
+		if (err) {
+			dev_warn(&client->dev,
+				"unable to set initial output frequency %lu: %d\n",
+				initial_fout, err);
+			return err;
+		}
+
+		dev_info(&client->dev,
+			"set initial output frequency %lu Hz\n",
+			initial_fout);
+	}
+
+	si570_client = client;
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int si570_remove(struct i2c_client *client)
+{
+	struct si570_data *data = i2c_get_clientdata(client);
+
+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
+	kfree(data);
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id i2c_si570_of_match[] = {
+	{ .compatible = "si570" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, i2c_si570_of_match);
+#endif
+
+static struct i2c_driver si570_driver = {
+	.driver = {
+		.name	= "si570",
+		.of_match_table = of_match_ptr(i2c_si570_of_match),
+	},
+	.probe		= si570_probe,
+	.remove		= si570_remove,
+	.id_table	= si570_id,
+};
+
+static int __init si570_init(void)
+{
+	return i2c_add_driver(&si570_driver);
+}
+
+static void __exit si570_exit(void)
+{
+	i2c_del_driver(&si570_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_DESCRIPTION("Si570 driver");
+MODULE_LICENSE("GPL");
+
+module_init(si570_init);
+module_exit(si570_exit);
Index: linux-3.12.24-rt38-xilinx/drivers/misc/xilinx_trafgen.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/misc/xilinx_trafgen.c	2014-07-20 22:06:36.741299367 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI Traffic Generator
+ *
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * Description:
+ * This driver is developed for AXI Traffic Generator IP, which is
+ * designed to generate AXI4 traffic which can be used to stress
+ * different modules/interconnect connected in the system. Different
+ * configurable options which are provided through sysfs entries
+ * allow the user to generate a wide variety of traffic based on
+ * their requirements.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Hw specific definitions */
+
+/* Internal RAM Offsets */
+#define XTG_PARAM_RAM_OFFSET	   0x1000  /* Parameter RAM offset */
+#define XTG_COMMAND_RAM_OFFSET	   0x8000  /* Command RAM offset */
+#define XTG_MASTER_RAM_INIT_OFFSET 0x10000 /* Master RAM initial offset(v1.0) */
+#define XTG_MASTER_RAM_OFFSET	   0xc000  /* Master RAM offset */
+
+/* Register Offsets */
+#define XTG_MCNTL_OFFSET	0x00	/* Master control */
+#define XTG_SCNTL_OFFSET	0x04	/* Slave control */
+#define XTG_ERR_STS_OFFSET	0x08	/* Error status  */
+#define XTG_ERR_EN_OFFSET	0x0C	/* Error enable */
+#define XTG_MSTERR_INTR_OFFSET	0x10	/* Master error interrupt enable */
+#define XTG_CFG_STS_OFFSET	0x14	/* Config status */
+#define XTG_STREAM_CNTL_OFFSET	0x30	/* Streaming Control */
+#define XTG_STREAM_TL_OFFSET	0x38    /* Streaming Transfer Length */
+#define XTG_STATIC_CNTL_OFFSET	0x60	/* Static Control */
+#define XTG_STATIC_LEN_OFFSET	0x64	/* Static Length */
+
+/* Register Bitmasks/shifts */
+
+/* Master logic enable */
+#define XTG_MCNTL_MSTEN_MASK		0x00100000
+/* Slave error interrupt enable */
+#define XTG_SCNTL_ERREN_MASK		0x00008000
+/* Master complete interrupt enable */
+#define XTG_ERR_EN_MSTIRQEN_MASK	0x80000000
+/* Master error interrupt enable */
+#define XTG_MSTERR_INTR_MINTREN_MASK	0x00008000
+/* Master complete done status */
+#define XTG_ERR_STS_MSTDONE_MASK	0x80000000
+/* Error mask for error status/enable registers */
+#define XTG_ERR_ALL_ERRS_MASK		0x001F0003
+/* Core Revision shift */
+#define XTG_MCNTL_REV_SHIFT		24
+
+/* Axi Traffic Generator Command RAM Entry field mask/shifts */
+
+/* Command RAM entry masks */
+#define XTG_LEN_MASK		0xFF		/* Driven to a*_len line  */
+#define XTG_LOCK_MASK		0x1		/* Driven to a*_lock line */
+#define XTG_BURST_MASK		0x3		/* Driven to a*_burst line */
+#define XTG_SIZE_MASK		0x7		/* Driven to a*_size line */
+#define XTG_ID_MASK		0x1F		/* Driven to a*_id line */
+#define XTG_PROT_MASK		0x7		/* Driven to a*_prot line */
+#define XTG_LAST_ADDR_MASK	0x7		/* Last address */
+#define XTG_VALID_CMD_MASK	0x1		/* Valid Command */
+#define XTG_MSTRAM_INDEX_MASK	0x1FFF		/* Master RAM Index */
+#define XTG_OTHER_DEPEND_MASK	0x1FF		/* Other depend Command no */
+#define XTG_MY_DEPEND_MASK	0x1FF		/* My depend command no */
+#define XTG_QOS_MASK		0xF		/* Driven to a*_qos line */
+#define XTG_USER_MASK		0xFF		/* Driven to a*_user line */
+#define XTG_CACHE_MASK		0xF		/* Driven to a*_cache line */
+#define XTG_EXPECTED_RESP_MASK	0x7		/* Expected response */
+
+/* Command RAM entry shift values */
+#define XTG_LEN_SHIFT		0		/* Driven to a*_len line  */
+#define XTG_LOCK_SHIFT		8		/* Driven to a*_lock line */
+#define XTG_BURST_SHIFT		10		/* Driven to a*_burst line */
+#define XTG_SIZE_SHIFT		12		/* Driven to a*_size line */
+#define XTG_ID_SHIFT		15		/* Driven to a*_id line */
+#define XTG_PROT_SHIFT		21		/* Driven to a*_prot line */
+#define XTG_LAST_ADDR_SHIFT	28		/* Last address */
+#define XTG_VALID_CMD_SHIFT	31		/* Valid Command */
+#define XTG_MSTRAM_INDEX_SHIFT	0		/* Master RAM Index */
+#define XTG_OTHER_DEPEND_SHIFT	13		/* Other depend cmd num */
+#define XTG_MY_DEPEND_SHIFT	22		/* My depend cmd num */
+#define XTG_QOS_SHIFT		16		/* Driven to a*_qos line */
+#define XTG_USER_SHIFT		5		/* Driven to a*_user line */
+#define XTG_CACHE_SHIFT		4		/* Driven to a*_cache line */
+#define XTG_EXPECTED_RESP_SHIFT	0		/* Expected response */
+
+/* Axi Traffic Generator Parameter RAM Entry field mask/shifts */
+
+/* Parameter RAM Entry field shift values */
+#define XTG_PARAM_ADDRMODE_SHIFT	24	/* Address mode */
+#define XTG_PARAM_INTERVALMODE_SHIFT	26	/* Interval mode */
+#define XTG_PARAM_IDMODE_SHIFT		28	/* Id mode */
+#define XTG_PARAM_OP_SHIFT		29	/* Opcode */
+
+/* PARAM RAM Opcode shift values */
+#define XTG_PARAM_COUNT_SHIFT		0	/* Repeat/Delay count */
+#define XTG_PARAM_DELAYRANGE_SHIFT	0	/* Delay range */
+#define XTG_PARAM_DELAY_SHIFT		8	/* FIXED RPT delay count */
+#define XTG_PARAM_ADDRRANGE_SHIFT	20	/* Address range */
+
+/* Parameter RAM Entry field mask values */
+#define XTG_PARAM_ADDRMODE_MASK		0x3	/* Address mode */
+#define XTG_PARAM_INTERVALMODE_MASK	0x3	/* Interval mode */
+#define XTG_PARAM_IDMODE_MASK		0x1	/* Id mode */
+#define XTG_PARAM_OP_MASK		0x7	/* Opcode */
+
+/* PARAM RAM Opcode mask values */
+#define XTG_PARAM_COUNT_MASK		0xFFFFFF/* Repeat/Delay count */
+#define XTG_PARAM_DELAYRANGE_MASK	0xFF	/* Delay range */
+#define XTG_PARAM_DELAY_MASK		0xFFF	/* FIXED RPT delay count */
+#define XTG_PARAM_ADDRRANGE_MASK	0xF	/* Address range */
+
+/* PARAM RAM Opcode values */
+#define XTG_PARAM_OP_NOP		0x0	/* NOP mode */
+#define XTG_PARAM_OP_RPT		0x1	/* Repeat mode */
+#define XTG_PARAM_OP_DELAY		0x2	/* Delay mode */
+#define XTG_PARAM_OP_FIXEDRPT		0x3	/* Fixed repeat delay */
+
+/* Axi Traffic Generator Static Mode masks */
+#define XTG_STATIC_CNTL_TD_MASK		0x00000002	/* Transfer Done Mask */
+#define XTG_STATIC_CNTL_STEN_MASK	0x00000001	/* Static Enable Mask */
+#define XTG_STATIC_CNTL_RESET_MASK	0x00000000	/* Static Reset Mask */
+
+/* Axi Traffic Generator Stream Mode mask/shifts */
+#define XTG_STREAM_CNTL_STEN_MASK   0x00000001	/* Stream Enable Mask */
+#define XTG_STREAM_TL_TCNT_MASK	    0xFFFF0000	/* Transfer Count Mask */
+#define XTG_STREAM_TL_TLEN_MASK	    0x0000FFFF	/* Transfer Length Mask */
+#define XTG_STREAM_TL_TCNT_SHIFT    16		/* Transfer Count Shift */
+
+/* Driver Specific Definitions */
+
+#define MAX_NUM_ENTRIES	256	/* Number of command entries per region */
+
+#define VALID_SIG	0xa5a5a5a5	/* Valid unique identifier */
+
+/* Internal RAM Sizes */
+#define XTG_PRM_RAM_BLOCK_SIZE	0x400	/* PRAM Block size (1KB) */
+#define XTG_CMD_RAM_BLOCK_SIZE	0x1000	/* CRAM Block size (4KB) */
+#define XTG_PARAM_RAM_SIZE	0x800	/* Parameter RAM (2KB) */
+#define XTG_COMMAND_RAM_SIZE	0x2000	/* Command RAM (8KB) */
+#define XTG_MASTER_RAM_SIZE	0x2000	/* Master RAM (8KB) */
+
+/* RAM Access Flags */
+#define XTG_READ_RAM		0x0	/* Read RAM flag */
+#define XTG_WRITE_RAM		0x1	/* Write RAM flag */
+#define XTG_WRITE_RAM_ZERO	0x2	/* Write Zero flag */
+
+/* Bytes per entry */
+#define XTG_CRAM_BYTES_PER_ENTRY	16 /* CRAM bytes per entry */
+#define XTG_PRAM_BYTES_PER_ENTRY	4  /* PRAM bytes per entry */
+
+/* Interrupt Definitions */
+#define XTG_MASTER_CMP_INTR	0x1	/* Master complete intr flag */
+#define XTG_MASTER_ERR_INTR	0x2	/* Master error intr flag */
+#define XTG_SLAVE_ERR_INTR	0x4	/* Slave error intr flag */
+
+/*
+ * Version value of the trafgen core.
+ * For the initial IP release the version(v1.0) value is 0x47
+ * From the v2.0 IP and onwards the value starts from  0x20.
+ * For eg:
+ * v2.1 -> 0x21
+ * v2.2 -> 0x22 ... so on.
+ *
+ */
+#define XTG_INIT_VERSION	0x47	/* Trafgen initial version(v1.0) */
+
+/* Macro */
+#define to_xtg_dev_info(n)	((struct xtg_dev_info *)dev_get_drvdata(n))
+
+/**
+ * struct xtg_cram - Command RAM structure
+ * @addr: Address Driven to a*_addr line
+ * @valid_cmd: Valid Command
+ * @last_addr: Last address
+ * @prot: Driven to a*_prot line
+ * @id: Driven to a*_id line
+ * @size: Driven to a*_size line
+ * @burst: Driven to a*_burst line
+ * @lock: Driven to a*_lock line
+ * @length: Driven to a*_len line
+ * @my_dpnd: My Depend command number
+ * @other_dpnd: Other depend command number
+ * @mram_idx: Master RAM index
+ * @qos: Driven to a*_qos line
+ * @user: Driven to a*_user line
+ * @cache: Driven to a*_cache line
+ * @expected_resp: Expected response
+ * @index: Command Index
+ * @is_write_block: Write/Read block
+ * @is_valid_req: Unique signature
+ *
+ * FIXME: This structure is shared with the user application and
+ * hence need to be synchronized. We know these kind of structures
+ * should not be defined in the driver and this need to be fixed
+ * if found a proper placeholder (in uapi/).
+ */
+struct xtg_cram {
+	u32 addr;
+	u32 valid_cmd;
+	u32 last_addr;
+	u32 prot;
+	u32 id;
+	u32 size;
+	u32 burst;
+	u32 lock;
+	u32 length;
+	u32 my_dpnd;
+	u32 other_dpnd;
+	u32 mram_idx;
+	u32 qos;
+	u32 user;
+	u32 cache;
+	u32 expected_resp;
+	u16 index;
+	bool is_write_block;
+	u32 is_valid_req;
+};
+
+/**
+ * struct xtg_pram - Parameter RAM structure
+ * @op_cntl0: Control field 0
+ * @op_cntl1: Control field 1
+ * @op_cntl2: Control field 2
+ * @addr_mode: Address mode
+ * @interval_mode: Interval mode
+ * @id_mode: Id mode
+ * @opcode: Opcode
+ * @index: Command Index
+ * @is_write_block: Write/Read block
+ * @is_valid_req: Unique signature
+ *
+ * FIXME: This structure is shared with the user application and
+ * hence need to be synchronized. We know these kind of structures
+ * should not be defined in the driver and this need to be fixed
+ * if found a proper placeholder (in uapi/).
+ */
+struct xtg_pram {
+	u32 op_cntl0;
+	u32 op_cntl1;
+	u32 op_cntl2;
+	u32 addr_mode;
+	u32 interval_mode;
+	u32 id_mode;
+	u32 opcode;
+	u16 index;
+	bool is_write_block;
+	u32 is_valid_req;
+};
+
+/**
+ * struct xtg_dev_info - Global Driver structure
+ * @regs: Iomapped base address
+ * @dev: Device structure
+ * @phys_base_addr: Physical base address
+ * @last_rd_valid_idx: Last Read Valid Command Index
+ * @last_wr_valid_idx: Last Write Valid Command Index
+ * @id: Device instance id
+ * @xtg_mram_offset: MasterRam offset
+ */
+struct xtg_dev_info {
+	void __iomem *regs;
+	struct device *dev;
+	u32 phys_base_addr;
+	s16 last_rd_valid_idx;
+	s16 last_wr_valid_idx;
+	u32 id;
+	u32 xtg_mram_offset;
+};
+
+/**
+ * enum xtg_sysfs_ioctl - Ioctl opcodes
+ * @XTG_GET_MASTER_CMP_STS: get master complete status
+ * @XTG_GET_SLV_CTRL_REG: get slave control reg status
+ * @XTG_GET_ERR_STS: get error status
+ * @XTG_GET_CFG_STS: get config status
+ * @XTG_GET_LAST_VALID_INDEX: get last valid index
+ * @XTG_GET_DEVICE_ID: get device id
+ * @XTG_GET_RESOURCE: get resource
+ * @XTG_GET_STATIC_ENABLE: get staic mode traffic genration state
+ * @XTG_GET_STATIC_BURSTLEN: get static mode burst length
+ * @XTG_GET_STATIC_TRANSFERDONE: get static transfer done
+ * @XTG_GET_STREAM_ENABLE : get strean mode traffic genration state
+ * @XTG_GET_STREAM_TRANSFERLEN: get streaming mode transfer length
+ * @XTG_GET_STREAM_TRANSFERCNT: get streaming mode transfer count
+ * @XTG_START_MASTER_LOGIC: start master logic
+ * @XTG_SET_SLV_CTRL_REG: set slave control
+ * @XTG_CLEAR_ERRORS: clear errors
+ * @XTG_ENABLE_ERRORS: enable errors
+ * @XTG_ENABLE_INTRS: enable interrupts
+ * @XTG_CLEAR_MRAM: clear master ram
+ * @XTG_CLEAR_CRAM: clear command ram
+ * @XTG_CLEAR_PRAM: clear parameter ram
+ * @XTG_SET_STATIC_ENABLE: enable static mode traffic genration
+ * @XTG_SET_STATIC_DISABLE: disable static mode traffic genration
+ * @XTG_SET_STATIC_BURSTLEN: set static mode burst length
+ * @XTG_SET_STATIC_TRANSFERDONE: set static transfer done
+ * @XTG_SET_STREAM_ENABLE: enable streaming mode traffic genration
+ * @XTG_SET_STREAM_DISABLE: disable streaming mode traffic genration
+ * @XTG_SET_STREAM_TRANSFERLEN: set streaming mode transfer length
+ * @XTG_SET_STREAM_TRANSFERCNT: set streaming mode transfer count
+ */
+enum xtg_sysfs_ioctl_opcode {
+	XTG_GET_MASTER_CMP_STS,
+	XTG_GET_SLV_CTRL_REG,
+	XTG_GET_ERR_STS,
+	XTG_GET_CFG_STS,
+	XTG_GET_LAST_VALID_INDEX,
+	XTG_GET_DEVICE_ID,
+	XTG_GET_RESOURCE,
+	XTG_GET_STATIC_ENABLE,
+	XTG_GET_STATIC_BURSTLEN,
+	XTG_GET_STATIC_TRANSFERDONE,
+	XTG_GET_STREAM_ENABLE,
+	XTG_GET_STREAM_TRANSFERLEN,
+	XTG_GET_STREAM_TRANSFERCNT,
+	XTG_START_MASTER_LOGIC,
+	XTG_SET_SLV_CTRL_REG,
+	XTG_CLEAR_ERRORS,
+	XTG_ENABLE_ERRORS,
+	XTG_ENABLE_INTRS,
+	XTG_CLEAR_MRAM,
+	XTG_CLEAR_CRAM,
+	XTG_CLEAR_PRAM,
+	XTG_SET_STATIC_ENABLE,
+	XTG_SET_STATIC_DISABLE,
+	XTG_SET_STATIC_BURSTLEN,
+	XTG_SET_STATIC_TRANSFERDONE,
+	XTG_SET_STREAM_ENABLE,
+	XTG_SET_STREAM_DISABLE,
+	XTG_SET_STREAM_TRANSFERLEN,
+	XTG_SET_STREAM_TRANSFERCNT
+};
+
+/**
+ * xtg_access_rams - Write/Read Master/Command/Parameter RAM
+ * @tg: Pointer to xtg_dev_info structure
+ * @where: Offset from base
+ * @count: Number of bytes to write/read
+ * @flags: Read/Write/Write Zero
+ * @data: Data pointer
+ */
+static void xtg_access_rams(struct xtg_dev_info *tg, int where,
+				int count, int flags, u32 *data)
+{
+	u32 index;
+
+	for (index = 0; count > 0; index++, count -= 4) {
+		if (flags) {
+			if (flags & XTG_WRITE_RAM_ZERO)
+				writel(0x0, tg->regs + where + index * 4);
+			else
+				writel(data[index],
+					tg->regs + where + index * 4);
+		} else {
+			data[index] = readl(tg->regs + where + index * 4);
+		}
+	}
+}
+
+/**
+ * xtg_prepare_cmd_words - Prepares all four Command RAM words
+ * @tg: Pointer to xtg_dev_info structure
+ * @cmdp: Pointer to xtg_cram structure
+ * @cmd_words: Pointer to Command Words that needs to be prepared
+ */
+static void xtg_prepare_cmd_words(struct xtg_dev_info *tg,
+				const struct xtg_cram *cmdp, u32 *cmd_words)
+{
+	/* Command Word 0 */
+	cmd_words[0] = cmdp->addr;
+
+	/* Command Word 1 */
+	cmd_words[1] = 0;
+	cmd_words[1] |= (cmdp->length & XTG_LEN_MASK) << XTG_LEN_SHIFT;
+	cmd_words[1] |= (cmdp->lock & XTG_LOCK_MASK) << XTG_LOCK_SHIFT;
+	cmd_words[1] |= (cmdp->burst & XTG_BURST_MASK) << XTG_BURST_SHIFT;
+	cmd_words[1] |= (cmdp->size & XTG_SIZE_MASK) << XTG_SIZE_SHIFT;
+	cmd_words[1] |= (cmdp->id & XTG_ID_MASK) << XTG_ID_SHIFT;
+	cmd_words[1] |= (cmdp->prot & XTG_PROT_MASK) << XTG_PROT_SHIFT;
+	cmd_words[1] |= (cmdp->last_addr & XTG_LAST_ADDR_MASK) <<
+					XTG_LAST_ADDR_SHIFT;
+	cmd_words[1] |= (cmdp->valid_cmd & XTG_VALID_CMD_MASK) <<
+					XTG_VALID_CMD_SHIFT;
+
+	/* Command Word 2 */
+	cmd_words[2] = 0;
+	cmd_words[2] |= (cmdp->mram_idx & XTG_MSTRAM_INDEX_MASK) <<
+					XTG_MSTRAM_INDEX_SHIFT;
+	cmd_words[2] |= (cmdp->other_dpnd & XTG_OTHER_DEPEND_MASK) <<
+					XTG_OTHER_DEPEND_SHIFT;
+	cmd_words[2] |= (cmdp->my_dpnd & XTG_MY_DEPEND_MASK) <<
+					XTG_MY_DEPEND_SHIFT;
+
+	/* Command Word 3 */
+	cmd_words[3] = 0;
+	cmd_words[3] |= (cmdp->qos & XTG_QOS_MASK) << XTG_QOS_SHIFT;
+	cmd_words[3] |= (cmdp->user & XTG_USER_MASK) << XTG_USER_SHIFT;
+	cmd_words[3] |= (cmdp->cache & XTG_CACHE_MASK) << XTG_CACHE_SHIFT;
+	cmd_words[3] |= (cmdp->expected_resp & XTG_EXPECTED_RESP_MASK) <<
+					XTG_EXPECTED_RESP_SHIFT;
+}
+
+/**
+ * xtg_prepare_param_words - Prepares Parameter RAM word
+ * @tg: Pointer to xtg_dev_info structure
+ * @cmdp: Pointer to xtg_pram structure
+ * @param_word: Pointer to Param Word that needs to be prepared
+ */
+static void xtg_prepare_param_word(struct xtg_dev_info *tg,
+			const struct xtg_pram *cmdp, u32 *param_word)
+{
+	*param_word = 0;
+	*param_word |= (cmdp->opcode & XTG_PARAM_OP_MASK) << XTG_PARAM_OP_SHIFT;
+	*param_word |= (cmdp->addr_mode & XTG_PARAM_ADDRMODE_MASK) <<
+					XTG_PARAM_ADDRMODE_SHIFT;
+	*param_word |= (cmdp->id_mode & XTG_PARAM_IDMODE_MASK) <<
+					XTG_PARAM_IDMODE_SHIFT;
+	*param_word |= (cmdp->interval_mode & XTG_PARAM_INTERVALMODE_MASK) <<
+					XTG_PARAM_INTERVALMODE_SHIFT;
+
+	switch (cmdp->opcode) {
+	case XTG_PARAM_OP_RPT:
+	case XTG_PARAM_OP_DELAY:
+		*param_word |= (cmdp->op_cntl0 & XTG_PARAM_COUNT_MASK) <<
+					XTG_PARAM_COUNT_SHIFT;
+		break;
+
+	case XTG_PARAM_OP_FIXEDRPT:
+		*param_word |= (cmdp->op_cntl0 & XTG_PARAM_ADDRRANGE_MASK) <<
+					XTG_PARAM_ADDRRANGE_SHIFT;
+		*param_word |= (cmdp->op_cntl1 & XTG_PARAM_DELAY_MASK) <<
+					XTG_PARAM_DELAY_SHIFT;
+		*param_word |= (cmdp->op_cntl2 & XTG_PARAM_DELAYRANGE_MASK) <<
+					XTG_PARAM_DELAYRANGE_SHIFT;
+		break;
+
+	case XTG_PARAM_OP_NOP:
+		*param_word = 0;
+		break;
+	}
+}
+
+/**
+ * xtg_sysfs_ioctl - Implements sysfs operations
+ * @dev: Device structure
+ * @buf: Value to write
+ * @opcode: Ioctl opcode
+ */
+static ssize_t xtg_sysfs_ioctl(struct device *dev, const char *buf,
+				enum xtg_sysfs_ioctl_opcode opcode)
+{
+	struct xtg_dev_info *tg = to_xtg_dev_info(dev);
+	unsigned long wrval;
+	ssize_t status, rdval = 0;
+
+	if (opcode > XTG_GET_STREAM_TRANSFERCNT) {
+		status = kstrtoul(buf, 16, &wrval);
+		if (status < 0)
+			return status;
+	}
+
+	switch (opcode) {
+	case XTG_GET_MASTER_CMP_STS:
+		rdval = (readl(tg->regs + XTG_MCNTL_OFFSET) &
+				XTG_MCNTL_MSTEN_MASK) ? 1 : 0;
+		break;
+
+	case XTG_GET_SLV_CTRL_REG:
+		rdval = readl(tg->regs + XTG_SCNTL_OFFSET);
+		break;
+
+	case XTG_GET_ERR_STS:
+		rdval = readl(tg->regs + XTG_ERR_STS_OFFSET) &
+				XTG_ERR_ALL_ERRS_MASK;
+		break;
+
+	case XTG_GET_CFG_STS:
+		rdval = readl(tg->regs + XTG_CFG_STS_OFFSET);
+		break;
+
+	case XTG_GET_LAST_VALID_INDEX:
+		rdval = (tg->last_wr_valid_idx << 16) |
+				tg->last_rd_valid_idx;
+		break;
+
+	case XTG_GET_DEVICE_ID:
+		rdval = tg->id;
+		break;
+
+	case XTG_GET_RESOURCE:
+		rdval = (unsigned long)tg->regs;
+		break;
+
+	case XTG_GET_STATIC_ENABLE:
+		rdval = readl(tg->regs + XTG_STATIC_CNTL_OFFSET);
+		break;
+
+	case XTG_GET_STATIC_BURSTLEN:
+		rdval = readl(tg->regs + XTG_STATIC_LEN_OFFSET);
+		break;
+
+	case XTG_GET_STATIC_TRANSFERDONE:
+		rdval = (readl(tg->regs + XTG_STATIC_CNTL_OFFSET) &
+				XTG_STATIC_CNTL_TD_MASK);
+		break;
+
+	case XTG_GET_STREAM_ENABLE:
+		rdval = readl(tg->regs + XTG_STREAM_CNTL_OFFSET);
+		break;
+
+	case XTG_GET_STREAM_TRANSFERLEN:
+		rdval = (readl(tg->regs + XTG_STREAM_TL_OFFSET) &
+				XTG_STREAM_TL_TLEN_MASK);
+		break;
+
+	case XTG_GET_STREAM_TRANSFERCNT:
+		rdval = ((readl(tg->regs + XTG_STREAM_TL_OFFSET) &
+				XTG_STREAM_TL_TCNT_MASK) >>
+				XTG_STREAM_TL_TCNT_SHIFT);
+		break;
+
+	case XTG_START_MASTER_LOGIC:
+		if (wrval)
+			writel(readl(tg->regs + XTG_MCNTL_OFFSET) |
+					XTG_MCNTL_MSTEN_MASK,
+				tg->regs + XTG_MCNTL_OFFSET);
+		break;
+
+	case XTG_SET_SLV_CTRL_REG:
+		writel(wrval, tg->regs + XTG_SCNTL_OFFSET);
+		break;
+
+	case XTG_ENABLE_ERRORS:
+		wrval &= XTG_ERR_ALL_ERRS_MASK;
+		writel(readl(tg->regs + XTG_ERR_EN_OFFSET) | wrval,
+			tg->regs + XTG_ERR_EN_OFFSET);
+		break;
+
+	case XTG_CLEAR_ERRORS:
+		wrval &= XTG_ERR_ALL_ERRS_MASK;
+		writel(readl(tg->regs + XTG_ERR_STS_OFFSET) | wrval,
+			tg->regs + XTG_ERR_STS_OFFSET);
+		break;
+
+	case XTG_ENABLE_INTRS:
+		if (wrval & XTG_MASTER_CMP_INTR) {
+			pr_info("Enabling Master Complete Interrupt\n");
+			writel(readl(tg->regs + XTG_ERR_EN_OFFSET) |
+					XTG_ERR_EN_MSTIRQEN_MASK,
+				tg->regs + XTG_ERR_EN_OFFSET);
+		}
+		if (wrval & XTG_MASTER_ERR_INTR) {
+			pr_info("Enabling Interrupt on Master Errors\n");
+			writel(readl(tg->regs + XTG_MSTERR_INTR_OFFSET) |
+					XTG_MSTERR_INTR_MINTREN_MASK,
+				tg->regs + XTG_MSTERR_INTR_OFFSET);
+		}
+		if (wrval & XTG_SLAVE_ERR_INTR) {
+			pr_info("Enabling Interrupt on Slave Errors\n");
+			writel(readl(tg->regs + XTG_SCNTL_OFFSET) |
+					XTG_SCNTL_ERREN_MASK,
+				tg->regs + XTG_SCNTL_OFFSET);
+		}
+		break;
+
+	case XTG_CLEAR_MRAM:
+		if (wrval)
+			xtg_access_rams(tg, tg->xtg_mram_offset,
+				XTG_MASTER_RAM_SIZE, XTG_WRITE_RAM |
+				XTG_WRITE_RAM_ZERO, NULL);
+		break;
+
+	case XTG_CLEAR_CRAM:
+		if (wrval)
+			xtg_access_rams(tg, XTG_COMMAND_RAM_OFFSET,
+				XTG_COMMAND_RAM_SIZE, XTG_WRITE_RAM |
+				XTG_WRITE_RAM_ZERO, NULL);
+		break;
+
+	case XTG_CLEAR_PRAM:
+		if (wrval)
+			xtg_access_rams(tg, XTG_PARAM_RAM_OFFSET,
+				XTG_PARAM_RAM_SIZE, XTG_WRITE_RAM |
+				XTG_WRITE_RAM_ZERO, NULL);
+		break;
+
+	case XTG_SET_STATIC_ENABLE:
+		if (wrval) {
+			wrval &= XTG_STATIC_CNTL_STEN_MASK;
+			writel(readl(tg->regs + XTG_STATIC_CNTL_OFFSET) | wrval,
+			tg->regs + XTG_STATIC_CNTL_OFFSET);
+		} else {
+			writel(readl(tg->regs + XTG_STATIC_CNTL_OFFSET) &
+				~XTG_STATIC_CNTL_STEN_MASK,
+				tg->regs + XTG_STATIC_CNTL_OFFSET);
+		}
+		break;
+
+	case XTG_SET_STATIC_BURSTLEN:
+		writel(wrval, tg->regs + XTG_STATIC_LEN_OFFSET);
+		break;
+
+	case XTG_SET_STATIC_TRANSFERDONE:
+		wrval |= XTG_STATIC_CNTL_TD_MASK;
+		writel(readl(tg->regs + XTG_STATIC_CNTL_OFFSET) | wrval,
+			tg->regs + XTG_STATIC_CNTL_OFFSET);
+		break;
+
+	case XTG_SET_STREAM_ENABLE:
+		if (wrval) {
+			wrval &= XTG_STREAM_CNTL_STEN_MASK;
+			writel(readl(tg->regs + XTG_STREAM_CNTL_OFFSET) | wrval,
+			tg->regs + XTG_STREAM_CNTL_OFFSET);
+		} else {
+			writel(readl(tg->regs + XTG_STREAM_CNTL_OFFSET) &
+			~XTG_STREAM_CNTL_STEN_MASK,
+			tg->regs + XTG_STREAM_CNTL_OFFSET);
+		}
+		break;
+
+	case XTG_SET_STREAM_TRANSFERLEN:
+		wrval &= XTG_STREAM_TL_TLEN_MASK;
+		writel(readl(tg->regs + XTG_STREAM_TL_OFFSET) | wrval,
+			tg->regs + XTG_STREAM_TL_OFFSET);
+		break;
+
+	case XTG_SET_STREAM_TRANSFERCNT:
+		wrval = ((wrval << XTG_STREAM_TL_TCNT_SHIFT) &
+				XTG_STREAM_TL_TCNT_MASK);
+		writel(readl(tg->regs + XTG_STREAM_TL_OFFSET) | wrval,
+			tg->regs + XTG_STREAM_TL_OFFSET);
+		break;
+
+	default:
+		break;
+	}
+
+	return rdval;
+}
+
+/* Sysfs functions */
+
+static ssize_t xtg_show_id(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_DEVICE_ID);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+static DEVICE_ATTR(id, S_IRUGO, xtg_show_id, NULL);
+
+static ssize_t xtg_show_resource(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_RESOURCE);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+static DEVICE_ATTR(resource, S_IRUGO, xtg_show_resource, NULL);
+
+static ssize_t xtg_show_master_cmp_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_MASTER_CMP_STS);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+
+static ssize_t xtg_start_master_logic(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_START_MASTER_LOGIC);
+
+	return size;
+}
+static DEVICE_ATTR(start_master, 0644, xtg_show_master_cmp_status,
+				xtg_start_master_logic);
+
+static ssize_t xtg_show_slv_ctrl_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_SLV_CTRL_REG);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+
+static ssize_t xtg_config_slv_ctrl(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_SLV_CTRL_REG);
+
+	return size;
+}
+static DEVICE_ATTR(config_slave, 0644, xtg_show_slv_ctrl_status,
+				xtg_config_slv_ctrl);
+
+static ssize_t xtg_show_errs(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_ERR_STS);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+
+static ssize_t xtg_clear_errs(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_CLEAR_ERRORS);
+
+	return size;
+}
+static DEVICE_ATTR(err_sts, 0644, xtg_show_errs, xtg_clear_errs);
+
+static ssize_t xtg_enable_errs(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_ENABLE_ERRORS);
+
+	return size;
+}
+static DEVICE_ATTR(err_en, 0644, NULL, xtg_enable_errs);
+
+static ssize_t xtg_enable_interrupts(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_ENABLE_INTRS);
+
+	return size;
+}
+static DEVICE_ATTR(intr_en, 0644, NULL, xtg_enable_interrupts);
+
+static ssize_t xtg_show_last_valid_index(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_LAST_VALID_INDEX);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+static DEVICE_ATTR(last_valid_index, S_IRUGO, xtg_show_last_valid_index, NULL);
+
+static ssize_t xtg_show_config_status(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_CFG_STS);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+static DEVICE_ATTR(config_sts, S_IRUGO, xtg_show_config_status, NULL);
+
+static ssize_t xtg_clear_mram(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_CLEAR_MRAM);
+
+	return size;
+}
+static DEVICE_ATTR(mram_clear, 0644, NULL, xtg_clear_mram);
+
+static ssize_t xtg_clear_cram(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_CLEAR_CRAM);
+
+	return size;
+}
+static DEVICE_ATTR(cram_clear, 0644, NULL, xtg_clear_cram);
+
+static ssize_t xtg_clear_pram(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_CLEAR_CRAM);
+
+	return size;
+}
+static DEVICE_ATTR(pram_clear, 0644, NULL, xtg_clear_pram);
+
+static ssize_t xtg_show_static_enable(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STATIC_ENABLE);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+
+static ssize_t xtg_static_enable(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STATIC_ENABLE);
+
+	return size;
+}
+static DEVICE_ATTR(static_en, 0644, xtg_show_static_enable, xtg_static_enable);
+
+static ssize_t xtg_get_static_burstlen(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STATIC_BURSTLEN);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+
+static ssize_t xtg_static_burstlen(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STATIC_BURSTLEN);
+
+	return size;
+}
+static DEVICE_ATTR(static_burstlen, 0644, xtg_get_static_burstlen,
+			xtg_static_burstlen);
+
+static ssize_t xtg_get_static_transferdone(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STATIC_TRANSFERDONE);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+
+static ssize_t xtg_static_transferdone(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STATIC_TRANSFERDONE);
+
+	return size;
+}
+static DEVICE_ATTR(static_transferdone, 0644, xtg_get_static_transferdone,
+				xtg_static_transferdone);
+
+static ssize_t xtg_reset_static_transferdone(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STATIC_TRANSFERDONE);
+	if (rdval == XTG_STATIC_CNTL_RESET_MASK)
+		rdval = 1;
+	else
+		rdval = 0;
+	return sprintf(buf, "%d\n", rdval);
+}
+static DEVICE_ATTR(reset_static_transferdone, 0644,
+			xtg_reset_static_transferdone, NULL);
+
+static ssize_t xtg_show_stream_enable(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STREAM_ENABLE);
+
+	return sprintf(buf, "0x%08x\n", rdval);
+}
+
+static ssize_t xtg_stream_enable(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STREAM_ENABLE);
+
+	return size;
+}
+static DEVICE_ATTR(stream_en, 0644, xtg_show_stream_enable, xtg_stream_enable);
+
+static ssize_t xtg_get_stream_transferlen(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STREAM_TRANSFERLEN);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+
+static ssize_t xtg_set_stream_transferlen(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STREAM_TRANSFERLEN);
+
+	return size;
+}
+static DEVICE_ATTR(stream_transferlen, 0644, xtg_get_stream_transferlen,
+				xtg_set_stream_transferlen);
+
+static ssize_t xtg_get_stream_transfercnt(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	ssize_t rdval = xtg_sysfs_ioctl(dev, buf, XTG_GET_STREAM_TRANSFERCNT);
+
+	return sprintf(buf, "%d\n", rdval);
+}
+
+static ssize_t xtg_set_stream_transfercnt(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	xtg_sysfs_ioctl(dev, buf, XTG_SET_STREAM_TRANSFERCNT);
+
+	return size;
+}
+static DEVICE_ATTR(stream_transfercnt, 0644, xtg_get_stream_transfercnt,
+				xtg_set_stream_transfercnt);
+
+static ssize_t xtg_pram_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	pr_info("No read access to Parameter RAM\n");
+
+	return 0;
+}
+
+static ssize_t xtg_pram_write(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+	u32 *data = (u32 *)buf;
+
+	if (off >= XTG_PARAM_RAM_SIZE) {
+		pr_err("Requested Write len exceeds 2K PRAM size\n");
+		return -ENOMEM;
+	}
+
+	if (count >= XTG_PARAM_RAM_SIZE)
+		count = XTG_PARAM_RAM_SIZE;
+
+	/* Program each command */
+	if (count == sizeof(struct xtg_pram)) {
+		struct xtg_pram *cmdp = (struct xtg_pram *)buf;
+		u32 param_word;
+
+		if (!cmdp)
+			return -EINVAL;
+
+		if (cmdp->is_valid_req == VALID_SIG) {
+			/* Prepare parameter word */
+			xtg_prepare_param_word(tg, cmdp, &param_word);
+
+			count = XTG_PRAM_BYTES_PER_ENTRY;
+			data = &param_word;
+
+			/* Maximum command entries are 256 */
+			if (cmdp->index > MAX_NUM_ENTRIES)
+				return -EINVAL;
+
+			/* Calculate the block index */
+			if (cmdp->is_write_block)
+				off = XTG_PRM_RAM_BLOCK_SIZE +
+						cmdp->index * count;
+			else
+				off = cmdp->index * count;
+		}
+	}
+
+	off += XTG_PARAM_RAM_OFFSET;
+	xtg_access_rams(tg, off, count, XTG_WRITE_RAM, data);
+
+	return count;
+}
+
+static ssize_t xtg_pram_mmap(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *attr,
+				struct vm_area_struct *vma)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+	int ret;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= VM_IO;
+
+	ret = remap_pfn_range(vma, vma->vm_start, (tg->phys_base_addr +
+			XTG_PARAM_RAM_OFFSET) >> PAGE_SHIFT,
+			XTG_PARAM_RAM_SIZE, vma->vm_page_prot);
+	return ret;
+}
+
+static struct bin_attribute xtg_pram_attr = {
+	.attr =	{
+		.name = "parameter_ram",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = XTG_PARAM_RAM_SIZE,
+	.read = xtg_pram_read,
+	.write = xtg_pram_write,
+	.mmap = xtg_pram_mmap,
+};
+
+static ssize_t xtg_cram_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+
+	off += XTG_COMMAND_RAM_OFFSET;
+	xtg_access_rams(tg, off, count, XTG_READ_RAM, (u32 *)buf);
+
+	return count;
+}
+
+static ssize_t xtg_cram_write(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+	u32 *data = (u32 *)buf;
+
+	if (off >= XTG_COMMAND_RAM_SIZE) {
+		pr_err("Requested Write len exceeds 8K CRAM size\n");
+		return -ENOMEM;
+	}
+
+	/* Program each command */
+	if (count == sizeof(struct xtg_cram)) {
+		struct xtg_cram *cmdp = (struct xtg_cram *)buf;
+		u32 cmd_words[4];
+
+		if (!cmdp)
+			return -EINVAL;
+
+		if (cmdp->is_valid_req == VALID_SIG) {
+			/* Prepare command words */
+			xtg_prepare_cmd_words(tg, cmdp, cmd_words);
+			count = XTG_CRAM_BYTES_PER_ENTRY;
+			data = cmd_words;
+
+			/* Maximum command entries are 256 */
+			if (cmdp->index > MAX_NUM_ENTRIES)
+				return -EINVAL;
+
+			/* Calculate the block index */
+			if (cmdp->is_write_block)
+				off = XTG_CMD_RAM_BLOCK_SIZE +
+						cmdp->index * count;
+			else
+				off = cmdp->index * count;
+
+			/* Store the valid command index */
+			if (cmdp->valid_cmd) {
+				if (cmdp->is_write_block)
+					tg->last_wr_valid_idx =
+							cmdp->index;
+				else
+					tg->last_rd_valid_idx =
+							cmdp->index;
+			}
+		}
+	}
+
+	off += XTG_COMMAND_RAM_OFFSET;
+	xtg_access_rams(tg, off, count, XTG_WRITE_RAM, data);
+
+	return count;
+}
+
+static ssize_t xtg_cram_mmap(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *attr,
+				struct vm_area_struct *vma)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+	int ret;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= VM_IO;
+
+	ret = remap_pfn_range(vma, vma->vm_start, (tg->phys_base_addr +
+			XTG_COMMAND_RAM_OFFSET) >> PAGE_SHIFT,
+			XTG_COMMAND_RAM_SIZE, vma->vm_page_prot);
+	return ret;
+}
+
+static struct bin_attribute xtg_cram_attr = {
+	.attr =	{
+		.name = "command_ram",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = XTG_COMMAND_RAM_SIZE,
+	.read = xtg_cram_read,
+	.write = xtg_cram_write,
+	.mmap = xtg_cram_mmap,
+};
+
+static ssize_t xtg_mram_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+
+	off += tg->xtg_mram_offset;
+	xtg_access_rams(tg, off, count, XTG_READ_RAM, (u32 *)buf);
+
+	return count;
+}
+
+static ssize_t xtg_mram_write(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+
+	if (off >= XTG_MASTER_RAM_SIZE) {
+		pr_err("Requested Write len exceeds 8K MRAM size\n");
+		return -ENOMEM;
+	}
+
+	off += tg->xtg_mram_offset;
+	xtg_access_rams(tg, off, count, XTG_WRITE_RAM, (u32 *)buf);
+
+	return count;
+}
+
+static ssize_t xtg_mram_mmap(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *attr,
+				struct vm_area_struct *vma)
+{
+	struct xtg_dev_info *tg =
+		to_xtg_dev_info(container_of(kobj, struct device, kobj));
+	int ret;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= VM_IO;
+
+	ret = remap_pfn_range(vma, vma->vm_start, (tg->phys_base_addr +
+			tg->xtg_mram_offset) >> PAGE_SHIFT,
+			XTG_MASTER_RAM_SIZE,
+			vma->vm_page_prot);
+	return ret;
+}
+
+static struct bin_attribute xtg_mram_attr = {
+	.attr =	{
+		.name = "master_ram",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = XTG_MASTER_RAM_SIZE,
+	.read = xtg_mram_read,
+	.write = xtg_mram_write,
+	.mmap = xtg_mram_mmap,
+};
+
+static const struct attribute *xtg_attrs[] = {
+	&dev_attr_id.attr,
+	&dev_attr_resource.attr,
+	&dev_attr_start_master.attr,
+	&dev_attr_config_slave.attr,
+	&dev_attr_err_en.attr,
+	&dev_attr_err_sts.attr,
+	&dev_attr_intr_en.attr,
+	&dev_attr_last_valid_index.attr,
+	&dev_attr_config_sts.attr,
+	&dev_attr_mram_clear.attr,
+	&dev_attr_cram_clear.attr,
+	&dev_attr_pram_clear.attr,
+	&dev_attr_static_en.attr,
+	&dev_attr_static_burstlen.attr,
+	&dev_attr_static_transferdone.attr,
+	&dev_attr_stream_transfercnt.attr,
+	&dev_attr_stream_transferlen.attr,
+	&dev_attr_stream_en.attr,
+	&dev_attr_reset_static_transferdone.attr,
+	NULL,
+};
+
+/**
+ * xtg_remove_sysfs_dev_files - Remove sysfs entries for device
+ * @tg: Pointer to xtg_dev_info structure
+ */
+static void xtg_remove_sysfs_dev_files(struct xtg_dev_info *tg)
+{
+	struct device *dev = tg->dev;
+
+	sysfs_remove_files(&dev->kobj, xtg_attrs);
+	sysfs_remove_bin_file(&dev->kobj, &xtg_mram_attr);
+	sysfs_remove_bin_file(&dev->kobj, &xtg_cram_attr);
+	sysfs_remove_bin_file(&dev->kobj, &xtg_pram_attr);
+}
+
+/**
+ * xtg_create_sysfs_dev_files - Create sysfs entries for device
+ * @tg: Pointer to xtg_dev_info structure
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xtg_create_sysfs_dev_files(struct xtg_dev_info *tg)
+{
+	struct device *dev = tg->dev;
+	int err;
+
+	err = sysfs_create_files(&dev->kobj, xtg_attrs);
+	if (err < 0)
+		goto out;
+
+	err = sysfs_create_bin_file(&dev->kobj, &xtg_mram_attr);
+	if (err < 0)
+		goto out;
+
+	err = sysfs_create_bin_file(&dev->kobj, &xtg_cram_attr);
+	if (err < 0)
+		goto out;
+
+	err = sysfs_create_bin_file(&dev->kobj, &xtg_pram_attr);
+	if (err < 0)
+		goto out;
+
+	return 0;
+
+out:
+	xtg_remove_sysfs_dev_files(tg);
+
+	return err;
+}
+
+/**
+ * xtg_cmp_intr_handler - Master Complete Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the xtg_dev_info structure
+ *
+ * Returns IRQ_HANDLED always
+ */
+static irqreturn_t xtg_cmp_intr_handler(int irq, void *data)
+{
+	struct xtg_dev_info *tg = (struct xtg_dev_info *)data;
+
+	writel(readl(tg->regs + XTG_ERR_STS_OFFSET) |
+			XTG_ERR_STS_MSTDONE_MASK,
+		tg->regs + XTG_ERR_STS_OFFSET);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xtg_err_intr_handler - Master/Slave Error Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the xtg_dev_info structure
+ *
+ * Returns IRQ_HANDLED always
+ */
+static irqreturn_t xtg_err_intr_handler(int irq, void *data)
+{
+	struct xtg_dev_info *tg = (struct xtg_dev_info *)data;
+	u32 value;
+
+	value = readl(tg->regs + XTG_ERR_STS_OFFSET) &
+			XTG_ERR_ALL_ERRS_MASK;
+
+	if (value) {
+		dev_err(tg->dev, "Found errors 0x%08x\n", value);
+		writel(readl(tg->regs + XTG_ERR_STS_OFFSET) | value,
+			tg->regs + XTG_ERR_STS_OFFSET);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xtg_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Returns '0' on success and failure value on error
+ */
+static int xtg_probe(struct platform_device *pdev)
+{
+	struct xtg_dev_info *tg;
+	struct device_node *node;
+	struct resource *res;
+	int err, irq, var;
+
+	tg = devm_kzalloc(&pdev->dev, sizeof(*tg), GFP_KERNEL);
+	if (!tg)
+		return -ENOMEM;
+
+	tg->dev = &(pdev->dev);
+
+	node = pdev->dev.of_node;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tg->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tg->regs))
+		return PTR_ERR(tg->regs);
+
+
+	/* Save physical base address */
+	tg->phys_base_addr = res->start;
+
+	/* Get the device instance id */
+	err = of_property_read_u32(node, "xlnx,device-id", &tg->id);
+	if (err < 0) {
+		dev_err(&pdev->dev, "unable to read property");
+		return err;
+	}
+
+	/* Map the error interrupt, if it exists in the device tree. */
+	irq = platform_get_irq_byname(pdev, "err-out");
+	if (irq < 0) {
+		dev_dbg(&pdev->dev, "unable to get err irq");
+	} else {
+		err = devm_request_irq(&pdev->dev, irq, xtg_err_intr_handler,
+					0, dev_name(&pdev->dev), tg);
+		if (err < 0) {
+			dev_err(&pdev->dev, "unable to request irq %d", irq);
+			return err;
+		}
+	}
+
+	/* Map the completion interrupt, if it exists in the device tree. */
+	irq = platform_get_irq_byname(pdev, "irq-out");
+	if (irq < 0) {
+		dev_dbg(&pdev->dev, "unable to get cmp irq");
+	} else {
+		err = devm_request_irq(&pdev->dev, irq, xtg_cmp_intr_handler,
+					0, dev_name(&pdev->dev), tg);
+		if (err < 0) {
+			dev_err(&pdev->dev, "unable to request irq %d", irq);
+			return err;
+		}
+	}
+
+	/*
+	 * Create sysfs file entries for the device
+	 *
+	 * NOTE: We can create sysfs entries by adding attribute groups
+	 * and then populate into device_driver structure. We see issue
+	 * here, as this process doesn't allow to add sysfs entries with
+	 * BIN attributes (SYSFS_KOBJ_BIN_ATTR). Also, this would create
+	 * sysfs entries under driver/ which will be a bit confusing for
+	 * users as bin files and normal files will be populated at diff
+	 * erent places. So to avoid this, we created this function to
+	 * add sysfs entries at a common place.
+	 *
+	 * this issue being addressed in mainline by
+	 * 'sysfs: add support for binary attributes in groups'.
+	 * It removes this overhead of creating/removing sysfs file entries.
+	 */
+	err = xtg_create_sysfs_dev_files(tg);
+	if (err < 0) {
+		dev_err(tg->dev, "unable to create sysfs entries\n");
+		return err;
+	}
+
+	/*
+	 * Initialize the write and read valid index values.
+	 * Possible range of values for these variables is <0 255>.
+	 */
+	tg->last_wr_valid_idx = -1;
+	tg->last_rd_valid_idx = -1;
+
+	dev_set_drvdata(&pdev->dev, tg);
+
+	/* Update the Proper MasterRam offset */
+	tg->xtg_mram_offset = XTG_MASTER_RAM_OFFSET;
+	var = readl(tg->regs + XTG_MCNTL_OFFSET) >> XTG_MCNTL_REV_SHIFT;
+	if (var == XTG_INIT_VERSION)
+		tg->xtg_mram_offset = XTG_MASTER_RAM_INIT_OFFSET;
+
+	dev_info(&pdev->dev, "Probing xilinx traffic generator success\n");
+
+	return 0;
+}
+
+/**
+ * xtg_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Always returns '0'
+ */
+static int xtg_remove(struct platform_device *pdev)
+{
+	struct xtg_dev_info *tg;
+
+	tg = dev_get_drvdata(&pdev->dev);
+
+	xtg_remove_sysfs_dev_files(tg);
+
+	return 0;
+}
+
+static struct of_device_id xtg_of_match[] = {
+	{ .compatible = "xlnx,axi-traffic-gen", },
+	{ /* end of table */ }
+};
+MODULE_DEVICE_TABLE(of, xtg_of_match);
+
+static struct platform_driver xtg_driver = {
+	.driver = {
+		.name = "xilinx-trafgen",
+		.owner = THIS_MODULE,
+		.of_match_table = xtg_of_match,
+	},
+	.probe = xtg_probe,
+	.remove = xtg_remove,
+};
+
+module_platform_driver(xtg_driver);
+
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_DESCRIPTION("Xilinx Traffic Generator driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/mmc/host/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mmc/host/Kconfig	2014-07-20 22:05:50.240066555 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mmc/host/Kconfig	2014-07-20 22:06:36.759299071 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:133 @
 
 	  If unsure, say N.
 
+config MMC_SDHCI_OF_ARASAN
+	tristate "SDHCI OF support for the Arasan SDHCI controllers"
+	depends on MMC_SDHCI_PLTFM
+	depends on OF
+	help
+	  This selects the Arasan Secure Digital Host Controller Interface
+	  (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_CNS3XXX
 	tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
 	depends on ARCH_CNS3XXX
Index: linux-3.12.24-rt38-xilinx/drivers/mmc/host/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mmc/host/Makefile	2014-07-20 22:05:50.238066588 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mmc/host/Makefile	2014-07-20 22:06:36.769298906 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:60 @
 obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX)	+= sdhci-esdhc-imx.o
 obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
+obj-$(CONFIG_MMC_SDHCI_OF_ARASAN)	+= sdhci-of-arasan.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
 obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
Index: linux-3.12.24-rt38-xilinx/drivers/mmc/host/sdhci-of-arasan.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/mmc/host/sdhci-of-arasan.c	2014-07-20 22:06:36.779298741 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Arasan Secure Digital Host Controller Interface.
+ * Copyright (C) 2011 - 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2012 Wind River Systems, Inc.
+ * Copyright (C) 2013 Pengutronix e.K.
+ * Copyright (C) 2013 Xilinx Inc.
+ *
+ * Based on sdhci-of-esdhc.c
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/module.h>
+#include "sdhci-pltfm.h"
+
+#define SDHCI_ARASAN_CLK_CTRL_OFFSET	0x2c
+
+#define CLK_CTRL_TIMEOUT_SHIFT		16
+#define CLK_CTRL_TIMEOUT_MASK		(0xf << CLK_CTRL_TIMEOUT_SHIFT)
+#define CLK_CTRL_TIMEOUT_MIN_EXP	13
+
+/**
+ * struct sdhci_arasan_data
+ * @clk_ahb:	Pointer to the AHB clock
+ */
+struct sdhci_arasan_data {
+	struct clk	*clk_ahb;
+};
+
+static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
+{
+	u32 div;
+	unsigned long freq;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	div = readl(host->ioaddr + SDHCI_ARASAN_CLK_CTRL_OFFSET);
+	div = (div & CLK_CTRL_TIMEOUT_MASK) >> CLK_CTRL_TIMEOUT_SHIFT;
+
+	freq = clk_get_rate(pltfm_host->clk);
+	freq /= 1 << (CLK_CTRL_TIMEOUT_MIN_EXP + div);
+
+	return freq;
+}
+
+static struct sdhci_ops sdhci_arasan_ops = {
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
+};
+
+static struct sdhci_pltfm_data sdhci_arasan_pdata = {
+	.ops = &sdhci_arasan_ops,
+};
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * sdhci_arasan_suspend - Suspend method for the driver
+ * @dev:	Address of the device structure
+ * Returns 0 on success and error value on error
+ *
+ * Put the device in a low power state.
+ */
+static int sdhci_arasan_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_arasan_data *sdhci_arasan = pltfm_host->priv;
+	int ret;
+
+	ret = sdhci_suspend_host(host);
+	if (ret)
+		return ret;
+
+	clk_disable(pltfm_host->clk);
+	clk_disable(sdhci_arasan->clk_ahb);
+
+	return 0;
+}
+
+/**
+ * sdhci_arasan_resume - Resume method for the driver
+ * @dev:	Address of the device structure
+ * Returns 0 on success and error value on error
+ *
+ * Resume operation after suspend
+ */
+static int sdhci_arasan_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_arasan_data *sdhci_arasan = pltfm_host->priv;
+	int ret;
+
+	ret = clk_enable(sdhci_arasan->clk_ahb);
+	if (ret) {
+		dev_err(dev, "Cannot enable AHB clock.\n");
+		return ret;
+	}
+
+	ret = clk_enable(pltfm_host->clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable SD clock.\n");
+		clk_disable(sdhci_arasan->clk_ahb);
+		return ret;
+	}
+
+	return sdhci_resume_host(host);
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend,
+			 sdhci_arasan_resume);
+
+static int sdhci_arasan_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct clk *clk_xin;
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_arasan_data *sdhci_arasan;
+
+	sdhci_arasan = devm_kzalloc(&pdev->dev, sizeof(*sdhci_arasan),
+			GFP_KERNEL);
+	if (!sdhci_arasan)
+		return -ENOMEM;
+
+	sdhci_arasan->clk_ahb = devm_clk_get(&pdev->dev, "clk_ahb");
+	if (IS_ERR(sdhci_arasan->clk_ahb)) {
+		dev_err(&pdev->dev, "clk_ahb clock not found.\n");
+		return PTR_ERR(sdhci_arasan->clk_ahb);
+	}
+
+	clk_xin = devm_clk_get(&pdev->dev, "clk_xin");
+	if (IS_ERR(clk_xin)) {
+		dev_err(&pdev->dev, "clk_xin clock not found.\n");
+		return PTR_ERR(clk_xin);
+	}
+
+	ret = clk_prepare_enable(sdhci_arasan->clk_ahb);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable AHB clock.\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(clk_xin);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable SD clock.\n");
+		goto clk_dis_ahb;
+	}
+
+	host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata, 0);
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		dev_err(&pdev->dev, "platform init failed (%u)\n", ret);
+		goto clk_disable_all;
+	}
+
+	sdhci_get_of_property(pdev);
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = sdhci_arasan;
+	pltfm_host->clk = clk_xin;
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(&pdev->dev, "platform register failed (%u)\n", ret);
+		goto err_pltfm_free;
+	}
+
+	return 0;
+
+err_pltfm_free:
+	sdhci_pltfm_free(pdev);
+clk_disable_all:
+	clk_disable_unprepare(clk_xin);
+clk_dis_ahb:
+	clk_disable_unprepare(sdhci_arasan->clk_ahb);
+
+	return ret;
+}
+
+static int sdhci_arasan_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_arasan_data *sdhci_arasan = pltfm_host->priv;
+
+	clk_disable_unprepare(pltfm_host->clk);
+	clk_disable_unprepare(sdhci_arasan->clk_ahb);
+
+	return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_arasan_of_match[] = {
+	{ .compatible = "arasan,sdhci-8.9a" },
+	{ .compatible = "xlnx,ps7-sdhci-1.00.a" },
+	{ .compatible = "generic-sdhci" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
+
+static struct platform_driver sdhci_arasan_driver = {
+	.driver = {
+		.name = "sdhci-arasan",
+		.owner = THIS_MODULE,
+		.of_match_table = sdhci_arasan_of_match,
+		.pm = &sdhci_arasan_dev_pm_ops,
+	},
+	.probe = sdhci_arasan_probe,
+	.remove = sdhci_arasan_remove,
+};
+
+module_platform_driver(sdhci_arasan_driver);
+
+MODULE_DESCRIPTION("Driver for the Arasan SDHCI Controller");
+MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/chips/cfi_probe.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mtd/chips/cfi_probe.c	2014-07-20 22:05:50.180067545 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/chips/cfi_probe.c	2014-07-20 22:06:36.794298493 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:161 @
 	__u32 base = 0;
 	int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
 	int i;
+	int extendedId1 = 0;
+	int extendedId2 = 0;
+	int extendedId3 = 0;
 	int addr_unlock1 = 0x555, addr_unlock2 = 0x2AA;
 
 	xip_enable(base, map, cfi);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:190 @
 	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
 		((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
 
+	/* Note we put the device back into Read Mode BEFORE going into Auto
+	 * Select Mode, as some devices support nesting of modes, others
+	 * don't. This way should always work.
+	 * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
+	 * so should be treated as nops or illegal (and so put the device
+	 * back into Read Mode, which is a nop in this case).
+	 */
+	cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi->mfr = cfi_read_query16(map, base);
+	cfi->id = cfi_read_query16(map, base + ofs_factor);
+
+	/* Get device ID cycle 1,2,3 for Numonyx/ST devices */
+	if ((cfi->mfr == CFI_MFR_INTEL || cfi->mfr == CFI_MFR_ST)
+		&& ((cfi->id & 0xff) == 0x7e)
+		&& (le16_to_cpu(cfi->cfiq->P_ID) == 0x0002)) {
+		extendedId1 = cfi_read_query16(map, base + 0x1 * ofs_factor);
+		extendedId2 = cfi_read_query16(map, base + 0xe * ofs_factor);
+		extendedId3 = cfi_read_query16(map, base + 0xf * ofs_factor);
+	}
+
+	/* Get AMD/Spansion extended JEDEC ID */
+	if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e)
+		cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 |
+			  cfi_read_query(map, base + 0xf * ofs_factor);
+
+	/* Put it back into Read Mode */
+	cfi_qry_mode_off(base, map, cfi);
+	xip_allowed(base, map);
+
 	/* Do any necessary byteswapping */
 	cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:231 @
 	cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
 	cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);
 
+   /* If the device is a M29EW used in 8-bit mode, adjust buffer size */
+	if ((cfi->cfiq->MaxBufWriteSize > 0x8) && (cfi->mfr == CFI_MFR_INTEL ||
+		 cfi->mfr == CFI_MFR_ST) && (extendedId1 == 0x7E) &&
+		 (extendedId2 == 0x22 || extendedId2 == 0x23 || extendedId2 == 0x28) &&
+		 (extendedId3 == 0x01)) {
+		cfi->cfiq->MaxBufWriteSize = 0x8;
+		pr_warning("Adjusted buffer size on Numonyx flash M29EW family");
+		pr_warning("in 8 bit mode\n");
+    }
+
 #ifdef DEBUG_CFI
 	/* Dump the information therein */
 	print_cfi_ident(cfi->cfiq);
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/devices/m25p80.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mtd/devices/m25p80.c	2014-07-20 22:05:50.179067562 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/devices/m25p80.c	2014-07-20 22:06:36.819298081 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:44 @
 #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
 #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
+#define OPCODE_QUAD_READ	0x6b	/* Quad read command */
 #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
+#define OPCODE_QPP		0x32	/* Quad page program */
 #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
 #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
 #define	OPCODE_BE_32K		0x52	/* Erase 32KiB block */
 #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define OPCODE_RDFSR		0x70	/* Read Flag Status Register */
+#define OPCODE_WREAR		0xc5	/* Write Extended Address Register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:73 @
 
 /* Used for Spansion flashes only. */
 #define	OPCODE_BRWR		0x17	/* Bank register write */
+#define	OPCODE_BRRD		0x16	/* Bank register read */
 
 /* Status Register bits. */
 #define	SR_WIP			1	/* Write in progress */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:84 @
 #define	SR_BP2			0x10	/* Block protect 2 */
 #define	SR_SRWD			0x80	/* SR write protect */
 
+/* Flag Status Register bits. */
+#define FSR_RDY			0x80	/* Ready/Busy program erase
+					controller */
 /* Define max times to check status register before we give up. */
-#define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
+#define	MAX_READY_WAIT_JIFFIES	(480 * HZ) /* N25Q specs 480s max chip erase */
 #define	MAX_CMD_SIZE		6
 
 #define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:106 @
 	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
+	u16			curbank;
+	u32			jedec_id;
+	bool			check_fsr;
+	bool			shift;
+	bool			isparallel;
+	bool			isstacked;
+	u8			dummycount;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:127 @
  */
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Read register, returning its value in the location
  * Returns negative if error occurred.
  */
-static int read_sr(struct m25p *flash)
+static inline int read_spi_reg(struct m25p *flash, u8 code, const char *name)
 {
 	ssize_t retval;
-	u8 code = OPCODE_RDSR;
 	u8 val;
 
 	retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
 
 	if (retval < 0) {
-		dev_err(&flash->spi->dev, "error %d reading SR\n",
-				(int) retval);
+		dev_err(&flash->spi->dev, "error %d reading %s\n",
+				(int) retval, name);
 		return retval;
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:147 @
 }
 
 /*
+ * Read flag status register, returning its value in the location
+ * Return flag status register value.
+ * Returns negative if error occurred.
+ */
+static int read_fsr(struct m25p *flash)
+{
+	return read_spi_reg(flash, OPCODE_RDFSR, "FSR");
+}
+
+/*
+ * Read the status register, returning its value in the location
+ * Return the status register value.
+ * Returns negative if error occurred.
+ */
+static int read_sr(struct m25p *flash)
+{
+	return read_spi_reg(flash, OPCODE_RDSR, "SR");
+}
+
+/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:206 @
 {
 	int status;
 	bool need_wren = false;
+	int ret;
+	u8 val;
 
 	switch (JEDEC_MFR(jedec_id)) {
 	case CFI_MFR_ST: /* Micron, actually */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:228 @
 	default:
 		/* Spansion style */
 		flash->command[0] = OPCODE_BRWR;
-		flash->command[1] = enable << 7;
-		return spi_write(flash->spi, flash->command, 2);
+		flash->command[1] = enable << 7 ;
+		ret = spi_write(flash->spi, flash->command, 2);
+
+		/* verify the 4 byte mode is enabled */
+		flash->command[0] = OPCODE_BRRD;
+		spi_write_then_read(flash->spi, flash->command, 1, &val, 1);
+		if (val != enable << 7) {
+			dev_warn(&flash->spi->dev,
+				 "fallback to 3-byte address mode\n");
+			dev_warn(&flash->spi->dev,
+				 "maximum accessible size is 16MB\n");
+			flash->addr_width = 3;
+		}
+		return ret;
 	}
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:252 @
 static int wait_till_ready(struct m25p *flash)
 {
 	unsigned long deadline;
-	int sr;
+	int sr, fsr;
 
 	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
 
 	do {
 		if ((sr = read_sr(flash)) < 0)
 			break;
-		else if (!(sr & SR_WIP))
+		else if (!(sr & SR_WIP)) {
+			if (flash->check_fsr) {
+				fsr = read_fsr(flash);
+				if (!(fsr & FSR_RDY))
+					return 1;
+			}
 			return 0;
+		}
 
 		cond_resched();
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:276 @
 }
 
 /*
+ * Update Extended Address/bank selection Register.
+ * Call with flash->lock locked.
+ */
+static int write_ear(struct m25p *flash, u32 addr)
+{
+	u8 ear;
+	int ret;
+
+	/* Wait until finished previous write command. */
+	if (wait_till_ready(flash))
+		return 1;
+
+	if (flash->mtd.size <= (0x1000000) << flash->shift)
+		return 0;
+
+	addr = addr % (u32) flash->mtd.size;
+	ear = addr >> 24;
+
+	if ((!flash->isstacked) && (ear == flash->curbank))
+		return 0;
+
+	if (flash->isstacked && (flash->mtd.size <= 0x2000000))
+		return 0;
+
+	if (JEDEC_MFR(flash->jedec_id) == 0x01)
+		flash->command[0] = OPCODE_BRWR;
+	if (JEDEC_MFR(flash->jedec_id) == 0x20) {
+		write_enable(flash);
+		flash->command[0] = OPCODE_WREAR;
+	}
+	flash->command[1] = ear;
+
+	ret = spi_write(flash->spi, flash->command, 2);
+	if (ret)
+		return ret;
+
+	flash->curbank = ear;
+
+	return 0;
+}
+
+/*
  * Erase the whole flash memory
  *
  * Returns 0 if successful, non-zero otherwise.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:331 @
 	if (wait_till_ready(flash))
 		return 1;
 
+	if (flash->isstacked)
+		flash->spi->master->flags &= ~SPI_MASTER_U_PAGE;
+
 	/* Send write enable, then erase commands. */
 	write_enable(flash);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:342 @
 
 	spi_write(flash->spi, flash->command, 1);
 
+	if (flash->isstacked) {
+		/* Wait until finished previous write command. */
+		if (wait_till_ready(flash))
+			return 1;
+
+		flash->spi->master->flags |= SPI_MASTER_U_PAGE;
+
+		/* Send write enable, then erase commands. */
+		write_enable(flash);
+
+		/* Set up command buffer. */
+		flash->command[0] = OPCODE_CHIP_ERASE;
+
+		spi_write(flash->spi, flash->command, 1);
+	}
+
 	return 0;
 }
 
 static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
 {
+	int i;
+
 	/* opcode is in cmd[0] */
-	cmd[1] = addr >> (flash->addr_width * 8 -  8);
-	cmd[2] = addr >> (flash->addr_width * 8 - 16);
-	cmd[3] = addr >> (flash->addr_width * 8 - 24);
-	cmd[4] = addr >> (flash->addr_width * 8 - 32);
+	for (i = 1; i <= flash->addr_width; i++)
+		cmd[i] = addr >> (flash->addr_width * 8 - i * 8);
 }
 
 static int m25p_cmdsz(struct m25p *flash)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:390 @
 	if (wait_till_ready(flash))
 		return 1;
 
+	/* update Extended Address Register */
+	if (write_ear(flash, offset))
+		return 1;
+
 	/* Send write enable, then erase commands. */
 	write_enable(flash);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:419 @
 static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct m25p *flash = mtd_to_m25p(mtd);
-	u32 addr,len;
+	u32 addr, len, offset;
 	uint32_t rem;
 
 	pr_debug("%s: %s at 0x%llx, len %lld\n", dev_name(&flash->spi->dev),
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:451 @
 	/* "sector"-at-a-time erase */
 	} else {
 		while (len) {
-			if (erase_sector(flash, addr)) {
+			offset = addr;
+			if (flash->isparallel == 1)
+				offset /= 2;
+			if (flash->isstacked == 1) {
+				if (offset >= (flash->mtd.size / 2)) {
+					offset = offset - (flash->mtd.size / 2);
+					flash->spi->master->flags |=
+							SPI_MASTER_U_PAGE;
+				} else
+					flash->spi->master->flags &=
+							~SPI_MASTER_U_PAGE;
+			}
+			if (erase_sector(flash, offset)) {
 				instr->state = MTD_ERASE_FAILED;
 				mutex_unlock(&flash->lock);
 				return -EIO;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:505 @
 	 * Should add 1 byte DUMMY_BYTE.
 	 */
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
+	t[0].len = m25p_cmdsz(flash) + flash->dummycount;
 	spi_message_add_tail(&t[0], &m);
 
 	t[1].rx_buf = buf;
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
 
-	mutex_lock(&flash->lock);
-
 	/* Wait till previous write/erase is done. */
-	if (wait_till_ready(flash)) {
+	if (wait_till_ready(flash))
 		/* REVISIT status return?? */
-		mutex_unlock(&flash->lock);
 		return 1;
-	}
 
 	/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
 	 * clocks; and at this writing, every chip this driver handles
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:530 @
 	spi_sync(flash->spi, &m);
 
 	*retlen = m.actual_length - m25p_cmdsz(flash) -
-			(flash->fast_read ? 1 : 0);
+			flash->dummycount;
 
-	mutex_unlock(&flash->lock);
+	return 0;
+}
+
+static int m25p80_read_ext(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char *buf)
+{
+	struct m25p *flash = mtd_to_m25p(mtd);
+	u32 addr = from;
+	u32 offset = from;
+	u32 read_len = 0;
+	u32 actual_len = 0;
+	u32 read_count = 0;
+	u32 rem_bank_len = 0;
+	u8 bank = 0;
+
+#define OFFSET_16_MB 0x1000000
 
+	mutex_lock(&flash->lock);
+
+	while (len) {
+		bank = addr / (OFFSET_16_MB << flash->shift);
+		rem_bank_len = ((OFFSET_16_MB << flash->shift) * (bank + 1)) -
+				addr;
+		offset = addr;
+		if (flash->isparallel == 1)
+			offset /= 2;
+		if (flash->isstacked == 1) {
+			if (offset >= (flash->mtd.size / 2)) {
+				offset = offset - (flash->mtd.size / 2);
+				flash->spi->master->flags |= SPI_MASTER_U_PAGE;
+			} else {
+				flash->spi->master->flags &= ~SPI_MASTER_U_PAGE;
+			}
+		}
+		write_ear(flash, offset);
+		if (len < rem_bank_len)
+			read_len = len;
+		else
+			read_len = rem_bank_len;
+
+		m25p80_read(mtd, offset, read_len, &actual_len, buf);
+
+		addr += actual_len;
+		len -= actual_len;
+		buf += actual_len;
+		read_count += actual_len;
+	}
+
+	*retlen = read_count;
+
+	mutex_unlock(&flash->lock);
 	return 0;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:612 @
 	t[1].tx_buf = buf;
 	spi_message_add_tail(&t[1], &m);
 
-	mutex_lock(&flash->lock);
-
 	/* Wait until finished previous write command. */
-	if (wait_till_ready(flash)) {
-		mutex_unlock(&flash->lock);
+	if (wait_till_ready(flash))
 		return 1;
-	}
 
 	write_enable(flash);
 
 	/* Set up the opcode in the write buffer. */
 	flash->command[0] = flash->program_opcode;
-	m25p_addr2cmd(flash, to, flash->command);
+	m25p_addr2cmd(flash, (to >> flash->shift), flash->command);
 
 	page_offset = to & (flash->page_size - 1);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:649 @
 				page_size = flash->page_size;
 
 			/* write the next page to flash */
-			m25p_addr2cmd(flash, to + i, flash->command);
+			m25p_addr2cmd(flash, ((to + i) >> flash->shift),
+					flash->command);
 
 			t[1].tx_buf = buf + i;
 			t[1].len = page_size;
 
-			wait_till_ready(flash);
+			if (wait_till_ready(flash))
+				return 1;
 
 			write_enable(flash);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:666 @
 		}
 	}
 
-	mutex_unlock(&flash->lock);
+	return 0;
+}
 
+static int m25p80_write_ext(struct mtd_info *mtd, loff_t to, size_t len,
+	size_t *retlen, const u_char *buf)
+{
+	struct m25p *flash = mtd_to_m25p(mtd);
+	u32 addr = to;
+	u32 offset = to;
+	u32 write_len = 0;
+	u32 actual_len = 0;
+	u32 write_count = 0;
+	u32 rem_bank_len = 0;
+	u8 bank = 0;
+
+#define OFFSET_16_MB 0x1000000
+
+	mutex_lock(&flash->lock);
+	while (len) {
+		bank = addr / (OFFSET_16_MB << flash->shift);
+		rem_bank_len = ((OFFSET_16_MB << flash->shift) * (bank + 1)) -
+				addr;
+		offset = addr;
+
+		if (flash->isstacked == 1) {
+			if (offset >= (flash->mtd.size / 2)) {
+				offset = offset - (flash->mtd.size / 2);
+				flash->spi->master->flags |= SPI_MASTER_U_PAGE;
+			} else {
+				flash->spi->master->flags &= ~SPI_MASTER_U_PAGE;
+			}
+		}
+		write_ear(flash, (offset >> flash->shift));
+		if (len < rem_bank_len)
+			write_len = len;
+		else
+			write_len = rem_bank_len;
+
+		m25p80_write(mtd, offset, write_len, &actual_len, buf);
+
+		addr += actual_len;
+		len -= actual_len;
+		buf += actual_len;
+		write_count += actual_len;
+	}
+
+	*retlen = write_count;
+
+	mutex_unlock(&flash->lock);
 	return 0;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:930 @
 #define	SST_WRITE	0x04		/* use SST byte programming */
 #define	M25P_NO_FR	0x08		/* Can't do fastread */
 #define	SECT_4K_PMC	0x10		/* OPCODE_BE_4K_PMC works uniformly */
+#define	SECT_32K	0x20		/* OPCODE_BE_32K */
+#define E_FSR		0x40		/* Flag SR exists for flash */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1012 @
 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
 	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+	/* Numonyx flash n25q128 - FIXME check the name */
+	{ "n25q128",   INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
+	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, E_FSR) },
+	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, E_FSR) },
+	{ "n25q256a13", INFO(0x20ba19,  0, 64 * 1024,  512, SECT_4K | E_FSR) },
+	{ "n25q256a11", INFO(0x20bb19,  0, 64 * 1024,  512, SECT_4K | E_FSR) },
+	{ "n25q512a13", INFO(0x20ba20,  0, 64 * 1024,  1024, SECT_4K | E_FSR) },
+	{ "n25q512a11", INFO(0x20bb20,  0, 64 * 1024,  1024, SECT_4K | E_FSR) },
+	{ "n25q00aa13", INFO(0x20ba21,  0, 64 * 1024,  2048, SECT_4K | E_FSR) },
 
 	/* PMC */
 	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1046 @
 	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
 	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
 	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
-	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
+	/* s25fl064k supports 4KiB, 32KiB and 64KiB sectors erase size. */
+	/* To support JFFS2, the minimum erase size is 8KiB(>4KiB). */
+	/* And thus, the sector size of s25fl064k is set to 32KiB for */
+	/* JFFS2 support. */
+	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_32K) },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
 	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1062 @
 	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
 	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
 	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024,  16, SECT_4K | SST_WRITE) },
 
 	/* ST Microelectronics -- newer production may have feature updates */
 	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1109 @
 	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+	/* Winbond -- w25q "blocks" are 64K, "sectors" are 32KiB */
+	/* w25q64 supports 4KiB, 32KiB and 64KiB sectors erase size. */
+	/* To support JFFS2, the minimum erase size is 8KiB(>4KiB). */
+	/* And thus, the sector size of w25q64 is set to 32KiB for */
+	/* JFFS2 support. */
+	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_32K) },
 	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
 	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
 	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1269 @
 	flash->mtd.writesize = 1;
 	flash->mtd.flags = MTD_CAP_NORFLASH;
 	flash->mtd.size = info->sector_size * info->n_sectors;
+
+	{
+#ifdef CONFIG_OF
+		const char *comp_str;
+		u32 is_dual;
+		np = of_get_next_parent(spi->dev.of_node);
+		of_property_read_string(np, "compatible", &comp_str);
+		if (!strcmp(comp_str, "xlnx,ps7-qspi-1.00.a")) {
+			if (of_property_read_u32(np, "is-dual", &is_dual) < 0) {
+				/* Default to single if prop not defined */
+				flash->shift = 0;
+				flash->isstacked = 0;
+				flash->isparallel = 0;
+			} else {
+				if (is_dual == 1) {
+					/* dual parallel */
+					flash->shift = 1;
+					info->sector_size <<= flash->shift;
+					info->page_size <<= flash->shift;
+					flash->mtd.size <<= flash->shift;
+					flash->isparallel = 1;
+					flash->isstacked = 0;
+				} else {
+#ifdef CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED
+					/* dual stacked */
+					flash->shift = 0;
+					flash->mtd.size <<= 1;
+					flash->isstacked = 1;
+					flash->isparallel = 0;
+#else
+					/* single */
+					flash->shift = 0;
+					flash->isstacked = 0;
+					flash->isparallel = 0;
+#endif
+				}
+			}
+		}
+#else
+		/* Default to single */
+		flash->shift = 0;
+		flash->isstacked = 0;
+		flash->isparallel = 0;
+#endif
+	}
+
 	flash->mtd._erase = m25p80_erase;
-	flash->mtd._read = m25p80_read;
+	flash->mtd._read = m25p80_read_ext;
 
 	/* flash protection support for STmicro chips */
 	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1328 @
 	if (info->flags & SST_WRITE)
 		flash->mtd._write = sst_write;
 	else
-		flash->mtd._write = m25p80_write;
+		flash->mtd._write = m25p80_write_ext;
 
 	/* prefer "small sector" erase if possible */
 	if (info->flags & SECT_4K) {
 		flash->erase_opcode = OPCODE_BE_4K;
-		flash->mtd.erasesize = 4096;
+		flash->mtd.erasesize = 4096 << flash->shift;
+	} else if (info->flags & SECT_32K) {
+		flash->erase_opcode = OPCODE_BE_32K;
+		flash->mtd.erasesize = 32768 << flash->shift;
 	} else if (info->flags & SECT_4K_PMC) {
 		flash->erase_opcode = OPCODE_BE_4K_PMC;
 		flash->mtd.erasesize = 4096;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1345 @
 		flash->mtd.erasesize = info->sector_size;
 	}
 
+	flash->read_opcode = OPCODE_NORM_READ;
+	flash->program_opcode = OPCODE_PP;
+	flash->dummycount = 0;
+
 	if (info->flags & M25P_NO_ERASE)
 		flash->mtd.flags |= MTD_NO_ERASE;
 
+	if (info->flags & E_FSR)
+		flash->check_fsr = 1;
+
+	flash->jedec_id = info->jedec_id;
 	ppdata.of_node = spi->dev.of_node;
 	flash->mtd.dev.parent = &spi->dev;
 	flash->page_size = info->page_size;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1372 @
 		flash->fast_read = false;
 
 	/* Default commands */
-	if (flash->fast_read)
+	if (flash->fast_read) {
 		flash->read_opcode = OPCODE_FAST_READ;
-	else
-		flash->read_opcode = OPCODE_NORM_READ;
+		flash->dummycount = 1;
+	}
 
 	flash->program_opcode = OPCODE_PP;
 
+	if (spi->master->flags & SPI_MASTER_QUAD_MODE) {
+		flash->read_opcode = OPCODE_QUAD_READ;
+		flash->program_opcode = OPCODE_QPP;
+		flash->dummycount = 1;
+	}
+
 	if (info->addr_width)
 		flash->addr_width = info->addr_width;
 	else if (flash->mtd.size > 0x1000000) {
 		/* enable 4-byte addressing if the device exceeds 16MiB */
-		flash->addr_width = 4;
-		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
-			/* Dedicated 4-byte command set */
-			flash->read_opcode = flash->fast_read ?
-				OPCODE_FAST_READ_4B :
-				OPCODE_NORM_READ_4B;
-			flash->program_opcode = OPCODE_PP_4B;
-			/* No small sector erase for 4-byte command set */
-			flash->erase_opcode = OPCODE_SE_4B;
-			flash->mtd.erasesize = info->sector_size;
-		} else
-			set_4byte(flash, info->jedec_id, 1);
+#ifdef CONFIG_OF
+		const char *comp_str;
+		np = of_get_next_parent(spi->dev.of_node);
+		of_property_read_string(np, "compatible", &comp_str);
+		if (!strcmp(comp_str, "xlnx,ps7-qspi-1.00.a")) {
+			flash->addr_width = 3;
+			set_4byte(flash, info->jedec_id, 0);
+		} else {
+#endif
+			flash->addr_width = 4;
+			if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
+				/* Dedicated 4-byte command set */
+				flash->read_opcode = flash->fast_read ?
+					OPCODE_FAST_READ_4B :
+					OPCODE_NORM_READ_4B;
+				flash->program_opcode = OPCODE_PP_4B;
+				/* No small sector erase for 4-byte
+				 * command set
+				 */
+				flash->erase_opcode = OPCODE_SE_4B;
+				flash->mtd.erasesize = info->sector_size;
+			} else
+				set_4byte(flash, info->jedec_id, 1);
+#ifdef CONFIG_OF
+		}
+#endif
 	} else {
 		flash->addr_width = 3;
 	}
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/nand/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mtd/nand/Kconfig	2014-07-20 22:05:50.177067595 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/nand/Kconfig	2014-07-20 22:06:36.835297817 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:520 @
 	  This enables the driver for the NAND Flash on evaluation board based
 	  on w90p910 / NUC9xx.
 
+config MTD_NAND_ZYNQ
+	tristate "Xilinx Zynq NAND flash driver"
+	depends on MTD_NAND && ARCH_ZYNQ
+	select ZYNQ_SMC
+	help
+	  This enables access to the NAND flash device on Xilinx Zynq.
+
 config MTD_NAND_JZ4740
 	tristate "Support for JZ4740 SoC NAND controller"
 	depends on MACH_JZ4740
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/nand/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mtd/nand/Makefile	2014-07-20 22:05:50.176067611 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/nand/Makefile	2014-07-20 22:06:36.845297652 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:52 @
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_ZYNQ)		+= zynq_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/nand/nand_base.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/mtd/nand/nand_base.c	2014-07-20 22:05:50.178067578 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/nand/nand_base.c	2014-07-20 22:06:36.877297124 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:814 @
 	int status, state = chip->state;
 	unsigned long timeo = (state == FL_ERASING ? 400 : 20);
 
+#if defined(ARCH_ZYNQ) && (CONFIG_HZ == 20)
+		/* Xilinx Zynq NAND work around for HZ=20 */
+		timeo += 1;
+#endif
+
 	led_trigger_event(nand_led_trigger, LED_FULL);
 
 	/*
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2943 @
 	int i;
 	int val;
 
+#ifdef CONFIG_MTD_NAND_XILINX_PS
+	uint8_t *buf;
+	unsigned int options;
+	int j;
+#endif
+
 	/* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */
 	if (chip->options & NAND_BUSWIDTH_16) {
 		pr_err("Trying ONFI probe in 16 bits mode, aborting !\n");
 		return 0;
 	}
+
 	/* Try ONFI for unknown chip or LP */
 	chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
 	if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2963 @
 
 	chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
 	for (i = 0; i < 3; i++) {
+#ifdef CONFIG_MTD_NAND_XILINX_PS
+		buf = (uint8_t *)p;
+		for(j = 0;j < 256;j++)
+			buf[j] = chip->read_byte(mtd);
+#else
 		chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+#endif
 		if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
 				le16_to_cpu(p->crc)) {
 			pr_info("ONFI param page %d valid\n", i);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3044 @
 			pr_info("Failed to detect the extended param page.\n");
 	}
 
+#ifdef CONFIG_MTD_NAND_XILINX_PS
+	/* Read the chip options before clearing the bits */
+	options = chip->options;
+#endif
+
 	pr_info("ONFI flash detected\n");
+#ifdef CONFIG_MTD_NAND_XILINX_PS
+	/* set the bus width option */
+	if (options & NAND_BUSWIDTH_16)
+		chip->options |= NAND_BUSWIDTH_16;
+#endif
 	return 1;
 }
 
Index: linux-3.12.24-rt38-xilinx/drivers/mtd/nand/zynq_nand.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/mtd/nand/zynq_nand.c	2014-07-20 22:06:36.897296794 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq NAND Flash Controller Driver
+ *
+ * Copyright (C) 2009 - 2013 Xilinx, Inc.
+ *
+ * This driver is based on plat_nand.c and mxc_nand.c drivers
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/memory/zynq-smc.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define XNANDPS_DRIVER_NAME "xilinx_nandps"
+
+/* NAND flash driver defines */
+#define XNANDPS_CMD_PHASE	1	/* End command valid in command phase */
+#define XNANDPS_DATA_PHASE	2	/* End command valid in data phase */
+#define XNANDPS_ECC_SIZE	512	/* Size of data for ECC operation */
+
+/* Flash memory controller operating parameters */
+
+#define XNANDPS_ECC_CONFIG	((1 << 4)  |	/* ECC read at end of page */ \
+				 (0 << 5))	/* No Jumping */
+
+/* AXI Address definitions */
+#define START_CMD_SHIFT		3
+#define END_CMD_SHIFT		11
+#define END_CMD_VALID_SHIFT	20
+#define ADDR_CYCLES_SHIFT	21
+#define CLEAR_CS_SHIFT		21
+#define ECC_LAST_SHIFT		10
+#define COMMAND_PHASE		(0 << 19)
+#define DATA_PHASE		(1 << 19)
+
+#define XNANDPS_ECC_LAST	(1 << ECC_LAST_SHIFT)	/* Set ECC_Last */
+#define XNANDPS_CLEAR_CS	(1 << CLEAR_CS_SHIFT)	/* Clear chip select */
+
+#define ONDIE_ECC_FEATURE_ADDR	0x90
+
+/* Macros for the NAND controller register read/write */
+#define xnandps_write32(addr, val)	__raw_writel((val), (addr))
+
+
+/**
+ * struct xnandps_command_format - Defines NAND flash command format
+ * @start_cmd:		First cycle command (Start command)
+ * @end_cmd:		Second cycle command (Last command)
+ * @addr_cycles:	Number of address cycles required to send the address
+ * @end_cmd_valid:	The second cycle command is valid for cmd or data phase
+ */
+struct xnandps_command_format {
+	int start_cmd;
+	int end_cmd;
+	u8 addr_cycles;
+	u8 end_cmd_valid;
+};
+
+/**
+ * struct xnandps_info - Defines the NAND flash driver instance
+ * @chip:		NAND chip information structure
+ * @mtd:		MTD information structure
+ * @parts:		Pointer	to the mtd_partition structure
+ * @nand_base:		Virtual address of the NAND flash device
+ * @end_cmd_pending:	End command is pending
+ * @end_cmd:		End command
+ */
+struct xnandps_info {
+	struct nand_chip	chip;
+	struct mtd_info		mtd;
+	struct mtd_partition	*parts;
+	void __iomem		*nand_base;
+	unsigned long		end_cmd_pending;
+	unsigned long		end_cmd;
+};
+
+/*
+ * The NAND flash operations command format
+ */
+static const struct xnandps_command_format xnandps_commands[] = {
+	{NAND_CMD_READ0, NAND_CMD_READSTART, 5, XNANDPS_CMD_PHASE},
+	{NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, 2, XNANDPS_CMD_PHASE},
+	{NAND_CMD_READID, NAND_CMD_NONE, 1, NAND_CMD_NONE},
+	{NAND_CMD_STATUS, NAND_CMD_NONE, 0, NAND_CMD_NONE},
+	{NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, 5, XNANDPS_DATA_PHASE},
+	{NAND_CMD_RNDIN, NAND_CMD_NONE, 2, NAND_CMD_NONE},
+	{NAND_CMD_ERASE1, NAND_CMD_ERASE2, 3, XNANDPS_CMD_PHASE},
+	{NAND_CMD_RESET, NAND_CMD_NONE, 0, NAND_CMD_NONE},
+	{NAND_CMD_PARAM, NAND_CMD_NONE, 1, NAND_CMD_NONE},
+	{NAND_CMD_GET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE},
+	{NAND_CMD_SET_FEATURES, NAND_CMD_NONE, 1, NAND_CMD_NONE},
+	{NAND_CMD_NONE, NAND_CMD_NONE, 0, 0},
+	/* Add all the flash commands supported by the flash device and Linux */
+	/* The cache program command is not supported by driver because driver
+	 * cant differentiate between page program and cached page program from
+	 * start command, these commands can be differentiated through end
+	 * command, which doesn't fit in to the driver design. The cache program
+	 * command is not supported by NAND subsystem also, look at 1612 line
+	 * number (in nand_write_page function) of nand_base.c file.
+	 * {NAND_CMD_SEQIN, NAND_CMD_CACHEDPROG, 5, XNANDPS_YES}, */
+};
+
+/* Define default oob placement schemes for large and small page devices */
+static struct nand_ecclayout nand_oob_16 = {
+	.eccbytes = 3,
+	.eccpos = {0, 1, 2},
+	.oobfree = {
+		{.offset = 8,
+		 . length = 8} }
+};
+
+static struct nand_ecclayout nand_oob_64 = {
+	.eccbytes = 12,
+	.eccpos = {
+		   52, 53, 54, 55, 56, 57,
+		   58, 59, 60, 61, 62, 63},
+	.oobfree = {
+		{.offset = 2,
+		 .length = 50} }
+};
+
+static struct nand_ecclayout ondie_nand_oob_64 = {
+	.eccbytes = 32,
+
+	.eccpos = {
+		8, 9, 10, 11, 12, 13, 14, 15,
+		24, 25, 26, 27, 28, 29, 30, 31,
+		40, 41, 42, 43, 44, 45, 46, 47,
+		56, 57, 58, 59, 60, 61, 62, 63
+	},
+
+	.oobfree = {
+		{ .offset = 4, .length = 4 },
+		{ .offset = 20, .length = 4 },
+		{ .offset = 36, .length = 4 },
+		{ .offset = 52, .length = 4 }
+	}
+};
+
+/* Generic flash bbt decriptors */
+static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs = 4,
+	.len = 4,
+	.veroffs = 20,
+	.maxblocks = 4,
+	.pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs = 4,
+	.len = 4,
+	.veroffs = 20,
+	.maxblocks = 4,
+	.pattern = mirror_pattern
+};
+
+/**
+ * xnandps_calculate_hwecc - Calculate Hardware ECC
+ * @mtd:	Pointer to the mtd_info structure
+ * @data:	Pointer to the page data
+ * @ecc_code:	Pointer to the ECC buffer where ECC data needs to be stored
+ *
+ * This function retrieves the Hardware ECC data from the controller and returns
+ * ECC data back to the MTD subsystem.
+ *
+ * returns:	0 on success or error value on failure
+ */
+static int
+xnandps_calculate_hwecc(struct mtd_info *mtd, const u8 *data, u8 *ecc_code)
+{
+	u32 ecc_value = 0;
+	u8 ecc_reg, ecc_byte;
+	u32 ecc_status;
+
+	/* Wait till the ECC operation is complete */
+	while (xsmcps_ecc_is_busy())
+		cpu_relax();
+
+	for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) {
+		/* Read ECC value for each block */
+		ecc_value = xsmcps_get_ecc_val(ecc_reg);
+		ecc_status = (ecc_value >> 24) & 0xFF;
+		/* ECC value valid */
+		if (ecc_status & 0x40) {
+			for (ecc_byte = 0; ecc_byte < 3; ecc_byte++) {
+				/* Copy ECC bytes to MTD buffer */
+				*ecc_code = ecc_value & 0xFF;
+				ecc_value = ecc_value >> 8;
+				ecc_code++;
+			}
+		} else {
+			/* TODO */
+			/* dev_dbg(&pdev->dev, "pl350: ecc status failed\n"); */
+		}
+	}
+	return 0;
+}
+
+/**
+ * onehot - onehot function
+ * @value:	Value to check for onehot
+ *
+ * This function checks whether a value is onehot or not.
+ * onehot is if and only if onebit is set.
+ */
+static int onehot(unsigned short value)
+{
+	return (value & (value - 1)) == 0;
+}
+
+/**
+ * xnandps_correct_data - ECC correction function
+ * @mtd:	Pointer to the mtd_info structure
+ * @buf:	Pointer to the page data
+ * @read_ecc:	Pointer to the ECC value read from spare data area
+ * @calc_ecc:	Pointer to the calculated ECC value
+ *
+ * This function corrects the ECC single bit errors & detects 2-bit errors.
+ *
+ * returns:	0 if no ECC errors found
+ *		1 if single bit error found and corrected.
+ *		-1 if multiple ECC errors found.
+ */
+static int xnandps_correct_data(struct mtd_info *mtd, unsigned char *buf,
+				unsigned char *read_ecc,
+				unsigned char *calc_ecc)
+{
+	unsigned char bit_addr;
+	unsigned int byte_addr;
+	unsigned short ecc_odd, ecc_even;
+	unsigned short read_ecc_lower, read_ecc_upper;
+	unsigned short calc_ecc_lower, calc_ecc_upper;
+
+	read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & 0xfff;
+	read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & 0xfff;
+
+	calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & 0xfff;
+	calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & 0xfff;
+
+	ecc_odd = read_ecc_lower ^ calc_ecc_lower;
+	ecc_even = read_ecc_upper ^ calc_ecc_upper;
+
+	if ((ecc_odd == 0) && (ecc_even == 0))
+		return 0;       /* no error */
+
+	if (ecc_odd == (~ecc_even & 0xfff)) {
+		/* bits [11:3] of error code is byte offset */
+		byte_addr = (ecc_odd >> 3) & 0x1ff;
+		/* bits [2:0] of error code is bit offset */
+		bit_addr = ecc_odd & 0x7;
+		/* Toggling error bit */
+		buf[byte_addr] ^= (1 << bit_addr);
+		return 1;
+	}
+
+	if (onehot(ecc_odd | ecc_even) == 1)
+		return 1; /* one error in parity */
+
+	return -1; /* Uncorrectable error */
+}
+
+/**
+ * xnandps_read_oob - [REPLACABLE] the most common OOB data read function
+ * @mtd:	Pointer to the mtd info structure
+ * @chip:	Pointer to the NAND chip info structure
+ * @page:	Page number to read
+ */
+static int xnandps_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			    int page)
+{
+	unsigned long data_width = 4;
+	unsigned long data_phase_addr = 0;
+	uint8_t *p;
+
+	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+
+	p = chip->oob_poi;
+	chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+	p += (mtd->oobsize - data_width);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+	chip->read_buf(mtd, p, data_width);
+
+	return 0;
+}
+
+/**
+ * xnandps_write_oob - [REPLACABLE] the most common OOB data write function
+ * @mtd:	Pointer to the mtd info structure
+ * @chip:	Pointer to the NAND chip info structure
+ * @page:	Page number to write
+ */
+static int xnandps_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			     int page)
+{
+	int status = 0;
+	const uint8_t *buf = chip->oob_poi;
+	unsigned long data_width = 4;
+	unsigned long data_phase_addr = 0;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+
+	chip->write_buf(mtd, buf, (mtd->oobsize - data_width));
+	buf += (mtd->oobsize - data_width);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+	chip->write_buf(mtd, buf, data_width);
+
+	/* Send command to program the OOB data */
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+	status = chip->waitfunc(mtd, chip);
+
+	return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/**
+ * xnandps_read_page_raw - [Intern] read raw page data without ecc
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ * @page:		Page number to read
+ */
+static int xnandps_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				 uint8_t *buf, int oob_required, int page)
+{
+	unsigned long data_width = 4;
+	unsigned long data_phase_addr = 0;
+	uint8_t *p;
+
+	chip->read_buf(mtd, buf, mtd->writesize);
+
+	p = chip->oob_poi;
+	chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+	p += (mtd->oobsize - data_width);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+
+	chip->read_buf(mtd, p, data_width);
+	return 0;
+}
+
+/**
+ * xnandps_write_page_raw - [Intern] raw page write function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ */
+static int xnandps_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+				  const uint8_t *buf, int oob_required)
+{
+	unsigned long data_width = 4;
+	unsigned long data_phase_addr = 0;
+	uint8_t *p;
+
+	chip->write_buf(mtd, buf, mtd->writesize);
+
+	p = chip->oob_poi;
+	chip->write_buf(mtd, p, (mtd->oobsize - data_width));
+	p += (mtd->oobsize - data_width);
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+
+	chip->write_buf(mtd, p, data_width);
+
+	return 0;
+}
+
+/**
+ * nand_write_page_hwecc - Hardware ECC based page write function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ *
+ * This functions writes data and hardware generated ECC values in to the page.
+ */
+static int xnandps_write_page_hwecc(struct mtd_info *mtd,
+				    struct nand_chip *chip, const uint8_t *buf,
+				    int oob_required)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	const uint8_t *p = buf;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	unsigned long data_phase_addr = 0;
+	unsigned long data_width = 4;
+	uint8_t *oob_ptr;
+
+	for ( ; (eccsteps - 1); eccsteps--) {
+		chip->write_buf(mtd, p, eccsize);
+		p += eccsize;
+	}
+	chip->write_buf(mtd, p, (eccsize - data_width));
+	p += (eccsize - data_width);
+
+	/* Set ECC Last bit to 1 */
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr |= XNANDPS_ECC_LAST;
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+	chip->write_buf(mtd, p, data_width);
+
+	/* Wait for ECC to be calculated and read the error values */
+	p = buf;
+	chip->ecc.calculate(mtd, p, &ecc_calc[0]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ~(ecc_calc[i]);
+
+	/* Clear ECC last bit */
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr &= ~XNANDPS_ECC_LAST;
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+
+	/* Write the spare area with ECC bytes */
+	oob_ptr = chip->oob_poi;
+	chip->write_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
+
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_W;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+	chip->IO_ADDR_W = (void __iomem * __force)data_phase_addr;
+	oob_ptr += (mtd->oobsize - data_width);
+	chip->write_buf(mtd, oob_ptr, data_width);
+
+	return 0;
+}
+
+/**
+ * xnandps_write_page_swecc - [REPLACABLE] software ecc based page write function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the data buffer
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ */
+static int xnandps_write_page_swecc(struct mtd_info *mtd,
+				    struct nand_chip *chip, const uint8_t *buf,
+				    int oob_required)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	const uint8_t *p = buf;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	/* Software ecc calculation */
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	chip->ecc.write_page_raw(mtd, chip, buf, 1);
+
+	return 0;
+}
+
+/**
+ * xnandps_read_page_hwecc - Hardware ECC based page read function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the buffer to store read data
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ * @page:		Page number to read
+ *
+ * This functions reads data and checks the data integrity by comparing hardware
+ * generated ECC values and read ECC values from spare area.
+ *
+ * returns:	0 always and updates ECC operation status in to MTD structure
+ */
+static int xnandps_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+				   uint8_t *buf, int oob_required, int page)
+{
+	int i, stat, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	unsigned long data_phase_addr = 0;
+	unsigned long data_width = 4;
+	uint8_t *oob_ptr;
+
+	for ( ; (eccsteps - 1); eccsteps--) {
+		chip->read_buf(mtd, p, eccsize);
+		p += eccsize;
+	}
+	chip->read_buf(mtd, p, (eccsize - data_width));
+	p += (eccsize - data_width);
+
+	/* Set ECC Last bit to 1 */
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr |= XNANDPS_ECC_LAST;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+	chip->read_buf(mtd, p, data_width);
+
+	/* Read the calculated ECC value */
+	p = buf;
+	chip->ecc.calculate(mtd, p, &ecc_calc[0]);
+
+	/* Clear ECC last bit */
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr &= ~XNANDPS_ECC_LAST;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+
+	/* Read the stored ECC value */
+	oob_ptr = chip->oob_poi;
+	chip->read_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
+
+	/* de-assert chip select */
+	data_phase_addr = (unsigned long __force)chip->IO_ADDR_R;
+	data_phase_addr |= XNANDPS_CLEAR_CS;
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+
+	oob_ptr += (mtd->oobsize - data_width);
+	chip->read_buf(mtd, oob_ptr, data_width);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = ~(chip->oob_poi[eccpos[i]]);
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	/* Check ECC error for all blocks and correct if it is correctable */
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+
+/**
+ * xnandps_read_page_swecc - [REPLACABLE] software ecc based page read function
+ * @mtd:		Pointer to the mtd info structure
+ * @chip:		Pointer to the NAND chip info structure
+ * @buf:		Pointer to the buffer to store read data
+ * @oob_required:	Caller requires OOB data read to chip->oob_poi
+ * @page:		Page number to read
+ */
+static int xnandps_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+				   uint8_t *buf,  int oob_required, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	chip->ecc.read_page_raw(mtd, chip, buf, page, 1);
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+
+/**
+ * xnandps_select_chip - Select the flash device
+ * @mtd:	Pointer to the mtd info structure
+ * @chip:	Pointer to the NAND chip info structure
+ *
+ * This function is empty as the NAND controller handles chip select line
+ * internally based on the chip address passed in command and data phase.
+ */
+static void xnandps_select_chip(struct mtd_info *mtd, int chip)
+{
+	return;
+}
+
+/**
+ * xnandps_cmd_function - Send command to NAND device
+ * @mtd:	Pointer to the mtd_info structure
+ * @command:	The command to be sent to the flash device
+ * @column:	The column address for this command, -1 if none
+ * @page_addr:	The page address for this command, -1 if none
+ */
+static void xnandps_cmd_function(struct mtd_info *mtd, unsigned int command,
+				 int column, int page_addr)
+{
+	struct nand_chip *chip = mtd->priv;
+	const struct xnandps_command_format *curr_cmd = NULL;
+	struct xnandps_info *xnand =
+		container_of(mtd, struct xnandps_info, mtd);
+	void __iomem *cmd_addr;
+	unsigned long cmd_data = 0;
+	unsigned long cmd_phase_addr = 0;
+	unsigned long data_phase_addr = 0;
+	unsigned long end_cmd = 0;
+	unsigned long end_cmd_valid = 0;
+	unsigned long i;
+
+	if (xnand->end_cmd_pending) {
+		/* Check for end command if this command request is same as the
+		 * pending command then return */
+		if (xnand->end_cmd == command) {
+			xnand->end_cmd = 0;
+			xnand->end_cmd_pending = 0;
+			return;
+		}
+	}
+
+	/* Emulate NAND_CMD_READOOB for large page device */
+	if ((mtd->writesize > XNANDPS_ECC_SIZE) &&
+	    (command == NAND_CMD_READOOB)) {
+		column += mtd->writesize;
+		command = NAND_CMD_READ0;
+	}
+
+	/* Get the command format */
+	for (i = 0; (xnandps_commands[i].start_cmd != NAND_CMD_NONE ||
+		     xnandps_commands[i].end_cmd != NAND_CMD_NONE); i++)
+		if (command == xnandps_commands[i].start_cmd)
+			curr_cmd = &xnandps_commands[i];
+
+	if (curr_cmd == NULL)
+		return;
+
+	/* Clear interrupt */
+	xsmcps_clr_nand_int();
+
+	/* Get the command phase address */
+	if (curr_cmd->end_cmd_valid == XNANDPS_CMD_PHASE)
+		end_cmd_valid = 1;
+
+	if (curr_cmd->end_cmd == NAND_CMD_NONE)
+		end_cmd = 0x0;
+	else
+		end_cmd = curr_cmd->end_cmd;
+
+	cmd_phase_addr = (unsigned long __force)xnand->nand_base        |
+			 (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT)    |
+			 (end_cmd_valid << END_CMD_VALID_SHIFT)          |
+			 (COMMAND_PHASE)                                 |
+			 (end_cmd << END_CMD_SHIFT)                      |
+			 (curr_cmd->start_cmd << START_CMD_SHIFT);
+
+	cmd_addr = (void __iomem * __force)cmd_phase_addr;
+
+	/* Get the data phase address */
+	end_cmd_valid = 0;
+
+	data_phase_addr = (unsigned long __force)xnand->nand_base       |
+			  (0x0 << CLEAR_CS_SHIFT)                         |
+			  (end_cmd_valid << END_CMD_VALID_SHIFT)          |
+			  (DATA_PHASE)                                    |
+			  (end_cmd << END_CMD_SHIFT)                      |
+			  (0x0 << ECC_LAST_SHIFT);
+
+	chip->IO_ADDR_R = (void __iomem * __force)data_phase_addr;
+	chip->IO_ADDR_W = chip->IO_ADDR_R;
+
+	/* Command phase AXI write */
+	/* Read & Write */
+	if (column != -1 && page_addr != -1) {
+		/* Adjust columns for 16 bit bus width */
+		if (chip->options & NAND_BUSWIDTH_16)
+			column >>= 1;
+		cmd_data = column;
+		if (mtd->writesize > XNANDPS_ECC_SIZE) {
+			cmd_data |= page_addr << 16;
+			/* Another address cycle for devices > 128MiB */
+			if (chip->chipsize > (128 << 20)) {
+				xnandps_write32(cmd_addr, cmd_data);
+				cmd_data = (page_addr >> 16);
+			}
+		} else {
+			cmd_data |= page_addr << 8;
+		}
+	} else if (page_addr != -1) {
+		/* Erase */
+		cmd_data = page_addr;
+	} else if (column != -1) {
+		/* Change read/write column, read id etc */
+		/* Adjust columns for 16 bit bus width */
+		if ((chip->options & NAND_BUSWIDTH_16) &&
+			((command == NAND_CMD_READ0) ||
+			(command == NAND_CMD_SEQIN) ||
+			(command == NAND_CMD_RNDOUT) ||
+			(command == NAND_CMD_RNDIN)))
+				column >>= 1;
+		cmd_data = column;
+	}
+
+	xnandps_write32(cmd_addr, cmd_data);
+
+	if (curr_cmd->end_cmd_valid) {
+		xnand->end_cmd = curr_cmd->end_cmd;
+		xnand->end_cmd_pending = 1;
+	}
+
+	ndelay(100);
+
+	if ((command == NAND_CMD_READ0) ||
+	    (command == NAND_CMD_RESET) ||
+	    (command == NAND_CMD_PARAM) ||
+	    (command == NAND_CMD_GET_FEATURES)) {
+
+		while (!chip->dev_ready(mtd))
+			;
+		return;
+	}
+}
+
+/**
+ * xnandps_read_buf - read chip data into buffer
+ * @mtd:	Pointer to the mtd info structure
+ * @buf:	Pointer to the buffer to store read data
+ * @len:	Number of bytes to read
+ */
+static void xnandps_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+	unsigned long *ptr = (unsigned long *)buf;
+
+	len >>= 2;
+	for (i = 0; i < len; i++)
+		ptr[i] = readl(chip->IO_ADDR_R);
+}
+
+/**
+ * xnandps_write_buf - write buffer to chip
+ * @mtd:	Pointer to the mtd info structure
+ * @buf:	Pointer to the buffer to store read data
+ * @len:	Number of bytes to write
+ */
+static void xnandps_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+	unsigned long *ptr = (unsigned long *)buf;
+
+	len >>= 2;
+
+	for (i = 0; i < len; i++)
+		writel(ptr[i], chip->IO_ADDR_W);
+}
+
+/**
+ * xnandps_device_ready - Check device ready/busy line
+ * @mtd:	Pointer to the mtd_info structure
+ *
+ * returns:	0 on busy or 1 on ready state
+ */
+static int xnandps_device_ready(struct mtd_info *mtd)
+{
+	if (xsmcps_get_nand_int_status_raw()) {
+		xsmcps_clr_nand_int();
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * xnandps_probe - Probe method for the NAND driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function initializes the driver data structures and the hardware.
+ *
+ * returns:	0 on success or error value on failure
+ */
+static int xnandps_probe(struct platform_device *pdev)
+{
+	struct xnandps_info *xnand;
+	struct mtd_info *mtd;
+	struct nand_chip *nand_chip;
+	struct resource *res;
+	u8 maf_id, dev_id, i;
+	u8 get_feature;
+	u8 set_feature[4] = { 0x08, 0x00, 0x00, 0x00 };
+	int ondie_ecc_enabled = 0;
+	struct mtd_part_parser_data ppdata;
+	const unsigned int *prop;
+	u32 options = 0;
+
+	xnand = devm_kzalloc(&pdev->dev, sizeof(*xnand), GFP_KERNEL);
+	if (!xnand)
+		return -ENOMEM;
+
+	/* Map physical address of NAND flash */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xnand->nand_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xnand->nand_base))
+		return PTR_ERR(xnand->nand_base);
+
+	/* Get x8 or x16 mode from device tree */
+	prop = of_get_property(pdev->dev.of_node, "xlnx,nand-width", NULL);
+	if (prop) {
+		if (be32_to_cpup(prop) == 16) {
+			options |= NAND_BUSWIDTH_16;
+		} else if (be32_to_cpup(prop) == 8) {
+			options &= ~NAND_BUSWIDTH_16;
+		} else {
+			dev_info(&pdev->dev, "xlnx,nand-width not valid, using 8");
+			options &= ~NAND_BUSWIDTH_16;
+		}
+	} else {
+		dev_info(&pdev->dev, "xlnx,nand-width not in device tree, using 8");
+		options &= ~NAND_BUSWIDTH_16;
+	}
+
+	/* Link the private data with the MTD structure */
+	mtd = &xnand->mtd;
+	nand_chip = &xnand->chip;
+
+	nand_chip->priv = xnand;
+	mtd->priv = nand_chip;
+	mtd->owner = THIS_MODULE;
+	mtd->name = "xilinx_nand";
+
+	/* Set address of NAND IO lines */
+	nand_chip->IO_ADDR_R = xnand->nand_base;
+	nand_chip->IO_ADDR_W = xnand->nand_base;
+
+	/* Set the driver entry points for MTD */
+	nand_chip->cmdfunc = xnandps_cmd_function;
+	nand_chip->dev_ready = xnandps_device_ready;
+	nand_chip->select_chip = xnandps_select_chip;
+
+	/* If we don't set this delay driver sets 20us by default */
+	nand_chip->chip_delay = 30;
+
+	/* Buffer read/write routines */
+	nand_chip->read_buf = xnandps_read_buf;
+	nand_chip->write_buf = xnandps_write_buf;
+
+	/* Set the device option and flash width */
+	nand_chip->options = options;
+	nand_chip->bbt_options = NAND_BBT_USE_FLASH;
+
+	platform_set_drvdata(pdev, xnand);
+
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		dev_err(&pdev->dev, "nand_scan_ident for NAND failed\n");
+		return -ENXIO;
+	}
+
+	/* Check if On-Die ECC flash */
+	nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+	nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+	/* Read manufacturer and device IDs */
+	maf_id = nand_chip->read_byte(mtd);
+	dev_id = nand_chip->read_byte(mtd);
+
+	if ((maf_id == 0x2c) &&
+	    ((dev_id == 0xf1) || (dev_id == 0xa1) ||
+	     (dev_id == 0xb1) ||
+	     (dev_id == 0xaa) || (dev_id == 0xba) ||
+	     (dev_id == 0xda) || (dev_id == 0xca) ||
+	     (dev_id == 0xac) || (dev_id == 0xbc) ||
+	     (dev_id == 0xdc) || (dev_id == 0xcc) ||
+	     (dev_id == 0xa3) || (dev_id == 0xb3) ||
+	     (dev_id == 0xd3) || (dev_id == 0xc3))) {
+
+		nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
+				   ONDIE_ECC_FEATURE_ADDR, -1);
+		get_feature = nand_chip->read_byte(mtd);
+
+		if (get_feature & 0x08) {
+			ondie_ecc_enabled = 1;
+		} else {
+			nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
+					   ONDIE_ECC_FEATURE_ADDR, -1);
+			for (i = 0; i < 4; i++)
+				writeb(set_feature[i], nand_chip->IO_ADDR_W);
+
+			ndelay(1000);
+
+			nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
+					   ONDIE_ECC_FEATURE_ADDR, -1);
+			get_feature = nand_chip->read_byte(mtd);
+
+			if (get_feature & 0x08)
+				ondie_ecc_enabled = 1;
+		}
+	}
+
+	nand_chip->ecc.mode = NAND_ECC_HW;
+	nand_chip->ecc.read_oob = xnandps_read_oob;
+	nand_chip->ecc.read_page_raw = xnandps_read_page_raw;
+	nand_chip->ecc.strength = 1;
+	nand_chip->ecc.write_oob = xnandps_write_oob;
+	nand_chip->ecc.write_page_raw = xnandps_write_page_raw;
+	if (ondie_ecc_enabled) {
+		/* bypass the controller ECC block */
+		xsmcps_set_ecc_mode(XSMCPS_ECCMODE_BYPASS);
+
+		/* The software ECC routines won't work with the
+				SMC controller */
+		nand_chip->ecc.bytes = 0;
+		nand_chip->ecc.layout = &ondie_nand_oob_64;
+		nand_chip->ecc.read_page = xnandps_read_page_raw;
+		nand_chip->ecc.write_page = xnandps_write_page_raw;
+		nand_chip->ecc.size = mtd->writesize;
+		/* On-Die ECC spare bytes offset 8 is used for ECC codes */
+		/* Use the BBT pattern descriptors */
+		nand_chip->bbt_td = &bbt_main_descr;
+		nand_chip->bbt_md = &bbt_mirror_descr;
+	} else {
+		/* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
+		nand_chip->ecc.bytes = 3;
+		nand_chip->ecc.calculate = xnandps_calculate_hwecc;
+		nand_chip->ecc.correct = xnandps_correct_data;
+		nand_chip->ecc.hwctl = NULL;
+		nand_chip->ecc.read_page = xnandps_read_page_hwecc;
+		nand_chip->ecc.size = XNANDPS_ECC_SIZE;
+		nand_chip->ecc.write_page = xnandps_write_page_hwecc;
+
+		xsmcps_set_ecc_pg_size(mtd->writesize);
+		switch (mtd->writesize) {
+		case 512:
+		case 1024:
+		case 2048:
+			xsmcps_set_ecc_mode(XSMCPS_ECCMODE_APB);
+			break;
+		default:
+			/* The software ECC routines won't work with the
+				SMC controller */
+			nand_chip->ecc.calculate = nand_calculate_ecc;
+			nand_chip->ecc.correct = nand_correct_data;
+			nand_chip->ecc.read_page = xnandps_read_page_swecc;
+			/* nand_chip->ecc.read_subpage = nand_read_subpage; */
+			nand_chip->ecc.write_page = xnandps_write_page_swecc;
+			nand_chip->ecc.size = 256;
+			break;
+		}
+
+		if (mtd->oobsize == 16)
+			nand_chip->ecc.layout = &nand_oob_16;
+		else if (mtd->oobsize == 64)
+			nand_chip->ecc.layout = &nand_oob_64;
+	}
+
+	/* second phase scan */
+	if (nand_scan_tail(mtd)) {
+		dev_err(&pdev->dev, "nand_scan_tail for NAND failed\n");
+		return -ENXIO;
+	}
+
+	ppdata.of_node = pdev->dev.of_node;
+
+	mtd_device_parse_register(&xnand->mtd, NULL, &ppdata, NULL, 0);
+
+	return 0;
+}
+
+/**
+ * xnandps_remove - Remove method for the NAND driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function is called if the driver module is being unloaded. It frees all
+ * resources allocated to the device.
+ *
+ * returns:	0 on success or error value on failure
+ */
+static int xnandps_remove(struct platform_device *pdev)
+{
+	struct xnandps_info *xnand = platform_get_drvdata(pdev);
+
+	/* Release resources, unregister device */
+	nand_release(&xnand->mtd);
+	/* kfree(NULL) is safe */
+	kfree(xnand->parts);
+
+	return 0;
+}
+
+/* Match table for device tree binding */
+static const struct of_device_id xnandps_of_match[] = {
+	{ .compatible = "xlnx,ps7-nand-1.00.a" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, xnandps_of_match);
+
+/*
+ * xnandps_driver - This structure defines the NAND subsystem platform driver
+ */
+static struct platform_driver xnandps_driver = {
+	.probe		= xnandps_probe,
+	.remove		= xnandps_remove,
+	.driver		= {
+		.name	= XNANDPS_DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = xnandps_of_match,
+	},
+};
+
+module_platform_driver(xnandps_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_ALIAS("platform:" XNANDPS_DRIVER_NAME);
+MODULE_DESCRIPTION("Xilinx PS NAND Flash Driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/net/can/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/can/Kconfig	2014-07-20 22:05:50.250066390 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/can/Kconfig	2014-07-20 22:06:36.912296547 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:128 @
 	  endian syntheses of the cores would need some modifications on
 	  the hardware level to work.
 
+config CAN_XILINXCAN
+	tristate "Xilinx CAN"
+	depends on CAN && (ARCH_ZYNQ || MICROBLAZE)
+	default n
+	---help---
+	  Xilinx CAN driver. This driver supports both soft AXI CAN IP and
+	  Zynq CANPS IP.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/net/can/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/can/Makefile	2014-07-20 22:05:50.249066407 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/can/Makefile	2014-07-20 22:06:36.921296398 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:28 @
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
 obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
+obj-$(CONFIG_CAN_XILINXCAN)	+= xilinx_can.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
Index: linux-3.12.24-rt38-xilinx/drivers/net/can/xilinx_can.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/can/xilinx_can.c	2014-07-20 22:06:36.940296085 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx CAN device driver
+ *
+ * Copyright (C) 2012 - 2013 Xilinx, Inc.
+ * Copyright (C) 2009 PetaLogix. All rights reserved.
+ *
+ * Description:
+ * This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+#define DRIVER_NAME	"XILINX_CAN"
+
+/* CAN registers set */
+#define XCAN_SRR_OFFSET			0x00 /* Software reset */
+#define XCAN_MSR_OFFSET			0x04 /* Mode select */
+#define XCAN_BRPR_OFFSET		0x08 /* Baud rate prescaler */
+#define XCAN_BTR_OFFSET			0x0C /* Bit timing */
+#define XCAN_ECR_OFFSET			0x10 /* Error counter */
+#define XCAN_ESR_OFFSET			0x14 /* Error status */
+#define XCAN_SR_OFFSET			0x18 /* Status */
+#define XCAN_ISR_OFFSET			0x1C /* Interrupt status */
+#define XCAN_IER_OFFSET			0x20 /* Interrupt enable */
+#define XCAN_ICR_OFFSET			0x24 /* Interrupt clear */
+#define XCAN_TXFIFO_ID_OFFSET		0x30 /* TX FIFO ID */
+#define XCAN_TXFIFO_DLC_OFFSET		0x34 /* TX FIFO DLC */
+#define XCAN_TXFIFO_DW1_OFFSET		0x38 /* TX FIFO Data Word 1 */
+#define XCAN_TXFIFO_DW2_OFFSET		0x3C /* TX FIFO Data Word 2 */
+#define XCAN_RXFIFO_ID_OFFSET		0x50 /* RX FIFO ID */
+#define XCAN_RXFIFO_DLC_OFFSET		0x54 /* RX FIFO DLC */
+#define XCAN_RXFIFO_DW1_OFFSET		0x58 /* RX FIFO Data Word 1 */
+#define XCAN_RXFIFO_DW2_OFFSET		0x5C /* RX FIFO Data Word 2 */
+
+/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
+#define XCAN_SRR_CEN_MASK		0x00000002 /* CAN enable */
+#define XCAN_MSR_LBACK_MASK		0x00000002 /* Loop back mode select */
+#define XCAN_MSR_SLEEP_MASK		0x00000001 /* Sleep mode select */
+#define XCAN_BRPR_BRP_MASK		0x000000FF /* Baud rate prescaler */
+#define XCAN_BTR_SJW_MASK		0x00000180 /* Synchronous jump width */
+#define XCAN_BTR_TS2_MASK		0x00000070 /* Time segment 2 */
+#define XCAN_BTR_TS1_MASK		0x0000000F /* Time segment 1 */
+#define XCAN_ECR_REC_MASK		0x0000FF00 /* Receive error counter */
+#define XCAN_ECR_TEC_MASK		0x000000FF /* Transmit error counter */
+#define XCAN_ESR_ACKER_MASK		0x00000010 /* ACK error */
+#define XCAN_ESR_BERR_MASK		0x00000008 /* Bit error */
+#define XCAN_ESR_STER_MASK		0x00000004 /* Stuff error */
+#define XCAN_ESR_FMER_MASK		0x00000002 /* Form error */
+#define XCAN_ESR_CRCER_MASK		0x00000001 /* CRC error */
+#define XCAN_SR_TXFLL_MASK		0x00000400 /* TX FIFO is full */
+#define XCAN_SR_ESTAT_MASK		0x00000180 /* Error status */
+#define XCAN_SR_ERRWRN_MASK		0x00000040 /* Error warning */
+#define XCAN_SR_NORMAL_MASK		0x00000008 /* Normal mode */
+#define XCAN_SR_LBACK_MASK		0x00000002 /* Loop back mode */
+#define XCAN_SR_CONFIG_MASK		0x00000001 /* Configuration mode */
+#define XCAN_IXR_TXFEMP_MASK		0x00004000 /* TX FIFO Empty */
+#define XCAN_IXR_WKUP_MASK		0x00000800 /* Wake up interrupt */
+#define XCAN_IXR_SLP_MASK		0x00000400 /* Sleep interrupt */
+#define XCAN_IXR_BSOFF_MASK		0x00000200 /* Bus off interrupt */
+#define XCAN_IXR_ERROR_MASK		0x00000100 /* Error interrupt */
+#define XCAN_IXR_RXNEMP_MASK		0x00000080 /* RX FIFO NotEmpty intr */
+#define XCAN_IXR_RXOFLW_MASK		0x00000040 /* RX FIFO Overflow intr */
+#define XCAN_IXR_RXOK_MASK		0x00000010 /* Message received intr */
+#define XCAN_IXR_TXOK_MASK		0x00000002 /* TX successful intr */
+#define XCAN_IXR_ARBLST_MASK		0x00000001 /* Arbitration lost intr */
+#define XCAN_IDR_ID1_MASK		0xFFE00000 /* Standard msg identifier */
+#define XCAN_IDR_SRR_MASK		0x00100000 /* Substitute remote TXreq */
+#define XCAN_IDR_IDE_MASK		0x00080000 /* Identifier extension */
+#define XCAN_IDR_ID2_MASK		0x0007FFFE /* Extended message ident */
+#define XCAN_IDR_RTR_MASK		0x00000001 /* Remote TX request */
+#define XCAN_DLCR_DLC_MASK		0xF0000000 /* Data length code */
+
+/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
+#define XCAN_BTR_SJW_SHIFT		7  /* Synchronous jump width */
+#define XCAN_BTR_TS2_SHIFT		4  /* Time segment 2 */
+#define XCAN_IDR_ID1_SHIFT		21 /* Standard Messg Identifier */
+#define XCAN_IDR_ID2_SHIFT		1  /* Extended Message Identifier */
+#define XCAN_DLCR_DLC_SHIFT		28 /* Data length code */
+
+/* CAN frame length constants */
+#define XCAN_ECHO_SKB_MAX		64
+#define XCAN_FRAME_MAX_DATA_LEN		8
+#define XCAN_TIMEOUT			(50 * HZ)
+
+/**
+ * struct xcan_priv - This definition define CAN driver instance
+ * @can:			CAN private data structure.
+ * @open_time:			For holding timeout values
+ * @waiting_ech_skb_index:	Pointer for skb
+ * @ech_skb_next:		This tell the next packet in the queue
+ * @waiting_ech_skb_num:	Gives the number of packets waiting
+ * @xcan_echo_skb_max:		Maximum number packets the driver CAN send
+ * @ech_skb_lock:		For spinlock purpose
+ * @read_reg:			For reading data from CAN registers
+ * @write_reg:			For writing data to CAN registers
+ * @dev:			Network device data structure
+ * @reg_base:			Ioremapped address to registers
+ * @irq_flags:			For request_irq()
+ * @aperclk:			Pointer to struct clk
+ * @devclk:			Pointer to struct clk
+ */
+struct xcan_priv {
+	struct can_priv can;
+	int open_time;
+	int waiting_ech_skb_index;
+	int ech_skb_next;
+	int waiting_ech_skb_num;
+	int xcan_echo_skb_max;
+	spinlock_t ech_skb_lock;
+	u32 (*read_reg)(const struct xcan_priv *priv, int reg);
+	void (*write_reg)(const struct xcan_priv *priv, int reg, u32 val);
+	struct net_device *dev;
+	void __iomem *reg_base;
+	unsigned long irq_flags;
+	struct clk *aperclk;
+	struct clk *devclk;
+};
+
+/* CAN Bittiming constants as per Xilinx CAN specs */
+static struct can_bittiming_const xcan_bittiming_const = {
+	.name = DRIVER_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 1,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 1,
+};
+
+/**
+ * xcan_write_reg - Write a value to the device register
+ * @priv:	Driver private data structure
+ * @reg:	Register offset
+ * @val:	Value to write at the Register offset
+ *
+ * Write data to the paricular CAN register
+ */
+static void xcan_write_reg(const struct xcan_priv *priv, int reg, u32 val)
+{
+	writel(val, priv->reg_base + reg);
+}
+
+/**
+ * xcan_read_reg - Read a value from the device register
+ * @priv:	Driver private data structure
+ * @reg:	Register offset
+ *
+ * Read data from the particular CAN register
+ * Return: value read from the CAN register
+ */
+static u32 xcan_read_reg(const struct xcan_priv *priv, int reg)
+{
+	return readl(priv->reg_base + reg);
+}
+
+/**
+ * set_reset_mode - Resets the CAN device mode
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver reset mode routine.The driver
+ * enters into configuration mode.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int set_reset_mode(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	unsigned long timeout;
+
+	priv->can.state = CAN_STATE_STOPPED;
+	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_OFFSET);
+
+	timeout = jiffies + XCAN_TIMEOUT;
+	while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_CONFIG_MASK)) {
+		if (time_after(jiffies, timeout)) {
+			netdev_warn(ndev, "timedout waiting for config mode\n");
+			return -ETIMEDOUT;
+		}
+		schedule_timeout(1);
+	}
+
+	return 0;
+}
+
+/**
+ * xcan_set_bittiming - CAN set bit timing routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver setbittiming  routine.
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_set_bittiming(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 btr0, btr1;
+	u32 is_config_mode;
+
+	/* Check whether Xilinx CAN is in configuration mode.
+	 * It cannot set bit timing if Xilinx CAN is not in configuration mode.
+	 */
+	is_config_mode = priv->read_reg(priv, XCAN_SR_OFFSET) &
+				XCAN_SR_CONFIG_MASK;
+	if (!is_config_mode) {
+		netdev_alert(ndev,
+			"Cannot set bittiming can is not in config mode\n");
+		return -EPERM;
+	}
+
+	netdev_dbg(ndev, "brp=%d,prop=%d,phase_seg1:%d,phase_reg2=%d,sjw=%d\n",
+			bt->brp, bt->prop_seg, bt->phase_seg1, bt->phase_seg2,
+			bt->sjw);
+
+	/* Setting Baud Rate prescalar value in BRPR Register */
+	btr0 = (bt->brp - 1) & XCAN_BRPR_BRP_MASK;
+
+	/* Setting Time Segment 1 in BTR Register */
+	btr1 = (bt->prop_seg + bt->phase_seg1 - 1) & XCAN_BTR_TS1_MASK;
+
+	/* Setting Time Segment 2 in BTR Register */
+	btr1 |= ((bt->phase_seg2 - 1) << XCAN_BTR_TS2_SHIFT) &
+		XCAN_BTR_TS2_MASK;
+
+	/* Setting Synchronous jump width in BTR Register */
+	btr1 |= ((bt->sjw - 1) << XCAN_BTR_SJW_SHIFT) & XCAN_BTR_SJW_MASK;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+		netdev_info(ndev, "Doesn't support Triple Sampling\n");
+	netdev_dbg(ndev, "Setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+	priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0);
+	priv->write_reg(priv, XCAN_BTR_OFFSET, btr1);
+
+	netdev_dbg(ndev, "BRPR=0x%08x, BTR=0x%08x\n",
+			priv->read_reg(priv, XCAN_BRPR_OFFSET),
+			priv->read_reg(priv, XCAN_BTR_OFFSET));
+
+	return 0;
+}
+
+/**
+ * set_normal_mode - CAN device mode setting routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This routine sets the CAN device  mode.
+ * Return: 0 on success
+ */
+static int set_normal_mode(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	/* Enable interrupts */
+	priv->write_reg(priv, XCAN_IER_OFFSET, XCAN_IXR_TXOK_MASK |
+			XCAN_IXR_BSOFF_MASK | XCAN_IXR_WKUP_MASK |
+			XCAN_IXR_SLP_MASK | XCAN_IXR_RXNEMP_MASK |
+			XCAN_IXR_ERROR_MASK | XCAN_IXR_ARBLST_MASK);
+
+	/* Check whether it is loopback mode or normal mode  */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+		/* Put device into loopback mode */
+		priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_LBACK_MASK);
+	else
+		/* The device is in normal mode */
+		priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
+
+	if (priv->can.state == CAN_STATE_STOPPED) {
+		/* Enable Xilinx CAN */
+		priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+			while ((priv->read_reg(priv, XCAN_SR_OFFSET) &
+					XCAN_SR_LBACK_MASK) == 0)
+					;
+		} else {
+			while ((priv->read_reg(priv, XCAN_SR_OFFSET)
+					& XCAN_SR_NORMAL_MASK) == 0)
+					;
+		}
+		netdev_dbg(ndev, "status:#x%08x\n",
+				priv->read_reg(priv, XCAN_SR_OFFSET));
+	}
+
+	return 0;
+}
+
+/**
+ * xcan_start - This the drivers start routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the drivers start routine.
+ * Based on the State of the CAN device it puts
+ * the CAN device into a proper mode.
+ *
+ * Return: 0 on success, negative errno otherwise
+ */
+static int xcan_start(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	/* Check if it is in reset mode */
+	if (priv->can.state != CAN_STATE_STOPPED)
+		set_reset_mode(ndev);
+
+	/* Leave reset mode */
+	return set_normal_mode(ndev);
+}
+
+/**
+ * xcan_do_set_mode - This sets the mode of the driver
+ * @ndev:	Pointer to net_device structure
+ * @mode:	Tells the mode of the driver
+ *
+ * This check the drivers state and calls the
+ * the corresponding modes to set.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	netdev_dbg(ndev, "Setting the mode of the driver%s\n", __func__);
+
+	if (!priv->open_time)
+		return -EINVAL;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		ret = xcan_start(ndev);
+		if (ret < 0)
+			netdev_err(ndev, "xcan_start failed!\n");
+
+		if (netif_queue_stopped(ndev))
+			netif_wake_queue(ndev);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * xcan_start_xmit - Starts the transmission
+ * @skb:	sk_buff pointer that contains data to be Txed
+ * @ndev:	Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate transmission. This
+ * function uses the next available free txbuff and populates their fields to
+ * start the transmission.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, dlc, tmp_dw1, tmp_dw2 = 0, data1, data2 = 0;
+	unsigned long flags;
+
+	/* Check if the TX buffer is full */
+	if (priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_TXFLL_MASK) {
+		netif_stop_queue(ndev);
+		netdev_err(ndev, "TX register is still full!\n");
+		return NETDEV_TX_BUSY;
+	} else if (priv->waiting_ech_skb_num == priv->xcan_echo_skb_max) {
+		netdev_err(ndev, "waiting:0x%08x, max:0x%08x\n",
+			priv->waiting_ech_skb_num, priv->xcan_echo_skb_max);
+		/* Theoretically, if TX interrupts get lost, we might end here
+		 * without ever recovering.Check if TX FIFO is empty recover
+		 * in this case
+		 */
+		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK);
+		netdev_err(ndev, "Trying to recover...\n");
+		if (priv->read_reg(priv, XCAN_ISR_OFFSET) &
+				XCAN_IXR_TXFEMP_MASK) {
+			spin_lock_irqsave(&priv->ech_skb_lock, flags);
+			while (priv->waiting_ech_skb_num > 0) {
+				spin_unlock_irqrestore(&priv->ech_skb_lock,
+				flags);
+				can_get_echo_skb(ndev,
+				priv->waiting_ech_skb_index);
+				priv->waiting_ech_skb_index =
+					(priv->waiting_ech_skb_index + 1) %
+					priv->xcan_echo_skb_max;
+				spin_lock_irqsave(&priv->ech_skb_lock, flags);
+				priv->waiting_ech_skb_num--;
+			}
+			spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
+			netdev_err(ndev, "...recovered!\n");
+		} else {
+			netdev_err(ndev, "...could not recover (yet)!\n");
+		}
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Watch carefully on the bit sequence */
+	if ((cf->can_id & CAN_EFF_FLAG) == 0) {
+		/* Standard CAN ID format */
+		id = ((cf->can_id & CAN_SFF_MASK) << XCAN_IDR_ID1_SHIFT) &
+			XCAN_IDR_ID1_MASK;
+
+		if ((cf->can_id & CAN_RTR_FLAG) != 0)
+			/* Extended frames remote TX request */
+			id |= XCAN_IDR_SRR_MASK;
+	} else {
+		/* Extended CAN ID formact */
+		id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT) &
+			XCAN_IDR_ID2_MASK;
+		id |= (((cf->can_id & CAN_EFF_MASK) >>
+			(CAN_EFF_ID_BITS-CAN_SFF_ID_BITS)) <<
+			XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK;
+
+		/* The substibute remote TX request bit should be "1"
+		 * for extended frames as in the Xilinx CAN datasheet
+		 */
+		id |= XCAN_IDR_IDE_MASK | XCAN_IDR_SRR_MASK;
+
+		if (cf->can_id & CAN_RTR_FLAG)
+			/* Extended frames remote TX request */
+			id |= XCAN_IDR_RTR_MASK;
+	}
+
+	dlc = (cf->can_dlc & 0xf) << XCAN_DLCR_DLC_SHIFT;
+
+	tmp_dw1 = le32_to_cpup((u32 *)(cf->data));
+	data1 = htonl(tmp_dw1);
+	if (dlc > 4) {
+		tmp_dw2 = le32_to_cpup((u32 *)(cf->data + 4));
+		data2 = htonl(tmp_dw2);
+	}
+
+	netdev_dbg(ndev, "can:id=0x%08x,dlc=0x%08x,d1=0x%08x,d2=0x%08x\n",
+			cf->can_id, cf->can_dlc, tmp_dw1, tmp_dw2);
+	netdev_dbg(ndev, "tx:id=0x%08x,dlc=0x%08x,d1=0x%08x,d2=0x%08x\n",
+			id, dlc, data1, data2);
+
+	/* Write the Frame to Xilinx CAN TX FIFO */
+	priv->write_reg(priv, XCAN_TXFIFO_ID_OFFSET, id);
+	priv->write_reg(priv, XCAN_TXFIFO_DLC_OFFSET, dlc);
+	priv->write_reg(priv, XCAN_TXFIFO_DW1_OFFSET, data1);
+	priv->write_reg(priv, XCAN_TXFIFO_DW2_OFFSET, data2);
+	stats->tx_bytes += (dlc & 0xf);
+	ndev->trans_start = jiffies;
+
+	can_put_echo_skb(skb, ndev, priv->ech_skb_next);
+
+	priv->ech_skb_next = (priv->ech_skb_next + 1) % priv->xcan_echo_skb_max;
+
+	spin_lock_irqsave(&priv->ech_skb_lock, flags);
+	priv->waiting_ech_skb_num++;
+	spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * xcan_rx -  Is called from CAN isr to complete the received
+ *		frame  processing
+ * @ndev:	Pointer to net_device structure
+ *
+ * This function is invoked from the CAN isr to process the Rx frames. It
+ * does minimal processing and invokes "netif_rx" to complete further
+ * processing.
+ */
+static void xcan_rx(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 id_xcan, dlc, tmp_dw1, tmp_dw2, data1, data2 = 0;
+
+	skb = alloc_can_skb(ndev, &cf);
+	if (!skb)
+		return;
+
+	/* Read a frame from Xilinx zynq CANPS */
+	id_xcan = priv->read_reg(priv, XCAN_RXFIFO_ID_OFFSET);
+	dlc = priv->read_reg(priv, XCAN_RXFIFO_DLC_OFFSET) & XCAN_DLCR_DLC_MASK;
+	tmp_dw1 = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
+	tmp_dw2 = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
+	netdev_dbg(ndev, "rx:id=0x%08x,dlc=0x%08x,d1=0x%08x,d2=0x%08x\n",
+		id_xcan, dlc, tmp_dw1, tmp_dw2);
+
+	/* Change Xilinx CAN data length format to socketCAN data format */
+	cf->can_dlc = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
+				XCAN_DLCR_DLC_SHIFT);
+
+	/* Change Xilinx CAN ID format to socketCAN ID format */
+	if (id_xcan & XCAN_IDR_IDE_MASK) {
+		/* The received frame is an Extended format frame */
+		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
+		cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
+				XCAN_IDR_ID2_SHIFT;
+		cf->can_id |= CAN_EFF_FLAG;
+		if (id_xcan & XCAN_IDR_RTR_MASK)
+			cf->can_id |= CAN_RTR_FLAG;
+	} else {
+		/* The received frame is a standard format frame */
+		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
+				XCAN_IDR_ID1_SHIFT;
+		if (id_xcan & XCAN_IDR_RTR_MASK)
+			cf->can_id |= CAN_RTR_FLAG;
+	}
+
+	/* Change Xilinx CAN data format to socketCAN data format */
+	data1 = cpu_to_le32((u32 *)tmp_dw1);
+	*(u32 *)(cf->data) = ntohl(data1);
+	if (cf->can_dlc > 4) {
+		data2 = cpu_to_le32((u32 *)tmp_dw2);
+		*(u32 *)(cf->data+4) = ntohl(data2);
+	} else {
+		*(u32 *)(cf->data+4) = 0;
+	}
+	stats->rx_bytes += cf->can_dlc;
+
+	can_led_event(ndev, CAN_LED_EVENT_RX);
+
+	netif_rx(skb);
+
+	stats->rx_packets++;
+}
+
+/**
+ * xcan_err_interrupt - error frame Isr
+ * @ndev:	net_device pointer
+ * @isr:	Interrupts status register value
+ *
+ * This is the CAN error interrupt and it will
+ * check the the type of error and forward the error
+ * frame to upper layers.
+ */
+static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 err_status, status;
+	u8 i;
+
+	skb = alloc_can_err_skb(ndev, &cf);
+	if (!skb)
+		return;
+
+	err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
+	status = priv->read_reg(priv, XCAN_SR_OFFSET);
+
+	cf->can_id = CAN_ERR_FLAG;
+	memset(cf->data, 0, sizeof(cf->data));
+
+	if (isr & XCAN_IXR_BSOFF_MASK) {
+		cf->can_id |= CAN_ERR_BUSOFF;
+		priv->can.state = CAN_STATE_BUS_OFF;
+		can_bus_off(ndev);
+	} else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) {
+		cf->can_id |= CAN_ERR_CRTL;
+		priv->can.state = CAN_STATE_ERROR_PASSIVE;
+		cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE |
+					CAN_ERR_CRTL_TX_PASSIVE;
+	} else if (status & XCAN_SR_ERRWRN_MASK) {
+		cf->can_id |= CAN_ERR_CRTL;
+		priv->can.state = CAN_STATE_ERROR_WARNING;
+		cf->data[1] |= CAN_ERR_CRTL_RX_WARNING |
+					CAN_ERR_CRTL_TX_WARNING;
+	}
+
+	/* Check for Arbitration lost interrupt */
+	if (isr & XCAN_IXR_ARBLST_MASK) {
+		cf->can_id |= CAN_ERR_LOSTARB;
+		cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
+	}
+
+	/* Check for RX FIFO Overflow interrupt */
+	if (isr & XCAN_IXR_RXOFLW_MASK) {
+		cf->can_id |= CAN_ERR_CRTL;
+		cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* Check for error interrupt */
+	if (isr & XCAN_IXR_ERROR_MASK)
+		cf->can_id |= CAN_ERR_PROT;
+
+	/* Check for Ack error interrupt */
+	if (err_status & XCAN_ESR_ACKER_MASK)
+		cf->can_id |= CAN_ERR_ACK;
+
+	/* Check for Bit error interrupt */
+	if (err_status & XCAN_ESR_BERR_MASK) {
+		cf->can_id |= CAN_ERR_PROT;
+		cf->data[2] = CAN_ERR_PROT_BIT;
+	}
+
+	/* Check for Stuff error interrupt */
+	if (err_status & XCAN_ESR_STER_MASK) {
+		cf->can_id |= CAN_ERR_PROT;
+		cf->data[2] = CAN_ERR_PROT_STUFF;
+	}
+
+	/* Check for Form error interrupt */
+	if (err_status & XCAN_ESR_FMER_MASK) {
+		cf->can_id |= CAN_ERR_PROT;
+		cf->data[2] = CAN_ERR_PROT_FORM;
+	}
+
+	/* Check for CRC error interrupt */
+	if (err_status & XCAN_ESR_CRCER_MASK) {
+		cf->can_id |= CAN_ERR_PROT;
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ |
+				CAN_ERR_PROT_LOC_CRC_DEL;
+	}
+
+	for (i = 0; i < XCAN_FRAME_MAX_DATA_LEN; )
+		if (cf->data[i++] != 0)
+			cf->can_dlc = i;
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+
+	priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);
+	netdev_dbg(ndev, "%s: error status register:0x%x\n",
+			__func__, priv->read_reg(priv, XCAN_ESR_OFFSET));
+}
+
+/**
+ * xcan_state_interrupt - It will check the state of the CAN device
+ * @ndev:	net_device pointer
+ * @isr:	interrupt status register value
+ *
+ * This will checks the state of the CAN device
+ * and puts the device into appropriate state.
+ */
+static void xcan_state_interrupt(struct net_device *ndev, u32 isr)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	/* Check for Sleep interrupt if set put CAN device in sleep state */
+	if (isr & XCAN_IXR_SLP_MASK)
+		priv->can.state = CAN_STATE_SLEEPING;
+
+	/* Check for Wake up interrupt if set put CAN device in Active state */
+	if (isr & XCAN_IXR_WKUP_MASK)
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+/**
+ * xcan_rx_interrupt - Rx Isr
+ * @ndev:	net_device pointer
+ *
+ * This is the CAN Rx Isr. It invokes "xcan_rx" to complete the
+ * received frame processing.
+ */
+static void xcan_rx_interrupt(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	u32 isr;
+
+	/* FIXME - Need to implement NAPI */
+	do {
+		xcan_rx(ndev);
+		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK);
+		isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+		netdev_dbg(ndev, "received one packet\n");
+	} while (isr & XCAN_IXR_RXNEMP_MASK);
+}
+
+/**
+ * xcan_tx_interrupt - Tx Done Isr
+ * @ndev:	net_device pointer
+ */
+static void xcan_tx_interrupt(struct net_device *ndev)
+{
+	unsigned long flags;
+	struct xcan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+
+	stats->tx_packets++;
+	netdev_dbg(ndev, "%s: waiting total:%d,current:%d\n", __func__,
+			priv->waiting_ech_skb_num, priv->waiting_ech_skb_index);
+
+	spin_lock_irqsave(&priv->ech_skb_lock, flags);
+
+	if (priv->waiting_ech_skb_num != 0) {
+		spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
+		can_get_echo_skb(ndev, priv->waiting_ech_skb_index);
+		priv->waiting_ech_skb_index =
+			(priv->waiting_ech_skb_index + 1) %
+			priv->xcan_echo_skb_max;
+		spin_lock_irqsave(&priv->ech_skb_lock, flags);
+		priv->waiting_ech_skb_num--;
+	}
+	spin_unlock_irqrestore(&priv->ech_skb_lock, flags);
+
+	netdev_dbg(ndev, "%s: waiting total:%d,current:%d\n", __func__,
+			priv->waiting_ech_skb_num, priv->waiting_ech_skb_index);
+
+	netif_wake_queue(ndev);
+
+	can_led_event(ndev, CAN_LED_EVENT_TX);
+}
+
+/**
+ * xcan_interrupt - CAN Isr
+ * @irq:	irq number
+ * @dev_id:	device id poniter
+ *
+ * This is the xilinx CAN Isr. It checks for the type of interrupt
+ * and invokes the corresponding ISR.
+ *
+ * Return:
+ * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
+ */
+static irqreturn_t xcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = (struct net_device *)dev_id;
+	struct xcan_priv *priv = netdev_priv(ndev);
+	u32 isr;
+
+	if (priv->can.state == CAN_STATE_STOPPED)
+		return IRQ_NONE;
+
+	/* Get the interrupt status from Xilinx CAN */
+	isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+	priv->write_reg(priv, XCAN_ICR_OFFSET, isr);
+	netdev_dbg(ndev, "%s: isr:#x%08x, err:#x%08x\n", __func__,
+			isr, priv->read_reg(priv, XCAN_ESR_OFFSET));
+
+	/* Check for the type of interrupt and Processing it */
+	if (isr & (XCAN_IXR_SLP_MASK | XCAN_IXR_WKUP_MASK))
+		xcan_state_interrupt(ndev, isr);
+
+	/* Check for the type of error interrupt and Processing it */
+	if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
+			XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK))
+		xcan_err_interrupt(ndev, isr);
+
+	/* Check for Rx interrupt and Processing it */
+	if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK))
+		xcan_rx_interrupt(ndev);
+
+	/* Check for Tx interrupt and Processing it */
+	if (isr & XCAN_IXR_TXOK_MASK)
+		xcan_tx_interrupt(ndev);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xcan_open - Driver open routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * This is the driver open routine.
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_open(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	int err;
+
+	/* Set chip into reset mode */
+	err = set_reset_mode(ndev);
+	if (err < 0)
+		netdev_err(ndev, "mode resetting failed failed!\n");
+
+	/* Common open */
+	err = open_candev(ndev);
+	if (err)
+		return err;
+
+	err = xcan_start(ndev);
+	if (err < 0)
+		netdev_err(ndev, "xcan_start failed!\n");
+
+	priv->open_time = jiffies;
+
+	can_led_event(ndev, CAN_LED_EVENT_OPEN);
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+/**
+ * xcan_close - Driver stop routine
+ * @ndev:	Pointer to net_device structure
+ *
+ * Return: 0 on success
+ */
+static int xcan_close(struct net_device *ndev)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	netif_stop_queue(ndev);
+	if (set_reset_mode(ndev) < 0)
+		netdev_err(ndev, "mode resetting failed failed!\n");
+
+	close_candev(ndev);
+
+	priv->open_time = 0;
+
+	can_led_event(ndev, CAN_LED_EVENT_STOP);
+
+	return 0;
+}
+
+/**
+ * xcan_get_berr_counter - error counter routine
+ * @ndev:	Pointer to net_device structure
+ * @bec:	Pointer to can_berr_counter structure
+ *
+ * This is the driver error counter routine.
+ * Return: 0 on success
+ */
+static int xcan_get_berr_counter(const struct net_device *ndev,
+					struct can_berr_counter *bec)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_REC_MASK;
+	bec->rxerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
+	netdev_dbg(ndev, "Bus Tx err count=0x%08x,Bus Rx err count=0x%08x\n",
+			bec->txerr, bec->rxerr);
+	return 0;
+}
+
+static const struct net_device_ops xcan_netdev_ops = {
+	.ndo_open	= xcan_open,
+	.ndo_stop	= xcan_close,
+	.ndo_start_xmit	= xcan_start_xmit,
+};
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xcan_suspend - Suspend method for the driver
+ * @_dev:	Address of the platform_device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 on success
+ */
+static int xcan_suspend(struct device *_dev)
+{
+	struct platform_device *pdev = container_of(_dev,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	if (netif_running(ndev)) {
+		netif_stop_queue(ndev);
+		netif_device_detach(ndev);
+	}
+
+	priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_SLEEP_MASK);
+	priv->can.state = CAN_STATE_SLEEPING;
+
+	clk_disable(priv->aperclk);
+	clk_disable(priv->devclk);
+
+	return 0;
+}
+
+/**
+ * xcan_resume - Resume from suspend
+ * @dev:	Address of the platformdevice structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success
+ */
+static int xcan_resume(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct xcan_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = clk_enable(priv->aperclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable clock.\n");
+		return ret;
+	}
+	ret = clk_enable(priv->devclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable clock.\n");
+		return ret;
+	}
+
+	priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
+	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	if (netif_running(ndev)) {
+		netif_device_attach(ndev);
+		netif_start_queue(ndev);
+	}
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+
+/**
+ * xcan_probe - Platform registration call
+ * @pdev:	Handle to the platform device structure
+ *
+ * This function does all the memory allocation and registration for the CAN
+ * device.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_probe(struct platform_device *pdev)
+{
+	struct resource *res; /* IO mem resources */
+	struct net_device *ndev;
+	struct xcan_priv *priv;
+	struct device *dev = &pdev->dev;
+	int ret, irq;
+
+	/* Create a CAN device instance */
+	ndev = alloc_candev(sizeof(struct xcan_priv), XCAN_ECHO_SKB_MAX);
+	if (!ndev)
+		return -ENOMEM;
+
+	priv = netdev_priv(ndev);
+	priv->dev = ndev;
+	priv->can.bittiming_const = &xcan_bittiming_const;
+	priv->can.do_set_bittiming = xcan_set_bittiming;
+	priv->can.do_set_mode = xcan_do_set_mode;
+	priv->can.do_get_berr_counter = xcan_get_berr_counter;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK;
+	priv->waiting_ech_skb_index = 0;
+	priv->ech_skb_next = 0;
+	priv->waiting_ech_skb_num = 0;
+	priv->xcan_echo_skb_max = XCAN_ECHO_SKB_MAX;
+
+	/* Get IRQ for the device */
+	ndev->irq = platform_get_irq(pdev, 0);
+	irq = devm_request_irq(&pdev->dev, ndev->irq, &xcan_interrupt,
+				priv->irq_flags, dev_name(&pdev->dev),
+				(void *)ndev);
+	if (irq < 0) {
+		ret = irq;
+		dev_err(&pdev->dev, "Irq allocation for CAN failed\n");
+		goto err_free;
+	}
+
+	spin_lock_init(&priv->ech_skb_lock);
+	ndev->flags |= IFF_ECHO;	/* We support local echo */
+
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+	ndev->netdev_ops = &xcan_netdev_ops;
+
+	/* Get the virtual base address for the device */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->reg_base)) {
+		ret = PTR_ERR(priv->reg_base);
+		goto err_free;
+	}
+	ndev->mem_start = res->start;
+	ndev->mem_end = res->end;
+
+	priv->write_reg	= xcan_write_reg;
+	priv->read_reg = xcan_read_reg;
+
+	/* Getting the CAN devclk info */
+	priv->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(priv->devclk)) {
+		dev_err(&pdev->dev, "Device clock not found.\n");
+		ret = PTR_ERR(priv->devclk);
+		goto err_free;
+	}
+
+	/* Check for type of CAN device */
+	if (of_device_is_compatible(pdev->dev.of_node, "xlnx,ps7-can")) {
+		priv->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+		if (IS_ERR(priv->aperclk)) {
+			dev_err(&pdev->dev, "aper clock not found\n");
+			ret = PTR_ERR(priv->aperclk);
+			goto err_free;
+		}
+	} else {
+		priv->aperclk = priv->devclk;
+	}
+
+	ret = clk_prepare_enable(priv->devclk);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable device clock\n");
+		goto err_free;
+	}
+
+	ret = clk_prepare_enable(priv->aperclk);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable aper clock\n");
+		goto err_unprepar_disabledev;
+	}
+
+	priv->can.clock.freq = clk_get_rate(priv->devclk);
+
+	ret = register_candev(ndev);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
+		goto err_unprepar_disableaper;
+	}
+
+	dev_info(&pdev->dev,
+			"reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
+			priv->reg_base, ndev->irq, priv->can.clock.freq,
+			priv->xcan_echo_skb_max);
+
+	return 0;
+
+err_unprepar_disableaper:
+	clk_disable_unprepare(priv->aperclk);
+err_unprepar_disabledev:
+	clk_disable_unprepare(priv->devclk);
+err_free:
+	free_candev(ndev);
+
+	return ret;
+}
+
+/**
+ * xcan_remove - Unregister the device after releasing the resources
+ * @pdev:	Handle to the platform device structure
+ *
+ * This function frees all the resources allocated to the device.
+ * Return: 0 on success
+ */
+static int xcan_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct xcan_priv *priv = netdev_priv(ndev);
+
+	if (set_reset_mode(ndev) < 0)
+		netdev_err(ndev, "mode resetting failed!\n");
+
+	unregister_candev(ndev);
+	clk_disable_unprepare(priv->aperclk);
+	clk_disable_unprepare(priv->devclk);
+
+	free_candev(ndev);
+
+	return 0;
+}
+
+/* Match table for OF platform binding */
+static struct of_device_id xcan_of_match[] = {
+	{ .compatible = "xlnx,ps7-can", },
+	{ .compatible = "xlnx,axi-can-1.00.a", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xcan_of_match);
+
+static struct platform_driver xcan_driver = {
+	.probe = xcan_probe,
+	.remove	= xcan_remove,
+	.driver	= {
+		.owner = THIS_MODULE,
+		.name = DRIVER_NAME,
+		.pm = &xcan_dev_pm_ops,
+		.of_match_table	= xcan_of_match,
+	},
+};
+
+module_platform_driver(xcan_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Xilinx Inc");
+MODULE_DESCRIPTION("Xilinx CAN interface");
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/cadence/macb.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/cadence/macb.c	2014-07-20 22:05:50.252066357 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/cadence/macb.c	2014-07-20 22:06:36.965295673 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:20 @
 #include <linux/circ_buf.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:207 @
 	return 0;
 }
 
+/**
+ * macb_set_tx_clk() - Set a clock to a new frequency
+ * @clk		Pointer to the clock to change
+ * @rate	New frequency in Hz
+ * @dev		Pointer to the struct net_device
+ */
+static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
+{
+	long ferr, rate, rate_rounded;
+
+	switch (speed) {
+	case SPEED_10:
+		rate = 2500000;
+		break;
+	case SPEED_100:
+		rate = 25000000;
+		break;
+	case SPEED_1000:
+		rate = 125000000;
+		break;
+	default:
+		return;
+	}
+
+	rate_rounded = clk_round_rate(clk, rate);
+	if (rate_rounded < 0)
+		return;
+
+	/* RGMII allows 50 ppm frequency error. Test and warn if this limit
+	 * is not satisfied.
+	 */
+	ferr = abs(rate_rounded - rate);
+	ferr = DIV_ROUND_UP(ferr, rate / 100000);
+	if (ferr > 5)
+		netdev_warn(dev, "unable to generate target frequency: %ld Hz\n",
+				rate);
+
+	if (clk_set_rate(clk, rate_rounded))
+		netdev_err(dev, "adjusting tx_clk failed.\n");
+}
+
 static void macb_handle_link_change(struct net_device *dev)
 {
 	struct macb *bp = netdev_priv(dev);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:295 @
 
 	spin_unlock_irqrestore(&bp->lock, flags);
 
+	if (!IS_ERR(bp->tx_clk))
+		macb_set_tx_clk(bp->tx_clk, phydev->speed, dev);
+
 	if (status_change) {
 		if (phydev->link) {
 			netif_carrier_on(dev);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1838 @
 	spin_lock_init(&bp->lock);
 	INIT_WORK(&bp->tx_error_task, macb_tx_error_task);
 
-	bp->pclk = clk_get(&pdev->dev, "pclk");
+	bp->pclk = devm_clk_get(&pdev->dev, "pclk");
 	if (IS_ERR(bp->pclk)) {
-		dev_err(&pdev->dev, "failed to get macb_clk\n");
+		err = PTR_ERR(bp->pclk);
+		dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err);
 		goto err_out_free_dev;
 	}
-	clk_prepare_enable(bp->pclk);
 
-	bp->hclk = clk_get(&pdev->dev, "hclk");
+	bp->hclk = devm_clk_get(&pdev->dev, "hclk");
 	if (IS_ERR(bp->hclk)) {
-		dev_err(&pdev->dev, "failed to get hclk\n");
-		goto err_out_put_pclk;
+		err = PTR_ERR(bp->hclk);
+		dev_err(&pdev->dev, "failed to get hclk (%u)\n", err);
+		goto err_out_free_dev;
+	}
+
+	bp->tx_clk = devm_clk_get(&pdev->dev, "tx_clk");
+
+	err = clk_prepare_enable(bp->pclk);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err);
+		goto err_out_free_dev;
+	}
+
+	err = clk_prepare_enable(bp->hclk);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err);
+		goto err_out_disable_pclk;
+	}
+
+	if (!IS_ERR(bp->tx_clk)) {
+		err = clk_prepare_enable(bp->tx_clk);
+		if (err) {
+			dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n",
+					err);
+			goto err_out_disable_hclk;
+		}
 	}
-	clk_prepare_enable(bp->hclk);
 
-	bp->regs = ioremap(regs->start, resource_size(regs));
+	bp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
 	if (!bp->regs) {
 		dev_err(&pdev->dev, "failed to map registers, aborting.\n");
 		err = -ENOMEM;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1883 @
 	}
 
 	dev->irq = platform_get_irq(pdev, 0);
-	err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev);
+	err = devm_request_irq(&pdev->dev, dev->irq, macb_interrupt, 0,
+			dev->name, dev);
 	if (err) {
 		dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n",
 			dev->irq, err);
-		goto err_out_iounmap;
+		goto err_out_disable_clocks;
 	}
 
 	dev->netdev_ops = &macb_netdev_ops;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1951 @
 	err = register_netdev(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-		goto err_out_free_irq;
+		goto err_out_disable_clocks;
 	}
 
 	err = macb_mii_init(bp);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1974 @
 
 err_out_unregister_netdev:
 	unregister_netdev(dev);
-err_out_free_irq:
-	free_irq(dev->irq, dev);
-err_out_iounmap:
-	iounmap(bp->regs);
 err_out_disable_clocks:
+	if (!IS_ERR(bp->tx_clk))
+		clk_disable_unprepare(bp->tx_clk);
+err_out_disable_hclk:
 	clk_disable_unprepare(bp->hclk);
-	clk_put(bp->hclk);
+err_out_disable_pclk:
 	clk_disable_unprepare(bp->pclk);
-err_out_put_pclk:
-	clk_put(bp->pclk);
 err_out_free_dev:
 	free_netdev(dev);
 err_out:
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2002 @
 		kfree(bp->mii_bus->irq);
 		mdiobus_free(bp->mii_bus);
 		unregister_netdev(dev);
-		free_irq(dev->irq, dev);
-		iounmap(bp->regs);
+		if (!IS_ERR(bp->tx_clk))
+			clk_disable_unprepare(bp->tx_clk);
 		clk_disable_unprepare(bp->hclk);
-		clk_put(bp->hclk);
 		clk_disable_unprepare(bp->pclk);
-		clk_put(bp->pclk);
 		free_netdev(dev);
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2013 @
 }
 
 #ifdef CONFIG_PM
-static int macb_suspend(struct platform_device *pdev, pm_message_t state)
+static int macb_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct net_device *netdev = platform_get_drvdata(pdev);
 	struct macb *bp = netdev_priv(netdev);
 
 	netif_carrier_off(netdev);
 	netif_device_detach(netdev);
 
+	if (!IS_ERR(bp->tx_clk))
+		clk_disable_unprepare(bp->tx_clk);
 	clk_disable_unprepare(bp->hclk);
 	clk_disable_unprepare(bp->pclk);
 
 	return 0;
 }
 
-static int macb_resume(struct platform_device *pdev)
+static int macb_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct net_device *netdev = platform_get_drvdata(pdev);
 	struct macb *bp = netdev_priv(netdev);
 
 	clk_prepare_enable(bp->pclk);
 	clk_prepare_enable(bp->hclk);
+	if (!IS_ERR(bp->tx_clk))
+		clk_prepare_enable(bp->tx_clk);
 
 	netif_device_attach(netdev);
 
 	return 0;
 }
-#else
-#define macb_suspend	NULL
-#define macb_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(macb_pm_ops, macb_suspend, macb_resume);
+
 static struct platform_driver macb_driver = {
 	.remove		= __exit_p(macb_remove),
-	.suspend	= macb_suspend,
-	.resume		= macb_resume,
 	.driver		= {
 		.name		= "macb",
 		.owner	= THIS_MODULE,
 		.of_match_table	= of_match_ptr(macb_dt_ids),
+		.pm	= &macb_pm_ops,
 	},
 };
 
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/cadence/macb.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/cadence/macb.h	2014-07-20 22:05:50.251066373 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/cadence/macb.h	2014-07-20 22:06:36.979295442 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:575 @
 	struct platform_device	*pdev;
 	struct clk		*pclk;
 	struct clk		*hclk;
+	struct clk		*tx_clk;
 	struct net_device	*dev;
 	struct napi_struct	napi;
 	struct work_struct	tx_error_task;
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/Kconfig	2014-07-20 22:05:50.257066275 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/Kconfig	2014-07-20 22:06:37.007294980 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:30 @
 
 config XILINX_AXI_EMAC
 	tristate "Xilinx 10/100/1000 AXI Ethernet support"
-	depends on MICROBLAZE
+	depends on (MICROBLAZE || ARCH_ZYNQ)
 	select PHYLIB
 	---help---
 	  This driver supports the 10/100/1000 Ethernet from Xilinx for the
 	  AXI bus interface used in Xilinx Virtex FPGAs.
 
-config XILINX_LL_TEMAC
-	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
-	depends on (PPC || MICROBLAZE)
+#config XILINX_LL_TEMAC
+#	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
+#	depends on (PPC || MICROBLAZE)
+#	select PHYLIB
+#	---help---
+#	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
+#	  core used in Xilinx Spartan and Virtex FPGAs
+
+config XILINX_LLTEMAC
+	tristate "Xilinx LLTEMAC 10/100/1000 Ethernet MAC driver"
+	depends on XILINX_DRIVERS
+	select XILINX_EDK
+	select NEED_XILINX_LLDMA
+	help
+	  This driver supports the 10/100/1000 LLTEMAC.
+
+choice
+	prompt "Xilinx LLTEMAC PHY Support"
+	depends on XILINX_LLTEMAC
+	default XILINX_LLTEMAC_MARVELL_88E1111_GMII
+
+config XILINX_LLTEMAC_MARVELL_88E1111_RGMII
+	bool "MARVELL 88E1111 using RGMII"
+   help
+	  This phy is used by many Xilinx boards.  This option includes
+	  code for enabling RGMII over copper.
+
+config XILINX_LLTEMAC_MARVELL_88E1111_GMII
+	bool "MARVELL 88E1111 using GMII"
+   help
+	  This phy is used by many Xilinx boards.  This option includes
+	  code for enabling GMII over copper, and for setting the correct
+	  speed based on whatever the phy is able to autonegotiate.  This is
+	  usually the best option to use on ML40x and ML50x boards.
+
+config XILINX_LLTEMAC_MARVELL_88E1111_MII
+	bool "MARVELL 88E1111 using MII or other PHY"
+   help
+	  If your physical interface is not covered by the other
+	  selections, then choose this option.  This option includes generic
+	  speed autonegotation code.
+
+config XILINX_LLTEMAC_XILINX_1000BASEX
+	bool "Xilinx 1000BASE-X PHY"
+	help
+	  This PHY supports physical attachment via GT/GTP/GTX transceivers.
+
+endchoice
+
+config XILINX_PS_EMAC
+	tristate "Xilinx PS tri-speed EMAC support"
+	depends on ARCH_ZYNQ
 	select PHYLIB
 	---help---
-	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
-	  core used in Xilinx Spartan and Virtex FPGAs
+	  This driver supports tri-speed EMAC.
+
+config XILINX_PS_EMAC_HWTSTAMP
+	bool "Generate hardware packet timestamps"
+	depends on XILINX_PS_EMAC
+	default n
+	---help---
+	  Generate hardare packet timestamps. This is to facilitate IEE 1588.
+
 
 endif # NET_VENDOR_XILINX
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/ll_temac_main.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/ll_temac_main.c	2014-07-20 22:05:50.253066340 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/ll_temac_main.c	2014-07-20 22:06:37.021294749 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:687 @
 	skb_frag_t *frag;
 
 	num_frag = skb_shinfo(skb)->nr_frags;
-	frag = &skb_shinfo(skb)->frags[0];
 	start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
 	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
 	if (temac_check_tx_bd_space(lp, num_frag)) {
-		if (!netif_queue_stopped(ndev)) {
+		if (!netif_queue_stopped(ndev))
 			netif_stop_queue(ndev);
-			return NETDEV_TX_BUSY;
-		}
 		return NETDEV_TX_BUSY;
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:708 @
 
 	cur_p->app0 |= STS_CTRL_APP0_SOP;
 	cur_p->len = skb_headlen(skb);
-	cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
-				     DMA_TO_DEVICE);
+	cur_p->phys = dma_map_single(ndev->dev.parent, skb->data,
+				skb_headlen(skb), DMA_TO_DEVICE);
 	cur_p->app4 = (unsigned long)skb;
 
 	for (ii = 0; ii < num_frag; ii++) {
+		frag = &skb_shinfo(skb)->frags[ii];
 		lp->tx_bd_tail++;
 		if (lp->tx_bd_tail >= TX_BD_NUM)
 			lp->tx_bd_tail = 0;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:724 @
 					     skb_frag_size(frag), DMA_TO_DEVICE);
 		cur_p->len = skb_frag_size(frag);
 		cur_p->app0 = 0;
-		frag++;
 	}
 	cur_p->app0 |= STS_CTRL_APP0_EOP;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1051 @
 	/* Setup checksum offload, but default to off if not specified */
 	lp->temac_features = 0;
 	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
+	dev_info(&op->dev, "TX_CSUM %d\n", be32_to_cpup(p));
 	if (p && be32_to_cpu(*p)) {
 		lp->temac_features |= TEMAC_FEATURE_TX_CSUM;
 		/* Can checksum TCP/UDP over IPv4. */
 		ndev->features |= NETIF_F_IP_CSUM;
 	}
 	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
+	dev_info(&op->dev, "RX_CSUM %d\n", be32_to_cpup(p));
 	if (p && be32_to_cpu(*p))
 		lp->temac_features |= TEMAC_FEATURE_RX_CSUM;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1106 @
 	}
 	temac_init_mac_address(ndev, (void *)addr);
 
-	rc = temac_mdio_setup(lp, op->dev.of_node);
-	if (rc)
-		dev_warn(&op->dev, "error registering MDIO bus\n");
-
 	lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
-	if (lp->phy_node)
+	if (lp->phy_node) {
 		dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
 
+		rc = temac_mdio_setup(lp, op->dev.of_node);
+		if (rc)
+			dev_warn(&op->dev, "error registering MDIO bus\n");
+	}
+
 	/* Add the device attributes */
 	rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
 	if (rc) {
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/ll_temac_mdio.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/ll_temac_mdio.c	2014-07-20 22:05:50.259066241 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/ll_temac_mdio.c	2014-07-20 22:06:37.031294584 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:66 @
 	int clk_div;
 	int rc, size;
 	struct resource res;
+	struct device_node *np1 = of_get_parent(lp->phy_node);
 
 	/* Calculate a reasonable divisor for the clock rate */
 	clk_div = 0x3f; /* worst-case default setting */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:89 @
 	if (!bus)
 		return -ENOMEM;
 
-	of_address_to_resource(np, 0, &res);
+	of_address_to_resource(np1, 0, &res);
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
 		 (unsigned long long)res.start);
 	bus->priv = lp;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:101 @
 
 	lp->mii_bus = bus;
 
-	rc = of_mdiobus_register(bus, np);
+	rc = of_mdiobus_register(bus, np1);
 	if (rc)
 		goto err_register;
 
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/Makefile	2014-07-20 22:05:50.255066308 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/Makefile	2014-07-20 22:06:37.041294419 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:8 @
 ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
 obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
 obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+obj-$(CONFIG_XILINX_PS_EMAC) += xilinx_emacps.o
 xilinx_emac-objs := xilinx_axienet_main.o xilinx_axienet_mdio.o
 obj-$(CONFIG_XILINX_AXI_EMAC) += xilinx_emac.o
+
+obj-$(CONFIG_XILINX_LLTEMAC) += xilinx_lltemac/
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/xilinx_axienet.h	2014-07-20 22:05:50.261066208 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet.h	2014-07-20 22:06:37.054294205 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:12 @
 #define XILINX_AXIENET_H
 
 #include <linux/netdevice.h>
+#include <linux/of_irq.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/if_vlan.h>
 
 /* Packet size info */
 #define XAE_HDR_SIZE			14 /* Size of Ethernet header */
-#define XAE_HDR_VLAN_SIZE		18 /* Size of an Ethernet hdr + VLAN */
 #define XAE_TRL_SIZE			 4 /* Size of Ethernet trailer (FCS) */
 #define XAE_MTU			      1500 /* Max MTU of an Ethernet frame */
 #define XAE_JUMBO_MTU		      9000 /* Max MTU of a jumbo Eth. frame */
 
 #define XAE_MAX_FRAME_SIZE	 (XAE_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE)
-#define XAE_MAX_VLAN_FRAME_SIZE  (XAE_MTU + XAE_HDR_VLAN_SIZE + XAE_TRL_SIZE)
+#define XAE_MAX_VLAN_FRAME_SIZE  (XAE_MTU + VLAN_ETH_HLEN + XAE_TRL_SIZE)
 #define XAE_MAX_JUMBO_FRAME_SIZE (XAE_JUMBO_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE)
 
 /* Configuration options */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:341 @
 
 #define DELAY_OF_ONE_MILLISEC		1000
 
+/* Read/Write access to the registers */
+#ifndef out_be32
+#ifdef CONFIG_ARCH_ZYNQ
+#define in_be32(offset)		__raw_readl(offset)
+#define out_be32(offset, val)	__raw_writel(val, offset)
+#endif
+#endif
+
 /**
  * struct axidma_bd - Axi Dma buffer descriptor layout
  * @next:         MM2S/S2MM Next Descriptor Pointer
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:460 @
 	u32 rx_bd_ci;
 
 	u32 max_frm_size;
-	u32 jumbo_support;
+	u32 rxmem;
 
 	int csum_offload_on_tx_path;
 	int csum_offload_on_rx_path;
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2014-07-20 22:05:50.260066225 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2014-07-20 22:06:37.076293842 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:266 @
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
 
 	/* Populate the tail pointer and bring the Rx Axi DMA engine out of
-	 * halted state. This will make the Rx side ready for reception.*/
+	 * halted state. This will make the Rx side ready for reception.
+	 */
 	axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
 	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
 	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:277 @
 
 	/* Write to the RS (Run-stop) bit in the Tx channel control register.
 	 * Tx channel is now ready to run. But only after we write to the
-	 * tail pointer register that the Tx channel will start transmitting */
+	 * tail pointer register that the Tx channel will start transmitting.
+	 */
 	axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
 	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:359 @
 	    netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) {
 		/* We must make the kernel realize we had to move into
 		 * promiscuous mode. If it was a promiscuous mode request
-		 * the flag is already set. If not we set it. */
+		 * the flag is already set. If not we set it.
+		 */
 		ndev->flags |= IFF_PROMISC;
 		reg = axienet_ior(lp, XAE_FMI_OFFSET);
 		reg |= XAE_FMI_PM_MASK;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:444 @
 	/* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset
 	 * process of Axi DMA takes a while to complete as all pending
 	 * commands/transfers will be flushed or completed during this
-	 * reset process. */
+	 * reset process.
+	 */
 	axienet_dma_out32(lp, offset, XAXIDMA_CR_RESET_MASK);
 	timeout = DELAY_OF_ONE_MILLISEC;
 	while (axienet_dma_in32(lp, offset) & XAXIDMA_CR_RESET_MASK) {
 		udelay(1);
 		if (--timeout == 0) {
-			dev_err(dev, "axienet_device_reset DMA "
-				"reset timeout!\n");
+			dev_err(dev,
+				"axienet_device_reset DMA reset timeout!\n");
 			break;
 		}
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:478 @
 	__axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET);
 
 	lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE;
+	lp->options |= XAE_OPTION_VLAN;
 	lp->options &= (~XAE_OPTION_JUMBO);
 
 	if ((ndev->mtu > XAE_MTU) &&
-	    (ndev->mtu <= XAE_JUMBO_MTU) &&
-	    (lp->jumbo_support)) {
-		lp->max_frm_size = ndev->mtu + XAE_HDR_VLAN_SIZE +
-				   XAE_TRL_SIZE;
-		lp->options |= XAE_OPTION_JUMBO;
+		(ndev->mtu <= XAE_JUMBO_MTU)) {
+		lp->max_frm_size = ndev->mtu + VLAN_ETH_HLEN +
+					XAE_TRL_SIZE;
+
+		if (lp->max_frm_size <= lp->rxmem)
+			lp->options |= XAE_OPTION_JUMBO;
 	}
 
 	if (axienet_dma_bd_init(ndev)) {
-		dev_err(&ndev->dev, "axienet_device_reset descriptor "
+		dev_err(&ndev->dev,
+			"axienet_device_reset descriptor "
 			"allocation failed\n");
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:507 @
 	axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK);
 
 	/* Sync default options with HW but leave receiver and
-	 * transmitter disabled.*/
+	 * transmitter disabled.
+	 */
 	axienet_setoptions(ndev, lp->options &
 			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
 	axienet_set_mac_address(ndev, NULL);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:560 @
 				emmc_reg |= XAE_EMMC_LINKSPD_10;
 				break;
 			default:
-				dev_err(&ndev->dev, "Speed other than 10, 100 "
+				dev_err(&ndev->dev,
+					"Speed other than 10, 100 "
 					"or 1Gbps is not supported\n");
 				break;
 			}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:570 @
 			lp->last_link = link_state;
 			phy_print_status(phy);
 		} else {
-			dev_err(&ndev->dev, "Error setting Axi Ethernet "
-				"mac speed\n");
+			dev_err(&ndev->dev,
+				"Error setting Axi Ethernet mac speed\n");
 		}
 	}
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:613 @
 		size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
 		packets++;
 
-		lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM;
+		++lp->tx_bd_ci;
+		lp->tx_bd_ci %= TX_BD_NUM;
 		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
 		status = cur_p->status;
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:700 @
 				     skb_headlen(skb), DMA_TO_DEVICE);
 
 	for (ii = 0; ii < num_frag; ii++) {
-		lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM;
+		++lp->tx_bd_tail;
+		lp->tx_bd_tail %= TX_BD_NUM;
 		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 		frag = &skb_shinfo(skb)->frags[ii];
 		cur_p->phys = dma_map_single(ndev->dev.parent,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:715 @
 	cur_p->app4 = (unsigned long)skb;
 
 	tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+	wmb();
+
 	/* Start the transfer */
 	axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p);
-	lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM;
+	++lp->tx_bd_tail;
+	lp->tx_bd_tail %= TX_BD_NUM;
 
 	return NETDEV_TX_OK;
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:740 @
 	u32 csumstatus;
 	u32 size = 0;
 	u32 packets = 0;
-	dma_addr_t tail_p;
+	dma_addr_t tail_p = 0;
 	struct axienet_local *lp = netdev_priv(ndev);
 	struct sk_buff *skb, *new_skb;
 	struct axidma_bd *cur_p;
 
-	tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
+	rmb();
 	cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
 
 	while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
+		tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
 		skb = (struct sk_buff *) (cur_p->sw_id_offset);
 		length = cur_p->app4 & 0x0000FFFF;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:793 @
 		cur_p->status = 0;
 		cur_p->sw_id_offset = (u32) new_skb;
 
-		lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM;
+		++lp->rx_bd_ci;
+		lp->rx_bd_ci %= RX_BD_NUM;
 		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
 	}
 
 	ndev->stats.rx_packets += packets;
 	ndev->stats.rx_bytes += size;
 
-	axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
+	if (tail_p)
+		axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
 }
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:824 @
 
 	status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
 	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+		axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
 		axienet_start_xmit_done(lp->ndev);
 		goto out;
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:848 @
 		axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
 
 		tasklet_schedule(&lp->dma_err_tasklet);
+		axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
 	}
 out:
-	axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
 	return IRQ_HANDLED;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:873 @
 
 	status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
 	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+		axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
 		axienet_recv(lp->ndev);
 		goto out;
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:897 @
 		axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
 
 		tasklet_schedule(&lp->dma_err_tasklet);
+		axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
 	}
 out:
-	axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
 	return IRQ_HANDLED;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:932 @
 	/* Disable the MDIO interface till Axi Ethernet Reset is completed.
 	 * When we do an Axi Ethernet reset, it resets the complete core
 	 * including the MDIO. If MDIO is not disabled when the reset
-	 * process is started, MDIO will be broken afterwards. */
+	 * process is started, MDIO will be broken afterwards.
+	 */
 	axienet_iow(lp, XAE_MDIO_MC_OFFSET,
 		    (mdio_mcreg & (~XAE_MDIO_MC_MDIOEN_MASK)));
 	axienet_device_reset(ndev);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:944 @
 		return ret;
 
 	if (lp->phy_node) {
-		lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+		if (lp->phy_type == XAE_PHY_TYPE_GMII) {
+			lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
 					     axienet_adjust_link, 0,
 					     PHY_INTERFACE_MODE_GMII);
-		if (!lp->phy_dev) {
-			dev_err(lp->dev, "of_phy_connect() failed\n");
-			return -ENODEV;
+		} else if (lp->phy_type == XAE_PHY_TYPE_RGMII_2_0) {
+			lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+					     axienet_adjust_link, 0,
+					     PHY_INTERFACE_MODE_RGMII_ID);
 		}
-		phy_start(lp->phy_dev);
+
+		if (!lp->phy_dev)
+			dev_err(lp->dev, "of_phy_connect() failed\n");
+		else
+			phy_start(lp->phy_dev);
 	}
 
 	/* Enable tasklets for Axi DMA error handling */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1042 @
 
 	if (netif_running(ndev))
 		return -EBUSY;
-	if (lp->jumbo_support) {
-		if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64))
-			return -EINVAL;
-		ndev->mtu = new_mtu;
-	} else {
-		if ((new_mtu > XAE_MTU) || (new_mtu < 64))
-			return -EINVAL;
-		ndev->mtu = new_mtu;
-	}
+
+	if ((new_mtu + VLAN_ETH_HLEN +
+		XAE_TRL_SIZE) > lp->rxmem)
+		return -EINVAL;
+
+	if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64))
+		return -EINVAL;
+
+	ndev->mtu = new_mtu;
 
 	return 0;
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1075 @
 }
 #endif
 
+/* Ioctl MII Interface */
+static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct axienet_local *priv = netdev_priv(dev);
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	if (!priv->phy_dev)
+		return -EOPNOTSUPP;
+
+	return phy_mii_ioctl(priv->phy_dev, rq, cmd);
+}
+
 static const struct net_device_ops axienet_netdev_ops = {
 	.ndo_open = axienet_open,
 	.ndo_stop = axienet_stop,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1097 @
 	.ndo_set_mac_address = netdev_set_mac_address,
 	.ndo_validate_addr = eth_validate_addr,
 	.ndo_set_rx_mode = axienet_set_multicast_list,
+	.ndo_do_ioctl = axienet_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = axienet_poll_controller,
 #endif
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1253 @
  * axienet_ethtools_set_pauseparam - Set device pause parameter(flow control)
  *				     settings.
  * @ndev:	Pointer to net_device structure
- * @epauseparam:Pointer to ethtool_pauseparam structure
+ * @epauseparm:Pointer to ethtool_pauseparam structure
  *
  * This implements ethtool command for enabling flow control on Rx and Tx
  * paths. Issue "ethtool -A ethX tx on|off" under linux prompt to execute this
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1267 @
 	struct axienet_local *lp = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
-		printk(KERN_ERR	"%s: Please stop netif before applying "
-		       "configruation\n", ndev->name);
+		dev_err(&ndev->dev,
+			"%s: Please stop netif before applying configuration\n",
+			ndev->name);
 		return -EFAULT;
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1325 @
 	struct axienet_local *lp = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
-		printk(KERN_ERR	"%s: Please stop netif before applying "
-		       "configruation\n", ndev->name);
+		dev_err(&ndev->dev,
+			"%s: Please stop netif before applying configuration\n",
+			ndev->name);
 		return -EFAULT;
 	}
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1396 @
 	/* Disable the MDIO interface till Axi Ethernet Reset is completed.
 	 * When we do an Axi Ethernet reset, it resets the complete core
 	 * including the MDIO. So if MDIO is not disabled when the reset
-	 * process is started, MDIO will be broken afterwards. */
+	 * process is started, MDIO will be broken afterwards.
+	 */
 	axienet_iow(lp, XAE_MDIO_MC_OFFSET, (mdio_mcreg &
 		    ~XAE_MDIO_MC_MDIOEN_MASK));
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1468 @
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
 
 	/* Populate the tail pointer and bring the Rx Axi DMA engine out of
-	 * halted state. This will make the Rx side ready for reception.*/
+	 * halted state. This will make the Rx side ready for reception.
+	 */
 	axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
 	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
 	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1479 @
 
 	/* Write to the RS (Run-stop) bit in the Tx channel control register.
 	 * Tx channel is now ready to run. But only after we write to the
-	 * tail pointer register that the Tx channel will start transmitting */
+	 * tail pointer register that the Tx channel will start transmitting
+	 */
 	axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
 	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1496 @
 	axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK);
 
 	/* Sync default options with HW but leave receiver and
-	 * transmitter disabled.*/
+	 * transmitter disabled.
+	 */
 	axienet_setoptions(ndev, lp->options &
 			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
 	axienet_set_mac_address(ndev, NULL);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1506 @
 }
 
 /**
- * axienet_of_probe - Axi Ethernet probe function.
- * @op:		Pointer to platform device structure.
- * @match:	Pointer to device id structure
+ * axienet_probe - Axi Ethernet probe function.
+ * @pdev:		Pointer to platform device structure.
  *
  * returns: 0, on success
  *	    Non-zero error value on failure.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1517 @
  * device. Parses through device tree and populates fields of
  * axienet_local. It registers the Ethernet device.
  */
-static int axienet_of_probe(struct platform_device *op)
+static int axienet_probe(struct platform_device *pdev)
 {
-	__be32 *p;
-	int size, ret = 0;
+	int ret;
 	struct device_node *np;
 	struct axienet_local *lp;
 	struct net_device *ndev;
-	const void *addr;
+	u8 mac_addr[6];
+	struct resource *ethres, dmares;
+	u32 value;
 
 	ndev = alloc_etherdev(sizeof(*lp));
 	if (!ndev)
 		return -ENOMEM;
 
 	ether_setup(ndev);
-	platform_set_drvdata(op, ndev);
+	platform_set_drvdata(pdev, ndev);
 
-	SET_NETDEV_DEV(ndev, &op->dev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
 	ndev->features = NETIF_F_SG;
 	ndev->netdev_ops = &axienet_netdev_ops;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1542 @
 
 	lp = netdev_priv(ndev);
 	lp->ndev = ndev;
-	lp->dev = &op->dev;
+	lp->dev = &pdev->dev;
 	lp->options = XAE_OPTION_DEFAULTS;
 	/* Map device registers */
-	lp->regs = of_iomap(op->dev.of_node, 0);
+	ethres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	lp->regs = devm_ioremap_resource(&pdev->dev, ethres);
 	if (!lp->regs) {
-		dev_err(&op->dev, "could not map Axi Ethernet regs.\n");
-		goto nodev;
+		dev_err(&pdev->dev, "could not map Axi Ethernet regs.\n");
+		ret = -ENOMEM;
+		goto free_netdev;
 	}
+
 	/* Setup checksum offload, but default to off if not specified */
 	lp->features = 0;
 
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
-	if (p) {
-		switch (be32_to_cpup(p)) {
+	ret = of_property_read_u32(pdev->dev.of_node, "xlnx,txcsum", &value);
+	if (!ret) {
+		dev_info(&pdev->dev, "TX_CSUM %d\n", value);
+
+		switch (value) {
 		case 1:
 			lp->csum_offload_on_tx_path =
 				XAE_FEATURE_PARTIAL_TX_CSUM;
 			lp->features |= XAE_FEATURE_PARTIAL_TX_CSUM;
 			/* Can checksum TCP/UDP over IPv4. */
-			ndev->features |= NETIF_F_IP_CSUM;
+			ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 			break;
 		case 2:
 			lp->csum_offload_on_tx_path =
 				XAE_FEATURE_FULL_TX_CSUM;
 			lp->features |= XAE_FEATURE_FULL_TX_CSUM;
 			/* Can checksum TCP/UDP over IPv4. */
-			ndev->features |= NETIF_F_IP_CSUM;
+			ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 			break;
 		default:
 			lp->csum_offload_on_tx_path = XAE_NO_CSUM_OFFLOAD;
 		}
 	}
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
-	if (p) {
-		switch (be32_to_cpup(p)) {
+	ret = of_property_read_u32(pdev->dev.of_node, "xlnx,rxcsum", &value);
+	if (!ret) {
+		dev_info(&pdev->dev, "RX_CSUM %d\n", value);
+
+		switch (value) {
 		case 1:
 			lp->csum_offload_on_rx_path =
 				XAE_FEATURE_PARTIAL_RX_CSUM;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1599 @
 		}
 	}
 	/* For supporting jumbo frames, the Axi Ethernet hardware must have
-	 * a larger Rx/Tx Memory. Typically, the size must be more than or
-	 * equal to 16384 bytes, so that we can enable jumbo option and start
-	 * supporting jumbo frames. Here we check for memory allocated for
-	 * Rx/Tx in the hardware from the device-tree and accordingly set
-	 * flags. */
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxmem", NULL);
-	if (p) {
-		if ((be32_to_cpup(p)) >= 0x4000)
-			lp->jumbo_support = 1;
-	}
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type",
-				       NULL);
-	if (p)
-		lp->temac_type = be32_to_cpup(p);
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL);
-	if (p)
-		lp->phy_type = be32_to_cpup(p);
+	 * a larger Rx/Tx Memory. Typically, the size must be large so that
+	 * we can enable jumbo option and start supporting jumbo frames.
+	 * Here we check for memory allocated for Rx/Tx in the hardware from
+	 * the device-tree and accordingly set flags.
+	 */
+	of_property_read_u32(pdev->dev.of_node, "xlnx,rxmem", &lp->rxmem);
+	of_property_read_u32(pdev->dev.of_node, "xlnx,temac-type",
+					&lp->temac_type);
+	of_property_read_u32(pdev->dev.of_node, "xlnx,phy-type", &lp->phy_type);
 
 	/* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
-	np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0);
-	if (!np) {
-		dev_err(&op->dev, "could not find DMA node\n");
-		goto err_iounmap;
-	}
-	lp->dma_regs = of_iomap(np, 0);
-	if (lp->dma_regs) {
-		dev_dbg(&op->dev, "MEM base: %p\n", lp->dma_regs);
-	} else {
-		dev_err(&op->dev, "unable to map DMA registers\n");
-		of_node_put(np);
+	np = of_parse_phandle(pdev->dev.of_node, "axistream-connected", 0);
+	if (IS_ERR(np)) {
+		dev_err(&pdev->dev, "could not find DMA node\n");
+		ret = PTR_ERR(np);
+		goto free_netdev;
+	}
+	ret = of_address_to_resource(np, 0, &dmares);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to get DMA resource\n");
+		goto free_netdev;
+	}
+	lp->dma_regs = devm_ioremap_resource(&pdev->dev, &dmares);
+	if (!lp->dma_regs) {
+		dev_err(&pdev->dev, "could not map DMA regs\n");
+		ret = -ENOMEM;
+		goto free_netdev;
 	}
 	lp->rx_irq = irq_of_parse_and_map(np, 1);
 	lp->tx_irq = irq_of_parse_and_map(np, 0);
 	of_node_put(np);
 	if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) {
-		dev_err(&op->dev, "could not determine irqs\n");
+		dev_err(&pdev->dev, "could not determine irqs\n");
 		ret = -ENOMEM;
-		goto err_iounmap_2;
+		goto free_netdev;
 	}
 
 	/* Retrieve the MAC address */
-	addr = of_get_property(op->dev.of_node, "local-mac-address", &size);
-	if ((!addr) || (size != 6)) {
-		dev_err(&op->dev, "could not find MAC address\n");
-		ret = -ENODEV;
-		goto err_iounmap_2;
+	ret = of_property_read_u8_array(pdev->dev.of_node,
+			"local-mac-address", mac_addr, 6);
+	if (ret) {
+		dev_err(&pdev->dev, "could not find MAC address\n");
+		goto free_netdev;
 	}
-	axienet_set_mac_address(ndev, (void *) addr);
+	axienet_set_mac_address(ndev, (void *) mac_addr);
 
 	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
 	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
 
-	lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
-	ret = axienet_mdio_setup(lp, op->dev.of_node);
-	if (ret)
-		dev_warn(&op->dev, "error registering MDIO bus\n");
+	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+	if (lp->phy_node) {
+		ret = axienet_mdio_setup(lp, pdev->dev.of_node);
+		if (ret)
+			dev_warn(&pdev->dev, "error registering MDIO bus\n");
+	}
 
 	ret = register_netdev(lp->ndev);
 	if (ret) {
 		dev_err(lp->dev, "register_netdev() error (%i)\n", ret);
-		goto err_iounmap_2;
+		goto free_netdev;
 	}
 
 	return 0;
 
-err_iounmap_2:
-	if (lp->dma_regs)
-		iounmap(lp->dma_regs);
-err_iounmap:
-	iounmap(lp->regs);
-nodev:
+free_netdev:
 	free_netdev(ndev);
-	ndev = NULL;
+
 	return ret;
 }
 
-static int axienet_of_remove(struct platform_device *op)
+static int axienet_remove(struct platform_device *pdev)
 {
-	struct net_device *ndev = platform_get_drvdata(op);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct axienet_local *lp = netdev_priv(ndev);
 
 	axienet_mdio_teardown(lp);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1681 @
 		of_node_put(lp->phy_node);
 	lp->phy_node = NULL;
 
-	iounmap(lp->regs);
-	if (lp->dma_regs)
-		iounmap(lp->dma_regs);
 	free_netdev(ndev);
 
 	return 0;
 }
 
-static struct platform_driver axienet_of_driver = {
-	.probe = axienet_of_probe,
-	.remove = axienet_of_remove,
+static struct platform_driver axienet_driver = {
+	.probe = axienet_probe,
+	.remove = axienet_remove,
 	.driver = {
 		 .owner = THIS_MODULE,
 		 .name = "xilinx_axienet",
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1696 @
 	},
 };
 
-module_platform_driver(axienet_of_driver);
+module_platform_driver(axienet_driver);
 
 MODULE_DESCRIPTION("Xilinx Axi Ethernet driver");
 MODULE_AUTHOR("Xilinx");
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c	2014-07-20 22:05:50.258066258 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c	2014-07-20 22:06:37.088293644 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:131 @
 int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
 {
 	int ret;
-	u32 clk_div, host_clock;
-	u32 *property_p;
+	u32 clk_div;
 	struct mii_bus *bus;
 	struct resource res;
 	struct device_node *np1;
+	/* the ethernet controller device node */
+	struct device_node *npp = NULL;
 
 	/* clk_div can be calculated by deriving it from the equation:
 	 * fMDIO = fHOST / ((1 + clk_div) * 2)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:162 @
 	 * fHOST can be read from the flattened device tree as property
 	 * "clock-frequency" from the CPU
 	 */
-
-	np1 = of_find_node_by_name(NULL, "cpu");
-	if (!np1) {
-		printk(KERN_WARNING "%s(): Could not find CPU device node.",
-		       __func__);
-		printk(KERN_WARNING "Setting MDIO clock divisor to "
-		       "default %d\n", DEFAULT_CLOCK_DIVISOR);
-		clk_div = DEFAULT_CLOCK_DIVISOR;
-		goto issue;
+	np1 = of_get_parent(lp->phy_node);
+	if (np1) {
+		npp = of_get_parent(np1);
+		of_node_put(np1);
 	}
-	property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL);
-	if (!property_p) {
-		printk(KERN_WARNING "%s(): Could not find CPU property: "
-		       "clock-frequency.", __func__);
-		printk(KERN_WARNING "Setting MDIO clock divisor to "
-		       "default %d\n", DEFAULT_CLOCK_DIVISOR);
+	if (!npp) {
+		dev_warn(lp->dev,
+			"Could not find ethernet controller device node.");
+		dev_warn(lp->dev, "Setting MDIO clock divisor to default %d\n",
+		       DEFAULT_CLOCK_DIVISOR);
 		clk_div = DEFAULT_CLOCK_DIVISOR;
-		of_node_put(np1);
-		goto issue;
+	} else {
+		u32 *property_p;
+
+		property_p = (uint32_t *)of_get_property(npp,
+						"clock-frequency", NULL);
+		if (!property_p) {
+			dev_warn(lp->dev,
+				"Could not find clock ethernet "
+				"controller property.");
+			dev_warn(lp->dev,
+				 "Setting MDIO clock divisor to default %d\n",
+							DEFAULT_CLOCK_DIVISOR);
+			clk_div = DEFAULT_CLOCK_DIVISOR;
+		} else {
+			u32 host_clock = be32_to_cpup(property_p);
+
+			clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1;
+
+			/* If there is any remainder from the division of
+			 * fHOST / (MAX_MDIO_FREQ * 2), then we need to add 1
+			 * to the clock divisor or we will surely be
+			 * above 2.5 MHz
+			 */
+			if (host_clock % (MAX_MDIO_FREQ * 2))
+				clk_div++;
+			dev_dbg(lp->dev,
+				"Setting MDIO clock divisor to %u "
+				"based on %u Hz host clock.\n",
+				clk_div, host_clock);
+		}
+		of_node_put(npp);
 	}
 
-	host_clock = be32_to_cpup(property_p);
-	clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1;
-	/* If there is any remainder from the division of
-	 * fHOST / (MAX_MDIO_FREQ * 2), then we need to add
-	 * 1 to the clock divisor or we will surely be above 2.5 MHz */
-	if (host_clock % (MAX_MDIO_FREQ * 2))
-		clk_div++;
-
-	printk(KERN_DEBUG "%s(): Setting MDIO clock divisor to %u based "
-	       "on %u Hz host clock.\n", __func__, clk_div, host_clock);
-
-	of_node_put(np1);
-issue:
-	axienet_iow(lp, XAE_MDIO_MC_OFFSET,
-		    (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK));
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET, (((u32)clk_div) |
+						XAE_MDIO_MC_MDIOEN_MASK));
 
 	ret = axienet_mdio_wait_until_ready(lp);
 	if (ret < 0)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:217 @
 	if (!bus)
 		return -ENOMEM;
 
-	np1 = of_get_parent(lp->phy_node);
-	of_address_to_resource(np1, 0, &res);
+	of_address_to_resource(npp, 0, &res);
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
 		 (unsigned long long) res.start);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:246 @
 void axienet_mdio_teardown(struct axienet_local *lp)
 {
 	mdiobus_unregister(lp->mii_bus);
-	kfree(lp->mii_bus->irq);
 	mdiobus_free(lp->mii_bus);
 	lp->mii_bus = NULL;
 }
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_emaclite.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/net/ethernet/xilinx/xilinx_emaclite.c	2014-07-20 22:05:50.256066291 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_emaclite.c	2014-07-20 22:06:37.105293363 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:25 @
 #include <linux/slab.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:35 @
 #define DRIVER_NAME "xilinx_emaclite"
 
 /* Register offsets for the EmacLite Core */
-#define XEL_TXBUFF_OFFSET 	0x0		/* Transmit Buffer */
+#define XEL_TXBUFF_OFFSET	0x0		/* Transmit Buffer */
 #define XEL_MDIOADDR_OFFSET	0x07E4		/* MDIO Address Register */
 #define XEL_MDIOWR_OFFSET	0x07E8		/* MDIO Write Data Register */
 #define XEL_MDIORD_OFFSET	0x07EC		/* MDIO Read Data Register */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:67 @
 #define XEL_MDIOCTRL_MDIOEN_MASK  0x00000008	/* MDIO Enable */
 
 /* Global Interrupt Enable Register (GIER) Bit Masks */
-#define XEL_GIER_GIE_MASK	0x80000000 	/* Global Enable */
+#define XEL_GIER_GIE_MASK	0x80000000	/* Global Enable */
 
 /* Transmit Status Register (TSR) Bit Masks */
-#define XEL_TSR_XMIT_BUSY_MASK	 0x00000001 	/* Tx complete */
-#define XEL_TSR_PROGRAM_MASK	 0x00000002 	/* Program the MAC address */
-#define XEL_TSR_XMIT_IE_MASK	 0x00000008 	/* Tx interrupt enable bit */
-#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 	/* Buffer is active, SW bit
+#define XEL_TSR_XMIT_BUSY_MASK	 0x00000001	/* Tx complete */
+#define XEL_TSR_PROGRAM_MASK	 0x00000002	/* Program the MAC address */
+#define XEL_TSR_XMIT_IE_MASK	 0x00000008	/* Tx interrupt enable bit */
+#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000	/* Buffer is active, SW bit
 						 * only. This is not documented
 						 * in the HW spec */
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:81 @
 #define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
 
 /* Receive Status Register (RSR) */
-#define XEL_RSR_RECV_DONE_MASK	0x00000001 	/* Rx complete */
-#define XEL_RSR_RECV_IE_MASK	0x00000008 	/* Rx interrupt enable bit */
+#define XEL_RSR_RECV_DONE_MASK	0x00000001	/* Rx complete */
+#define XEL_RSR_RECV_IE_MASK	0x00000008	/* Rx interrupt enable bit */
 
 /* Transmit Packet Length Register (TPLR) */
-#define XEL_TPLR_LENGTH_MASK	0x0000FFFF 	/* Tx packet length */
+#define XEL_TPLR_LENGTH_MASK	0x0000FFFF	/* Tx packet length */
 
 /* Receive Packet Length Register (RPLR) */
-#define XEL_RPLR_LENGTH_MASK	0x0000FFFF 	/* Rx packet length */
+#define XEL_RPLR_LENGTH_MASK	0x0000FFFF	/* Rx packet length */
 
-#define XEL_HEADER_OFFSET	12 		/* Offset to length field */
-#define XEL_HEADER_SHIFT	16 		/* Shift value for length */
+#define XEL_HEADER_OFFSET	12		/* Offset to length field */
+#define XEL_HEADER_SHIFT	16		/* Shift value for length */
 
 /* General Ethernet Definitions */
-#define XEL_ARP_PACKET_SIZE		28 	/* Max ARP packet size */
-#define XEL_HEADER_IP_LENGTH_OFFSET	16 	/* IP Length Offset */
+#define XEL_ARP_PACKET_SIZE		28	/* Max ARP packet size */
+#define XEL_HEADER_IP_LENGTH_OFFSET	16	/* IP Length Offset */
 
 
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:167 @
 	__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
 		     drvdata->base_addr + XEL_TSR_OFFSET);
 
-	/* Enable the Tx interrupts for the second Buffer if
-	 * configured in HW */
-	if (drvdata->tx_ping_pong != 0) {
-		reg_data = __raw_readl(drvdata->base_addr +
-				   XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
-		__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
-			     drvdata->base_addr + XEL_BUFFER_OFFSET +
-			     XEL_TSR_OFFSET);
-	}
-
 	/* Enable the Rx interrupts for the first buffer */
 	__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET);
 
-	/* Enable the Rx interrupts for the second Buffer if
-	 * configured in HW */
-	if (drvdata->rx_ping_pong != 0) {
-		__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr +
-			     XEL_BUFFER_OFFSET + XEL_RSR_OFFSET);
-	}
-
 	/* Enable the Global Interrupt Enable */
 	__raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET);
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:193 @
 	__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
 		     drvdata->base_addr + XEL_TSR_OFFSET);
 
-	/* Disable the Tx interrupts for the second Buffer
-	 * if configured in HW */
-	if (drvdata->tx_ping_pong != 0) {
-		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
-				   XEL_TSR_OFFSET);
-		__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
-			     drvdata->base_addr + XEL_BUFFER_OFFSET +
-			     XEL_TSR_OFFSET);
-	}
-
 	/* Disable the Rx interrupts for the first buffer */
 	reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET);
 	__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
 		     drvdata->base_addr + XEL_RSR_OFFSET);
-
-	/* Disable the Rx interrupts for the second buffer
-	 * if configured in HW */
-	if (drvdata->rx_ping_pong != 0) {
-
-		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
-				   XEL_RSR_OFFSET);
-		__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
-			     drvdata->base_addr + XEL_BUFFER_OFFSET +
-			     XEL_RSR_OFFSET);
-	}
 }
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:224 @
 		*to_u16_ptr++ = *from_u16_ptr++;
 		*to_u16_ptr++ = *from_u16_ptr++;
 
+		/* This barrier resolves occasional issues seen around
+		 * cases where the data is not properly flushed out
+		 * from the processor store buffers to the destination
+		 * memory locations.
+		 */
+		wmb();
+
 		/* Output a word */
 		*to_u32_ptr++ = align_buffer;
 	}
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:246 @
 		for (; length > 0; length--)
 			*to_u8_ptr++ = *from_u8_ptr++;
 
+		/* This barrier resolves occasional issues seen around
+		 * cases where the data is not properly flushed out
+		 * from the processor store buffers to the destination
+		 * memory locations.
+		 */
+		wmb();
 		*to_u32_ptr = align_buffer;
 	}
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1054 @
  * This function un maps the IO region of the Emaclite device and frees the net
  * device.
  */
-static void xemaclite_remove_ndev(struct net_device *ndev,
-				  struct platform_device *pdev)
+static void xemaclite_remove_ndev(struct net_device *ndev)
 {
 	if (ndev) {
-		struct net_local *lp = netdev_priv(ndev);
-
-		if (lp->base_addr)
-			devm_iounmap(&pdev->dev, lp->base_addr);
 		free_netdev(ndev);
 	}
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1188 @
 	return 0;
 
 error:
-	xemaclite_remove_ndev(ndev, ofdev);
+	xemaclite_remove_ndev(ndev);
 	return rc;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1222 @
 		of_node_put(lp->phy_node);
 	lp->phy_node = NULL;
 
-	xemaclite_remove_ndev(ndev, of_dev);
+	xemaclite_remove_ndev(ndev);
 
 	return 0;
 }
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_emacps.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_emacps.c	2014-07-20 22:06:37.141292770 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Ethernet: Linux driver for Ethernet.
+ *
+ * Author: Xilinx, Inc.
+ *
+ * 2010 (c) Xilinx, Inc. This file is licensed uner the terms of the GNU
+ * General Public License version 2. This program is licensed "as is"
+ * without any warranty of any kind, whether express or implied.
+ *
+ * This is a driver for xilinx processor sub-system (ps) ethernet device.
+ * This driver is mainly used in Linux 2.6.30 and above and it does _not_
+ * support Linux 2.4 kernel due to certain new features (e.g. NAPI) is
+ * introduced in this driver.
+ *
+ * TODO:
+ * 1. JUMBO frame is not enabled per EPs spec. Please update it if this
+ *    support is added in and set MAX_MTU to 9000.
+ * 2. PTP slave mode: Findout and implement the proper equation and algorithm
+ *    for adjusting the hw timer frequency inorder to sync with the master
+ *    clock offset. Also formula for deriving the max adjustable frequency
+ *    value in ppb.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/mii.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/ethtool.h>
+#include <linux/vmalloc.h>
+#include <linux/version.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/net_tstamp.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/of_net.h>
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/timer.h>
+#include <linux/ptp_clock_kernel.h>
+
+/************************** Constant Definitions *****************************/
+
+/* Must be shorter than length of ethtool_drvinfo.driver field to fit */
+#define DRIVER_NAME			"xemacps"
+#define DRIVER_DESCRIPTION		"Xilinx Tri-Mode Ethernet MAC driver"
+#define DRIVER_VERSION			"1.00a"
+
+/* Transmission timeout is 3 seconds. */
+#define TX_TIMEOUT			(3*HZ)
+
+/* for RX skb IP header word-aligned */
+#define RX_IP_ALIGN_OFFSET		2
+
+/* DMA buffer descriptors must be aligned on a 4-byte boundary. */
+#define ALIGNMENT_BD			8
+
+/* Maximum value for hash bits. 2**6 */
+#define XEMACPS_MAX_HASH_BITS		64
+
+/* MDC clock division
+ * currently supporting 8, 16, 32, 48, 64, 96, 128, 224.
+ */
+enum { MDC_DIV_8 = 0, MDC_DIV_16, MDC_DIV_32, MDC_DIV_48,
+MDC_DIV_64, MDC_DIV_96, MDC_DIV_128, MDC_DIV_224 };
+
+/* Specify the receive buffer size in bytes, 64, 128, 192, 10240 */
+#define XEMACPS_RX_BUF_SIZE		1536
+
+/* Number of receive buffer bytes as a unit, this is HW setup */
+#define XEMACPS_RX_BUF_UNIT		64
+
+/* Default SEND and RECV buffer descriptors (BD) numbers.
+ * BD Space needed is (XEMACPS_SEND_BD_CNT+XEMACPS_RECV_BD_CNT)*8
+ */
+#undef  DEBUG
+#define DEBUG
+
+#define XEMACPS_SEND_BD_CNT		256
+#define XEMACPS_RECV_BD_CNT		256
+
+#define XEMACPS_NAPI_WEIGHT		64
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit. Names are self explained here.
+ */
+#define XEMACPS_NWCTRL_OFFSET		0x00000000 /* Network Control reg */
+#define XEMACPS_NWCFG_OFFSET		0x00000004 /* Network Config reg */
+#define XEMACPS_NWSR_OFFSET		0x00000008 /* Network Status reg */
+#define XEMACPS_USERIO_OFFSET		0x0000000C /* User IO reg */
+#define XEMACPS_DMACR_OFFSET		0x00000010 /* DMA Control reg */
+#define XEMACPS_TXSR_OFFSET		0x00000014 /* TX Status reg */
+#define XEMACPS_RXQBASE_OFFSET		0x00000018 /* RX Q Base address reg */
+#define XEMACPS_TXQBASE_OFFSET		0x0000001C /* TX Q Base address reg */
+#define XEMACPS_RXSR_OFFSET		0x00000020 /* RX Status reg */
+#define XEMACPS_ISR_OFFSET		0x00000024 /* Interrupt Status reg */
+#define XEMACPS_IER_OFFSET		0x00000028 /* Interrupt Enable reg */
+#define XEMACPS_IDR_OFFSET		0x0000002C /* Interrupt Disable reg */
+#define XEMACPS_IMR_OFFSET		0x00000030 /* Interrupt Mask reg */
+#define XEMACPS_PHYMNTNC_OFFSET		0x00000034 /* Phy Maintaince reg */
+#define XEMACPS_RXPAUSE_OFFSET		0x00000038 /* RX Pause Time reg */
+#define XEMACPS_TXPAUSE_OFFSET		0x0000003C /* TX Pause Time reg */
+#define XEMACPS_HASHL_OFFSET		0x00000080 /* Hash Low address reg */
+#define XEMACPS_HASHH_OFFSET		0x00000084 /* Hash High address reg */
+#define XEMACPS_LADDR1L_OFFSET		0x00000088 /* Specific1 addr low */
+#define XEMACPS_LADDR1H_OFFSET		0x0000008C /* Specific1 addr high */
+#define XEMACPS_LADDR2L_OFFSET		0x00000090 /* Specific2 addr low */
+#define XEMACPS_LADDR2H_OFFSET		0x00000094 /* Specific2 addr high */
+#define XEMACPS_LADDR3L_OFFSET		0x00000098 /* Specific3 addr low */
+#define XEMACPS_LADDR3H_OFFSET		0x0000009C /* Specific3 addr high */
+#define XEMACPS_LADDR4L_OFFSET		0x000000A0 /* Specific4 addr low */
+#define XEMACPS_LADDR4H_OFFSET		0x000000A4 /* Specific4 addr high */
+#define XEMACPS_MATCH1_OFFSET		0x000000A8 /* Type ID1 Match reg */
+#define XEMACPS_MATCH2_OFFSET		0x000000AC /* Type ID2 Match reg */
+#define XEMACPS_MATCH3_OFFSET		0x000000B0 /* Type ID3 Match reg */
+#define XEMACPS_MATCH4_OFFSET		0x000000B4 /* Type ID4 Match reg */
+#define XEMACPS_WOL_OFFSET		0x000000B8 /* Wake on LAN reg */
+#define XEMACPS_STRETCH_OFFSET		0x000000BC /* IPG Stretch reg */
+#define XEMACPS_SVLAN_OFFSET		0x000000C0 /* Stacked VLAN reg */
+#define XEMACPS_MODID_OFFSET		0x000000FC /* Module ID reg */
+#define XEMACPS_OCTTXL_OFFSET		0x00000100 /* Octects transmitted Low
+						reg */
+#define XEMACPS_OCTTXH_OFFSET		0x00000104 /* Octects transmitted High
+						reg */
+#define XEMACPS_TXCNT_OFFSET		0x00000108 /* Error-free Frmaes
+						transmitted counter */
+#define XEMACPS_TXBCCNT_OFFSET		0x0000010C /* Error-free Broadcast
+						Frames counter*/
+#define XEMACPS_TXMCCNT_OFFSET		0x00000110 /* Error-free Multicast
+						Frame counter */
+#define XEMACPS_TXPAUSECNT_OFFSET	0x00000114 /* Pause Frames Transmitted
+						Counter */
+#define XEMACPS_TX64CNT_OFFSET		0x00000118 /* Error-free 64 byte Frames
+						Transmitted counter */
+#define XEMACPS_TX65CNT_OFFSET		0x0000011C /* Error-free 65-127 byte
+						Frames Transmitted counter */
+#define XEMACPS_TX128CNT_OFFSET		0x00000120 /* Error-free 128-255 byte
+						Frames Transmitted counter */
+#define XEMACPS_TX256CNT_OFFSET		0x00000124 /* Error-free 256-511 byte
+						Frames transmitted counter */
+#define XEMACPS_TX512CNT_OFFSET		0x00000128 /* Error-free 512-1023 byte
+						Frames transmitted counter */
+#define XEMACPS_TX1024CNT_OFFSET	0x0000012C /* Error-free 1024-1518 byte
+						Frames transmitted counter */
+#define XEMACPS_TX1519CNT_OFFSET	0x00000130 /* Error-free larger than
+						1519 byte Frames transmitted
+						Counter */
+#define XEMACPS_TXURUNCNT_OFFSET	0x00000134 /* TX under run error
+						Counter */
+#define XEMACPS_SNGLCOLLCNT_OFFSET	0x00000138 /* Single Collision Frame
+						Counter */
+#define XEMACPS_MULTICOLLCNT_OFFSET	0x0000013C /* Multiple Collision Frame
+						Counter */
+#define XEMACPS_EXCESSCOLLCNT_OFFSET	0x00000140 /* Excessive Collision Frame
+						Counter */
+#define XEMACPS_LATECOLLCNT_OFFSET	0x00000144 /* Late Collision Frame
+						Counter */
+#define XEMACPS_TXDEFERCNT_OFFSET	0x00000148 /* Deferred Transmission
+						Frame Counter */
+#define XEMACPS_CSENSECNT_OFFSET	0x0000014C /* Carrier Sense Error
+						Counter */
+#define XEMACPS_OCTRXL_OFFSET		0x00000150 /* Octects Received register
+						Low */
+#define XEMACPS_OCTRXH_OFFSET		0x00000154 /* Octects Received register
+						High */
+#define XEMACPS_RXCNT_OFFSET		0x00000158 /* Error-free Frames
+						Received Counter */
+#define XEMACPS_RXBROADCNT_OFFSET	0x0000015C /* Error-free Broadcast
+						Frames Received Counter */
+#define XEMACPS_RXMULTICNT_OFFSET	0x00000160 /* Error-free Multicast
+						Frames Received Counter */
+#define XEMACPS_RXPAUSECNT_OFFSET	0x00000164 /* Pause Frames
+						Received Counter */
+#define XEMACPS_RX64CNT_OFFSET		0x00000168 /* Error-free 64 byte Frames
+						Received Counter */
+#define XEMACPS_RX65CNT_OFFSET		0x0000016C /* Error-free 65-127 byte
+						Frames Received Counter */
+#define XEMACPS_RX128CNT_OFFSET		0x00000170 /* Error-free 128-255 byte
+						Frames Received Counter */
+#define XEMACPS_RX256CNT_OFFSET		0x00000174 /* Error-free 256-512 byte
+						Frames Received Counter */
+#define XEMACPS_RX512CNT_OFFSET		0x00000178 /* Error-free 512-1023 byte
+						Frames Received Counter */
+#define XEMACPS_RX1024CNT_OFFSET	0x0000017C /* Error-free 1024-1518 byte
+						Frames Received Counter */
+#define XEMACPS_RX1519CNT_OFFSET	0x00000180 /* Error-free 1519-max byte
+						Frames Received Counter */
+#define XEMACPS_RXUNDRCNT_OFFSET	0x00000184 /* Undersize Frames Received
+						Counter */
+#define XEMACPS_RXOVRCNT_OFFSET		0x00000188 /* Oversize Frames Received
+						Counter */
+#define XEMACPS_RXJABCNT_OFFSET		0x0000018C /* Jabbers Received
+						Counter */
+#define XEMACPS_RXFCSCNT_OFFSET		0x00000190 /* Frame Check Sequence
+						Error Counter */
+#define XEMACPS_RXLENGTHCNT_OFFSET	0x00000194 /* Length Field Error
+						Counter */
+#define XEMACPS_RXSYMBCNT_OFFSET	0x00000198 /* Symbol Error Counter */
+#define XEMACPS_RXALIGNCNT_OFFSET	0x0000019C /* Alignment Error
+						Counter */
+#define XEMACPS_RXRESERRCNT_OFFSET	0x000001A0 /* Receive Resource Error
+						Counter */
+#define XEMACPS_RXORCNT_OFFSET		0x000001A4 /* Receive Overrun */
+#define XEMACPS_RXIPCCNT_OFFSET		0x000001A8 /* IP header Checksum Error
+						Counter */
+#define XEMACPS_RXTCPCCNT_OFFSET	0x000001AC /* TCP Checksum Error
+						Counter */
+#define XEMACPS_RXUDPCCNT_OFFSET	0x000001B0 /* UDP Checksum Error
+						Counter */
+
+#define XEMACPS_1588S_OFFSET		0x000001D0 /* 1588 Timer Seconds */
+#define XEMACPS_1588NS_OFFSET		0x000001D4 /* 1588 Timer Nanoseconds */
+#define XEMACPS_1588ADJ_OFFSET		0x000001D8 /* 1588 Timer Adjust */
+#define XEMACPS_1588INC_OFFSET		0x000001DC /* 1588 Timer Increment */
+#define XEMACPS_PTPETXS_OFFSET		0x000001E0 /* PTP Event Frame
+						Transmitted Seconds */
+#define XEMACPS_PTPETXNS_OFFSET		0x000001E4 /* PTP Event Frame
+						Transmitted Nanoseconds */
+#define XEMACPS_PTPERXS_OFFSET		0x000001E8 /* PTP Event Frame Received
+						Seconds */
+#define XEMACPS_PTPERXNS_OFFSET		0x000001EC /* PTP Event Frame Received
+						Nanoseconds */
+#define XEMACPS_PTPPTXS_OFFSET		0x000001F0 /* PTP Peer Frame
+						Transmitted Seconds */
+#define XEMACPS_PTPPTXNS_OFFSET		0x000001F4 /* PTP Peer Frame
+						Transmitted Nanoseconds */
+#define XEMACPS_PTPPRXS_OFFSET		0x000001F8 /* PTP Peer Frame Received
+						Seconds */
+#define XEMACPS_PTPPRXNS_OFFSET		0x000001FC /* PTP Peer Frame Received
+						Nanoseconds */
+
+/* network control register bit definitions */
+#define XEMACPS_NWCTRL_FLUSH_DPRAM_MASK	0x00040000
+#define XEMACPS_NWCTRL_RXTSTAMP_MASK	0x00008000 /* RX Timestamp in CRC */
+#define XEMACPS_NWCTRL_ZEROPAUSETX_MASK	0x00001000 /* Transmit zero quantum
+						pause frame */
+#define XEMACPS_NWCTRL_PAUSETX_MASK	0x00000800 /* Transmit pause frame */
+#define XEMACPS_NWCTRL_HALTTX_MASK	0x00000400 /* Halt transmission
+						after current frame */
+#define XEMACPS_NWCTRL_STARTTX_MASK	0x00000200 /* Start tx (tx_go) */
+
+#define XEMACPS_NWCTRL_STATWEN_MASK	0x00000080 /* Enable writing to
+						stat counters */
+#define XEMACPS_NWCTRL_STATINC_MASK	0x00000040 /* Increment statistic
+						registers */
+#define XEMACPS_NWCTRL_STATCLR_MASK	0x00000020 /* Clear statistic
+						registers */
+#define XEMACPS_NWCTRL_MDEN_MASK	0x00000010 /* Enable MDIO port */
+#define XEMACPS_NWCTRL_TXEN_MASK	0x00000008 /* Enable transmit */
+#define XEMACPS_NWCTRL_RXEN_MASK	0x00000004 /* Enable receive */
+#define XEMACPS_NWCTRL_LOOPEN_MASK	0x00000002 /* local loopback */
+
+/* name network configuration register bit definitions */
+#define XEMACPS_NWCFG_BADPREAMBEN_MASK	0x20000000 /* disable rejection of
+						non-standard preamble */
+#define XEMACPS_NWCFG_IPDSTRETCH_MASK	0x10000000 /* enable transmit IPG */
+#define XEMACPS_NWCFG_FCSIGNORE_MASK	0x04000000 /* disable rejection of
+						FCS error */
+#define XEMACPS_NWCFG_HDRXEN_MASK	0x02000000 /* RX half duplex */
+#define XEMACPS_NWCFG_RXCHKSUMEN_MASK	0x01000000 /* enable RX checksum
+						offload */
+#define XEMACPS_NWCFG_PAUSECOPYDI_MASK	0x00800000 /* Do not copy pause
+						Frames to memory */
+#define XEMACPS_NWCFG_MDC_SHIFT_MASK	18 /* shift bits for MDC */
+#define XEMACPS_NWCFG_MDCCLKDIV_MASK	0x001C0000 /* MDC Mask PCLK divisor */
+#define XEMACPS_NWCFG_FCSREM_MASK	0x00020000 /* Discard FCS from
+						received frames */
+#define XEMACPS_NWCFG_LENGTHERRDSCRD_MASK 0x00010000
+/* RX length error discard */
+#define XEMACPS_NWCFG_RXOFFS_MASK	0x0000C000 /* RX buffer offset */
+#define XEMACPS_NWCFG_PAUSEEN_MASK	0x00002000 /* Enable pause TX */
+#define XEMACPS_NWCFG_RETRYTESTEN_MASK	0x00001000 /* Retry test */
+#define XEMACPS_NWCFG_1000_MASK		0x00000400 /* Gigbit mode */
+#define XEMACPS_NWCFG_EXTADDRMATCHEN_MASK	0x00000200
+/* External address match enable */
+#define XEMACPS_NWCFG_UCASTHASHEN_MASK	0x00000080 /* Receive unicast hash
+						frames */
+#define XEMACPS_NWCFG_MCASTHASHEN_MASK	0x00000040 /* Receive multicast hash
+						frames */
+#define XEMACPS_NWCFG_BCASTDI_MASK	0x00000020 /* Do not receive
+						broadcast frames */
+#define XEMACPS_NWCFG_COPYALLEN_MASK	0x00000010 /* Copy all frames */
+
+#define XEMACPS_NWCFG_NVLANDISC_MASK	0x00000004 /* Receive only VLAN
+						frames */
+#define XEMACPS_NWCFG_FDEN_MASK		0x00000002 /* Full duplex */
+#define XEMACPS_NWCFG_100_MASK		0x00000001 /* 10 or 100 Mbs */
+
+/* network status register bit definitaions */
+#define XEMACPS_NWSR_MDIOIDLE_MASK	0x00000004 /* PHY management idle */
+#define XEMACPS_NWSR_MDIO_MASK		0x00000002 /* Status of mdio_in */
+
+/* MAC address register word 1 mask */
+#define XEMACPS_LADDR_MACH_MASK		0x0000FFFF /* Address bits[47:32]
+						bit[31:0] are in BOTTOM */
+
+/* DMA control register bit definitions */
+#define XEMACPS_DMACR_RXBUF_MASK	0x00FF0000 /* Mask bit for RX buffer
+						size */
+#define XEMACPS_DMACR_RXBUF_SHIFT	16 /* Shift bit for RX buffer
+						size */
+#define XEMACPS_DMACR_TCPCKSUM_MASK	0x00000800 /* enable/disable TX
+						checksum offload */
+#define XEMACPS_DMACR_TXSIZE_MASK	0x00000400 /* TX buffer memory size */
+#define XEMACPS_DMACR_RXSIZE_MASK	0x00000300 /* RX buffer memory size */
+#define XEMACPS_DMACR_ENDIAN_MASK	0x00000080 /* Endian configuration */
+#define XEMACPS_DMACR_BLENGTH_MASK	0x0000001F /* Buffer burst length */
+#define XEMACPS_DMACR_BLENGTH_INCR16	0x00000010 /* Buffer burst length */
+#define XEMACPS_DMACR_BLENGTH_INCR8	0x00000008 /* Buffer burst length */
+#define XEMACPS_DMACR_BLENGTH_INCR4	0x00000004 /* Buffer burst length */
+#define XEMACPS_DMACR_BLENGTH_SINGLE	0x00000002 /* Buffer burst length */
+
+/* transmit status register bit definitions */
+#define XEMACPS_TXSR_HRESPNOK_MASK	0x00000100 /* Transmit hresp not OK */
+#define XEMACPS_TXSR_COL1000_MASK	0x00000080 /* Collision Gbs mode */
+#define XEMACPS_TXSR_URUN_MASK		0x00000040 /* Transmit underrun */
+#define XEMACPS_TXSR_TXCOMPL_MASK	0x00000020 /* Transmit completed OK */
+#define XEMACPS_TXSR_BUFEXH_MASK	0x00000010 /* Transmit buffs exhausted
+						mid frame */
+#define XEMACPS_TXSR_TXGO_MASK		0x00000008 /* Status of go flag */
+#define XEMACPS_TXSR_RXOVR_MASK		0x00000004 /* Retry limit exceeded */
+#define XEMACPS_TXSR_COL100_MASK	0x00000002 /* Collision 10/100  mode */
+#define XEMACPS_TXSR_USEDREAD_MASK	0x00000001 /* TX buffer used bit set */
+
+#define XEMACPS_TXSR_ERROR_MASK	(XEMACPS_TXSR_HRESPNOK_MASK |		\
+					XEMACPS_TXSR_COL1000_MASK |	\
+					XEMACPS_TXSR_URUN_MASK |	\
+					XEMACPS_TXSR_BUFEXH_MASK |	\
+					XEMACPS_TXSR_RXOVR_MASK |	\
+					XEMACPS_TXSR_COL100_MASK |	\
+					XEMACPS_TXSR_USEDREAD_MASK)
+
+/* receive status register bit definitions */
+#define XEMACPS_RXSR_HRESPNOK_MASK	0x00000008 /* Receive hresp not OK */
+#define XEMACPS_RXSR_RXOVR_MASK		0x00000004 /* Receive overrun */
+#define XEMACPS_RXSR_FRAMERX_MASK	0x00000002 /* Frame received OK */
+#define XEMACPS_RXSR_BUFFNA_MASK	0x00000001 /* RX buffer used bit set */
+
+#define XEMACPS_RXSR_ERROR_MASK	(XEMACPS_RXSR_HRESPNOK_MASK | \
+					XEMACPS_RXSR_RXOVR_MASK | \
+					XEMACPS_RXSR_BUFFNA_MASK)
+
+/* interrupts bit definitions
+ * Bits definitions are same in XEMACPS_ISR_OFFSET,
+ * XEMACPS_IER_OFFSET, XEMACPS_IDR_OFFSET, and XEMACPS_IMR_OFFSET
+ */
+#define XEMACPS_IXR_PTPPSTX_MASK	0x02000000 /* PTP Psync transmitted */
+#define XEMACPS_IXR_PTPPDRTX_MASK	0x01000000 /* PTP Pdelay_req
+							transmitted */
+#define XEMACPS_IXR_PTPSTX_MASK		0x00800000 /* PTP Sync transmitted */
+#define XEMACPS_IXR_PTPDRTX_MASK	0x00400000 /* PTP Delay_req
+							transmitted */
+#define XEMACPS_IXR_PTPPSRX_MASK	0x00200000 /* PTP Psync received */
+#define XEMACPS_IXR_PTPPDRRX_MASK	0x00100000 /* PTP Pdelay_req
+							received */
+#define XEMACPS_IXR_PTPSRX_MASK		0x00080000 /* PTP Sync received */
+#define XEMACPS_IXR_PTPDRRX_MASK	0x00040000 /* PTP Delay_req received */
+#define XEMACPS_IXR_PAUSETX_MASK	0x00004000 /* Pause frame
+							transmitted */
+#define XEMACPS_IXR_PAUSEZERO_MASK	0x00002000 /* Pause time has reached
+							zero */
+#define XEMACPS_IXR_PAUSENZERO_MASK	0x00001000 /* Pause frame received */
+#define XEMACPS_IXR_HRESPNOK_MASK	0x00000800 /* hresp not ok */
+#define XEMACPS_IXR_RXOVR_MASK		0x00000400 /* Receive overrun
+							occurred */
+#define XEMACPS_IXR_TXCOMPL_MASK	0x00000080 /* Frame transmitted ok */
+#define XEMACPS_IXR_TXEXH_MASK		0x00000040 /* Transmit err occurred or
+							no buffers*/
+#define XEMACPS_IXR_RETRY_MASK		0x00000020 /* Retry limit exceeded */
+#define XEMACPS_IXR_URUN_MASK		0x00000010 /* Transmit underrun */
+#define XEMACPS_IXR_TXUSED_MASK		0x00000008 /* Tx buffer used bit read */
+#define XEMACPS_IXR_RXUSED_MASK		0x00000004 /* Rx buffer used bit read */
+#define XEMACPS_IXR_FRAMERX_MASK	0x00000002 /* Frame received ok */
+#define XEMACPS_IXR_MGMNT_MASK		0x00000001 /* PHY management complete */
+#define XEMACPS_IXR_ALL_MASK		0x03FC7FFE /* Everything except MDIO */
+
+#define XEMACPS_IXR_TX_ERR_MASK	(XEMACPS_IXR_TXEXH_MASK |		\
+					XEMACPS_IXR_RETRY_MASK |	\
+					XEMACPS_IXR_URUN_MASK |		\
+					XEMACPS_IXR_TXUSED_MASK)
+
+#define XEMACPS_IXR_RX_ERR_MASK	(XEMACPS_IXR_HRESPNOK_MASK |		\
+					XEMACPS_IXR_RXUSED_MASK |	\
+					XEMACPS_IXR_RXOVR_MASK)
+/* PHY Maintenance bit definitions */
+#define XEMACPS_PHYMNTNC_OP_MASK	0x40020000 /* operation mask bits */
+#define XEMACPS_PHYMNTNC_OP_R_MASK	0x20000000 /* read operation */
+#define XEMACPS_PHYMNTNC_OP_W_MASK	0x10000000 /* write operation */
+#define XEMACPS_PHYMNTNC_ADDR_MASK	0x0F800000 /* Address bits */
+#define XEMACPS_PHYMNTNC_REG_MASK	0x007C0000 /* register bits */
+#define XEMACPS_PHYMNTNC_DATA_MASK	0x0000FFFF /* data bits */
+#define XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK	23 /* Shift bits for PHYAD */
+#define XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK	18 /* Shift bits for PHREG */
+
+/* Wake on LAN bit definition */
+#define XEMACPS_WOL_MCAST_MASK		0x00080000
+#define XEMACPS_WOL_SPEREG1_MASK	0x00040000
+#define XEMACPS_WOL_ARP_MASK		0x00020000
+#define XEMACPS_WOL_MAGIC_MASK		0x00010000
+#define XEMACPS_WOL_ARP_ADDR_MASK	0x0000FFFF
+
+/* Buffer descriptor status words offset */
+#define XEMACPS_BD_ADDR_OFFSET		0x00000000 /**< word 0/addr of BDs */
+#define XEMACPS_BD_STAT_OFFSET		0x00000004 /**< word 1/status of BDs */
+
+/* Transmit buffer descriptor status words bit positions.
+ * Transmit buffer descriptor consists of two 32-bit registers,
+ * the first - word0 contains a 32-bit address pointing to the location of
+ * the transmit data.
+ * The following register - word1, consists of various information to
+ * control transmit process.  After transmit, this is updated with status
+ * information, whether the frame was transmitted OK or why it had failed.
+ */
+#define XEMACPS_TXBUF_USED_MASK		0x80000000 /* Used bit. */
+#define XEMACPS_TXBUF_WRAP_MASK		0x40000000 /* Wrap bit, last
+							descriptor */
+#define XEMACPS_TXBUF_RETRY_MASK	0x20000000 /* Retry limit exceeded */
+#define XEMACPS_TXBUF_EXH_MASK		0x08000000 /* Buffers exhausted */
+#define XEMACPS_TXBUF_LAC_MASK		0x04000000 /* Late collision. */
+#define XEMACPS_TXBUF_NOCRC_MASK	0x00010000 /* No CRC */
+#define XEMACPS_TXBUF_LAST_MASK		0x00008000 /* Last buffer */
+#define XEMACPS_TXBUF_LEN_MASK		0x00003FFF /* Mask for length field */
+
+#define XEMACPS_TXBUF_ERR_MASK		0x3C000000 /* Mask for length field */
+
+/* Receive buffer descriptor status words bit positions.
+ * Receive buffer descriptor consists of two 32-bit registers,
+ * the first - word0 contains a 32-bit word aligned address pointing to the
+ * address of the buffer. The lower two bits make up the wrap bit indicating
+ * the last descriptor and the ownership bit to indicate it has been used.
+ * The following register - word1, contains status information regarding why
+ * the frame was received (the filter match condition) as well as other
+ * useful info.
+ */
+#define XEMACPS_RXBUF_BCAST_MASK	0x80000000 /* Broadcast frame */
+#define XEMACPS_RXBUF_MULTIHASH_MASK	0x40000000 /* Multicast hashed frame */
+#define XEMACPS_RXBUF_UNIHASH_MASK	0x20000000 /* Unicast hashed frame */
+#define XEMACPS_RXBUF_EXH_MASK		0x08000000 /* buffer exhausted */
+#define XEMACPS_RXBUF_AMATCH_MASK	0x06000000 /* Specific address
+						matched */
+#define XEMACPS_RXBUF_IDFOUND_MASK	0x01000000 /* Type ID matched */
+#define XEMACPS_RXBUF_IDMATCH_MASK	0x00C00000 /* ID matched mask */
+#define XEMACPS_RXBUF_VLAN_MASK		0x00200000 /* VLAN tagged */
+#define XEMACPS_RXBUF_PRI_MASK		0x00100000 /* Priority tagged */
+#define XEMACPS_RXBUF_VPRI_MASK		0x000E0000 /* Vlan priority */
+#define XEMACPS_RXBUF_CFI_MASK		0x00010000 /* CFI frame */
+#define XEMACPS_RXBUF_EOF_MASK		0x00008000 /* End of frame. */
+#define XEMACPS_RXBUF_SOF_MASK		0x00004000 /* Start of frame. */
+#define XEMACPS_RXBUF_LEN_MASK		0x00003FFF /* Mask for length field */
+
+#define XEMACPS_RXBUF_WRAP_MASK		0x00000002 /* Wrap bit, last BD */
+#define XEMACPS_RXBUF_NEW_MASK		0x00000001 /* Used bit.. */
+#define XEMACPS_RXBUF_ADD_MASK		0xFFFFFFFC /* Mask for address */
+
+#define XEAMCPS_GEN_PURPOSE_TIMER_LOAD	100 /* timeout value is msecs */
+
+#define XEMACPS_GMII2RGMII_FULLDPLX		BMCR_FULLDPLX
+#define XEMACPS_GMII2RGMII_SPEED1000		BMCR_SPEED1000
+#define XEMACPS_GMII2RGMII_SPEED100		BMCR_SPEED100
+#define XEMACPS_GMII2RGMII_REG_NUM			0x10
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+#define NS_PER_SEC			1000000000ULL /* Nanoseconds per
+							second */
+/* Sum of Ethernet, IP and UDP header length */
+#define XEMACPS_TX_PTPHDR_OFFSET	42
+#define XEMACPS_RX_PTPHDR_OFFSET	28 /* Sum of IP and UDP header length */
+#define XEMACPS_IP_PROTO_OFFSET		9  /* Protocol field offset */
+#define XEMACPS_UDP_PORT_OFFSET		22 /* UDP dst port offset */
+#define XEMACPS_PTP_EVENT_PORT_NUM	0x13F /* Transport port for ptp */
+#endif
+
+#define xemacps_read(base, reg)						\
+	__raw_readl(((void __iomem *)(base)) + (reg))
+#define xemacps_write(base, reg, val)					\
+	__raw_writel((val), ((void __iomem *)(base)) + (reg))
+
+struct ring_info {
+	struct sk_buff *skb;
+	dma_addr_t mapping;
+	size_t len;
+};
+
+/* DMA buffer descriptor structure. Each BD is two words */
+struct xemacps_bd {
+	u32 addr;
+	u32 ctrl;
+};
+
+
+/* Our private device data. */
+struct net_local {
+	void __iomem *baseaddr;
+	struct clk *devclk;
+	struct clk *aperclk;
+	struct notifier_block clk_rate_change_nb;
+
+	struct device_node *phy_node;
+	struct device_node *gmii2rgmii_phy_node;
+	struct ring_info *tx_skb;
+	struct ring_info *rx_skb;
+
+	struct xemacps_bd *rx_bd;
+	struct xemacps_bd *tx_bd;
+
+	dma_addr_t rx_bd_dma; /* physical address */
+	dma_addr_t tx_bd_dma; /* physical address */
+
+	u32 tx_bd_ci;
+	u32 tx_bd_tail;
+	u32 rx_bd_ci;
+
+	u32 tx_bd_freecnt;
+
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
+	spinlock_t nwctrlreg_lock;
+
+	struct platform_device *pdev;
+	struct net_device *ndev; /* this device */
+	struct tasklet_struct tx_bdreclaim_tasklet;
+	struct workqueue_struct *txtimeout_handler_wq;
+	struct work_struct txtimeout_reinit;
+
+	struct napi_struct napi; /* napi information for device */
+	struct net_device_stats stats; /* Statistics for this device */
+
+	struct timer_list gen_purpose_timer; /* Used for stats update */
+
+	struct mii_bus *mii_bus;
+	struct phy_device *phy_dev;
+	struct phy_device *gmii2rgmii_phy_dev;
+	phy_interface_t phy_interface;
+	unsigned int link;
+	unsigned int speed;
+	unsigned int duplex;
+	/* RX ip/tcp/udp checksum */
+	unsigned ip_summed;
+	unsigned int enetnum;
+	unsigned int lastrxfrmscntr;
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+	struct hwtstamp_config hwtstamp_config;
+	struct ptp_clock *ptp_clock;
+	struct ptp_clock_info ptp_caps;
+	spinlock_t tmreg_lock;
+	int phc_index;
+	unsigned int tmr_add;
+#endif
+};
+#define to_net_local(_nb)	container_of(_nb, struct net_local,\
+		clk_rate_change_nb)
+
+static struct net_device_ops netdev_ops;
+
+/**
+ * xemacps_mdio_read - Read current value of phy register indicated by
+ * phyreg.
+ * @bus: mdio bus
+ * @mii_id: mii id
+ * @phyreg: phy register to be read
+ *
+ * @return: value read from specified phy register.
+ *
+ * note: This is for 802.3 clause 22 phys access. For 802.3 clause 45 phys
+ * access, set bit 30 to be 1. e.g. change XEMACPS_PHYMNTNC_OP_MASK to
+ * 0x00020000.
+ */
+static int xemacps_mdio_read(struct mii_bus *bus, int mii_id, int phyreg)
+{
+	struct net_local *lp = bus->priv;
+	u32 regval;
+	int value;
+	volatile u32 ipisr;
+
+	regval  = XEMACPS_PHYMNTNC_OP_MASK;
+	regval |= XEMACPS_PHYMNTNC_OP_R_MASK;
+	regval |= (mii_id << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK);
+	regval |= (phyreg << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK);
+
+	xemacps_write(lp->baseaddr, XEMACPS_PHYMNTNC_OFFSET, regval);
+
+	/* wait for end of transfer */
+	do {
+		cpu_relax();
+		ipisr = xemacps_read(lp->baseaddr, XEMACPS_NWSR_OFFSET);
+	} while ((ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
+
+	value = xemacps_read(lp->baseaddr, XEMACPS_PHYMNTNC_OFFSET) &
+			XEMACPS_PHYMNTNC_DATA_MASK;
+
+	return value;
+}
+
+/**
+ * xemacps_mdio_write - Write passed in value to phy register indicated
+ * by phyreg.
+ * @bus: mdio bus
+ * @mii_id: mii id
+ * @phyreg: phy register to be configured.
+ * @value: value to be written to phy register.
+ * return 0. This API requires to be int type or compile warning generated
+ *
+ * note: This is for 802.3 clause 22 phys access. For 802.3 clause 45 phys
+ * access, set bit 30 to be 1. e.g. change XEMACPS_PHYMNTNC_OP_MASK to
+ * 0x00020000.
+ */
+static int xemacps_mdio_write(struct mii_bus *bus, int mii_id, int phyreg,
+	u16 value)
+{
+	struct net_local *lp = bus->priv;
+	u32 regval;
+	volatile u32 ipisr;
+
+	regval  = XEMACPS_PHYMNTNC_OP_MASK;
+	regval |= XEMACPS_PHYMNTNC_OP_W_MASK;
+	regval |= (mii_id << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK);
+	regval |= (phyreg << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK);
+	regval |= value;
+
+	xemacps_write(lp->baseaddr, XEMACPS_PHYMNTNC_OFFSET, regval);
+
+	/* wait for end of transfer */
+	do {
+		cpu_relax();
+		ipisr = xemacps_read(lp->baseaddr, XEMACPS_NWSR_OFFSET);
+	} while ((ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
+
+	return 0;
+}
+
+
+/**
+ * xemacps_mdio_reset - mdio reset. It seems to be required per open
+ * source documentation phy.txt. But there is no reset in this device.
+ * Provide function API for now.
+ * @bus: mdio bus
+ **/
+static int xemacps_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+/**
+ * xemacps_set_freq() - Set a clock to a new frequency
+ * @clk		Pointer to the clock to change
+ * @rate	New frequency in Hz
+ * @dev		Pointer to the struct device
+ */
+static void xemacps_set_freq(struct clk *clk, long rate, struct device *dev)
+{
+	rate = clk_round_rate(clk, rate);
+	if (rate < 0)
+		return;
+
+	dev_info(dev, "Set clk to %ld Hz\n", rate);
+	if (clk_set_rate(clk, rate))
+		dev_err(dev, "Setting new clock rate failed.\n");
+}
+
+/**
+ * xemacps_adjust_link - handles link status changes, such as speed,
+ * duplex, up/down, ...
+ * @ndev: network device
+ */
+static void xemacps_adjust_link(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+	struct phy_device *gmii2rgmii_phydev = lp->gmii2rgmii_phy_dev;
+	int status_change = 0;
+	u32 regval;
+	u16 gmii2rgmii_reg = 0;
+
+	if (phydev->link) {
+		if ((lp->speed != phydev->speed) ||
+			(lp->duplex != phydev->duplex)) {
+			regval = xemacps_read(lp->baseaddr,
+				XEMACPS_NWCFG_OFFSET);
+			regval &= ~(XEMACPS_NWCFG_FDEN_MASK |
+					XEMACPS_NWCFG_1000_MASK |
+					XEMACPS_NWCFG_100_MASK);
+
+			if (phydev->duplex) {
+				regval |= XEMACPS_NWCFG_FDEN_MASK;
+				gmii2rgmii_reg |= XEMACPS_GMII2RGMII_FULLDPLX;
+			}
+
+			if (phydev->speed == SPEED_1000) {
+				regval |= XEMACPS_NWCFG_1000_MASK;
+				gmii2rgmii_reg |= XEMACPS_GMII2RGMII_SPEED1000;
+				xemacps_set_freq(lp->devclk, 125000000,
+						&lp->pdev->dev);
+			} else if (phydev->speed == SPEED_100) {
+				regval |= XEMACPS_NWCFG_100_MASK;
+				gmii2rgmii_reg |= XEMACPS_GMII2RGMII_SPEED100;
+				xemacps_set_freq(lp->devclk, 25000000,
+						&lp->pdev->dev);
+			} else if (phydev->speed == SPEED_10) {
+				xemacps_set_freq(lp->devclk, 2500000,
+						&lp->pdev->dev);
+			} else {
+				dev_err(&lp->pdev->dev,
+					"%s: unknown PHY speed %d\n",
+					__func__, phydev->speed);
+				return;
+			}
+
+			xemacps_write(lp->baseaddr, XEMACPS_NWCFG_OFFSET,
+			regval);
+
+			if (gmii2rgmii_phydev != NULL) {
+				xemacps_mdio_write(lp->mii_bus,
+					gmii2rgmii_phydev->addr,
+					XEMACPS_GMII2RGMII_REG_NUM,
+					gmii2rgmii_reg);
+			}
+
+			lp->speed = phydev->speed;
+			lp->duplex = phydev->duplex;
+			status_change = 1;
+		}
+	}
+
+	if (phydev->link != lp->link) {
+		lp->link = phydev->link;
+		status_change = 1;
+	}
+
+	if (status_change) {
+		if (phydev->link)
+			dev_info(&lp->pdev->dev, "link up (%d/%s)\n",
+				phydev->speed,
+				DUPLEX_FULL == phydev->duplex ?
+				"FULL" : "HALF");
+		else
+			dev_info(&lp->pdev->dev, "link down\n");
+	}
+}
+
+static int xemacps_clk_notifier_cb(struct notifier_block *nb, unsigned long
+		event, void *data)
+{
+/*
+	struct clk_notifier_data *ndata = data;
+	struct net_local *nl = to_net_local(nb);
+*/
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers.
+		 * I don't see how this can be done using the current fmwk!?
+		 * For now we always allow the rate change. Otherwise we would
+		 * even prevent ourself to change the rate.
+		 */
+		return NOTIFY_OK;
+	case POST_RATE_CHANGE:
+		/* not sure this will work. actually i'm sure it does not. this
+		 * callback is not allowed to call back into COMMON_CLK, what
+		 * adjust_link() does...*/
+		/*xemacps_adjust_link(nl->ndev); would likely lock up kernel */
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+/**
+ * xemacps_mii_probe - probe mii bus, find the right bus_id to register
+ * phy callback function.
+ * @ndev: network interface device structure
+ * return 0 on success, negative value if error
+ **/
+static int xemacps_mii_probe(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = NULL;
+
+	if (lp->phy_node) {
+		phydev = of_phy_connect(lp->ndev,
+					lp->phy_node,
+					&xemacps_adjust_link,
+					0,
+					lp->phy_interface);
+	}
+	if (!phydev) {
+		dev_err(&lp->pdev->dev, "%s: no PHY found\n", ndev->name);
+		return -1;
+	}
+
+	dev_dbg(&lp->pdev->dev,
+		"GEM: phydev %p, phydev->phy_id 0x%x, phydev->addr 0x%x\n",
+		phydev, phydev->phy_id, phydev->addr);
+
+	phydev->supported &= (PHY_GBIT_FEATURES | SUPPORTED_Pause |
+							SUPPORTED_Asym_Pause);
+	phydev->advertising = phydev->supported;
+
+	lp->link    = 0;
+	lp->speed   = 0;
+	lp->duplex  = -1;
+	lp->phy_dev = phydev;
+
+	phy_start(lp->phy_dev);
+
+	dev_dbg(&lp->pdev->dev, "phy_addr 0x%x, phy_id 0x%08x\n",
+			lp->phy_dev->addr, lp->phy_dev->phy_id);
+
+	dev_dbg(&lp->pdev->dev, "attach [%s] phy driver\n",
+			lp->phy_dev->drv->name);
+
+	if (lp->gmii2rgmii_phy_node) {
+		phydev = of_phy_connect(lp->ndev,
+					lp->gmii2rgmii_phy_node,
+					NULL,
+					0, 0);
+		if (!phydev) {
+			dev_err(&lp->pdev->dev, "%s: no gmii to rgmii converter found\n",
+			ndev->name);
+			return -1;
+		}
+		lp->gmii2rgmii_phy_dev = phydev;
+	} else
+		lp->gmii2rgmii_phy_dev = NULL;
+
+	return 0;
+}
+
+/**
+ * xemacps_mii_init - Initialize and register mii bus to network device
+ * @lp: local device instance pointer
+ * return 0 on success, negative value if error
+ **/
+static int xemacps_mii_init(struct net_local *lp)
+{
+	int rc = -ENXIO, i;
+	struct resource res;
+	struct device_node *np = of_get_parent(lp->phy_node);
+	struct device_node *npp;
+
+	lp->mii_bus = mdiobus_alloc();
+	if (lp->mii_bus == NULL) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
+	lp->mii_bus->name  = "XEMACPS mii bus";
+	lp->mii_bus->read  = &xemacps_mdio_read;
+	lp->mii_bus->write = &xemacps_mdio_write;
+	lp->mii_bus->reset = &xemacps_mdio_reset;
+	lp->mii_bus->priv = lp;
+	lp->mii_bus->parent = &lp->ndev->dev;
+
+	lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+	if (!lp->mii_bus->irq) {
+		rc = -ENOMEM;
+		goto err_out_free_mdiobus;
+	}
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		lp->mii_bus->irq[i] = PHY_POLL;
+	npp = of_get_parent(np);
+	of_address_to_resource(npp, 0, &res);
+	snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%.8llx",
+		 (unsigned long long)res.start);
+	if (of_mdiobus_register(lp->mii_bus, np))
+		goto err_out_free_mdio_irq;
+
+	return 0;
+
+err_out_free_mdio_irq:
+	kfree(lp->mii_bus->irq);
+err_out_free_mdiobus:
+	mdiobus_free(lp->mii_bus);
+err_out:
+	return rc;
+}
+
+/**
+ * xemacps_update_hdaddr - Update device's MAC address when configured
+ * MAC address is not valid, reconfigure with a good one.
+ * @lp: local device instance pointer
+ **/
+static void xemacps_update_hwaddr(struct net_local *lp)
+{
+	u32 regvall;
+	u16 regvalh;
+	u8  addr[6];
+
+	regvall = xemacps_read(lp->baseaddr, XEMACPS_LADDR1L_OFFSET);
+	regvalh = xemacps_read(lp->baseaddr, XEMACPS_LADDR1H_OFFSET);
+	addr[0] = regvall & 0xFF;
+	addr[1] = (regvall >> 8) & 0xFF;
+	addr[2] = (regvall >> 16) & 0xFF;
+	addr[3] = (regvall >> 24) & 0xFF;
+	addr[4] = regvalh & 0xFF;
+	addr[5] = (regvalh >> 8) & 0xFF;
+
+	if (is_valid_ether_addr(addr)) {
+		memcpy(lp->ndev->dev_addr, addr, sizeof(addr));
+	} else {
+		dev_info(&lp->pdev->dev, "invalid address, use assigned\n");
+		random_ether_addr(lp->ndev->dev_addr);
+		dev_info(&lp->pdev->dev,
+				"MAC updated %02x:%02x:%02x:%02x:%02x:%02x\n",
+				lp->ndev->dev_addr[0], lp->ndev->dev_addr[1],
+				lp->ndev->dev_addr[2], lp->ndev->dev_addr[3],
+				lp->ndev->dev_addr[4], lp->ndev->dev_addr[5]);
+	}
+}
+
+/**
+ * xemacps_set_hwaddr - Set device's MAC address from ndev->dev_addr
+ * @lp: local device instance pointer
+ **/
+static void xemacps_set_hwaddr(struct net_local *lp)
+{
+	u32 regvall = 0;
+	u16 regvalh = 0;
+#ifdef __LITTLE_ENDIAN
+	regvall = cpu_to_le32(*((u32 *)lp->ndev->dev_addr));
+	regvalh = cpu_to_le16(*((u16 *)(lp->ndev->dev_addr + 4)));
+#endif
+#ifdef __BIG_ENDIAN
+	regvall = cpu_to_be32(*((u32 *)lp->ndev->dev_addr));
+	regvalh = cpu_to_be16(*((u16 *)(lp->ndev->dev_addr + 4)));
+#endif
+	/* LADDRXH has to be wriiten latter than LADDRXL to enable
+	 * this address even if these 16 bits are zeros. */
+	xemacps_write(lp->baseaddr, XEMACPS_LADDR1L_OFFSET, regvall);
+	xemacps_write(lp->baseaddr, XEMACPS_LADDR1H_OFFSET, regvalh);
+#ifdef DEBUG
+	regvall = xemacps_read(lp->baseaddr, XEMACPS_LADDR1L_OFFSET);
+	regvalh = xemacps_read(lp->baseaddr, XEMACPS_LADDR1H_OFFSET);
+	dev_dbg(&lp->pdev->dev,
+			"MAC 0x%08x, 0x%08x, %02x:%02x:%02x:%02x:%02x:%02x\n",
+		regvall, regvalh,
+		(regvall & 0xff), ((regvall >> 8) & 0xff),
+		((regvall >> 16) & 0xff), (regvall >> 24),
+		(regvalh & 0xff), (regvalh >> 8));
+#endif
+}
+
+/*
+ * xemacps_reset_hw - Helper function to reset the underlying hardware.
+ * This is called when we get into such deep trouble that we don't know
+ * how to handle otherwise.
+ * @lp: local device instance pointer
+ */
+static void xemacps_reset_hw(struct net_local *lp)
+{
+	u32 regisr;
+	/* make sure we have the buffer for ourselves */
+	wmb();
+
+	/* Have a clean start */
+	xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET, 0);
+
+	/* Clear statistic counters */
+	xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET,
+		XEMACPS_NWCTRL_STATCLR_MASK);
+
+	/* Clear TX and RX status */
+	xemacps_write(lp->baseaddr, XEMACPS_TXSR_OFFSET, ~0UL);
+	xemacps_write(lp->baseaddr, XEMACPS_RXSR_OFFSET, ~0UL);
+
+	/* Disable all interrupts */
+	xemacps_write(lp->baseaddr, XEMACPS_IDR_OFFSET, ~0UL);
+	synchronize_irq(lp->ndev->irq);
+	regisr = xemacps_read(lp->baseaddr, XEMACPS_ISR_OFFSET);
+	xemacps_write(lp->baseaddr, XEMACPS_ISR_OFFSET, regisr);
+}
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+
+/**
+ * xemacps_ptp_read - Read timestamp information from the timer counters
+ * @lp: Local device instance pointer
+ * @ts: Timespec structure to hold the current time value
+ * return: None
+ */
+static inline void xemacps_ptp_read(struct net_local *lp,
+				    struct timespec *ts)
+{
+	ts->tv_sec = xemacps_read(lp->baseaddr, XEMACPS_1588S_OFFSET);
+	ts->tv_nsec = xemacps_read(lp->baseaddr, XEMACPS_1588NS_OFFSET);
+
+	if (ts->tv_sec < xemacps_read(lp->baseaddr, XEMACPS_1588S_OFFSET))
+		ts->tv_nsec = xemacps_read(lp->baseaddr, XEMACPS_1588NS_OFFSET);
+}
+
+/**
+ * xemacps_ptp_write - Update the currenrt time value to the timer counters
+ * @lp: Local device instance pointer
+ * @ts: Timespec structure to hold the time value
+ * return: None
+ */
+static inline void xemacps_ptp_write(struct net_local *lp,
+				     const struct timespec *ts)
+{
+	xemacps_write(lp->baseaddr, XEMACPS_1588S_OFFSET, ts->tv_sec);
+	xemacps_write(lp->baseaddr, XEMACPS_1588NS_OFFSET, ts->tv_nsec);
+}
+
+/**
+ * xemacps_rx_hwtstamp - Read rx timestamp from hw and update it to the skbuff
+ * @lp: Local device instance pointer
+ * @skb: Pointer to the socket buffer
+ * @msg_type: PTP message type
+ * return: None
+ */
+static void xemacps_rx_hwtstamp(struct net_local *lp,
+				struct sk_buff *skb, unsigned msg_type)
+{
+	u32 sec, nsec;
+
+	if (msg_type) {
+		/* PTP Peer Event Frame packets */
+		sec = xemacps_read(lp->baseaddr, XEMACPS_PTPPRXS_OFFSET);
+		nsec = xemacps_read(lp->baseaddr, XEMACPS_PTPPRXNS_OFFSET);
+	} else {
+		/* PTP Event Frame packets */
+		sec = xemacps_read(lp->baseaddr, XEMACPS_PTPERXS_OFFSET);
+		nsec = xemacps_read(lp->baseaddr, XEMACPS_PTPERXNS_OFFSET);
+	}
+	skb_hwtstamps(skb)->hwtstamp = ktime_set(sec, nsec);
+}
+
+/**
+ * xemacps_tx_hwtstamp - Read tx timestamp from hw and update it to the skbuff
+ * @lp: Local device instance pointer
+ * @skb: Pointer to the socket buffer
+ * @msg_type: PTP message type
+ * return: None
+ */
+static void xemacps_tx_hwtstamp(struct net_local *lp,
+				struct sk_buff *skb, unsigned msg_type)
+{
+	u32 sec, nsec;
+
+	if (msg_type)  {
+		/* PTP Peer Event Frame packets */
+		sec = xemacps_read(lp->baseaddr, XEMACPS_PTPPTXS_OFFSET);
+		nsec = xemacps_read(lp->baseaddr, XEMACPS_PTPPTXNS_OFFSET);
+	} else {
+		/* PTP Event Frame packets */
+		sec = xemacps_read(lp->baseaddr, XEMACPS_PTPETXS_OFFSET);
+		nsec = xemacps_read(lp->baseaddr, XEMACPS_PTPETXNS_OFFSET);
+	}
+	skb_hwtstamps(skb)->hwtstamp = ktime_set(sec, nsec);
+	skb_tstamp_tx(skb, skb_hwtstamps(skb));
+}
+
+/**
+ * xemacps_ptp_enable - Select the mode of operation
+ * @ptp: PTP clock structure
+ * @rq: Requested feature to change
+ * @on: Whether to enable or disable the feature
+ * return: Always returns EOPNOTSUPP
+ */
+static int xemacps_ptp_enable(struct ptp_clock_info *ptp,
+			      struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * xemacps_ptp_gettime - Get the current time from the timer counter registers
+ * @ptp: PTP clock structure
+ * @ts: Timespec structure to hold the current time value
+ * return: Always returns zero
+ */
+static int xemacps_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	unsigned long flags;
+	struct net_local *lp = container_of(ptp, struct net_local, ptp_caps);
+
+	spin_lock_irqsave(&lp->tmreg_lock, flags);
+	xemacps_ptp_read(lp, ts);
+	spin_unlock_irqrestore(&lp->tmreg_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xemacps_ptp_settime - Apply the time info to the timer counter registers
+ * @ptp: PTP clock structure
+ * @ts: Timespec structure to hold the current time value
+ * return: Always returns zero
+ */
+static int xemacps_ptp_settime(struct ptp_clock_info *ptp,
+			       const struct timespec *ts)
+{
+	unsigned long flags;
+	struct net_local *lp = container_of(ptp, struct net_local, ptp_caps);
+
+	spin_lock_irqsave(&lp->tmreg_lock, flags);
+	xemacps_ptp_write(lp, ts);
+	spin_unlock_irqrestore(&lp->tmreg_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xemacps_ptp_adjfreq - Adjust the clock freequency
+ * @ptp: PTP clock info structure
+ * @ppb: Frequency in parts per billion
+ * return: Always returns zero
+ */
+static int xemacps_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	struct net_local *lp = container_of(ptp, struct net_local, ptp_caps);
+	u64 adj;
+	u32 diff, addend;
+	int neg_adj = 0;
+
+	/* FIXME: the following logic is not working and need to
+	 * fine tune the algorithm and parameters
+	 */
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+
+	addend = lp->tmr_add;
+	adj = addend;
+	adj *= ppb;
+	diff = div_u64(adj, 1000000000ULL);
+
+	addend = neg_adj ? addend - diff : addend + diff;
+	xemacps_write(lp->baseaddr, XEMACPS_1588INC_OFFSET, addend);
+
+	return 0;
+}
+
+/**
+ * xemacps_ptp_adjtime - Adjust the timer counter value with delta
+ * @ptp: PTP clock info structure
+ * @delta: Delta value in nano seconds
+ * return: Always returns zero
+ */
+static int xemacps_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	unsigned long flags;
+	struct net_local *lp = container_of(ptp, struct net_local, ptp_caps);
+	struct timespec now, then = ns_to_timespec(delta);
+
+	spin_lock_irqsave(&lp->tmreg_lock, flags);
+	xemacps_ptp_read(lp, &now);
+	now = timespec_add(now, then);
+	xemacps_ptp_write(lp, (const struct timespec *)&now);
+	spin_unlock_irqrestore(&lp->tmreg_lock, flags);
+	return 0;
+}
+
+/**
+ * xemacps_ptp_init - Initialize the clock and register with ptp sub system
+ * @lp: Local device instance pointer
+ * return: None
+ */
+static void xemacps_ptp_init(struct net_local *lp)
+{
+	struct timespec now;
+	unsigned long rate;
+	u32 delta;
+
+	lp->ptp_caps.owner = THIS_MODULE;
+	snprintf(lp->ptp_caps.name, 16, "zynq ptp");
+	lp->ptp_caps.n_alarm = 0;
+	lp->ptp_caps.n_ext_ts = 0;
+	lp->ptp_caps.n_per_out = 0;
+	lp->ptp_caps.pps = 0;
+	lp->ptp_caps.adjfreq = xemacps_ptp_adjfreq;
+	lp->ptp_caps.adjtime = xemacps_ptp_adjtime;
+	lp->ptp_caps.gettime = xemacps_ptp_gettime;
+	lp->ptp_caps.settime = xemacps_ptp_settime;
+	lp->ptp_caps.enable = xemacps_ptp_enable;
+
+	rate = clk_get_rate(lp->aperclk);
+
+	spin_lock_init(&lp->tmreg_lock);
+	getnstimeofday(&now);
+	xemacps_ptp_write(lp, (const struct timespec *)&now);
+	lp->tmr_add = (NS_PER_SEC/rate);
+	xemacps_write(lp->baseaddr, XEMACPS_1588INC_OFFSET,
+			lp->tmr_add);
+
+	/* Having eight bits for the number of increments field,
+	 * the max adjustable frequency is inputfreq/(2 pow 8)
+	 * formula for converting the freq hz to ppm is
+	 * Delta(Hz)  = (inputfreq(Hz) * ppm)/(10 pow 6)
+	 */
+
+	delta = rate / 256;
+	rate = rate / 1000000;
+	lp->ptp_caps.max_adj = (delta / rate) * 1000;
+
+	lp->ptp_clock = ptp_clock_register(&lp->ptp_caps, &lp->pdev->dev);
+	if (IS_ERR(lp->ptp_clock))
+		pr_err("ptp_clock_register failed\n");
+
+	lp->phc_index = ptp_clock_index(lp->ptp_clock);
+}
+
+/**
+ * xemacps_ptp_close - Disable the ptp interface
+ * @lp: Local device instance pointer
+ * return: None
+ */
+static void xemacps_ptp_close(struct net_local *lp)
+{
+	/* Clear the time counters */
+	xemacps_write(lp->baseaddr, XEMACPS_1588NS_OFFSET, 0x0);
+	xemacps_write(lp->baseaddr, XEMACPS_1588S_OFFSET, 0x0);
+	xemacps_write(lp->baseaddr, XEMACPS_1588ADJ_OFFSET, 0x0);
+	xemacps_write(lp->baseaddr, XEMACPS_1588INC_OFFSET, 0x0);
+
+	ptp_clock_unregister(lp->ptp_clock);
+
+	/* Initialize hwstamp config */
+	lp->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+	lp->hwtstamp_config.tx_type = HWTSTAMP_TX_OFF;
+}
+#endif /* CONFIG_XILINX_PS_EMAC_HWTSTAMP */
+
+/**
+ * xemacps_rx - process received packets when napi called
+ * @lp: local device instance pointer
+ * @budget: NAPI budget
+ * return: number of BDs processed
+ **/
+static int xemacps_rx(struct net_local *lp, int budget)
+{
+	struct xemacps_bd *cur_p;
+	u32 len;
+	struct sk_buff *skb;
+	struct sk_buff *new_skb;
+	u32 new_skb_baddr;
+	unsigned int numbdfree = 0;
+	u32 size = 0;
+	u32 packets = 0;
+	u32 regval;
+
+	cur_p = &lp->rx_bd[lp->rx_bd_ci];
+	regval = cur_p->addr;
+	rmb();
+	while (numbdfree < budget) {
+		if (!(regval & XEMACPS_RXBUF_NEW_MASK))
+			break;
+
+		new_skb = netdev_alloc_skb(lp->ndev, XEMACPS_RX_BUF_SIZE);
+		if (new_skb == NULL) {
+			dev_err(&lp->ndev->dev, "no memory for new sk_buff\n");
+			break;
+		}
+		/* Get dma handle of skb->data */
+		new_skb_baddr = (u32) dma_map_single(lp->ndev->dev.parent,
+					new_skb->data,
+					XEMACPS_RX_BUF_SIZE,
+					DMA_FROM_DEVICE);
+
+		/* the packet length */
+		len = cur_p->ctrl & XEMACPS_RXBUF_LEN_MASK;
+		rmb();
+		skb = lp->rx_skb[lp->rx_bd_ci].skb;
+		dma_unmap_single(lp->ndev->dev.parent,
+				lp->rx_skb[lp->rx_bd_ci].mapping,
+				lp->rx_skb[lp->rx_bd_ci].len,
+				DMA_FROM_DEVICE);
+
+		/* setup received skb and send it upstream */
+		skb_put(skb, len);  /* Tell the skb how much data we got. */
+		skb->protocol = eth_type_trans(skb, lp->ndev);
+
+		skb->ip_summed = lp->ip_summed;
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+		if ((lp->hwtstamp_config.rx_filter == HWTSTAMP_FILTER_ALL) &&
+		    (ntohs(skb->protocol) == ETH_P_IP)) {
+			u8 transport_poto, msg_type;
+			u16 dst_port;
+			/* While the GEM can timestamp PTP packets, it does
+			 * not mark the RX descriptor to identify them.  This
+			 * is entirely the wrong place to be parsing UDP
+			 * headers, but some minimal effort must be made.
+			 * NOTE: the below parsing of ip_proto and dest_port
+			 * depend on the use of Ethernet_II encapsulation,
+			 * IPv4 without any options.
+			 */
+			skb_copy_from_linear_data_offset(skb,
+				XEMACPS_IP_PROTO_OFFSET, &transport_poto, 1);
+			if (transport_poto == IPPROTO_UDP) {
+				skb_copy_from_linear_data_offset(skb,
+					XEMACPS_UDP_PORT_OFFSET, &dst_port, 2);
+				if (ntohs(dst_port) ==
+						XEMACPS_PTP_EVENT_PORT_NUM) {
+					skb_copy_from_linear_data_offset(skb,
+						XEMACPS_RX_PTPHDR_OFFSET,
+							&msg_type, 1);
+					xemacps_rx_hwtstamp(lp, skb,
+							msg_type & 0x2);
+				}
+			}
+		}
+#endif /* CONFIG_XILINX_PS_EMAC_HWTSTAMP */
+		size += len;
+		packets++;
+		netif_receive_skb(skb);
+
+		cur_p->addr = (cur_p->addr & ~XEMACPS_RXBUF_ADD_MASK)
+					| (new_skb_baddr);
+		lp->rx_skb[lp->rx_bd_ci].skb = new_skb;
+		lp->rx_skb[lp->rx_bd_ci].mapping = new_skb_baddr;
+		lp->rx_skb[lp->rx_bd_ci].len = XEMACPS_RX_BUF_SIZE;
+
+		cur_p->ctrl = 0;
+		cur_p->addr &= (~XEMACPS_RXBUF_NEW_MASK);
+		wmb();
+
+		lp->rx_bd_ci++;
+		lp->rx_bd_ci = lp->rx_bd_ci % XEMACPS_RECV_BD_CNT;
+		cur_p = &lp->rx_bd[lp->rx_bd_ci];
+		regval = cur_p->addr;
+		rmb();
+		numbdfree++;
+	}
+	wmb();
+	lp->stats.rx_packets += packets;
+	lp->stats.rx_bytes += size;
+	return numbdfree;
+}
+
+/**
+ * xemacps_rx_poll - NAPI poll routine
+ * napi: pointer to napi struct
+ * budget:
+ **/
+static int xemacps_rx_poll(struct napi_struct *napi, int budget)
+{
+	struct net_local *lp = container_of(napi, struct net_local, napi);
+	int work_done = 0;
+	u32 regval;
+
+	spin_lock(&lp->rx_lock);
+	while (1) {
+		regval = xemacps_read(lp->baseaddr, XEMACPS_RXSR_OFFSET);
+		xemacps_write(lp->baseaddr, XEMACPS_RXSR_OFFSET, regval);
+		if (regval & XEMACPS_RXSR_HRESPNOK_MASK)
+			dev_err(&lp->pdev->dev, "RX error 0x%x\n", regval);
+
+		work_done += xemacps_rx(lp, budget - work_done);
+		if (work_done >= budget)
+			break;
+
+		napi_complete(napi);
+		/* We disabled RX interrupts in interrupt service
+		 * routine, now it is time to enable it back.
+		 */
+		xemacps_write(lp->baseaddr,
+			XEMACPS_IER_OFFSET, XEMACPS_IXR_FRAMERX_MASK);
+
+		/* If a packet has come in between the last check of the BD
+		 * list and unmasking the interrupts, we may have missed the
+		 * interrupt, so reschedule here.
+		 */
+		if ((lp->rx_bd[lp->rx_bd_ci].addr & XEMACPS_RXBUF_NEW_MASK)
+		&&  napi_reschedule(napi)) {
+			xemacps_write(lp->baseaddr,
+				XEMACPS_IDR_OFFSET, XEMACPS_IXR_FRAMERX_MASK);
+			continue;
+		}
+		break;
+	}
+	spin_unlock(&lp->rx_lock);
+	return work_done;
+}
+
+/**
+ * xemacps_tx_poll - tx bd reclaim tasklet handler
+ * @data: pointer to network interface device structure
+ **/
+static void xemacps_tx_poll(unsigned long data)
+{
+	struct net_device *ndev = (struct net_device *)data;
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+	struct xemacps_bd *cur_p;
+	u32 numbdsinhw;
+	struct ring_info *rp;
+	struct sk_buff *skb;
+	unsigned long flags;
+	u32 txbdcount = 0;
+	bool isfrag = false;
+
+	numbdsinhw = XEMACPS_SEND_BD_CNT - lp->tx_bd_freecnt;
+	if (!numbdsinhw)
+		return;
+
+	regval = xemacps_read(lp->baseaddr, XEMACPS_TXSR_OFFSET);
+	xemacps_write(lp->baseaddr, XEMACPS_TXSR_OFFSET, regval);
+	dev_dbg(&lp->pdev->dev, "TX status 0x%x\n", regval);
+	if (regval & (XEMACPS_TXSR_HRESPNOK_MASK | XEMACPS_TXSR_BUFEXH_MASK))
+		dev_err(&lp->pdev->dev, "TX error 0x%x\n", regval);
+
+	cur_p = &lp->tx_bd[lp->tx_bd_ci];
+
+	while (numbdsinhw) {
+
+		if ((cur_p->ctrl & XEMACPS_TXBUF_USED_MASK) !=
+					XEMACPS_TXBUF_USED_MASK) {
+			if (isfrag == false)
+				break;
+		}
+		rp = &lp->tx_skb[lp->tx_bd_ci];
+		skb = rp->skb;
+		lp->stats.tx_bytes += cur_p->ctrl & XEMACPS_TXBUF_LEN_MASK;
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+			u8 msg_type;
+			skb_copy_from_linear_data_offset(skb,
+				XEMACPS_TX_PTPHDR_OFFSET, &msg_type, 1);
+			xemacps_tx_hwtstamp(lp, skb, msg_type & 0x2);
+		}
+#endif /* CONFIG_XILINX_PS_EMAC_HWTSTAMP */
+
+		dma_unmap_single(&lp->pdev->dev, rp->mapping, rp->len,
+			DMA_TO_DEVICE);
+		rp->skb = NULL;
+		dev_kfree_skb(skb);
+		/* log tx completed packets, errors logs
+		 * are in other error counters.
+		 */
+		if (cur_p->ctrl & XEMACPS_TXBUF_LAST_MASK) {
+			lp->stats.tx_packets++;
+			isfrag = false;
+		} else {
+			isfrag = true;
+		}
+
+		/* Set used bit, preserve wrap bit; clear everything else. */
+		cur_p->ctrl |= XEMACPS_TXBUF_USED_MASK;
+		cur_p->ctrl &= (XEMACPS_TXBUF_USED_MASK |
+					XEMACPS_TXBUF_WRAP_MASK);
+		lp->tx_bd_ci++;
+		lp->tx_bd_ci = lp->tx_bd_ci % XEMACPS_SEND_BD_CNT;
+		cur_p = &lp->tx_bd[lp->tx_bd_ci];
+		numbdsinhw--;
+		txbdcount++;
+	}
+
+	spin_lock(&lp->tx_lock);
+	lp->tx_bd_freecnt += txbdcount;
+	spin_unlock(&lp->tx_lock);
+
+	if (numbdsinhw) {
+		spin_lock_irqsave(&lp->nwctrlreg_lock, flags);
+		regval = xemacps_read(lp->baseaddr, XEMACPS_NWCTRL_OFFSET);
+		regval |= XEMACPS_NWCTRL_STARTTX_MASK;
+		xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET, regval);
+		spin_unlock_irqrestore(&lp->nwctrlreg_lock, flags);
+	}
+
+	netif_wake_queue(ndev);
+}
+
+/**
+ * xemacps_interrupt - interrupt main service routine
+ * @irq: interrupt number
+ * @dev_id: pointer to a network device structure
+ * return IRQ_HANDLED or IRQ_NONE
+ **/
+static irqreturn_t xemacps_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = dev_id;
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regisr;
+	u32 regctrl;
+
+	regisr = xemacps_read(lp->baseaddr, XEMACPS_ISR_OFFSET);
+	if (unlikely(!regisr))
+		return IRQ_NONE;
+
+	xemacps_write(lp->baseaddr, XEMACPS_ISR_OFFSET, regisr);
+
+	while (regisr) {
+		if (regisr & (XEMACPS_IXR_TXCOMPL_MASK |
+				XEMACPS_IXR_TX_ERR_MASK)) {
+			tasklet_schedule(&lp->tx_bdreclaim_tasklet);
+		}
+
+		if (regisr & XEMACPS_IXR_RXUSED_MASK) {
+			spin_lock(&lp->nwctrlreg_lock);
+			regctrl = xemacps_read(lp->baseaddr,
+					XEMACPS_NWCTRL_OFFSET);
+			regctrl |= XEMACPS_NWCTRL_FLUSH_DPRAM_MASK;
+			xemacps_write(lp->baseaddr,
+					XEMACPS_NWCTRL_OFFSET, regctrl);
+			spin_unlock(&lp->nwctrlreg_lock);
+		}
+
+		if (regisr & XEMACPS_IXR_FRAMERX_MASK) {
+			xemacps_write(lp->baseaddr,
+				XEMACPS_IDR_OFFSET, XEMACPS_IXR_FRAMERX_MASK);
+			napi_schedule(&lp->napi);
+		}
+		regisr = xemacps_read(lp->baseaddr, XEMACPS_ISR_OFFSET);
+		xemacps_write(lp->baseaddr, XEMACPS_ISR_OFFSET, regisr);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Free all packets presently in the descriptor rings.
+ */
+static void xemacps_clean_rings(struct net_local *lp)
+{
+	int i;
+
+	for (i = 0; i < XEMACPS_RECV_BD_CNT; i++) {
+		if (lp->rx_skb && lp->rx_skb[i].skb) {
+			dma_unmap_single(lp->ndev->dev.parent,
+					 lp->rx_skb[i].mapping,
+					 lp->rx_skb[i].len,
+					 DMA_FROM_DEVICE);
+
+			dev_kfree_skb(lp->rx_skb[i].skb);
+			lp->rx_skb[i].skb = NULL;
+			lp->rx_skb[i].mapping = 0;
+		}
+	}
+
+	for (i = 0; i < XEMACPS_SEND_BD_CNT; i++) {
+		if (lp->tx_skb && lp->tx_skb[i].skb) {
+			dma_unmap_single(lp->ndev->dev.parent,
+					 lp->tx_skb[i].mapping,
+					 lp->tx_skb[i].len,
+					 DMA_TO_DEVICE);
+
+			dev_kfree_skb(lp->tx_skb[i].skb);
+			lp->tx_skb[i].skb = NULL;
+			lp->tx_skb[i].mapping = 0;
+		}
+	}
+}
+
+/**
+ * xemacps_descriptor_free - Free allocated TX and RX BDs
+ * @lp: local device instance pointer
+ **/
+static void xemacps_descriptor_free(struct net_local *lp)
+{
+	int size;
+
+	xemacps_clean_rings(lp);
+
+	/* kfree(NULL) is safe, no need to check here */
+	kfree(lp->tx_skb);
+	lp->tx_skb = NULL;
+	kfree(lp->rx_skb);
+	lp->rx_skb = NULL;
+
+	size = XEMACPS_RECV_BD_CNT * sizeof(struct xemacps_bd);
+	if (lp->rx_bd) {
+		dma_free_coherent(&lp->pdev->dev, size,
+			lp->rx_bd, lp->rx_bd_dma);
+		lp->rx_bd = NULL;
+	}
+
+	size = XEMACPS_SEND_BD_CNT * sizeof(struct xemacps_bd);
+	if (lp->tx_bd) {
+		dma_free_coherent(&lp->pdev->dev, size,
+			lp->tx_bd, lp->tx_bd_dma);
+		lp->tx_bd = NULL;
+	}
+}
+
+/**
+ * xemacps_descriptor_init - Allocate both TX and RX BDs
+ * @lp: local device instance pointer
+ * return 0 on success, negative value if error
+ **/
+static int xemacps_descriptor_init(struct net_local *lp)
+{
+	int size;
+	struct sk_buff *new_skb;
+	u32 new_skb_baddr;
+	u32 i;
+	struct xemacps_bd *cur_p;
+	u32 regval;
+
+	lp->tx_skb = NULL;
+	lp->rx_skb = NULL;
+	lp->rx_bd = NULL;
+	lp->tx_bd = NULL;
+
+	/* Reset the indexes which are used for accessing the BDs */
+	lp->tx_bd_ci = 0;
+	lp->tx_bd_tail = 0;
+	lp->rx_bd_ci = 0;
+
+	size = XEMACPS_SEND_BD_CNT * sizeof(struct ring_info);
+	lp->tx_skb = kzalloc(size, GFP_KERNEL);
+	if (!lp->tx_skb)
+		goto err_out;
+	size = XEMACPS_RECV_BD_CNT * sizeof(struct ring_info);
+	lp->rx_skb = kzalloc(size, GFP_KERNEL);
+	if (!lp->rx_skb)
+		goto err_out;
+
+	/*
+	 * Set up RX buffer descriptors.
+	 */
+
+	size = XEMACPS_RECV_BD_CNT * sizeof(struct xemacps_bd);
+	lp->rx_bd = dma_alloc_coherent(&lp->pdev->dev, size,
+			&lp->rx_bd_dma, GFP_KERNEL);
+	if (!lp->rx_bd)
+		goto err_out;
+	dev_dbg(&lp->pdev->dev, "RX ring %d bytes at 0x%x mapped %p\n",
+			size, lp->rx_bd_dma, lp->rx_bd);
+
+	for (i = 0; i < XEMACPS_RECV_BD_CNT; i++) {
+		cur_p = &lp->rx_bd[i];
+
+		new_skb = netdev_alloc_skb(lp->ndev, XEMACPS_RX_BUF_SIZE);
+		if (new_skb == NULL) {
+			dev_err(&lp->ndev->dev, "alloc_skb error %d\n", i);
+			goto err_out;
+		}
+
+		/* Get dma handle of skb->data */
+		new_skb_baddr = (u32) dma_map_single(lp->ndev->dev.parent,
+							new_skb->data,
+							XEMACPS_RX_BUF_SIZE,
+							DMA_FROM_DEVICE);
+
+		/* set wrap bit for last BD */
+		regval = (new_skb_baddr & XEMACPS_RXBUF_ADD_MASK);
+		if (i == XEMACPS_RECV_BD_CNT - 1)
+			regval |= XEMACPS_RXBUF_WRAP_MASK;
+		cur_p->addr = regval;
+		cur_p->ctrl = 0;
+		wmb();
+
+		lp->rx_skb[i].skb = new_skb;
+		lp->rx_skb[i].mapping = new_skb_baddr;
+		lp->rx_skb[i].len = XEMACPS_RX_BUF_SIZE;
+	}
+
+	/*
+	 * Set up TX buffer descriptors.
+	 */
+
+	size = XEMACPS_SEND_BD_CNT * sizeof(struct xemacps_bd);
+	lp->tx_bd = dma_alloc_coherent(&lp->pdev->dev, size,
+			&lp->tx_bd_dma, GFP_KERNEL);
+	if (!lp->tx_bd)
+		goto err_out;
+	dev_dbg(&lp->pdev->dev, "TX ring %d bytes at 0x%x mapped %p\n",
+			size, lp->tx_bd_dma, lp->tx_bd);
+
+	for (i = 0; i < XEMACPS_SEND_BD_CNT; i++) {
+		cur_p = &lp->tx_bd[i];
+		/* set wrap bit for last BD */
+		cur_p->addr = 0;
+		regval = XEMACPS_TXBUF_USED_MASK;
+		if (i == XEMACPS_SEND_BD_CNT - 1)
+			regval |= XEMACPS_TXBUF_WRAP_MASK;
+		cur_p->ctrl = regval;
+	}
+	wmb();
+
+	lp->tx_bd_freecnt = XEMACPS_SEND_BD_CNT;
+
+	dev_dbg(&lp->pdev->dev,
+		"lp->tx_bd %p lp->tx_bd_dma %p lp->tx_skb %p\n",
+		lp->tx_bd, (void *)lp->tx_bd_dma, lp->tx_skb);
+	dev_dbg(&lp->pdev->dev,
+		"lp->rx_bd %p lp->rx_bd_dma %p lp->rx_skb %p\n",
+		lp->rx_bd, (void *)lp->rx_bd_dma, lp->rx_skb);
+
+	return 0;
+
+err_out:
+	xemacps_descriptor_free(lp);
+	return -ENOMEM;
+}
+
+/**
+ * xemacps_init_hw - Initialize hardware to known good state
+ * @lp: local device instance pointer
+ **/
+static void xemacps_init_hw(struct net_local *lp)
+{
+	u32 regval;
+
+	xemacps_reset_hw(lp);
+	xemacps_set_hwaddr(lp);
+
+	/* network configuration */
+	regval  = 0;
+	regval |= XEMACPS_NWCFG_FDEN_MASK;
+	regval |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
+	regval |= XEMACPS_NWCFG_PAUSECOPYDI_MASK;
+	regval |= XEMACPS_NWCFG_FCSREM_MASK;
+	regval |= XEMACPS_NWCFG_PAUSEEN_MASK;
+	regval |= XEMACPS_NWCFG_100_MASK;
+	regval |= XEMACPS_NWCFG_HDRXEN_MASK;
+
+	regval |= (MDC_DIV_224 << XEMACPS_NWCFG_MDC_SHIFT_MASK);
+	if (lp->ndev->flags & IFF_PROMISC)	/* copy all */
+		regval |= XEMACPS_NWCFG_COPYALLEN_MASK;
+	if (!(lp->ndev->flags & IFF_BROADCAST))	/* No broadcast */
+		regval |= XEMACPS_NWCFG_BCASTDI_MASK;
+	xemacps_write(lp->baseaddr, XEMACPS_NWCFG_OFFSET, regval);
+
+	/* Init TX and RX DMA Q address */
+	xemacps_write(lp->baseaddr, XEMACPS_RXQBASE_OFFSET, lp->rx_bd_dma);
+	xemacps_write(lp->baseaddr, XEMACPS_TXQBASE_OFFSET, lp->tx_bd_dma);
+
+	/* DMACR configurations */
+	regval  = (((XEMACPS_RX_BUF_SIZE / XEMACPS_RX_BUF_UNIT) +
+		((XEMACPS_RX_BUF_SIZE % XEMACPS_RX_BUF_UNIT) ? 1 : 0)) <<
+		XEMACPS_DMACR_RXBUF_SHIFT);
+	regval |= XEMACPS_DMACR_RXSIZE_MASK;
+	regval |= XEMACPS_DMACR_TXSIZE_MASK;
+	regval |= XEMACPS_DMACR_TCPCKSUM_MASK;
+#ifdef __LITTLE_ENDIAN
+	regval &= ~XEMACPS_DMACR_ENDIAN_MASK;
+#endif
+#ifdef __BIG_ENDIAN
+	regval |= XEMACPS_DMACR_ENDIAN_MASK;
+#endif
+	regval |= XEMACPS_DMACR_BLENGTH_INCR16;
+	xemacps_write(lp->baseaddr, XEMACPS_DMACR_OFFSET, regval);
+
+	/* Enable TX, RX and MDIO port */
+	regval  = 0;
+	regval |= XEMACPS_NWCTRL_MDEN_MASK;
+	regval |= XEMACPS_NWCTRL_TXEN_MASK;
+	regval |= XEMACPS_NWCTRL_RXEN_MASK;
+	xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET, regval);
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+	/* Initialize the ptp clock */
+	xemacps_ptp_init(lp);
+#endif
+
+	/* Enable interrupts */
+	regval  = XEMACPS_IXR_ALL_MASK;
+	xemacps_write(lp->baseaddr, XEMACPS_IER_OFFSET, regval);
+}
+
+/**
+ * xemacps_resetrx_for_no_rxdata - Resets the Rx if there is no data
+ * for a while (presently 100 msecs)
+ * @data: Used for net_local instance pointer
+ **/
+static void xemacps_resetrx_for_no_rxdata(unsigned long data)
+{
+	struct net_local *lp = (struct net_local *)data;
+	unsigned long regctrl;
+	unsigned long tempcntr;
+	unsigned long flags;
+
+	tempcntr = xemacps_read(lp->baseaddr, XEMACPS_RXCNT_OFFSET);
+	if ((!tempcntr) && (!(lp->lastrxfrmscntr))) {
+		spin_lock_irqsave(&lp->nwctrlreg_lock, flags);
+		regctrl = xemacps_read(lp->baseaddr,
+				XEMACPS_NWCTRL_OFFSET);
+		regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
+		xemacps_write(lp->baseaddr,
+				XEMACPS_NWCTRL_OFFSET, regctrl);
+		regctrl = xemacps_read(lp->baseaddr, XEMACPS_NWCTRL_OFFSET);
+		regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
+		xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET, regctrl);
+		spin_unlock_irqrestore(&lp->nwctrlreg_lock, flags);
+	}
+	lp->lastrxfrmscntr = tempcntr;
+}
+
+/**
+ * xemacps_update_stats - Update the statistic structure entries from
+ * the corresponding emacps hardware statistic registers
+ * @data: Used for net_local instance pointer
+ **/
+static void xemacps_update_stats(unsigned long data)
+{
+	struct net_local *lp = (struct net_local *)data;
+	struct net_device_stats *nstat = &lp->stats;
+	u32 cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXUNDRCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_length_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXOVRCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_length_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXJABCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_length_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXFCSCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_crc_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXLENGTHCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_length_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXALIGNCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_frame_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXRESERRCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_missed_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_RXORCNT_OFFSET);
+	nstat->rx_errors += cnt;
+	nstat->rx_fifo_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_TXURUNCNT_OFFSET);
+	nstat->tx_errors += cnt;
+	nstat->tx_fifo_errors += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_SNGLCOLLCNT_OFFSET);
+	nstat->collisions += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_MULTICOLLCNT_OFFSET);
+	nstat->collisions += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_EXCESSCOLLCNT_OFFSET);
+	nstat->tx_errors += cnt;
+	nstat->tx_aborted_errors += cnt;
+	nstat->collisions += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_LATECOLLCNT_OFFSET);
+	nstat->tx_errors += cnt;
+	nstat->collisions += cnt;
+
+	cnt = xemacps_read(lp->baseaddr, XEMACPS_CSENSECNT_OFFSET);
+	nstat->tx_errors += cnt;
+	nstat->tx_carrier_errors += cnt;
+}
+
+/**
+ * xemacps_gen_purpose_timerhandler - Timer handler that is called at regular
+ * intervals upon expiry of the gen_purpose_timer defined in net_local struct.
+ * @data: Used for net_local instance pointer
+ *
+ * This timer handler is used to update the statistics by calling the API
+ * xemacps_update_stats. The statistics register can typically overflow pretty
+ * quickly under heavy load conditions. This timer is used to periodically
+ * read the stats registers and update the corresponding stats structure
+ * entries. The stats registers when read reset to 0.
+ **/
+static void xemacps_gen_purpose_timerhandler(unsigned long data)
+{
+	struct net_local *lp = (struct net_local *)data;
+
+	xemacps_update_stats(data);
+	xemacps_resetrx_for_no_rxdata(data);
+	mod_timer(&(lp->gen_purpose_timer),
+		jiffies + msecs_to_jiffies(XEAMCPS_GEN_PURPOSE_TIMER_LOAD));
+}
+
+/**
+ * xemacps_open - Called when a network device is made active
+ * @ndev: network interface device structure
+ * return 0 on success, negative value if error
+ *
+ * The open entry point is called when a network interface is made active
+ * by the system (IFF_UP). At this point all resources needed for transmit
+ * and receive operations are allocated, the interrupt handler is
+ * registered with OS, the watchdog timer is started, and the stack is
+ * notified that the interface is ready.
+ *
+ * note: if error(s), allocated resources before error require to be
+ * released or system issues (such as memory) leak might happen.
+ **/
+static int xemacps_open(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	int rc;
+
+	dev_dbg(&lp->pdev->dev, "open\n");
+	if (!is_valid_ether_addr(ndev->dev_addr))
+		return  -EADDRNOTAVAIL;
+
+	rc = xemacps_descriptor_init(lp);
+	if (rc) {
+		dev_err(&lp->pdev->dev,
+			"Unable to allocate DMA memory, rc %d\n", rc);
+		return rc;
+	}
+
+	rc = pm_runtime_get_sync(&lp->pdev->dev);
+	if (rc < 0) {
+		dev_err(&lp->pdev->dev,
+			"pm_runtime_get_sync() failed, rc %d\n", rc);
+		goto err_free_rings;
+	}
+
+	napi_enable(&lp->napi);
+	xemacps_init_hw(lp);
+	rc = xemacps_mii_probe(ndev);
+	if (rc != 0) {
+		dev_err(&lp->pdev->dev,
+			"%s mii_probe fail.\n", lp->mii_bus->name);
+		if (rc == (-2)) {
+			mdiobus_unregister(lp->mii_bus);
+			kfree(lp->mii_bus->irq);
+			mdiobus_free(lp->mii_bus);
+		}
+		rc = -ENXIO;
+		goto err_pm_put;
+	}
+
+	setup_timer(&(lp->gen_purpose_timer), xemacps_gen_purpose_timerhandler,
+							(unsigned long)lp);
+	mod_timer(&(lp->gen_purpose_timer),
+		jiffies + msecs_to_jiffies(XEAMCPS_GEN_PURPOSE_TIMER_LOAD));
+
+	netif_carrier_on(ndev);
+	netif_start_queue(ndev);
+	tasklet_enable(&lp->tx_bdreclaim_tasklet);
+
+	return 0;
+
+err_pm_put:
+	napi_disable(&lp->napi);
+	xemacps_reset_hw(lp);
+	pm_runtime_put(&lp->pdev->dev);
+err_free_rings:
+	xemacps_descriptor_free(lp);
+
+	return rc;
+}
+
+/**
+ * xemacps_close - disable a network interface
+ * @ndev: network interface device structure
+ * return 0
+ *
+ * The close entry point is called when a network interface is de-activated
+ * by OS. The hardware is still under the driver control, but needs to be
+ * disabled. A global MAC reset is issued to stop the hardware, and all
+ * transmit and receive resources are freed.
+ **/
+static int xemacps_close(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+
+	del_timer_sync(&(lp->gen_purpose_timer));
+	netif_stop_queue(ndev);
+	napi_disable(&lp->napi);
+	tasklet_disable(&lp->tx_bdreclaim_tasklet);
+	netif_carrier_off(ndev);
+	if (lp->phy_dev)
+		phy_disconnect(lp->phy_dev);
+	if (lp->gmii2rgmii_phy_node)
+		phy_disconnect(lp->gmii2rgmii_phy_dev);
+	xemacps_reset_hw(lp);
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+	xemacps_ptp_close(lp);
+#endif
+	mdelay(500);
+	xemacps_descriptor_free(lp);
+
+	pm_runtime_put(&lp->pdev->dev);
+
+	return 0;
+}
+
+/**
+ * xemacps_reinit_for_txtimeout - work queue scheduled for the tx timeout
+ * handling.
+ * @ndev: queue work structure
+ **/
+static void xemacps_reinit_for_txtimeout(struct work_struct *data)
+{
+	struct net_local *lp = container_of(data, struct net_local,
+		txtimeout_reinit);
+	int rc;
+
+	netif_stop_queue(lp->ndev);
+	napi_disable(&lp->napi);
+	tasklet_disable(&lp->tx_bdreclaim_tasklet);
+	spin_lock_bh(&lp->tx_lock);
+	xemacps_reset_hw(lp);
+	spin_unlock_bh(&lp->tx_lock);
+
+	if (lp->phy_dev)
+		phy_stop(lp->phy_dev);
+
+	xemacps_descriptor_free(lp);
+	rc = xemacps_descriptor_init(lp);
+	if (rc) {
+		dev_err(&lp->pdev->dev,
+			"Unable to allocate DMA memory, rc %d\n", rc);
+		return;
+	}
+
+	xemacps_init_hw(lp);
+
+	lp->link    = 0;
+	lp->speed   = 0;
+	lp->duplex  = -1;
+
+	if (lp->phy_dev)
+		phy_start(lp->phy_dev);
+
+	napi_enable(&lp->napi);
+	tasklet_enable(&lp->tx_bdreclaim_tasklet);
+	lp->ndev->trans_start = jiffies;
+	netif_wake_queue(lp->ndev);
+}
+
+/**
+ * xemacps_tx_timeout - callback used when the transmitter has not made
+ * any progress for dev->watchdog ticks.
+ * @ndev: network interface device structure
+ **/
+static void xemacps_tx_timeout(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+
+	dev_err(&lp->pdev->dev, "transmit timeout %lu ms, reseting...\n",
+		TX_TIMEOUT * 1000UL / HZ);
+	queue_work(lp->txtimeout_handler_wq, &lp->txtimeout_reinit);
+}
+
+/**
+ * xemacps_set_mac_address - set network interface mac address
+ * @ndev: network interface device structure
+ * @addr: pointer to MAC address
+ * return 0 on success, negative value if error
+ **/
+static int xemacps_set_mac_address(struct net_device *ndev, void *addr)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct sockaddr *hwaddr = (struct sockaddr *)addr;
+
+	if (netif_running(ndev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(hwaddr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	dev_dbg(&lp->pdev->dev, "hwaddr 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		hwaddr->sa_data[0], hwaddr->sa_data[1], hwaddr->sa_data[2],
+		hwaddr->sa_data[3], hwaddr->sa_data[4], hwaddr->sa_data[5]);
+
+	memcpy(ndev->dev_addr, hwaddr->sa_data, ndev->addr_len);
+
+	xemacps_set_hwaddr(lp);
+	return 0;
+}
+
+/**
+ * xemacps_clear_csum - Clear the csum field for  transport protocols
+ * @skb: socket buffer
+ * @ndev: network interface device structure
+ * return 0 on success, other value if error
+ **/
+static int xemacps_clear_csum(struct sk_buff *skb, struct net_device *ndev)
+{
+	/* Only run for packets requiring a checksum. */
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return 0;
+
+	if (unlikely(skb_cow_head(skb, 0)))
+		return -1;
+
+	*(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = 0;
+
+	return 0;
+}
+
+/**
+ * xemacps_start_xmit - transmit a packet (called by kernel)
+ * @skb: socket buffer
+ * @ndev: network interface device structure
+ * return 0 on success, other value if error
+ **/
+static int xemacps_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	dma_addr_t  mapping;
+	unsigned int nr_frags, len;
+	int i;
+	u32 regval;
+	void       *virt_addr;
+	skb_frag_t *frag;
+	struct xemacps_bd *cur_p;
+	unsigned long flags;
+	u32 bd_tail;
+
+	nr_frags = skb_shinfo(skb)->nr_frags + 1;
+	if (nr_frags > lp->tx_bd_freecnt) {
+		netif_stop_queue(ndev); /* stop send queue */
+		return NETDEV_TX_BUSY;
+	}
+
+	if (xemacps_clear_csum(skb, ndev)) {
+		kfree(skb);
+		return NETDEV_TX_OK;
+	}
+
+	bd_tail = lp->tx_bd_tail;
+	cur_p = &lp->tx_bd[bd_tail];
+	frag = &skb_shinfo(skb)->frags[0];
+
+	for (i = 0; i < nr_frags; i++) {
+		if (i == 0) {
+			len = skb_headlen(skb);
+			mapping = dma_map_single(&lp->pdev->dev, skb->data,
+				len, DMA_TO_DEVICE);
+		} else {
+			len = skb_frag_size(frag);
+			virt_addr = skb_frag_address(frag);
+			mapping = dma_map_single(&lp->pdev->dev, virt_addr,
+				len, DMA_TO_DEVICE);
+			frag++;
+			skb_get(skb);
+		}
+
+		lp->tx_skb[lp->tx_bd_tail].skb = skb;
+		lp->tx_skb[lp->tx_bd_tail].mapping = mapping;
+		lp->tx_skb[lp->tx_bd_tail].len = len;
+		cur_p->addr = mapping;
+
+		/* preserve critical status bits */
+		regval = cur_p->ctrl;
+		regval &= (XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK);
+		/* update length field */
+		regval |= ((regval & ~XEMACPS_TXBUF_LEN_MASK) | len);
+		/* commit second to last buffer to hardware */
+		if (i != 0)
+			regval &= ~XEMACPS_TXBUF_USED_MASK;
+		/* last fragment of this packet? */
+		if (i == (nr_frags - 1))
+			regval |= XEMACPS_TXBUF_LAST_MASK;
+		cur_p->ctrl = regval;
+
+		lp->tx_bd_tail++;
+		lp->tx_bd_tail = lp->tx_bd_tail % XEMACPS_SEND_BD_CNT;
+		cur_p = &(lp->tx_bd[lp->tx_bd_tail]);
+	}
+
+	/* commit first buffer to hardware -- do this after
+	 * committing the other buffers to avoid an underrun */
+	cur_p = &lp->tx_bd[bd_tail];
+	regval = cur_p->ctrl;
+	regval &= ~XEMACPS_TXBUF_USED_MASK;
+	cur_p->ctrl = regval;
+
+	spin_lock_bh(&lp->tx_lock);
+	lp->tx_bd_freecnt -= nr_frags;
+	spin_unlock_bh(&lp->tx_lock);
+
+	spin_lock_irqsave(&lp->nwctrlreg_lock, flags);
+	regval = xemacps_read(lp->baseaddr, XEMACPS_NWCTRL_OFFSET);
+	xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET,
+			(regval | XEMACPS_NWCTRL_STARTTX_MASK));
+	spin_unlock_irqrestore(&lp->nwctrlreg_lock, flags);
+
+	ndev->trans_start = jiffies;
+	return 0;
+}
+
+/*
+ * Get the MAC Address bit from the specified position
+ */
+static unsigned get_bit(u8 *mac, unsigned bit)
+{
+	unsigned byte;
+
+	byte = mac[bit / 8];
+	byte >>= (bit & 0x7);
+	byte &= 1;
+
+	return byte;
+}
+
+/*
+ * Calculate a GEM MAC Address hash index
+ */
+static unsigned calc_mac_hash(u8 *mac)
+{
+	int index_bit, mac_bit;
+	unsigned hash_index;
+
+	hash_index = 0;
+	mac_bit = 5;
+	for (index_bit = 5; index_bit >= 0; index_bit--) {
+		hash_index |= (get_bit(mac,  mac_bit) ^
+					get_bit(mac, mac_bit + 6) ^
+					get_bit(mac, mac_bit + 12) ^
+					get_bit(mac, mac_bit + 18) ^
+					get_bit(mac, mac_bit + 24) ^
+					get_bit(mac, mac_bit + 30) ^
+					get_bit(mac, mac_bit + 36) ^
+					get_bit(mac, mac_bit + 42))
+						<< index_bit;
+		mac_bit--;
+	}
+
+	return hash_index;
+}
+
+/**
+ * xemacps_set_hashtable - Add multicast addresses to the internal
+ * multicast-hash table. Called from xemac_set_rx_mode().
+ * @ndev: network interface device structure
+ *
+ * The hash address register is 64 bits long and takes up two
+ * locations in the memory map.  The least significant bits are stored
+ * in EMAC_HSL and the most significant bits in EMAC_HSH.
+ *
+ * The unicast hash enable and the multicast hash enable bits in the
+ * network configuration register enable the reception of hash matched
+ * frames. The destination address is reduced to a 6 bit index into
+ * the 64 bit hash register using the following hash function.  The
+ * hash function is an exclusive or of every sixth bit of the
+ * destination address.
+ *
+ * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
+ * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
+ * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
+ * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
+ * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
+ * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
+ *
+ * da[0] represents the least significant bit of the first byte
+ * received, that is, the multicast/unicast indicator, and da[47]
+ * represents the most significant bit of the last byte received.  If
+ * the hash index, hi[n], points to a bit that is set in the hash
+ * register then the frame will be matched according to whether the
+ * frame is multicast or unicast.  A multicast match will be signalled
+ * if the multicast hash enable bit is set, da[0] is 1 and the hash
+ * index points to a bit set in the hash register.  A unicast match
+ * will be signalled if the unicast hash enable bit is set, da[0] is 0
+ * and the hash index points to a bit set in the hash register.  To
+ * receive all multicast frames, the hash register should be set with
+ * all ones and the multicast hash enable bit should be set in the
+ * network configuration register.
+ **/
+static void xemacps_set_hashtable(struct net_device *ndev)
+{
+	struct netdev_hw_addr *curr;
+	u32 regvalh, regvall, hash_index;
+	u8 *mc_addr;
+	struct net_local *lp;
+
+	lp = netdev_priv(ndev);
+
+	regvalh = regvall = 0;
+
+	netdev_for_each_mc_addr(curr, ndev) {
+		if (!curr)	/* end of list */
+			break;
+		mc_addr = curr->addr;
+		hash_index = calc_mac_hash(mc_addr);
+
+		if (hash_index >= XEMACPS_MAX_HASH_BITS) {
+			dev_err(&lp->pdev->dev,
+					"hash calculation out of range %d\n",
+					hash_index);
+			break;
+		}
+		if (hash_index < 32)
+			regvall |= (1 << hash_index);
+		else
+			regvalh |= (1 << (hash_index - 32));
+	}
+
+	xemacps_write(lp->baseaddr, XEMACPS_HASHL_OFFSET, regvall);
+	xemacps_write(lp->baseaddr, XEMACPS_HASHH_OFFSET, regvalh);
+}
+
+/**
+ * xemacps_set_rx_mode - enable/disable promiscuous and multicast modes
+ * @ndev: network interface device structure
+ **/
+static void xemacps_set_rx_mode(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+
+	regval = xemacps_read(lp->baseaddr, XEMACPS_NWCFG_OFFSET);
+
+	/* promisc mode */
+	if (ndev->flags & IFF_PROMISC)
+		regval |= XEMACPS_NWCFG_COPYALLEN_MASK;
+	if (!(ndev->flags & IFF_PROMISC))
+		regval &= ~XEMACPS_NWCFG_COPYALLEN_MASK;
+
+	/* All multicast mode */
+	if (ndev->flags & IFF_ALLMULTI) {
+		regval |= XEMACPS_NWCFG_MCASTHASHEN_MASK;
+		xemacps_write(lp->baseaddr, XEMACPS_HASHL_OFFSET, ~0UL);
+		xemacps_write(lp->baseaddr, XEMACPS_HASHH_OFFSET, ~0UL);
+	/* Specific multicast mode */
+	} else if ((ndev->flags & IFF_MULTICAST)
+			&& (netdev_mc_count(ndev) > 0)) {
+		regval |= XEMACPS_NWCFG_MCASTHASHEN_MASK;
+		xemacps_set_hashtable(ndev);
+	/* Disable multicast mode */
+	} else {
+		xemacps_write(lp->baseaddr, XEMACPS_HASHL_OFFSET, 0x0);
+		xemacps_write(lp->baseaddr, XEMACPS_HASHH_OFFSET, 0x0);
+		regval &= ~XEMACPS_NWCFG_MCASTHASHEN_MASK;
+	}
+
+	/* broadcast mode */
+	if (ndev->flags & IFF_BROADCAST)
+		regval &= ~XEMACPS_NWCFG_BCASTDI_MASK;
+	/* No broadcast */
+	if (!(ndev->flags & IFF_BROADCAST))
+		regval |= XEMACPS_NWCFG_BCASTDI_MASK;
+
+	xemacps_write(lp->baseaddr, XEMACPS_NWCFG_OFFSET, regval);
+}
+
+#define MIN_MTU 60
+#define MAX_MTU 1500
+/**
+ * xemacps_change_mtu - Change maximum transfer unit
+ * @ndev: network interface device structure
+ * @new_mtu: new vlaue for maximum frame size
+ * return: 0 on success, negative value if error.
+ **/
+static int xemacps_change_mtu(struct net_device *ndev, int new_mtu)
+{
+	if ((new_mtu < MIN_MTU) ||
+		((new_mtu + ndev->hard_header_len) > MAX_MTU))
+		return -EINVAL;
+
+	ndev->mtu = new_mtu;	/* change mtu in net_device structure */
+	return 0;
+}
+
+/**
+ * xemacps_get_settings - get device specific settings.
+ * Usage: Issue "ethtool ethX" under linux prompt.
+ * @ndev: network device
+ * @ecmd: ethtool command structure
+ * return: 0 on success, negative value if error.
+ **/
+static int
+xemacps_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_gset(phydev, ecmd);
+}
+
+/**
+ * xemacps_set_settings - set device specific settings.
+ * Usage: Issue "ethtool -s ethX speed 1000" under linux prompt
+ * to change speed
+ * @ndev: network device
+ * @ecmd: ethtool command structure
+ * return: 0 on success, negative value if error.
+ **/
+static int
+xemacps_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phydev, ecmd);
+}
+
+/**
+ * xemacps_get_drvinfo - report driver information
+ * Usage: Issue "ethtool -i ethX" under linux prompt
+ * @ndev: network device
+ * @ed: device driver information structure
+ **/
+static void
+xemacps_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *ed)
+{
+	struct net_local *lp = netdev_priv(ndev);
+
+	memset(ed, 0, sizeof(struct ethtool_drvinfo));
+	strcpy(ed->driver, lp->pdev->dev.driver->name);
+	strcpy(ed->version, DRIVER_VERSION);
+}
+
+/**
+ * xemacps_get_ringparam - get device dma ring information.
+ * Usage: Issue "ethtool -g ethX" under linux prompt
+ * @ndev: network device
+ * @erp: ethtool ring parameter structure
+ **/
+static void
+xemacps_get_ringparam(struct net_device *ndev, struct ethtool_ringparam *erp)
+{
+	memset(erp, 0, sizeof(struct ethtool_ringparam));
+
+	erp->rx_max_pending = XEMACPS_RECV_BD_CNT;
+	erp->tx_max_pending = XEMACPS_SEND_BD_CNT;
+	erp->rx_pending = 0;
+	erp->tx_pending = 0;
+}
+
+/**
+ * xemacps_get_wol - get device wake on lan status
+ * Usage: Issue "ethtool ethX" under linux prompt
+ * @ndev: network device
+ * @ewol: wol status
+ **/
+static void
+xemacps_get_wol(struct net_device *ndev, struct ethtool_wolinfo *ewol)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+
+	ewol->supported = WAKE_MAGIC | WAKE_ARP | WAKE_UCAST | WAKE_MCAST;
+
+	regval = xemacps_read(lp->baseaddr, XEMACPS_WOL_OFFSET);
+	if (regval | XEMACPS_WOL_MCAST_MASK)
+		ewol->wolopts |= WAKE_MCAST;
+	if (regval | XEMACPS_WOL_ARP_MASK)
+		ewol->wolopts |= WAKE_ARP;
+	if (regval | XEMACPS_WOL_SPEREG1_MASK)
+		ewol->wolopts |= WAKE_UCAST;
+	if (regval | XEMACPS_WOL_MAGIC_MASK)
+		ewol->wolopts |= WAKE_MAGIC;
+
+}
+
+/**
+ * xemacps_set_wol - set device wake on lan configuration
+ * Usage: Issue "ethtool -s ethX wol u|m|b|g" under linux prompt to enable
+ * specified type of packet.
+ * Usage: Issue "ethtool -s ethX wol d" under linux prompt to disable
+ * this feature.
+ * @ndev: network device
+ * @ewol: wol status
+ * return 0 on success, negative value if not supported
+ **/
+static int
+xemacps_set_wol(struct net_device *ndev, struct ethtool_wolinfo *ewol)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+
+	if (ewol->wolopts & ~(WAKE_MAGIC | WAKE_ARP | WAKE_UCAST | WAKE_MCAST))
+		return -EOPNOTSUPP;
+
+	regval  = xemacps_read(lp->baseaddr, XEMACPS_WOL_OFFSET);
+	regval &= ~(XEMACPS_WOL_MCAST_MASK | XEMACPS_WOL_ARP_MASK |
+		XEMACPS_WOL_SPEREG1_MASK | XEMACPS_WOL_MAGIC_MASK);
+
+	if (ewol->wolopts & WAKE_MAGIC)
+		regval |= XEMACPS_WOL_MAGIC_MASK;
+	if (ewol->wolopts & WAKE_ARP)
+		regval |= XEMACPS_WOL_ARP_MASK;
+	if (ewol->wolopts & WAKE_UCAST)
+		regval |= XEMACPS_WOL_SPEREG1_MASK;
+	if (ewol->wolopts & WAKE_MCAST)
+		regval |= XEMACPS_WOL_MCAST_MASK;
+
+	xemacps_write(lp->baseaddr, XEMACPS_WOL_OFFSET, regval);
+
+	return 0;
+}
+
+/**
+ * xemacps_get_pauseparam - get device pause status
+ * Usage: Issue "ethtool -a ethX" under linux prompt
+ * @ndev: network device
+ * @epauseparam: pause parameter
+ *
+ * note: hardware supports only tx flow control
+ **/
+static void
+xemacps_get_pauseparam(struct net_device *ndev,
+		struct ethtool_pauseparam *epauseparm)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+
+	epauseparm->autoneg  = 0;
+	epauseparm->rx_pause = 0;
+
+	regval = xemacps_read(lp->baseaddr, XEMACPS_NWCFG_OFFSET);
+	epauseparm->tx_pause = regval & XEMACPS_NWCFG_PAUSEEN_MASK;
+}
+
+/**
+ * xemacps_set_pauseparam - set device pause parameter(flow control)
+ * Usage: Issue "ethtool -A ethX tx on|off" under linux prompt
+ * @ndev: network device
+ * @epauseparam: pause parameter
+ * return 0 on success, negative value if not supported
+ *
+ * note: hardware supports only tx flow control
+ **/
+static int
+xemacps_set_pauseparam(struct net_device *ndev,
+		struct ethtool_pauseparam *epauseparm)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	u32 regval;
+
+	if (netif_running(ndev)) {
+		dev_err(&lp->pdev->dev,
+			"Please stop netif before apply configruation\n");
+		return -EFAULT;
+	}
+
+	regval = xemacps_read(lp->baseaddr, XEMACPS_NWCFG_OFFSET);
+
+	if (epauseparm->tx_pause)
+		regval |= XEMACPS_NWCFG_PAUSEEN_MASK;
+	if (!(epauseparm->tx_pause))
+		regval &= ~XEMACPS_NWCFG_PAUSEEN_MASK;
+
+	xemacps_write(lp->baseaddr, XEMACPS_NWCFG_OFFSET, regval);
+	return 0;
+}
+
+/**
+ * xemacps_get_stats - get device statistic raw data in 64bit mode
+ * @ndev: network device
+ **/
+static struct net_device_stats
+*xemacps_get_stats(struct net_device *ndev)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct net_device_stats *nstat = &lp->stats;
+
+	xemacps_update_stats((unsigned long)lp);
+	return nstat;
+}
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+/**
+ * xemacps_get_ts_info - Get the interface timestamp capabilities
+ * @dev: Network device
+ * @info: Holds the interface timestamp capability info
+ * retur: Always return zero
+ */
+static int xemacps_get_ts_info(struct net_device *dev,
+			struct ethtool_ts_info *info)
+{
+	struct net_local *lp = netdev_priv(dev);
+
+	info->so_timestamping =
+			SOF_TIMESTAMPING_TX_HARDWARE |
+			SOF_TIMESTAMPING_RX_HARDWARE |
+			SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = lp->phc_index;
+	info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+			(1 << HWTSTAMP_TX_ON);
+	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+			(1 << HWTSTAMP_FILTER_ALL);
+	return 0;
+}
+#endif
+
+static struct ethtool_ops xemacps_ethtool_ops = {
+	.get_settings   = xemacps_get_settings,
+	.set_settings   = xemacps_set_settings,
+	.get_drvinfo    = xemacps_get_drvinfo,
+	.get_link       = ethtool_op_get_link, /* ethtool default */
+	.get_ringparam  = xemacps_get_ringparam,
+	.get_wol        = xemacps_get_wol,
+	.set_wol        = xemacps_set_wol,
+	.get_pauseparam = xemacps_get_pauseparam,
+	.set_pauseparam = xemacps_set_pauseparam,
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+	.get_ts_info    = xemacps_get_ts_info,
+#endif
+};
+
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+static int xemacps_hwtstamp_ioctl(struct net_device *netdev,
+				struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config config;
+	struct net_local *lp;
+	u32 regval;
+
+	lp = netdev_priv(netdev);
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	/* reserved for future extensions */
+	if (config.flags)
+		return -EINVAL;
+
+	if ((config.tx_type != HWTSTAMP_TX_OFF) &&
+		(config.tx_type != HWTSTAMP_TX_ON))
+		return -ERANGE;
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		regval = xemacps_read(lp->baseaddr, XEMACPS_NWCTRL_OFFSET);
+		xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET,
+			(regval | XEMACPS_NWCTRL_RXTSTAMP_MASK));
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	config.tx_type = HWTSTAMP_TX_ON;
+	lp->hwtstamp_config = config;
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+		-EFAULT : 0;
+}
+#endif /* CONFIG_XILINX_PS_EMAC_HWTSTAMP */
+
+/**
+ * xemacps_ioctl - ioctl entry point
+ * @ndev: network device
+ * @rq: interface request ioctl
+ * @cmd: command code
+ *
+ * Called when user issues an ioctl request to the network device.
+ **/
+static int xemacps_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
+{
+	struct net_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+
+	if (!netif_running(ndev))
+		return -EINVAL;
+
+	if (!phydev)
+		return -ENODEV;
+
+	switch (cmd) {
+	case SIOCGMIIPHY:
+	case SIOCGMIIREG:
+	case SIOCSMIIREG:
+		return phy_mii_ioctl(phydev, rq, cmd);
+#ifdef CONFIG_XILINX_PS_EMAC_HWTSTAMP
+	case SIOCSHWTSTAMP:
+		return xemacps_hwtstamp_ioctl(ndev, rq, cmd);
+#endif
+	default:
+		dev_info(&lp->pdev->dev, "ioctl %d not implemented.\n", cmd);
+		return -EOPNOTSUPP;
+	}
+
+}
+
+/**
+ * xemacps_probe - Platform driver probe
+ * @pdev: Pointer to platform device structure
+ *
+ * Return 0 on success, negative value if error
+ */
+static int xemacps_probe(struct platform_device *pdev)
+{
+	struct resource *r_mem = NULL;
+	struct resource *r_irq = NULL;
+	struct net_device *ndev;
+	struct net_local *lp;
+	u32 regval = 0;
+	int rc = -ENXIO;
+
+	r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!r_mem || !r_irq) {
+		dev_err(&pdev->dev, "no IO resource defined.\n");
+		return -ENXIO;
+	}
+
+	ndev = alloc_etherdev(sizeof(*lp));
+	if (!ndev) {
+		dev_err(&pdev->dev, "etherdev allocation failed.\n");
+		return -ENOMEM;
+	}
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	lp = netdev_priv(ndev);
+	lp->pdev = pdev;
+	lp->ndev = ndev;
+
+	spin_lock_init(&lp->tx_lock);
+	spin_lock_init(&lp->rx_lock);
+	spin_lock_init(&lp->nwctrlreg_lock);
+
+	lp->baseaddr = devm_ioremap_resource(&pdev->dev, r_mem);
+	if (IS_ERR(lp->baseaddr)) {
+		rc = PTR_ERR(lp->baseaddr);
+		goto err_out_free_netdev;
+	}
+
+	dev_dbg(&lp->pdev->dev, "BASEADDRESS hw: %p virt: %p\n",
+			(void *)r_mem->start, lp->baseaddr);
+
+	ndev->irq = platform_get_irq(pdev, 0);
+
+	ndev->netdev_ops = &netdev_ops;
+	ndev->watchdog_timeo = TX_TIMEOUT;
+	ndev->ethtool_ops = &xemacps_ethtool_ops;
+	ndev->base_addr = r_mem->start;
+	ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+	netif_napi_add(ndev, &lp->napi, xemacps_rx_poll, XEMACPS_NAPI_WEIGHT);
+
+	lp->ip_summed = CHECKSUM_UNNECESSARY;
+
+	rc = register_netdev(ndev);
+	if (rc) {
+		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
+		goto err_out_free_netdev;
+	}
+
+	if (ndev->irq == 54)
+		lp->enetnum = 0;
+	else
+		lp->enetnum = 1;
+
+	lp->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+	if (IS_ERR(lp->aperclk)) {
+		dev_err(&pdev->dev, "aper_clk clock not found.\n");
+		rc = PTR_ERR(lp->aperclk);
+		goto err_out_unregister_netdev;
+	}
+	lp->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(lp->devclk)) {
+		dev_err(&pdev->dev, "ref_clk clock not found.\n");
+		rc = PTR_ERR(lp->devclk);
+		goto err_out_unregister_netdev;
+	}
+
+	rc = clk_prepare_enable(lp->aperclk);
+	if (rc) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto err_out_unregister_netdev;
+	}
+	rc = clk_prepare_enable(lp->devclk);
+	if (rc) {
+		dev_err(&pdev->dev, "Unable to enable device clock.\n");
+		goto err_out_clk_dis_aper;
+	}
+
+	lp->clk_rate_change_nb.notifier_call = xemacps_clk_notifier_cb;
+	lp->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(lp->devclk, &lp->clk_rate_change_nb))
+		dev_warn(&pdev->dev,
+			"Unable to register clock notifier.\n");
+
+	lp->phy_node = of_parse_phandle(lp->pdev->dev.of_node,
+						"phy-handle", 0);
+	lp->gmii2rgmii_phy_node = of_parse_phandle(lp->pdev->dev.of_node,
+						"gmii2rgmii-phy-handle", 0);
+	rc = of_get_phy_mode(lp->pdev->dev.of_node);
+	if (rc < 0) {
+		dev_err(&lp->pdev->dev, "error in getting phy i/f\n");
+		goto err_out_unregister_clk_notifier;
+	}
+
+	lp->phy_interface = rc;
+
+	/* Set MDIO clock divider */
+	regval = (MDC_DIV_224 << XEMACPS_NWCFG_MDC_SHIFT_MASK);
+	xemacps_write(lp->baseaddr, XEMACPS_NWCFG_OFFSET, regval);
+
+
+	regval = XEMACPS_NWCTRL_MDEN_MASK;
+	xemacps_write(lp->baseaddr, XEMACPS_NWCTRL_OFFSET, regval);
+
+	rc = xemacps_mii_init(lp);
+	if (rc) {
+		dev_err(&lp->pdev->dev, "error in xemacps_mii_init\n");
+		goto err_out_unregister_clk_notifier;
+	}
+
+	xemacps_update_hwaddr(lp);
+	tasklet_init(&lp->tx_bdreclaim_tasklet, xemacps_tx_poll,
+		     (unsigned long) ndev);
+	tasklet_disable(&lp->tx_bdreclaim_tasklet);
+
+	lp->txtimeout_handler_wq = create_singlethread_workqueue(DRIVER_NAME);
+	INIT_WORK(&lp->txtimeout_reinit, xemacps_reinit_for_txtimeout);
+
+	platform_set_drvdata(pdev, ndev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n",
+		pdev->id, ndev->base_addr, ndev->irq);
+
+	rc = devm_request_irq(&pdev->dev, ndev->irq, &xemacps_interrupt, 0,
+		ndev->name, ndev);
+	if (rc) {
+		dev_err(&lp->pdev->dev, "Unable to request IRQ %p, error %d\n",
+				r_irq, rc);
+		goto err_out_unregister_clk_notifier;
+	}
+
+	return 0;
+
+err_out_unregister_clk_notifier:
+	clk_notifier_unregister(lp->devclk, &lp->clk_rate_change_nb);
+	clk_disable_unprepare(lp->devclk);
+err_out_clk_dis_aper:
+	clk_disable_unprepare(lp->aperclk);
+err_out_unregister_netdev:
+	unregister_netdev(ndev);
+err_out_free_netdev:
+	free_netdev(ndev);
+
+	return rc;
+}
+
+/**
+ * xemacps_remove - called when platform driver is unregistered
+ * @pdev: Pointer to the platform device structure
+ *
+ * return: 0 on success
+ */
+static int xemacps_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_local *lp;
+
+	if (ndev) {
+		lp = netdev_priv(ndev);
+
+		mdiobus_unregister(lp->mii_bus);
+		kfree(lp->mii_bus->irq);
+		mdiobus_free(lp->mii_bus);
+		unregister_netdev(ndev);
+
+		clk_notifier_unregister(lp->devclk, &lp->clk_rate_change_nb);
+		if (!pm_runtime_suspended(&pdev->dev)) {
+			clk_disable_unprepare(lp->devclk);
+			clk_disable_unprepare(lp->aperclk);
+		} else {
+			clk_unprepare(lp->devclk);
+			clk_unprepare(lp->aperclk);
+		}
+
+		free_netdev(ndev);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xemacps_suspend - Suspend event
+ * @device: Pointer to device structure
+ *
+ * Return 0
+ */
+static int xemacps_suspend(struct device *device)
+{
+	struct platform_device *pdev = container_of(device,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_local *lp = netdev_priv(ndev);
+
+	netif_device_detach(ndev);
+	if (!pm_runtime_suspended(device)) {
+		clk_disable(lp->devclk);
+		clk_disable(lp->aperclk);
+	}
+	return 0;
+}
+
+/**
+ * xemacps_resume - Resume after previous suspend
+ * @pdev: Pointer to platform device structure
+ *
+ * Returns 0 on success, errno otherwise.
+ */
+static int xemacps_resume(struct device *device)
+{
+	struct platform_device *pdev = container_of(device,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_local *lp = netdev_priv(ndev);
+
+	if (!pm_runtime_suspended(device)) {
+		int ret;
+
+		ret = clk_enable(lp->aperclk);
+		if (ret)
+			return ret;
+
+		ret = clk_enable(lp->devclk);
+		if (ret) {
+			clk_disable(lp->aperclk);
+			return ret;
+		}
+	}
+	netif_device_attach(ndev);
+	return 0;
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_RUNTIME
+static int xemacps_runtime_idle(struct device *dev)
+{
+	return pm_schedule_suspend(dev, 1);
+}
+
+static int xemacps_runtime_resume(struct device *device)
+{
+	int ret;
+	struct platform_device *pdev = container_of(device,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_local *lp = netdev_priv(ndev);
+
+	ret = clk_enable(lp->aperclk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(lp->devclk);
+	if (ret) {
+		clk_disable(lp->aperclk);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int xemacps_runtime_suspend(struct device *device)
+{
+	struct platform_device *pdev = container_of(device,
+			struct platform_device, dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_local *lp = netdev_priv(ndev);
+
+	clk_disable(lp->devclk);
+	clk_disable(lp->aperclk);
+	return 0;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops xemacps_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xemacps_suspend, xemacps_resume)
+	SET_RUNTIME_PM_OPS(xemacps_runtime_suspend, xemacps_runtime_resume,
+			xemacps_runtime_idle)
+};
+#define XEMACPS_PM	(&xemacps_dev_pm_ops)
+#else /* ! CONFIG_PM */
+#define XEMACPS_PM	NULL
+#endif /* ! CONFIG_PM */
+
+static struct net_device_ops netdev_ops = {
+	.ndo_open		= xemacps_open,
+	.ndo_stop		= xemacps_close,
+	.ndo_start_xmit		= xemacps_start_xmit,
+	.ndo_set_rx_mode	= xemacps_set_rx_mode,
+	.ndo_set_mac_address    = xemacps_set_mac_address,
+	.ndo_do_ioctl		= xemacps_ioctl,
+	.ndo_change_mtu		= xemacps_change_mtu,
+	.ndo_tx_timeout		= xemacps_tx_timeout,
+	.ndo_get_stats		= xemacps_get_stats,
+};
+
+static struct of_device_id xemacps_of_match[] = {
+	{ .compatible = "xlnx,ps7-ethernet-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xemacps_of_match);
+
+static struct platform_driver xemacps_driver = {
+	.probe   = xemacps_probe,
+	.remove  = xemacps_remove,
+	.driver  = {
+		.name  = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = xemacps_of_match,
+		.pm = XEMACPS_PM,
+	},
+};
+
+module_platform_driver(xemacps_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx Ethernet driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/Makefile	2014-07-20 22:06:37.153292572 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# Makefile for the Xilinx Tri-mode ethernet driver
+#
+
+EXTRA_CFLAGS		+= -Idrivers/xilinx_common
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_temac-objs	:= xlltemac_main.o xlltemac.o xlltemac_control.o
+
+obj-$(CONFIG_XILINX_LLTEMAC) := xilinx_temac.o
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac.c	2014-07-20 22:06:37.174292225 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac.c
+ *
+ * The XLlTemac driver. Functions in this file are the minimum required functions
+ * for this driver. See xlltemac.h for a detailed description of the driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  11/10/06 First release
+ * </pre>
+ ******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+
+#include "xlltemac.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static void InitHw(XLlTemac *InstancePtr);	/* HW reset */
+
+/************************** Variable Definitions *****************************/
+
+xdbg_stmnt(int indent_on = 0;
+
+	)
+	xdbg_stmnt(u32 _xlltemac_rir_value;
+
+	)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_CfgInitialize initializes a TEMAC channel along with the
+ * <i>InstancePtr</i> that references it. Each TEMAC channel is treated as a
+ * separate device from the point of view of this driver.
+ *
+ * The PHY is setup independently from the TEMAC. Use the MII or whatever other
+ * interface may be present for setup.
+ *
+ * @param  InstancePtr references the memory instance to be associated with
+ *         the TEMAC channel upon initialization.
+ * @param  CfgPtr references the structure holding the hardware configuration
+ *         for the TEMAC channel to initialize.
+ * @param  EffectiveAddress is the processor address used to access the
+ *         base address of the TEMAC channel. In systems with an MMU and virtual
+ *         memory, <i>EffectiveAddress</i> is the virtual address mapped to the
+ *         physical in <code>ConfigPtr->Config.BaseAddress</code>. In systems
+ *         without an active MMU, <i>EffectiveAddress</i> should be set to the
+ *         same value as <code>ConfigPtr->Config.BaseAddress</code>.
+ *
+ * @return XLlTemac_CfgInitialize returns XST_SUCCESS.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ *
+ ******************************************************************************/
+     int XLlTemac_CfgInitialize(XLlTemac *InstancePtr,
+				XLlTemac_Config *CfgPtr, u32 EffectiveAddress)
+{
+	/* Verify arguments */
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* Clear instance memory and make copy of configuration */
+	memset(InstancePtr, 0, sizeof(XLlTemac));
+	memcpy(&InstancePtr->Config, CfgPtr, sizeof(XLlTemac_Config));
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_CfgInitialize\n");
+	/* Set device base address */
+	InstancePtr->Config.BaseAddress = EffectiveAddress;
+
+	/* Reset the hardware and set default options */
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	XLlTemac_Reset(InstancePtr, XTE_NORESET_HARD);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "Temac_CfgInitialize: returning SUCCESS\n");
+	return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Start starts the TEMAC channel as follows:
+ *   - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
+ *   - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Start(XLlTemac *InstancePtr)
+{
+	u32 Reg;
+
+	/* Assert bad arguments and conditions */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	/* If already started, then there is nothing to do */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return;
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Start\n");
+	/* Enable transmitter if not already enabled */
+	if (InstancePtr->Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL, "enabling transmitter\n");
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_TC_OFFSET);
+		if (!(Reg & XTE_TC_TX_MASK)) {
+			xdbg_printf(XDBG_DEBUG_GENERAL,
+				    "transmitter not enabled, enabling now\n");
+			XLlTemac_WriteIndirectReg(InstancePtr->Config.
+						  BaseAddress, XTE_TC_OFFSET,
+						  Reg | XTE_TC_TX_MASK);
+		}
+		xdbg_printf(XDBG_DEBUG_GENERAL, "transmitter enabled\n");
+	}
+
+	/* Enable receiver */
+	if (InstancePtr->Options & XTE_RECEIVER_ENABLE_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL, "enabling receiver\n");
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_RCW1_OFFSET);
+		if (!(Reg & XTE_RCW1_RX_MASK)) {
+			xdbg_printf(XDBG_DEBUG_GENERAL,
+				    "receiver not enabled, enabling now\n");
+
+			XLlTemac_WriteIndirectReg(InstancePtr->Config.
+						  BaseAddress, XTE_RCW1_OFFSET,
+						  Reg | XTE_RCW1_RX_MASK);
+		}
+		xdbg_printf(XDBG_DEBUG_GENERAL, "receiver enabled\n");
+	}
+
+	/* Mark as started */
+	InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Start: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Stop gracefully stops the TEMAC channel as follows:
+ *   - Disable all interrupts from this device
+ *   - Disable the receiver
+ *
+ * XLlTemac_Stop does not modify any of the current device options.
+ *
+ * Since the transmitter is not disabled, frames currently in internal buffers
+ * or in process by a DMA engine are allowed to be transmitted.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Stop(XLlTemac *InstancePtr)
+{
+	u32 Reg;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	/* If already stopped, then there is nothing to do */
+	if (InstancePtr->IsStarted == 0) {
+		return;
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop\n");
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_Stop: disabling interrupts\n");
+	/* Disable interrupts */
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, 0);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop: disabling receiver\n");
+	/* Disable the receiver */
+	Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_RCW1_OFFSET);
+	Reg &= ~XTE_RCW1_RX_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_RCW1_OFFSET, Reg);
+
+	/* Stopping the receiver in mid-packet causes a dropped packet indication
+	 * from HW. Clear it.
+	 */
+	/* get the interrupt pending register */
+	Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IP_OFFSET);
+	if (Reg & XTE_INT_RXRJECT_MASK) {
+		/* set the interrupt status register to clear the interrupt */
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_IS_OFFSET, XTE_INT_RXRJECT_MASK);
+	}
+
+	/* Mark as stopped */
+	InstancePtr->IsStarted = 0;
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop: done\n");
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Reset performs a reset of the TEMAC channel, specified by
+ * <i>InstancePtr</i>, or both channels if <i>HardCoreAction</i> is set to
+ * XTE_RESET_HARD.
+ *
+ * XLlTemac_Reset also resets the TEMAC channel's options to their default values.
+ *
+ * The calling software is responsible for re-configuring the TEMAC channel
+ * (if necessary) and restarting the MAC after the reset.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param HardCoreAction describes how XLlTemac_Reset should treat the hard core
+ *        block of the TEMAC.<br><br>
+ *
+ *        If XTE_RESET_HARD is set to XTE_RESET_HARD, then XLlTemac_Reset asserts
+ *        the reset signal to the hard core block which will reset both channels
+ *        of the TEMAC. This, of course, will bork any activity that may be
+ *        occuring on the other channel. So, be careful here.<br><br>
+ *
+ *        Otherwise, XLlTemac_Reset resets just the transmitter and receiver of
+ *        this TEMAC channel.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction)
+{
+	u32 Reg;
+	u32 TimeoutCount = 2;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Reset\n");
+	/* Stop the device and reset HW */
+	XLlTemac_Stop(InstancePtr);
+	InstancePtr->Options = XTE_DEFAULT_OPTIONS;
+
+	/* Reset the receiver */
+	xdbg_printf(XDBG_DEBUG_GENERAL, "resetting the receiver\n");
+	Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_RCW1_OFFSET);
+	Reg |= XTE_RCW1_RST_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_RCW1_OFFSET, Reg);
+
+	/* Reset the transmitter */
+	xdbg_printf(XDBG_DEBUG_GENERAL, "resetting the transmitter\n");
+	Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_TC_OFFSET);
+	Reg |= XTE_TC_RST_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_TC_OFFSET, Reg);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "waiting until reset is done\n");
+	/* Poll until the reset is done */
+	while (Reg & (XTE_RCW1_RST_MASK | XTE_TC_RST_MASK)) {
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_RCW1_OFFSET);
+		Reg |= XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+						XTE_TC_OFFSET);
+	}
+
+	/* Reset hard core if required */
+	/* Resetting hard core will cause both channels to reset :-( */
+	if (HardCoreAction == XTE_RESET_HARD) {
+		xdbg_printf(XDBG_DEBUG_GENERAL, "hard reset\n");
+		Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RAF_OFFSET);
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_RAF_OFFSET, Reg | XTE_RAF_HTRST_MASK);
+		while (TimeoutCount &&
+		       (!(XLlTemac_ReadReg
+			  (InstancePtr->Config.BaseAddress,
+			   XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK))) {
+			udelay(XTE_RESET_HARD_DELAY_US);
+			TimeoutCount--;
+		}
+	}
+
+	/* Setup HW */
+	InitHw(InstancePtr);
+}
+
+
+/******************************************************************************
+ * InitHw (internal use only) performs a one-time setup of a TEMAC channel. The
+ * setup performed here only need to occur once after any reset.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+static void InitHw(XLlTemac *InstancePtr)
+{
+	u32 Reg;
+
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw\n");
+	/* Disable the receiver */
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw\n");
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac InitHw: disabling receiver\n");
+	Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_RCW1_OFFSET);
+	Reg &= ~XTE_RCW1_RX_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_RCW1_OFFSET, Reg);
+
+	/*
+	 * Stopping the receiver in mid-packet causes a dropped packet
+	 * indication from HW. Clear it.
+	 */
+	/* get the interrupt pending register */
+	Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IP_OFFSET);
+	if (Reg & XTE_INT_RXRJECT_MASK) {
+		/*
+		 * set the interrupt status register to clear the pending
+		 * interrupt
+		 */
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_IS_OFFSET, XTE_INT_RXRJECT_MASK);
+	}
+
+	/* Sync default options with HW but leave receiver and transmitter
+	 * disabled. They get enabled with XLlTemac_Start() if
+	 * XTE_TRANSMITTER_ENABLE_OPTION and XTE_RECEIVER_ENABLE_OPTION are set
+	 */
+	XLlTemac_SetOptions(InstancePtr, InstancePtr->Options &
+			    ~(XTE_TRANSMITTER_ENABLE_OPTION |
+			      XTE_RECEIVER_ENABLE_OPTION));
+
+	XLlTemac_ClearOptions(InstancePtr, ~InstancePtr->Options);
+
+	/* Set default MDIO divisor */
+	XLlTemac_PhySetMdioDivisor(InstancePtr, XTE_MDIO_DIV_DFT);
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetMacAddress sets the MAC address for the TEMAC channel, specified
+ * by <i>InstancePtr</i> to the MAC address specified by <i>AddressPtr</i>.
+ * The TEMAC channel must be stopped before calling this function.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a reference to the 6-byte MAC address to set.
+ *
+ * @return On successful completion, XLlTemac_SetMacAddress returns XST_SUCCESS.
+ *         Otherwise, if the TEMAC channel has not stopped,
+ *         XLlTemac_SetMacAddress returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetMacAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	u32 MacAddr;
+	u8 *Aptr = (u8 *) AddressPtr;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_NONVOID(AddressPtr != NULL);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+					 XTE_RDY_OFFSET) &
+			XTE_RDY_HARD_ACS_RDY_MASK);
+
+	/* Be sure device has been stopped */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_SetMacAddress: setting mac address to: 0x%08x%8x%8x%8x%8x%8x\n",
+		    Aptr[0], Aptr[1], Aptr[2], Aptr[3], Aptr[4], Aptr[5]);
+	/*
+	 * Set the MAC bits [31:0] in UAW0
+	 * Having Aptr be unsigned type prevents the following operations from sign extending
+	 */
+	MacAddr = Aptr[0];
+	MacAddr |= Aptr[1] << 8;
+	MacAddr |= Aptr[2] << 16;
+	MacAddr |= Aptr[3] << 24;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_UAW0_OFFSET, MacAddr);
+
+	/* There are reserved bits in UAW1 so don't affect them */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_UAW1_OFFSET);
+	MacAddr &= ~XTE_UAW1_UNICASTADDR_MASK;
+
+	/* Set MAC bits [47:32] in UAW1 */
+	MacAddr |= Aptr[4];
+	MacAddr |= Aptr[5] << 8;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_UAW1_OFFSET, MacAddr);
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetMacAddress gets the MAC address for the TEMAC channel, specified
+ * by <i>InstancePtr</i> into the memory buffer specified by <i>AddressPtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved MAC
+ *        address. This memory buffer must be at least 6 bytes in length.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_GetMacAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	u32 MacAddr;
+	u8 *Aptr = (u8 *) AddressPtr;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	/* Read MAC bits [31:0] in UAW0 */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_UAW0_OFFSET);
+	Aptr[0] = (u8) MacAddr;
+	Aptr[1] = (u8) (MacAddr >> 8);
+	Aptr[2] = (u8) (MacAddr >> 16);
+	Aptr[3] = (u8) (MacAddr >> 24);
+
+	/* Read MAC bits [47:32] in UAW1 */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_UAW1_OFFSET);
+	Aptr[4] = (u8) MacAddr;
+	Aptr[5] = (u8) (MacAddr >> 8);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetOptions enables the options, <i>Options</i> for the TEMAC channel,
+ * specified by <i>InstancePtr</i>. The TEMAC channel should be stopped with
+ * XLlTemac_Stop() before changing options.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Options is a bitmask of OR'd XTE_*_OPTION values for options to
+ *        set. Options not specified are not affected.
+ *
+ * @return On successful completion, XLlTemac_SetOptions returns XST_SUCCESS.
+ *         Otherwise, if the device has not been stopped, XLlTemac_SetOptions
+ *         returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options)
+{
+	u32 Reg;		/* Generic register contents */
+	u32 RegRcw1;		/* Reflects original contents of RCW1 */
+	u32 RegTc;		/* Reflects original contents of TC  */
+	u32 RegNewRcw1;		/* Reflects new contents of RCW1 */
+	u32 RegNewTc;		/* Reflects new contents of TC  */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+					 XTE_RDY_OFFSET) &
+			XTE_RDY_HARD_ACS_RDY_MASK);
+
+	/* Be sure device has been stopped */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOptions\n");
+	/* Many of these options will change the RCW1 or TC registers.
+	 * To reduce the amount of IO to the device, group these options here
+	 * and change them all at once.
+	 */
+
+	/* Grab current register contents */
+	RegRcw1 = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_RCW1_OFFSET);
+	RegTc = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					 XTE_TC_OFFSET);
+	RegNewRcw1 = RegRcw1;
+	RegNewTc = RegTc;
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "current control regs: RCW1: 0x%0x; TC: 0x%0x\n", RegRcw1,
+		    RegTc);
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "Options: 0x%0x; default options: 0x%0x\n", Options,
+		    XTE_DEFAULT_OPTIONS);
+
+	/* Turn on jumbo packet support for both Rx and Tx */
+	if (Options & XTE_JUMBO_OPTION) {
+		RegNewTc |= XTE_TC_JUM_MASK;
+		RegNewRcw1 |= XTE_RCW1_JUM_MASK;
+	}
+
+	/* Turn on VLAN packet support for both Rx and Tx */
+	if (Options & XTE_VLAN_OPTION) {
+		RegNewTc |= XTE_TC_VLAN_MASK;
+		RegNewRcw1 |= XTE_RCW1_VLAN_MASK;
+	}
+
+	/* Turn on FCS stripping on receive packets */
+	if (Options & XTE_FCS_STRIP_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: enabling fcs stripping\n");
+		RegNewRcw1 &= ~XTE_RCW1_FCS_MASK;
+	}
+
+	/* Turn on FCS insertion on transmit packets */
+	if (Options & XTE_FCS_INSERT_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: enabling fcs insertion\n");
+		RegNewTc &= ~XTE_TC_FCS_MASK;
+	}
+
+	/* Turn on length/type field checking on receive packets */
+	if (Options & XTE_LENTYPE_ERR_OPTION) {
+		RegNewRcw1 &= ~XTE_RCW1_LT_DIS_MASK;
+	}
+
+	/* Enable transmitter */
+	if (Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+		RegNewTc |= XTE_TC_TX_MASK;
+	}
+
+	/* Enable receiver */
+	if (Options & XTE_RECEIVER_ENABLE_OPTION) {
+		RegNewRcw1 |= XTE_RCW1_RX_MASK;
+	}
+
+	/* Change the TC or RCW1 registers if they need to be modified */
+	if (RegTc != RegNewTc) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: writting tc: 0x%0x\n", RegNewTc);
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_TC_OFFSET, RegNewTc);
+	}
+
+	if (RegRcw1 != RegNewRcw1) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: writting rcw1: 0x%0x\n", RegNewRcw1);
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_RCW1_OFFSET, RegNewRcw1);
+	}
+
+	/* Rest of options twiddle bits of other registers. Handle them one at
+	 * a time
+	 */
+
+	/* Turn on flow control */
+	if (Options & XTE_FLOW_CONTROL_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: endabling flow control\n");
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_FCC_OFFSET);
+		Reg |= XTE_FCC_FCRX_MASK;
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_FCC_OFFSET, Reg);
+	}
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "setOptions: rcw1 is now (fcc): 0x%0x\n",
+		    XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					     XTE_RCW1_OFFSET));
+
+	/* Turn on promiscuous frame filtering (all frames are received ) */
+	if (Options & XTE_PROMISC_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "setOptions: endabling promiscuous mode\n");
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_AFM_OFFSET);
+		Reg |= XTE_AFM_PM_MASK;
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_AFM_OFFSET, Reg);
+	}
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "setOptions: rcw1 is now (afm): 0x%0x\n",
+		    XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					     XTE_RCW1_OFFSET));
+
+	/* Allow broadcast address filtering */
+	if (Options & XTE_BROADCAST_OPTION) {
+		Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RAF_OFFSET);
+		Reg &= ~XTE_RAF_BCSTREJ_MASK;
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_RAF_OFFSET, Reg);
+	}
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "setOptions: rcw1 is now (raf): 0x%0x\n",
+		    XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					     XTE_RCW1_OFFSET));
+
+	/* Allow multicast address filtering */
+	if (Options & XTE_MULTICAST_OPTION) {
+		Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RAF_OFFSET);
+		Reg &= ~XTE_RAF_MCSTREJ_MASK;
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_RAF_OFFSET, Reg);
+	}
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "setOptions: rcw1 is now (raf2): 0x%0x\n",
+		    XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					     XTE_RCW1_OFFSET));
+
+	/* The remaining options not handled here are managed elsewhere in the
+	 * driver. No register modifications are needed at this time. Reflecting the
+	 * option in InstancePtr->Options is good enough for now.
+	 */
+
+	/* Set options word to its new value */
+	InstancePtr->Options |= Options;
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "setOptions: rcw1 is now (end): 0x%0x\n",
+		    XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					     XTE_RCW1_OFFSET));
+	xdbg_printf(XDBG_DEBUG_GENERAL, "setOptions: returning SUCCESS\n");
+	return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_ClearOptions clears the options, <i>Options</i> for the TEMAC channel,
+ * specified by <i>InstancePtr</i>. The TEMAC channel should be stopped with
+ * XLlTemac_Stop() before changing options.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Options is a bitmask of OR'd XTE_*_OPTION values for options to
+ *        clear. Options not specified are not affected.
+ *
+ * @return On successful completion, XLlTemac_ClearOptions returns XST_SUCCESS.
+ *         Otherwise, if the device has not been stopped, XLlTemac_ClearOptions
+ *         returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options)
+{
+	u32 Reg;		/* Generic */
+	u32 RegRcw1;		/* Reflects original contents of RCW1 */
+	u32 RegTc;		/* Reflects original contents of TC  */
+	u32 RegNewRcw1;		/* Reflects new contents of RCW1 */
+	u32 RegNewTc;		/* Reflects new contents of TC  */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+					 XTE_RDY_OFFSET) &
+			XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "Xtemac_ClearOptions: 0x%08x\n",
+		    Options);
+	/* Be sure device has been stopped */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Many of these options will change the RCW1 or TC registers.
+	 * Group these options here and change them all at once. What we are
+	 * trying to accomplish is to reduce the amount of IO to the device
+	 */
+
+	/* Grab current register contents */
+	RegRcw1 = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_RCW1_OFFSET);
+	RegTc = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					 XTE_TC_OFFSET);
+	RegNewRcw1 = RegRcw1;
+	RegNewTc = RegTc;
+
+	/* Turn off jumbo packet support for both Rx and Tx */
+	if (Options & XTE_JUMBO_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling jumbo\n");
+		RegNewTc &= ~XTE_TC_JUM_MASK;
+		RegNewRcw1 &= ~XTE_RCW1_JUM_MASK;
+	}
+
+	/* Turn off VLAN packet support for both Rx and Tx */
+	if (Options & XTE_VLAN_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling vlan\n");
+		RegNewTc &= ~XTE_TC_VLAN_MASK;
+		RegNewRcw1 &= ~XTE_RCW1_VLAN_MASK;
+	}
+
+	/* Turn off FCS stripping on receive packets */
+	if (Options & XTE_FCS_STRIP_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling fcs strip\n");
+		RegNewRcw1 |= XTE_RCW1_FCS_MASK;
+	}
+
+	/* Turn off FCS insertion on transmit packets */
+	if (Options & XTE_FCS_INSERT_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling fcs insert\n");
+		RegNewTc |= XTE_TC_FCS_MASK;
+	}
+
+	/* Turn off length/type field checking on receive packets */
+	if (Options & XTE_LENTYPE_ERR_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling lentype err\n");
+		RegNewRcw1 |= XTE_RCW1_LT_DIS_MASK;
+	}
+
+	/* Disable transmitter */
+	if (Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling transmitter\n");
+		RegNewTc &= ~XTE_TC_TX_MASK;
+	}
+
+	/* Disable receiver */
+	if (Options & XTE_RECEIVER_ENABLE_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling receiver\n");
+		RegNewRcw1 &= ~XTE_RCW1_RX_MASK;
+	}
+
+	/* Change the TC and RCW1 registers if they need to be
+	 * modified
+	 */
+	if (RegTc != RegNewTc) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: setting TC: 0x%0x\n",
+			    RegNewTc);
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_TC_OFFSET, RegNewTc);
+	}
+
+	if (RegRcw1 != RegNewRcw1) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: setting RCW1: 0x%0x\n",
+			    RegNewRcw1);
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_RCW1_OFFSET, RegNewRcw1);
+	}
+
+	/* Rest of options twiddle bits of other registers. Handle them one at
+	 * a time
+	 */
+
+	/* Turn off flow control */
+	if (Options & XTE_FLOW_CONTROL_OPTION) {
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_FCC_OFFSET);
+		Reg &= ~XTE_FCC_FCRX_MASK;
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_FCC_OFFSET, Reg);
+	}
+
+	/* Turn off promiscuous frame filtering */
+	if (Options & XTE_PROMISC_OPTION) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: disabling promiscuous mode\n");
+		Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					       XTE_AFM_OFFSET);
+		Reg &= ~XTE_AFM_PM_MASK;
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "Xtemac_ClearOptions: setting AFM: 0x%0x\n", Reg);
+		XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+					  XTE_AFM_OFFSET, Reg);
+	}
+
+	/* Disable broadcast address filtering */
+	if (Options & XTE_BROADCAST_OPTION) {
+		Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RAF_OFFSET);
+		Reg |= XTE_RAF_BCSTREJ_MASK;
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_RAF_OFFSET, Reg);
+	}
+
+	/* Disable multicast address filtering */
+	if (Options & XTE_MULTICAST_OPTION) {
+		Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RAF_OFFSET);
+		Reg |= XTE_RAF_MCSTREJ_MASK;
+		XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+				  XTE_RAF_OFFSET, Reg);
+	}
+
+	/* The remaining options not handled here are managed elsewhere in the
+	 * driver. No register modifications are needed at this time. Reflecting the
+	 * option in InstancePtr->Options is good enough for now.
+	 */
+
+	/* Set options word to its new value */
+	InstancePtr->Options &= ~Options;
+
+	return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetOptions returns the current option settings.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetOptions returns a bitmask of XTE_*_OPTION constants,
+ *         each bit specifying an option that is currently active.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ ******************************************************************************/
+u32 XLlTemac_GetOptions(XLlTemac *InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return (InstancePtr->Options);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetOperatingSpeed gets the current operating link speed. This may be
+ * the value set by XLlTemac_SetOperatingSpeed() or a hardware default.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetOperatingSpeed returns the link speed in units of megabits
+ *         per second.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+u16 XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+					 XTE_RDY_OFFSET) &
+			XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetOperatingSpeed\n");
+	switch (XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					 XTE_EMMC_OFFSET) &
+		XTE_EMMC_LINKSPEED_MASK) {
+	case XTE_EMMC_LINKSPD_1000:
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "XLlTemac_GetOperatingSpeed: returning 1000\n");
+		return (1000);
+
+	case XTE_EMMC_LINKSPD_100:
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "XLlTemac_GetOperatingSpeed: returning 100\n");
+		return (100);
+
+	case XTE_EMMC_LINKSPD_10:
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			    "XLlTemac_GetOperatingSpeed: returning 10\n");
+		return (10);
+
+	default:
+		return (0);
+	}
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetOperatingSpeed sets the current operating link speed. For any
+ * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII
+ * link speed.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100,
+ *        or 1000. XLlTemac_SetOperatingSpeed ignores invalid values.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed)
+{
+	u32 EmmcReg;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_VOID((Speed == 10) || (Speed == 100) || (Speed == 1000));
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOperatingSpeed\n");
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_SetOperatingSpeed: setting speed to: %d (0x%0x)\n",
+		    Speed, Speed);
+	/* Get the current contents of the EMAC config register and zero out
+	 * speed bits
+	 */
+	EmmcReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+					   XTE_EMMC_OFFSET) &
+		~XTE_EMMC_LINKSPEED_MASK;
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_SetOperatingSpeed: current speed: 0x%0x\n",
+		    EmmcReg);
+	switch (Speed) {
+	case 10:
+		break;
+
+	case 100:
+		EmmcReg |= XTE_EMMC_LINKSPD_100;
+		break;
+
+	case 1000:
+		EmmcReg |= XTE_EMMC_LINKSPD_1000;
+		break;
+
+	default:
+		return;
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_SetOperatingSpeed: new speed: 0x%0x\n", EmmcReg);
+	/* Set register and return */
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_EMMC_OFFSET, EmmcReg);
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOperatingSpeed: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_PhySetMdioDivisor sets the MDIO clock divisor in the TEMAC channel,
+ * specified by <i>InstancePtr</i> to the value, <i>Divisor</i>. This function
+ * must be called once after each reset prior to accessing MII PHY registers.
+ *
+ * From the Virtex-4 Embedded Tri-Mode Ethernet MAC User's Guide, the
+ * following equation governs the MDIO clock to the PHY:
+ *
+ * <pre>
+ *              f[HOSTCLK]
+ *   f[MDC] = -----------------
+ *            (1 + Divisor) * 2
+ * </pre>
+ *
+ * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
+ * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
+ * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
+ * access.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Divisor is the divisor value to set within the range of 0 to
+ *        XTE_MC_CLK_DVD_MAX.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY)
+		XASSERT_VOID(Divisor <= XTE_MC_CLOCK_DIVIDE_MAX);
+
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_PhySetMdioDivisor\n");
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_MC_OFFSET,
+				  (u32) Divisor | XTE_MC_MDIOEN_MASK);
+}
+
+/*****************************************************************************/
+/*
+ * XLlTemac_PhyRead reads the specified PHY register, <i>RegiseterNum</i> on the
+ * PHY specified by <i>PhyAddress</i> into <i>PhyDataPtr</i>. This Ethernet
+ * driver does not require the device to be stopped before reading from the PHY.
+ * It is the responsibility of the calling code to stop the device if it is
+ * deemed necessary.
+ *
+ * Note that the TEMAC hardware provides the ability to talk to a PHY that
+ * adheres to the Media Independent Interface (MII) as defined in the IEEE 802.3
+ * standard.
+ *
+ * <b>It is important that calling code set up the MDIO clock with
+ * XLlTemac_PhySetMdioDivisor() prior to accessing the PHY with this function.</b>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PhyAddress is the address of the PHY to be written (multiple
+ *        PHYs supported).
+ * @param RegisterNum is the register number, 0-31, of the specific PHY register
+ *        to write.
+ * @param PhyDataPtr is a reference to the location where the 16-bit result
+ *        value is stored.
+ *
+ * @return N/A
+ *
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.<br><br>
+ *
+ * There is the possibility that this function will not return if the hardware
+ * is broken (i.e., it never sets the status bit indicating that the write is
+ * done). If this is of concern, the calling code should provide a mechanism
+ * suitable for recovery.
+ *
+ ******************************************************************************/
+void XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress,
+		      u32 RegisterNum, u16 *PhyDataPtr)
+{
+	u32 MiiReg;
+	u32 Rdy;
+	u32 Ie;
+	u32 Tis;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_PhyRead: BaseAddress: 0x%08x\n",
+		    InstancePtr->Config.BaseAddress);
+	/*
+	 * XLlTemac_PhyRead saves the state of the IE register so that it can
+	 * clear the HardAcsCmplt bit and later restore the state of the IE
+	 * register. Since XLlTemac_PhyRead will poll for the status already, the
+	 * HardAcsCmplt bit is cleared in the IE register so that the
+	 * application code above doesn't also receive the interrupt.
+	 */
+	Ie = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET);
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET,
+			  Ie & ~XTE_INT_HARDACSCMPLT_MASK);
+
+	/*
+	 * This is a double indirect mechanism. We indirectly write the
+	 * PHYAD and REGAD so we can read the PHY register back out in
+	 * the LSW register.
+	 *
+	 * In this case, the method of reading the data is a little unusual.
+	 * Normally to write to a TEMAC register, one would set the WEN bit
+	 * in the CTL register so that the values of the LSW will be written.
+	 *
+	 * In this case, the WEN bit is not set, and the PHYAD and REGAD
+	 * values in the LSW will still get sent to the PHY before actually
+	 * reading the result in the LSW.
+	 *
+	 * What needs to be done, is the following:
+	 * 1) Write lsw reg with the phyad, and the regad
+	 * 2) write the ctl reg with the miimai value (BUT WEN bit set to 0!!!)
+	 * 3) poll the ready bit
+	 * 4) get the value out of lsw
+	 */
+	MiiReg = RegisterNum & XTE_MIIM_REGAD_MASK;
+	MiiReg |= ((PhyAddress << XTE_MIIM_PHYAD_SHIFT) & XTE_MIIM_PHYAD_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_PhyRead: Mii Reg: 0x%0x; Value written: 0x%0x\n",
+		    RegisterNum, MiiReg);
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_LSW_OFFSET,
+			  MiiReg);
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_CTL_OFFSET,
+			  XTE_MIIMAI_OFFSET);
+
+	/*
+	 * Wait here polling, until the value is ready to be read.
+	 */
+	do {
+		Rdy = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RDY_OFFSET);
+	} while (!(Rdy & XTE_RSE_MIIM_RR_MASK));
+
+	/* Read data */
+	*PhyDataPtr = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_LSW_OFFSET);
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_PhyRead: Value retrieved: 0x%0x\n", *PhyDataPtr);
+
+	/*
+	 * Clear MII status bits. The TIS register in the hard TEMAC doesn't
+	 * use the 'write a 1 to clear' method, so we need to read the TIS
+	 * register, clear the MIIM RST bit, and then write it back out.
+	 */
+	Tis = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_TIS_OFFSET);
+	Tis &= ~XTE_RSE_MIIM_RR_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_TIS_OFFSET, Tis);
+
+	/*
+	 * restore the state of the IE reg
+	 */
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, Ie);
+}
+
+
+/*****************************************************************************/
+/*
+ * XLlTemac_PhyWrite writes <i>PhyData</i> to the specified PHY register,
+ * <i>RegiseterNum</i> on the PHY specified by <i>PhyAddress</i>. This Ethernet
+ * driver does not require the device to be stopped before writing to the PHY.
+ * It is the responsibility of the calling code to stop the device if it is
+ * deemed necessary.
+ *
+ * Note that the TEMAC hardware provides the ability to talk to a PHY that
+ * adheres to the Media Independent Interface (MII) as defined in the IEEE 802.3
+ * standard.
+ *
+ * <b>It is important that calling code set up the MDIO clock with
+ * XLlTemac_PhySetMdioDivisor() prior to accessing the PHY with this function.</b>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PhyAddress is the address of the PHY to be written (multiple
+ *        PHYs supported).
+ * @param RegisterNum is the register number, 0-31, of the specific PHY register
+ *        to write.
+ * @param PhyData is the 16-bit value that will be written to the register.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.<br><br>
+ *
+ * There is the possibility that this function will not return if the hardware
+ * is broken (i.e., it never sets the status bit indicating that the write is
+ * done). If this is of concern, the calling code should provide a mechanism
+ * suitable for recovery.
+ *
+ ******************************************************************************/
+void XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress,
+		       u32 RegisterNum, u16 PhyData)
+{
+	u32 MiiReg;
+	u32 Rdy;
+	u32 Ie;
+	u32 Tis;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				      XTE_RDY_OFFSET) &
+		     XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_PhyWrite\n");
+	/*
+	 * XLlTemac_PhyWrite saves the state of the IE register so that it can
+	 * clear the HardAcsCmplt bit and later restore the state of the IE
+	 * register. Since XLlTemac_PhyWrite will poll for the status already, the
+	 * HardAcsCmplt bit is cleared in the IE register so that the
+	 * application code above doesn't also receive the interrupt.
+	 */
+	Ie = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET);
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET,
+			  Ie & ~XTE_INT_HARDACSCMPLT_MASK);
+
+	/*
+	 * This is a double indirect mechanism. We indirectly write the
+	 * PhyData to the MIIMWD register, and then indirectly write PHYAD and
+	 * REGAD so the value in MIIMWD will get written to the PHY.
+	 */
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_MIIMWD_OFFSET, PhyData);
+
+	MiiReg = RegisterNum & XTE_MIIM_REGAD_MASK;
+	MiiReg |= ((PhyAddress << XTE_MIIM_PHYAD_SHIFT) & XTE_MIIM_PHYAD_MASK);
+
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_MIIMAI_OFFSET, MiiReg);
+
+	/*
+	 * Wait here polling, until the value is ready to be read.
+	 */
+	do {
+		Rdy = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+				       XTE_RDY_OFFSET);
+	} while (!(Rdy & XTE_RSE_MIIM_WR_MASK));
+
+	/*
+	 * Clear MII status bits. The TIS register in the hard TEMAC doesn't
+	 * use the 'write a 1 to clear' method, so we need to read the TIS
+	 * register, clear the MIIM WST bit, and then write it back out.
+	 */
+	Tis = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+				       XTE_TIS_OFFSET);
+	Tis &= XTE_RSE_MIIM_WR_MASK;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+				  XTE_TIS_OFFSET, Tis);
+
+	/*
+	 * restore the state of the IE reg
+	 */
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, Ie);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_control.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_control.c	2014-07-20 22:06:37.188291994 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac_control.c
+ *
+ * Functions in this file implement general purpose command and control related
+ * functionality. See xlltemac.h for a detailed description of the driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  11/10/06 First release
+ * </pre>
+ *****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xlltemac.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * in the TEMAC channel's multicast filter list.
+ *
+ * XLlTemac_MulticastAdd adds the Ethernet address, <i>AddressPtr</i> to the
+ * TEMAC channel's multicast filter list, at list index <i>Entry</i>. The
+ * address referenced by <i>AddressPtr</i> may be of any unicast, multicast, or
+ * broadcast address form. The harware for the TEMAC channel can hold up to
+ * XTE_MULTI_MAT_ENTRIES addresses in this filter list.<br><br>
+ *
+ * The device must be stopped to use this function.<br><br>
+ *
+ * Once an Ethernet address is programmed, the TEMAC channel will begin
+ * receiving data sent from that address. The TEMAC hardware does not have a
+ * control bit to disable multicast filtering. The only way to prevent the
+ * TEMAC channel from receiving messages from an Ethernet address in the
+ * Multicast Address Table (MAT) is to clear it with XLlTemac_MulticastClear().
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a pointer to the 6-byte Ethernet address to set. The
+ *        previous address at the location <i>Entry</i> (if any) is overwritten
+ *        with the value at <i>AddressPtr</i>.
+ * @param Entry is the hardware storage location to program this address and
+ *        must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return On successful completion, XLlTemac_MulticastAdd returns XST_SUCCESS.
+ *         Otherwise, if the TEMAC channel is not stopped, XLlTemac_MulticastAdd
+ *         returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_MulticastAdd(XLlTemac *InstancePtr, void *AddressPtr, int Entry)
+{
+	u32 Maw0Reg;
+	u32 Maw1Reg;
+	u8 *Aptr = (u8 *) AddressPtr;
+	u32 Rdy;
+	int MaxWait = 100;
+	u32 BaseAddress = InstancePtr->Config.BaseAddress;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_NONVOID(AddressPtr != NULL);
+	XASSERT_NONVOID(Entry < XTE_MULTI_MAT_ENTRIES);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastAdd\n");
+
+	/* The device must be stopped before clearing the multicast hash table */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_MulticastAdd: returning DEVICE_IS_STARTED\n");
+
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Set MAC bits [31:0] */
+	Maw0Reg = Aptr[0];
+	Maw0Reg |= Aptr[1] << 8;
+	Maw0Reg |= Aptr[2] << 16;
+	Maw0Reg |= Aptr[3] << 24;
+
+	/* Set MAC bits [47:32] */
+	Maw1Reg = Aptr[4];
+	Maw1Reg |= Aptr[5] << 8;
+
+	/* Add in MAT address */
+	Maw1Reg |= (Entry << XTE_MAW1_MATADDR_SHIFT_MASK);
+
+	/* Program HW */
+	xdbg_printf(XDBG_DEBUG_GENERAL, "Setting MAT entry: %d\n", Entry);
+	XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET, Maw0Reg);
+	XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+			XTE_MAW0_OFFSET | XTE_CTL_WEN_MASK);
+	Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+	while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+		Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+		xdbg_stmnt(
+			if (MaxWait == 100) {
+				xdbg_printf(XDBG_DEBUG_GENERAL,
+					    "RDY reg not initially ready\n");
+			}
+		);
+		MaxWait--;
+		xdbg_stmnt(
+			if (MaxWait == 0) {
+				xdbg_printf (XDBG_DEBUG_GENERAL,
+					     "RDY reg never showed ready\n");
+			}
+		)
+	}
+	XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET,
+			Maw1Reg);
+	XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+			XTE_MAW1_OFFSET | XTE_CTL_WEN_MASK);
+	Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+	while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+		Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+		xdbg_stmnt(
+			if (MaxWait == 100) {
+				xdbg_printf(XDBG_DEBUG_GENERAL,
+					    "RDY reg not initially ready\n");
+			}
+		);
+		MaxWait--;
+		xdbg_stmnt(
+			if (MaxWait == 0) {
+				xdbg_printf (XDBG_DEBUG_GENERAL,
+					     "RDY reg never showed ready\n");
+			}
+		)
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastAdd: returning SUCCESS\n");
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_MulticastGet gets the Ethernet address stored at index <i>Entry</i>
+ * in the TEMAC channel's multicast filter list.<br><br>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved
+ *        Ethernet address. This memory buffer must be at least 6 bytes in
+ *        length.
+ * @param Entry is the hardware storage location from which to retrieve the
+ *        address and must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_MulticastGet(XLlTemac *InstancePtr, void *AddressPtr, int Entry)
+{
+	u32 Maw0Reg;
+	u32 Maw1Reg;
+	u8 *Aptr = (u8 *) AddressPtr;
+	u32 Rdy;
+	int MaxWait = 100;
+	u32 BaseAddress = InstancePtr->Config.BaseAddress;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_VOID(Entry < XTE_MULTI_MAT_ENTRIES);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET) &
+			XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastGet\n");
+
+	/*
+	 * Tell HW to provide address stored in given entry.
+	 * In this case, the Access is a little weird, becuase we need to
+	 * write the LSW register first, then initiate a write operation,
+	 * even though it's a read operation.
+	 */
+	xdbg_printf(XDBG_DEBUG_GENERAL, "Getting MAT entry: %d\n", Entry);
+	XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET,
+			 Entry << XTE_MAW1_MATADDR_SHIFT_MASK | XTE_MAW1_RNW_MASK);
+	XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+			 XTE_MAW1_OFFSET | XTE_CTL_WEN_MASK);
+	Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+	while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+		Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+		xdbg_stmnt(
+			if (MaxWait == 100) {
+				xdbg_printf(XDBG_DEBUG_GENERAL,
+					    "RDY reg not initially ready\n");
+			}
+		);
+		MaxWait--;
+		xdbg_stmnt(
+			if (MaxWait == 0) {
+				xdbg_printf(XDBG_DEBUG_GENERAL,
+					     "RDY reg never showed ready\n");
+			}
+		)
+
+	}
+	Maw0Reg = XLlTemac_ReadReg(BaseAddress, XTE_LSW_OFFSET);
+	Maw1Reg = XLlTemac_ReadReg(BaseAddress, XTE_MSW_OFFSET);
+
+	/* Copy the address to the user buffer */
+	Aptr[0] = (u8) Maw0Reg;
+	Aptr[1] = (u8) (Maw0Reg >> 8);
+	Aptr[2] = (u8) (Maw0Reg >> 16);
+	Aptr[3] = (u8) (Maw0Reg >> 24);
+	Aptr[4] = (u8) Maw1Reg;
+	Aptr[5] = (u8) (Maw1Reg >> 8);
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastGet: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_MulticastClear clears the Ethernet address stored at index <i>Entry</i>
+ * in the TEMAC channel's multicast filter list.<br><br>
+ *
+ * The device must be stopped to use this function.<br><br>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Entry is the HW storage location used when this address was added.
+ *        It must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ * @param Entry is the hardware storage location to clear and must be between
+ *        0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return On successful completion, XLlTemac_MulticastClear returns XST_SUCCESS.
+ *         Otherwise, if the TEMAC channel is not stopped, XLlTemac_MulticastClear
+ *         returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_NONVOID(Entry < XTE_MULTI_MAT_ENTRIES);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastClear\n");
+
+	/* The device must be stopped before clearing the multicast hash table */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_MulticastClear: returning DEVICE_IS_STARTED\n");
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Clear the entry by writing 0:0:0:0:0:0 to it */
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_MAW0_OFFSET, 0);
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_MAW1_OFFSET, Entry << XTE_MAW1_MATADDR_SHIFT_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		    "XLlTemac_MulticastClear: returning SUCCESS\n");
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetMacPauseAddress sets the MAC address used for pause frames to
+ * <i>AddressPtr</i>. <i>AddressPtr</i> will be the address the TEMAC channel
+ * will recognize as being for pause frames. Pause frames transmitted with
+ * XLlTemac_SendPausePacket() will also use this address.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a pointer to the 6-byte Ethernet address to set.
+ *
+ * @return On successful completion, XLlTemac_SetMacPauseAddress returns
+ *         XST_SUCCESS. Otherwise, if the TEMAC channel is not stopped,
+ *         XLlTemac_SetMacPauseAddress returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	u32 MacAddr;
+	u8 *Aptr = (u8 *) AddressPtr;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+	/* Be sure device has been stopped */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_SetMacPauseAddress: returning DEVICE_IS_STARTED\n");
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Set the MAC bits [31:0] in ERXC0 */
+	MacAddr = Aptr[0];
+	MacAddr |= Aptr[1] << 8;
+	MacAddr |= Aptr[2] << 16;
+	MacAddr |= Aptr[3] << 24;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_RCW0_OFFSET, MacAddr);
+
+	/* ERCW1 contains other info that must be preserved */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_RCW1_OFFSET);
+	MacAddr &= ~XTE_RCW1_PAUSEADDR_MASK;
+
+	/* Set MAC bits [47:32] */
+	MacAddr |= Aptr[4];
+	MacAddr |= Aptr[5] << 8;
+	XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_RCW1_OFFSET, MacAddr);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		   "XLlTemac_SetMacPauseAddress: returning SUCCESS\n");
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetMacPauseAddress gets the MAC address used for pause frames for the
+ * TEMAC channel specified by <i>InstancePtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved MAC
+ *        address. This memory buffer must be at least 6 bytes in length.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	u32 MacAddr;
+	u8 *Aptr = (u8 *) AddressPtr;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+
+	/* Read MAC bits [31:0] in ERXC0 */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_RCW0_OFFSET);
+	Aptr[0] = (u8) MacAddr;
+	Aptr[1] = (u8) (MacAddr >> 8);
+	Aptr[2] = (u8) (MacAddr >> 16);
+	Aptr[3] = (u8) (MacAddr >> 24);
+
+	/* Read MAC bits [47:32] in RCW1 */
+	MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_RCW1_OFFSET);
+	Aptr[4] = (u8) MacAddr;
+	Aptr[5] = (u8) (MacAddr >> 8);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SendPausePacket sends a pause packet with the value of
+ * <i>PauseValue</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PauseValue is the pause value in units of 512 bit times.
+ *
+ * @return On successful completion, XLlTemac_SendPausePacket returns
+ *         XST_SUCCESS. Otherwise, if the TEMAC channel is not started,
+ *         XLlTemac_SendPausePacket returns XST_DEVICE_IS_STOPPED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SendPausePacket(XLlTemac *InstancePtr, u16 PauseValue)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+
+	/* Make sure device is ready for this operation */
+	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_SendPausePacket: returning DEVICE_IS_STOPPED\n");
+		return (XST_DEVICE_IS_STOPPED);
+	}
+
+	/* Send flow control frame */
+	XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_TPF_OFFSET,
+			     (u32) PauseValue & XTE_TPF_TPFV_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		   "XLlTemac_SendPausePacket: returning SUCCESS\n");
+	return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetSgmiiStatus get the state of the link when using the SGMII media
+ * interface.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param SpeedPtr references the location to store the result, which is the
+ *        autonegotiated link speed in units of Mbits/sec, either 0, 10, 100,
+ *        or 1000.
+ *
+ * @return On successful completion, XLlTemac_GetSgmiiStatus returns XST_SUCCESS.
+ *         Otherwise, if TEMAC channel is not using an SGMII interface,
+ *         XLlTemac_GetSgmiiStatus returns XST_NO_FEATURE.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr)
+{
+	int PhyType;
+	u32 EgmicReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetSgmiiStatus\n");
+	/* Make sure PHY is SGMII */
+	PhyType = XLlTemac_GetPhysicalInterface(InstancePtr);
+	if (PhyType != XTE_PHY_TYPE_SGMII) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_GetSgmiiStatus: returning NO_FEATURE\n");
+		return (XST_NO_FEATURE);
+	}
+
+	/* Get the current contents of RGMII/SGMII config register */
+	EgmicReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_PHYC_OFFSET);
+
+	/* Extract speed */
+	switch (EgmicReg & XTE_PHYC_SGMIILINKSPEED_MASK) {
+	case XTE_PHYC_SGLINKSPD_10:
+		*SpeedPtr = 10;
+		break;
+
+	case XTE_PHYC_SGLINKSPD_100:
+		*SpeedPtr = 100;
+		break;
+
+	case XTE_PHYC_SGLINKSPD_1000:
+		*SpeedPtr = 1000;
+		break;
+
+	default:
+		*SpeedPtr = 0;
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		   "XLlTemac_GetSgmiiStatus: returning SUCCESS\n");
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetRgmiiStatus get the state of the link when using the RGMII media
+ * interface.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param SpeedPtr references the location to store the result, which is the
+ *        autonegotiaged link speed in units of Mbits/sec, either 0, 10, 100,
+ *        or 1000.
+ * @param IsFullDuplexPtr references the value to set to indicate full duplex
+ *        operation. XLlTemac_GetRgmiiStatus sets <i>IsFullDuplexPtr</i> to TRUE
+ *        when the RGMII link is operating in full duplex mode. Otherwise,
+ *        XLlTemac_GetRgmiiStatus sets <i>IsFullDuplexPtr</i> to FALSE.
+ * @param IsLinkUpPtr references the value to set to indicate the link status.
+ *        XLlTemac_GetRgmiiStatus sets <i>IsLinkUpPtr</i> to TRUE when the RGMII
+ *        link up. Otherwise, XLlTemac_GetRgmiiStatus sets <i>IsLinkUpPtr</i> to
+ *        FALSE.
+ *
+ * @return On successful completion, XLlTemac_GetRgmiiStatus returns XST_SUCCESS.
+ *         Otherwise, if TEMAC channel is not using an RGMII interface,
+ *         XLlTemac_GetRgmiiStatus returns XST_NO_FEATURE.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr,
+			      int *IsFullDuplexPtr, int *IsLinkUpPtr)
+{
+	int PhyType;
+	u32 EgmicReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	/*
+	 * If the mutual exclusion is enforced properly in the calling code, we
+	 * should never get into the following case.
+	 */
+	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetRgmiiStatus\n");
+	/* Make sure PHY is RGMII */
+	PhyType = XLlTemac_GetPhysicalInterface(InstancePtr);
+	if ((PhyType != XTE_PHY_TYPE_RGMII_1_3) &&
+	    (PhyType != XTE_PHY_TYPE_RGMII_2_0)) {
+		xdbg_printf(XDBG_DEBUG_GENERAL,
+			   "XLlTemac_GetRgmiiStatus: returning NO_FEATURE\n");
+		return (XST_NO_FEATURE);
+	}
+
+	/* Get the current contents of RGMII/SGMII config register */
+	EgmicReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+			XTE_PHYC_OFFSET);
+
+	/* Extract speed */
+	switch (EgmicReg & XTE_PHYC_RGMIILINKSPEED_MASK) {
+	case XTE_PHYC_RGLINKSPD_10:
+		*SpeedPtr = 10;
+		break;
+
+	case XTE_PHYC_RGLINKSPD_100:
+		*SpeedPtr = 100;
+		break;
+
+	case XTE_PHYC_RGLINKSPD_1000:
+		*SpeedPtr = 1000;
+		break;
+
+	default:
+		*SpeedPtr = 0;
+	}
+
+	/* Extract duplex and link status */
+	if (EgmicReg & XTE_PHYC_RGMIIHD_MASK) {
+		*IsFullDuplexPtr = FALSE;
+	}
+	else {
+		*IsFullDuplexPtr = TRUE;
+	}
+
+	if (EgmicReg & XTE_PHYC_RGMIILINK_MASK) {
+		*IsLinkUpPtr = TRUE;
+	}
+	else {
+		*IsLinkUpPtr = FALSE;
+	}
+
+	xdbg_printf(XDBG_DEBUG_GENERAL,
+		   "XLlTemac_GetRgmiiStatus: returning SUCCESS\n");
+	return (XST_SUCCESS);
+}
+
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac.h	2014-07-20 22:06:37.203291747 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac.h
+ *
+ * The Xilinx Tri-Mode Ethernet driver component. This driver supports the
+ * Virtex-5(TM) and Virtex-4(TM) 10/100/1000 MAC (TEMAC).
+ *
+ * For a full description of TEMAC features, please see the hardware spec. This driver
+ * supports the following features:
+ *   - Memory mapped access to host interface registers
+ *   - Virtual memory support
+ *   - Unicast, broadcast, and multicast receive address filtering
+ *   - Full duplex operation (half duplex not supported)
+ *   - Automatic source address insertion or overwrite (programmable)
+ *   - Automatic PAD & FCS insertion and stripping (programmable)
+ *   - Flow control
+ *   - VLAN frame support
+ *   - Pause frame support
+ *   - Jumbo frame support
+ *   - Checksum offload
+ *
+ * <h2>Driver Description</h2>
+ *
+ * The device driver enables higher layer software (e.g., an application) to
+ * configure a TEMAC channel. It is intended that this driver be used in
+ * cooperation with another driver (FIFO or DMA) for data communication. This
+ * device driver can support multiple devices even when those devices have
+ * significantly different configurations.
+ *
+ * <h2>Initialization & Configuration</h2>
+ *
+ * The XLlTemac_Config structure can be used by the driver to configure itself.
+ * This configuration structure is typically created by the tool-chain based on
+ * hardware build properties, although, other methods are allowed and currently
+ * used in some systems.
+ *
+ * To support multiple runtime loading and initialization strategies employed
+ * by various operating systems, the driver instance can be initialized using
+ * the XLlTemac_CfgInitialze() routine.
+ *
+ * <h2>Interrupts and Asynchronous Callbacks</h2>
+ *
+ * The driver has no dependencies on the interrupt controller. It provides
+ * no interrupt handlers. The application/OS software should set up its own
+ * interrupt handlers if required.
+ *
+ * <h2>Device Reset</h2>
+ *
+ * When a TEMAC channel is connected up to a FIFO or DMA core in hardware,
+ * errors may be reported on one of those cores (FIFO or DMA) such that it can
+ * be determined that the TEMAC channel needs to be reset. If a reset is
+ * performed, the calling code should also reconfigure and reapply the proper
+ * settings in the TEMAC channel.
+ *
+ * When a TEMAC channel reset is required, XLlTemac_Reset() should be utilized.
+ *
+ * <h2>Virtual Memory</h2>
+ *
+ * This driver may be used in systems with virtual memory support by passing
+ * the appropriate value for the <i>EffectiveAddress</i> parameter to the
+ * XLlTemac_CfgInitialize() routine.
+ *
+ * <h2>Transfering Data</h2>
+ *
+ * The TEMAC core by itself is not cabable of transmitting or receiving data in
+ * any meaninful way. Instead one or both TEMAC channels need to be connected
+ * to a FIFO or DMA core in hardware.
+ *
+ * This TEMAC driver is modeled in a similar fashion where the application code
+ * or O/S adapter driver needs to make use of a separte FIFO or DMA driver in
+ * connection with this driver to establish meaningful communication over
+ * ethernet.
+ *
+ * <h2>Checksum Offloading</h2>
+ *
+ * If configured, the device can compute a 16-bit checksum from frame data. In
+ * most circumstances this can lead to a substantial gain in throughput.
+ *
+ * The checksum offload settings for each frame sent or recieved are
+ * transmitted through the LocalLink interface in hardware. What this means is
+ * that the checksum offload feature is indirectly controlled in the TEMAC
+ * channel through the driver for the FIFO or DMA core connected to the TEMAC
+ * channel.
+ *
+ * Refer to the documentation for the FIFO or DMA driver used for data
+ * communication on how to set the values for the relevant LocalLink header
+ * words.
+ *
+ * Since this hardware implementation is general purpose in nature system software must
+ * perform pre and post frame processing to obtain the desired results for the
+ * types of packets being transferred. Most of the time this will be TCP/IP
+ * traffic.
+ *
+ * TCP/IP and UDP/IP frames contain separate checksums for the IP header and
+ * UDP/TCP header+data. With this hardware implementation, the IP header checksum
+ * cannot be offloaded. Many stacks that support offloading will compute the IP
+ * header if required and use hardware to compute the UDP/TCP header+data checksum.
+ * There are other complications concerning the IP pseudo header that must be
+ * taken into consideration. Readers should consult a TCP/IP design reference
+ * for more details.
+ *
+ * There are certain device options that will affect the checksum calculation
+ * performed by hardware for Tx:
+ *
+ *   - FCS insertion disabled (XTE_FCS_INSERT_OPTION): software is required to
+ *     calculate and insert the FCS value at the end of the frame, but the
+ *     checksum must be known ahead of time prior to calculating the FCS.
+ *     Therefore checksum offloading cannot be used in this situation.
+ *
+ * And for Rx:
+ *
+ *   - FCS/PAD stripping disabled (XTE_FCS_STRIP_OPTION): The 4 byte FCS at the
+ *     end of frame will be included in the hardware calculated checksum. software must
+ *     subtract out this data.
+ *
+ *   - FCS/PAD stripping disabled (XTE_FCS_STRIP_OPTION): For frames smaller
+ *     than 64 bytes, padding will be included in the hardware calculated checksum.
+ *     software must subtract out this data. It may be better to allow the TCP/IP
+ *     stack verify checksums for this type of packet.
+ *
+ *   - VLAN enabled (XTE_VLAN_OPTION): The 4 extra bytes in the Ethernet header
+ *     affect the hardware calculated checksum. software must subtract out the 1st two
+ *     16-bit words starting at the 15th byte.
+ *
+ * <h3>Transmit Checksum Offloading</h3>
+ *
+ * For transmit, the software can specify where in the frame the checksum
+ * calculation is to start, where the result should be inserted, and a seed
+ * value. The checksum is calculated from the start point through the end of
+ * frame.
+ *
+ * The checsum offloading settings are sent in the transmit LocalLink header
+ * words. The relevant LocalLink header words are described in brief below.
+ * Refer to the XPS_LL_TEMAC v1.00a hardware specification for more details.
+ *
+ *   <h4>LocalLink header word 3:</h4>
+ *   <pre>
+ *   Bits    31 (MSB): Transmit Checksum Enable: 1 - enabled, 0 - disabled
+ *   Bits  0-30 (LSB): Reserved
+ *   </pre>
+ *
+ *   <h4>LocalLink header word 4:</h4>
+ *   <pre>
+ *   Bits 16-31 (MSB): Transmit Checksum Insertion Point: Frame offset where the
+ *                     computed checksum value is stored, which should be in the
+ *                     TCP or UDP header
+ *   Bits  0-15 (LSB): Transmit Checksum Calculation Starting Point: Offset
+ *                     in the frame where checksum calculation should begin
+ *   </pre>
+ *
+ *   <h4>LocalLink header word 5:</h4>
+ *   <pre>
+ *   Bits 16-31 (MSB): Transmit Checksum Calculation Initial Value: Checksum
+ *                     seed value
+ *   Bits  0-15 (LSB): Reserved
+ *   </pre>
+ *
+ * <h3>Receive Checksum Offloading</h3>
+ *
+ * For Receive, the 15th byte to end of frame is checksummed. This range of
+ * bytes is the entire Ethernet payload (for non-VLAN frames).
+ *
+ * The checsum offloading information is sent in the receive LocalLink header
+ * words. The relevant LocalLink header words are described in brief below.
+ * Refer to the XPS_LL_TEMAC v1.00a hardware specification for more details.
+ *
+ *   <h4>LocalLink header word 6:</h4>
+ *   <pre>
+ *   Bits 16-31 (MSB): Receive Raw Checksum: Computed checksum value
+ *   Bits  0-15 (LSB): Reserved
+ *   </pre>
+ *
+ * <h2>PHY Communication</h2>
+ *
+ * Prior to PHY access, the MDIO clock must be setup. This driver will set a
+ * safe default that should work with PLB bus speeds of up to 150 MHz and keep
+ * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY
+ * then the clock divisor can be set to a different value (see
+ * XLlTemac_PhySetMdioDivisor()).
+ *
+ * MII register access is performed through the functions XLlTemac_PhyRead() and
+ * XLlTemac_PhyWrite().
+ *
+ * <h2>Link Sync</h2>
+ *
+ * When the device is used in a multispeed environment, the link speed must be
+ * explicitly set using XLlTemac_SetOperatingSpeed() and must match the speed the
+ * PHY has negotiated. If the speeds are mismatched, then the MAC will not pass
+ * traffic.
+ *
+ * The application/OS software may use the AutoNegotiation interrupt to be
+ * notified when the PHY has completed auto-negotiation.
+ *
+ * <h2>Asserts</h2>
+ *
+ * Asserts are used within all Xilinx drivers to enforce constraints on argument
+ * values. Asserts can be turned off on a system-wide basis by defining, at
+ * compile time, the NDEBUG identifier. By default, asserts are turned on and it
+ * is recommended that users leave asserts on during development. For deployment
+ * use -DNDEBUG compiler switch to remove assert code.
+ *
+ * <h2>Driver Errata</h2>
+ *
+ *   - A dropped receive frame indication may be reported by the driver after
+ *     calling XLlTemac_Stop() followed by XLlTemac_Start(). This can occur if a
+ *     frame is arriving when stop is called.
+ *   - On Rx with checksum offloading enabled and FCS/PAD stripping disabled,
+ *     FCS and PAD data will be included in the checksum result.
+ *   - On Tx with checksum offloading enabled and auto FCS insertion disabled,
+ *     the user calculated FCS will be included in the checksum result.
+ *
+ * @note
+ *
+ * Xilinx drivers are typically composed of two components, one is the driver
+ * and the other is the adapter.  The driver is independent of OS and processor
+ * and is intended to be highly portable.  The adapter is OS-specific and
+ * facilitates communication between the driver and an OS.
+ * <br><br>
+ * This driver is intended to be RTOS and processor independent. Any needs for
+ * dynamic memory management, threads or thread mutual exclusion, or cache
+ * control must be satisfied by the layer above this driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  11/10/06 First release
+ * 1.00a rpm  06/08/07 Added interrupt IDs to config structure for convenience
+ * </pre>
+ *
+ *****************************************************************************/
+
+#ifndef XTEMAC_H		/* prevent circular inclusions */
+#define XTEMAC_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xenv.h"
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xlltemac_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Device information
+ */
+#define XTE_DEVICE_NAME     "xlltemac"
+#define XTE_DEVICE_DESC     "Xilinx Tri-speed 10/100/1000 MAC"
+
+/* LocalLink TYPE Enumerations */
+#define XPAR_LL_FIFO    1
+#define XPAR_LL_DMA     2
+
+/** @name Configuration options
+ *
+ * The following are device configuration options. See the
+ * <i>XLlTemac_SetOptions</i>, <i>XLlTemac_ClearOptions</i> and
+ * <i>XLlTemac_GetOptions</i> routines for information on how to use options.
+ *
+ * The default state of the options are also noted below.
+ *
+ * @{
+ */
+
+#define XTE_PROMISC_OPTION               0x00000001
+/**< XTE_PROMISC_OPTION specifies the TEMAC channel to accept all incoming
+ *   packets.
+ *   This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_JUMBO_OPTION                 0x00000002
+/**< XTE_JUMBO_OPTION specifies the TEMAC channel to accept jumbo frames
+ *   for transmit and receive.
+ *   This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_VLAN_OPTION                  0x00000004
+/**< XTE_VLAN_OPTION specifies the TEMAC channel to enable VLAN support for
+ *   transmit and receive.
+ *   This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_FLOW_CONTROL_OPTION          0x00000008
+/**< XTE_FLOW_CONTROL_OPTION specifies the TEMAC channel to recognize
+ *   received flow control frames.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_FCS_STRIP_OPTION             0x00000010
+/**< XTE_FCS_STRIP_OPTION specifies the TEMAC channel to strip FCS and PAD
+ *   from received frames. Note that PAD from VLAN frames is not stripped.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_FCS_INSERT_OPTION            0x00000020
+/**< XTE_FCS_INSERT_OPTION specifies the TEMAC channel to generate the FCS
+ *   field and add PAD automatically for outgoing frames.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_LENTYPE_ERR_OPTION           0x00000040
+/**< XTE_LENTYPE_ERR_OPTION specifies the TEMAC channel to enable
+ *   Length/Type error checking (mismatched type/length field) for received
+ *   frames.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_TRANSMITTER_ENABLE_OPTION    0x00000080
+/**< XTE_TRANSMITTER_ENABLE_OPTION specifies the TEMAC channel transmitter
+ *   to be enabled.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_RECEIVER_ENABLE_OPTION       0x00000100
+/**< XTE_RECEIVER_ENABLE_OPTION specifies the TEMAC channel receiver to be
+ *   enabled.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_BROADCAST_OPTION             0x00000200
+/**< XTE_BROADCAST_OPTION specifies the TEMAC channel to receive frames
+ *   sent to the broadcast Ethernet address.
+ *   This driver sets this option to enabled (set) by default. */
+
+#define XTE_MULTICAST_OPTION         0x00000400
+/**< XTE_MULTICAST_OPTION specifies the TEMAC channel to receive frames
+ *   sent to Ethernet addresses that are programmed into the Multicast Address
+ *   Table (MAT).
+ *   This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_DEFAULT_OPTIONS                     \
+    (XTE_FLOW_CONTROL_OPTION |                  \
+     XTE_BROADCAST_OPTION |                     \
+     XTE_FCS_INSERT_OPTION |                    \
+     XTE_FCS_STRIP_OPTION |                     \
+     XTE_LENTYPE_ERR_OPTION |                   \
+     XTE_TRANSMITTER_ENABLE_OPTION |            \
+     XTE_RECEIVER_ENABLE_OPTION)
+/**< XTE_DEFAULT_OPTIONS specify the options set in XLlTemac_Reset() and
+ *   XLlTemac_CfgInitialize() */
+
+/*@}*/
+
+/** @name Reset parameters
+ *
+ *  These are used by function XLlTemac_Reset().
+ * @{
+ */
+#define XTE_RESET_HARD    1
+#define XTE_NORESET_HARD  0
+/*@}*/
+
+#define XTE_MULTI_MAT_ENTRIES       4	/* Number of storable addresses in
+					   the Multicast Address Table */
+
+#define XTE_MDIO_DIV_DFT            29	/* Default MDIO clock divisor */
+
+/* The next few constants help upper layers determine the size of memory
+ * pools used for Ethernet buffers and descriptor lists.
+ */
+#define XTE_MAC_ADDR_SIZE   6		/* MAC addresses are 6 bytes */
+#define XTE_MTU             1500	/* max MTU size of an Ethernet frame */
+#define XTE_JUMBO_MTU       8982	/* max MTU size of a jumbo Ethernet frame */
+#define XTE_HDR_SIZE        14	/* size of an Ethernet header */
+#define XTE_HDR_VLAN_SIZE   18	/* size of an Ethernet header with VLAN */
+#define XTE_TRL_SIZE        4	/* size of an Ethernet trailer (FCS) */
+#define XTE_MAX_FRAME_SIZE       (XTE_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+#define XTE_MAX_VLAN_FRAME_SIZE  (XTE_MTU + XTE_HDR_VLAN_SIZE + XTE_TRL_SIZE)
+#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/* Constant values returned by XLlTemac_mGetPhysicalInterface(). Note that these
+ * values match design parameters from the PLB_TEMAC spec
+ */
+#define XTE_PHY_TYPE_MII         0
+#define XTE_PHY_TYPE_GMII        1
+#define XTE_PHY_TYPE_RGMII_1_3   2
+#define XTE_PHY_TYPE_RGMII_2_0   3
+#define XTE_PHY_TYPE_SGMII       4
+#define XTE_PHY_TYPE_1000BASE_X  5
+
+/**************************** Type Definitions *******************************/
+
+
+/**
+ * This typedef contains configuration information for a TEMAC channel.
+ * Each channel is treated as a separate device from the point of view of this
+ * driver.
+ */
+typedef struct {
+        /** u16 DeviceId;	< DeviceId is the unique ID  of the device */
+	u32 BaseAddress;/**< BaseAddress is the physical base address of the
+                          *  channel's registers
+                          */
+	u8 TxCsum;	/**< TxCsum indicates that the channel has checksum
+	                  *  offload on the Tx channel or not.
+	                  */
+	u8 RxCsum;	/**< RxCsum indicates that the channel has checksum
+	                  *  offload on the Rx channel or not.
+	                  */
+	u8 PhyType;	/**< PhyType indicates which type of PHY interface is
+	                  *  used (MII, GMII, RGMII, ect.
+	                  */
+	u8 TemacIntr;	/**< TEMAC interrupt ID */
+
+	int LLDevType;	/**< LLDevType is the type of device attached to the
+			 *   temac's local link interface.
+			 */
+	u32 LLDevBaseAddress; /**< LLDevBaseAddress is the base address of then
+			       *   device attached to the temac's local link
+			       *   interface.
+			       */
+	u8 LLFifoIntr;	/**< LL FIFO interrupt ID (unused if DMA) */
+	u8 LLDmaRxIntr;	/**< LL DMA RX interrupt ID (unused if FIFO) */
+	u8 LLDmaTxIntr;	/**< LL DMA TX interrupt ID (unused if FIFO) */
+
+} XLlTemac_Config;
+
+
+/**
+ * struct XLlTemac is the type for TEMAC driver instance data. The calling code
+ * is required to use a unique instance of this structure for every TEMAC
+ * channel used in the system. Each channel is treated as a separate device
+ * from the point of view of this driver. A reference to a structure of this
+ * type is then passed to the driver API functions.
+ */
+typedef struct XLlTemac {
+	XLlTemac_Config Config;	/* hardware configuration */
+	u32 IsStarted;		/* Device is currently started */
+	u32 IsReady;		/* Device is initialized and ready */
+	u32 Options;		/* Current options word */
+	u32 Flags;		/* Internal driver flags */
+} XLlTemac;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsStarted reports if the device is in the started or stopped state. To
+ * be in the started state, the calling code must have made a successful call to
+ * <i>XLlTemac_Start</i>. To be in the stopped state, <i>XLlTemac_Stop</i> or
+ * <i>XLlTemac_CfgInitialize</i> function must have been called.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsStarted returns TRUE if the device has been started.
+ *         Otherwise, XLlTemac_IsStarted returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsStarted(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsStarted(InstancePtr) \
+	(((InstancePtr)->IsStarted == XCOMPONENT_IS_STARTED) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_IsDma reports if the device is currently connected to DMA.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsDma returns TRUE if the device is connected DMA. Otherwise,
+*         XLlTemac_IsDma returns FALSE.
+*
+* @note
+*
+* Signature: u32 XLlTemac_IsDma(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_IsDma(InstancePtr) \
+	(((InstancePtr)->Config.LLDevType == XPAR_LL_DMA) ? TRUE: FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_IsFifo reports if the device is currently connected to a fifo core.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsFifo returns TRUE if the device is connected to a fifo core.
+*         Otherwise, XLlTemac_IsFifo returns FALSE.
+*
+* @note
+*
+* Signature: u32 XLlTemac_IsFifo(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_IsFifo(InstancePtr) \
+	(((InstancePtr)->Config.LLDevType == XPAR_LL_FIFO) ? TRUE: FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_LlDevBaseAddress reports the base address of the core connected to
+* the TEMAC's local link interface.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsFifo returns the base address of the core connected to
+* the TEMAC's local link interface.
+*
+* @note
+*
+* Signature: u32 XLlTemac_LlDevBaseAddress(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_LlDevBaseAddress(InstancePtr) \
+	((InstancePtr)->Config.LLDevBaseAddress)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsRecvFrameDropped determines if the device thinks it has dropped a
+ * receive frame.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsRecvFrameDropped returns TRUE if the device interrupt
+ * status register reports that a frame has been dropped. Otherwise,
+ * XLlTemac_IsRecvFrameDropped returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsRecvFrameDropped(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsRecvFrameDropped(InstancePtr)                     \
+	((XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET) \
+	& XTE_INT_RXRJECT_MASK) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsRxCsum determines if the device is configured with checksum
+ * offloading on the receive channel.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsRxCsum returns TRUE if the device is configured with
+ *         checksum offloading on the receive channel. Otherwise,
+ *         XLlTemac_IsRxCsum returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsRxCsum(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsRxCsum(InstancePtr) (((InstancePtr)->Config.RxCsum) ?  \
+                                       TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsTxCsum determines if the device is configured with checksum
+ * offloading on the transmit channel.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsTxCsum returns TRUE if the device is configured with
+ *         checksum offloading on the transmit channel. Otherwise,
+ *         XLlTemac_IsTxCsum returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsTxCsum(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsTxCsum(InstancePtr) (((InstancePtr)->Config.TxCsum) ?  \
+                                       TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_GetPhysicalInterface returns the type of PHY interface being used by
+ * the given instance, specified by <i>InstancePtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetPhysicalInterface returns one of XTE_PHY_TYPE_<x> where
+ * <x> is MII, GMII, RGMII_1_3, RGMII_2_0, SGMII, or 1000BASE_X (defined in
+ * xlltemac.h).
+ *
+ * @note
+ *
+ * Signature: int XLlTemac_GetPhysicalInterface(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_GetPhysicalInterface(InstancePtr)       \
+	((InstancePtr)->Config.PhyType)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_Status returns a bit mask of the interrupt status register (ISR).
+* XLlTemac_Status can be used to query the status without having to have
+* interrupts enabled.
+*
+* @param    InstancePtr references the TEMAC channel on which to operate.
+*
+* @return   XLlTemac_IntStatus returns a bit mask of the status conditions.
+*           The mask will be a set of bitwise or'd values from the
+*           <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    u32 XLlTemac_IntStatus(XLlTemac *InstancePtr)
+*
+*****************************************************************************/
+#define XLlTemac_Status(InstancePtr) \
+	 XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntEnable enables the interrupts specified in <i>Mask</i>. The
+* corresponding interrupt for each bit set to 1 in <i>Mask</i>, will be
+* enabled.
+*
+* @param    InstancePtr references the TEMAC channel on which to operate.
+*
+* @param    Mask contains a bit mask of the interrupts to enable. The mask
+*           can be formed using a set of bitwise or'd values from the
+*           <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlTemac_IntEnable(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntEnable(InstancePtr, Mask) \
+	XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IE_OFFSET, \
+		XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, \
+				XTE_IE_OFFSET) | ((Mask) & XTE_INT_ALL_MASK)); \
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntDisable disables the interrupts specified in <i>Mask</i>. The
+* corresponding interrupt for each bit set to 1 in <i>Mask</i>, will be
+* disabled. In other words, XLlTemac_IntDisable uses the "set a bit to clear it"
+* scheme.
+*
+* @param    InstancePtr references the TEMAC channel on which to operate.
+*
+* @param    Mask contains a bit mask of the interrupts to disable. The mask
+*           can be formed using a set of bitwise or'd values from the
+*           <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlTemac_IntDisable(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntDisable(InstancePtr, Mask) \
+	XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IE_OFFSET, \
+		XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, \
+				XTE_IE_OFFSET) & ~((Mask) & XTE_INT_ALL_MASK)); \
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntPending returns a bit mask of the pending interrupts. Each bit
+* set to 1 in the return value represents a pending interrupt.
+*
+* @param    InstancePtr references the TEMAC channel on which to operate.
+*
+* @return   XLlTemac_IntPending returns a bit mask of the interrupts that are
+*           pending. The mask will be a set of bitwise or'd values from the
+*           <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    u32 XLlTemac_IntPending(XLlTemac *InstancePtr)
+*
+*****************************************************************************/
+#define XLlTemac_IntPending(InstancePtr) \
+	XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IP_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntClear clears pending interrupts specified in <i>Mask</i>.
+* The corresponding pending interrupt for each bit set to 1 in <i>Mask</i>,
+* will be cleared. In other words, XLlTemac_IntClear uses the "set a bit to
+* clear it" scheme.
+*
+* @param    InstancePtr references the TEMAC channel on which to operate.
+*
+* @param    Mask contains a bit mask of the pending interrupts to clear. The
+*           mask can be formed using a set of bitwise or'd values from the
+*           <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    void XLlTemac_IntClear(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntClear(InstancePtr, Mask) \
+	XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET, \
+			((Mask) & XTE_INT_ALL_MASK))
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization functions in xlltemac.c
+ */
+int XLlTemac_CfgInitialize(XLlTemac *InstancePtr, XLlTemac_Config *CfgPtr,
+			   u32 VirtualAddress);
+void XLlTemac_Start(XLlTemac *InstancePtr);
+void XLlTemac_Stop(XLlTemac *InstancePtr);
+void XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction);
+
+/*
+ * Initialization functions in xlltemac_sinit.c
+ */
+XLlTemac_Config *XLlTemac_LookupConfig(u16 DeviceId);
+
+/*
+ * MAC configuration/control functions in xlltemac_control.c
+ */
+int XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options);
+int XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options);
+u32 XLlTemac_GetOptions(XLlTemac *InstancePtr);
+
+int XLlTemac_SetMacAddress(XLlTemac *InstancePtr, void *AddressPtr);
+void XLlTemac_GetMacAddress(XLlTemac *InstancePtr, void *AddressPtr);
+
+int XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr);
+void XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr);
+int XLlTemac_SendPausePacket(XLlTemac *InstancePtr, u16 PauseValue);
+
+int XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr);
+int XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr,
+			    int *IsFullDuplexPtr, int *IsLinkUpPtr);
+u16 XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr);
+void XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed);
+
+void XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor);
+void XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress, u32 RegisterNum,
+		      u16 *PhyDataPtr);
+void XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress, u32 RegisterNum,
+		       u16 PhyData);
+int XLlTemac_MulticastAdd(XLlTemac *InstancePtr, void *AddressPtr, int Entry);
+void XLlTemac_MulticastGet(XLlTemac *InstancePtr, void *AddressPtr, int Entry);
+int XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_hw.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_hw.h	2014-07-20 22:06:37.216291532 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* iId: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac_hw.h
+ *
+ * This header file contains identifiers and low-level driver functions (or
+ * macros) that can be used to access the Tri-Mode MAC Ethernet (TEMAC) device.
+ * High-level driver functions are defined in xlltemac.h.
+ *
+ * @note
+ *
+ * Some registers are not accessible when a HW instance is configured for SGDMA.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  11/10/06 First release
+ * </pre>
+ *
+ ******************************************************************************/
+
+#ifndef XTEMAC_HW_H		/* prevent circular inclusions */
+#define XTEMAC_HW_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xdebug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************** Constant Definitions *****************************/
+
+#define XTE_RESET_HARD_DELAY_US 4    /**< Us to delay for hard core reset */
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name Direct registers
+ *  @{
+ */
+#define XTE_RAF_OFFSET  0x00000000  /**< Reset and address filter */
+#define XTE_TPF_OFFSET  0x00000004  /**< Transmit pause frame */
+#define XTE_IFGP_OFFSET 0x00000008  /**< Transmit inter-frame gap adjustment */
+#define XTE_IS_OFFSET   0x0000000C  /**< Interrupt status */
+#define XTE_IP_OFFSET   0x00000010  /**< Interrupt pending */
+#define XTE_IE_OFFSET   0x00000014  /**< Interrupt enable */
+
+#define XTE_MSW_OFFSET  0x00000020  /**< Most significant word data */
+#define XTE_LSW_OFFSET  0x00000024  /**< Least significant word data */
+#define XTE_CTL_OFFSET  0x00000028  /**< Control */
+#define XTE_RDY_OFFSET  0x0000002C  /**< Ready status */
+/*@}*/
+
+
+/** @name HARD_TEMAC Core Registers
+ * These are registers defined within the device's hard core located in the
+ * processor block. They are accessed indirectly through the registers, MSW,
+ * LSW, and CTL.
+ *
+ * Access to these registers should go through macros XLlTemac_ReadIndirectReg()
+ * and XLlTemac_WriteIndirectReg() to guarantee proper access.
+ * @{
+ */
+#define XTE_RCW0_OFFSET         0x00000200  /**< Rx configuration word 0 */
+#define XTE_RCW1_OFFSET         0x00000240  /**< Rx configuration word 1 */
+#define XTE_TC_OFFSET           0x00000280  /**< Tx configuration */
+#define XTE_FCC_OFFSET          0x000002C0  /**< Flow control configuration */
+#define XTE_EMMC_OFFSET         0x00000300  /**< EMAC mode configuration */
+#define XTE_PHYC_OFFSET         0x00000320  /**< RGMII/SGMII configuration */
+#define XTE_MC_OFFSET           0x00000340  /**< Management configuration */
+#define XTE_UAW0_OFFSET         0x00000380  /**< Unicast address word 0 */
+#define XTE_UAW1_OFFSET         0x00000384  /**< Unicast address word 1 */
+#define XTE_MAW0_OFFSET         0x00000388  /**< Multicast address word 0 */
+#define XTE_MAW1_OFFSET         0x0000038C  /**< Multicast address word 1 */
+#define XTE_AFM_OFFSET          0x00000390  /**< Address Filter (promiscuous) mode */
+#define XTE_TIS_OFFSET          0x000003A0  /**< Interrupt status */
+#define XTE_TIE_OFFSET          0x000003A4  /**< Interrupt enable */
+#define XTE_MIIMWD_OFFSET       0x000003B0  /**< MII management write data */
+#define XTE_MIIMAI_OFFSET       0x000003B4  /**< MII management access initiate */
+/*@}*/
+
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+/** @name Reset and Address Filter bits
+ *  These bits are associated with the XTE_RAF_OFFSET register.
+ * @{
+ */
+#define XTE_RAF_HTRST_MASK       0x00000001 /**< Hard TEMAC Reset */
+#define XTE_RAF_MCSTREJ_MASK     0x00000002 /**< Reject receive multicast destination address */
+#define XTE_RAF_BCSTREJ_MASK     0x00000004 /**< Reject receive broadcast destination address */
+/*@}*/
+
+/** @name Transmit Pause Frame Register (TPF)
+ *  @{
+ */
+#define XTE_TPF_TPFV_MASK        0x0000FFFF   /**< Tx pause frame value */
+/*@}*/
+
+/** @name Transmit Inter-Frame Gap Adjustement Register (TFGP)
+ *  @{
+ */
+#define XTE_TFGP_IFGP_MASK       0x0000007F   /**< Transmit inter-frame gap adjustment value */
+/*@}*/
+
+/** @name Interrupt bits
+ *  These bits are associated with the XTE_IS_OFFSET, XTE_IP_OFFSET, and
+ *  XTE_IE_OFFSET registers.
+ * @{
+ */
+#define XTE_INT_HARDACSCMPLT_MASK 0x00000001 /**< Hard register access complete */
+#define XTE_INT_AUTONEG_MASK      0x00000002 /**< Auto negotiation complete */
+#define XTE_INT_RC_MASK           0x00000004 /**< Receive complete */
+#define XTE_INT_RXRJECT_MASK      0x00000008 /**< Receive frame rejected */
+#define XTE_INT_RXFIFOOVR_MASK    0x00000010 /**< Receive fifo overrun */
+#define XTE_INT_TC_MASK           0x00000020 /**< Transmit complete */
+#define XTE_INT_ALL_MASK          0x0000003f /**< All the ints */
+/*@}*/
+
+
+#define XTE_INT_RECV_ERROR_MASK \
+    (XTE_INT_RXRJECT_MASK | XTE_INT_RXFIFOOVR_MASK) /**< INT bits that indicate receive errors */
+/*@}*/
+
+
+/** @name Control Register (CTL)
+ *  @{
+ */
+#define XTE_CTL_WEN_MASK          0x00008000   /**< Write Enable */
+/*@}*/
+
+
+/** @name Ready Status, TEMAC Interrupt Status, TEMAC Interrupt Enable Registers
+ * (RDY, TIS, TIE)
+ *  @{
+ */
+#define XTE_RSE_FABR_RR_MASK      0x00000001   /**< Fabric read ready */
+#define XTE_RSE_MIIM_RR_MASK      0x00000002   /**< MII management read ready */
+#define XTE_RSE_MIIM_WR_MASK      0x00000004   /**< MII management write ready */
+#define XTE_RSE_AF_RR_MASK        0x00000008   /**< Address filter read ready*/
+#define XTE_RSE_AF_WR_MASK        0x00000010   /**< Address filter write ready*/
+#define XTE_RSE_CFG_RR_MASK       0x00000020   /**< Configuration register read ready*/
+#define XTE_RSE_CFG_WR_MASK       0x00000040   /**< Configuration register write ready*/
+#define XTE_RDY_HARD_ACS_RDY_MASK 0x00010000   /**< Hard register access ready */
+#define XTE_RDY_ALL               (XTE_RSE_FABR_RR_MASK | \
+                                   XTE_RSE_MIIM_RR_MASK | \
+                                   XTE_RSE_MIIM_WR_MASK | \
+                                   XTE_RSE_AF_RR_MASK | \
+                                   XTE_RSE_AF_WR_MASK | \
+                                   XTE_RSE_CFG_RR_MASK | \
+                                   XTE_RSE_CFG_WR_MASK | \
+                                   XTE_RDY_HARD_ACS_RDY_MASK)
+/*@}*/
+
+
+/** @name Receive Configuration Word 1 (RCW1)
+ *  @{
+ */
+#define XTE_RCW1_RST_MASK         0x80000000   /**< Reset */
+#define XTE_RCW1_JUM_MASK         0x40000000   /**< Jumbo frame enable */
+#define XTE_RCW1_FCS_MASK         0x20000000   /**< In-Band FCS enable (FCS not stripped) */
+#define XTE_RCW1_RX_MASK          0x10000000   /**< Receiver enable */
+#define XTE_RCW1_VLAN_MASK        0x08000000   /**< VLAN frame enable */
+#define XTE_RCW1_HD_MASK          0x04000000   /**< Half duplex mode */
+#define XTE_RCW1_LT_DIS_MASK      0x02000000   /**< Length/type field valid check disable */
+#define XTE_RCW1_PAUSEADDR_MASK   0x0000FFFF   /**< Pause frame source address
+                                                    bits [47:32]. Bits [31:0]
+                                                    are stored in register
+                                                    RCW0 */
+/*@}*/
+
+
+/** @name Transmitter Configuration (TC)
+ *  @{
+ */
+#define XTE_TC_RST_MASK           0x80000000   /**< reset */
+#define XTE_TC_JUM_MASK           0x40000000   /**< Jumbo frame enable */
+#define XTE_TC_FCS_MASK           0x20000000   /**< In-Band FCS enable (FCS not generated) */
+#define XTE_TC_TX_MASK            0x10000000   /**< Transmitter enable */
+#define XTE_TC_VLAN_MASK          0x08000000   /**< VLAN frame enable */
+#define XTE_TC_HD_MASK            0x04000000   /**< Half duplex mode */
+#define XTE_TC_IFG_MASK           0x02000000   /**< Inter-frame gap adjustment enable */
+/*@}*/
+
+
+/** @name Flow Control Configuration (FCC)
+ *  @{
+ */
+#define XTE_FCC_FCRX_MASK         0x20000000   /**< Rx flow control enable */
+#define XTE_FCC_FCTX_MASK         0x40000000   /**< Tx flow control enable */
+/*@}*/
+
+
+/** @name EMAC Configuration (EMMC)
+ * @{
+ */
+#define XTE_EMMC_LINKSPEED_MASK   0xC0000000  /**< Link speed */
+#define XTE_EMMC_RGMII_MASK       0x20000000  /**< RGMII mode enable */
+#define XTE_EMMC_SGMII_MASK       0x10000000  /**< SGMII mode enable */
+#define XTE_EMMC_GPCS_MASK        0x08000000  /**< 1000BaseX mode enable */
+#define XTE_EMMC_HOST_MASK        0x04000000  /**< Host interface enable */
+#define XTE_EMMC_TX16BIT          0x02000000  /**< 16 bit Tx client enable */
+#define XTE_EMMC_RX16BIT          0x01000000  /**< 16 bit Rx client enable */
+
+#define XTE_EMMC_LINKSPD_10       0x00000000   /**< XTE_EMCFG_LINKSPD_MASK for
+                                                     10 Mbit */
+#define XTE_EMMC_LINKSPD_100      0x40000000   /**< XTE_EMCFG_LINKSPD_MASK for
+                                                     100 Mbit */
+#define XTE_EMMC_LINKSPD_1000     0x80000000   /**< XTE_EMCFG_LINKSPD_MASK for
+                                                     1000 Mbit */
+/*@}*/
+
+
+/** @name EMAC RGMII/SGMII Configuration (PHYC)
+ * @{
+ */
+#define XTE_PHYC_SGMIILINKSPEED_MASK 0xC0000000	  /**< SGMII link speed */
+#define XTE_PHYC_RGMIILINKSPEED_MASK 0x0000000C	  /**< RGMII link speed */
+#define XTE_PHYC_RGMIIHD_MASK        0x00000002	  /**< RGMII Half-duplex mode */
+#define XTE_PHYC_RGMIILINK_MASK      0x00000001	  /**< RGMII link status */
+
+#define XTE_PHYC_RGLINKSPD_10        0x00000000	  /**< XTE_GMIC_RGLINKSPD_MASK
+                                                       for 10 Mbit */
+#define XTE_PHYC_RGLINKSPD_100       0x00000004	  /**< XTE_GMIC_RGLINKSPD_MASK
+                                                       for 100 Mbit */
+#define XTE_PHYC_RGLINKSPD_1000      0x00000008	  /**< XTE_GMIC_RGLINKSPD_MASK
+                                                       for 1000 Mbit */
+#define XTE_PHYC_SGLINKSPD_10        0x00000000	  /**< XTE_SGMIC_RGLINKSPD_MASK
+                                                       for 10 Mbit */
+#define XTE_PHYC_SGLINKSPD_100       0x40000000	  /**< XTE_SGMIC_RGLINKSPD_MASK
+                                                       for 100 Mbit */
+#define XTE_PHYC_SGLINKSPD_1000      0x80000000	  /**< XTE_SGMIC_RGLINKSPD_MASK
+                                                       for 1000 Mbit */
+/*@}*/
+
+
+/** @name EMAC Management Configuration (MC)
+ * @{
+ */
+#define XTE_MC_MDIOEN_MASK        0x00000040   /**< MII management enable */
+#define XTE_MC_CLOCK_DIVIDE_MAX   0x3F	       /**< Maximum MDIO divisor */
+/*@}*/
+
+
+/** @name EMAC Unicast Address Register Word 1 (UAW1)
+ * @{
+ */
+#define XTE_UAW1_UNICASTADDR_MASK 0x0000FFFF   /**< Station address bits [47:32]
+                                                    Station address bits [31:0]
+                                                    are stored in register
+                                                    UAW0 */
+/*@}*/
+
+
+/** @name EMAC Multicast Address Register Word 1 (MAW1)
+ * @{
+ */
+#define XTE_MAW1_RNW_MASK         0x00800000   /**< Multicast address table register read enable */
+#define XTE_MAW1_ADDR_MASK        0x00030000   /**< Multicast address table register address */
+#define XTE_MAW1_MULTICADDR_MASK  0x0000FFFF   /**< Multicast address bits [47:32]
+                                                    Multicast address bits [31:0]
+                                                    are stored in register
+                                                    MAW0 */
+#define XTE_MAW1_MATADDR_SHIFT_MASK 16	       /**< Number of bits to shift right
+                                                    to align with
+                                                    XTE_MAW1_CAMADDR_MASK */
+/*@}*/
+
+
+/** @name EMAC Address Filter Mode (AFM)
+ * @{
+ */
+#define XTE_AFM_PM_MASK           0x80000000   /**< Promiscuous mode enable */
+/*@}*/
+
+
+/** @name Media Independent Interface Management (MIIM)
+ * @{
+ */
+#define XTE_MIIM_REGAD_MASK     0x1F	/**< MII Phy register address (REGAD) */
+#define XTE_MIIM_PHYAD_MASK     0x03E0	/**< MII Phy address (PHYAD) */
+#define XTE_MIIM_PHYAD_SHIFT    5	/**< MII Shift bits for PHYAD */
+/*@}*/
+
+
+/** @name Checksum offload buffer descriptor extensions
+ * @{
+ */
+/** Byte offset where checksum should begin (16 bit word) */
+#define XTE_BD_TX_CSBEGIN_OFFSET  XDMAV3_BD_USR0_OFFSET
+
+/** Offset where checksum should be inserted (16 bit word) */
+#define XTE_BD_TX_CSINSERT_OFFSET (XDMAV3_BD_USR0_OFFSET + 2)
+
+/** Checksum offload control for transmit (16 bit word) */
+#define XTE_BD_TX_CSCNTRL_OFFSET  XDMAV3_BD_USR1_OFFSET
+
+/** Seed value for checksum calculation (16 bit word) */
+#define XTE_BD_TX_CSINIT_OFFSET   (XDMAV3_BD_USR1_OFFSET + 2)
+
+/** Receive frame checksum calculation (16 bit word) */
+#define XTE_BD_RX_CSRAW_OFFSET    (XDMAV3_BD_USR5_OFFSET + 2)
+
+/*@}*/
+
+/** @name TX_CSCNTRL bit mask
+ * @{
+ */
+#define XTE_BD_TX_CSCNTRL_CALC_MASK  0x0001  /**< Enable/disable Tx
+                                                  checksum */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+xdbg_stmnt(extern int indent_on);
+
+#define XLlTemac_indent(RegOffset) \
+ ((indent_on && ((RegOffset) >= XTE_RAF_OFFSET) && ((RegOffset) <= XTE_RDY_OFFSET)) ? "\t" : "")
+
+#define XLlTemac_reg_name(RegOffset) \
+	(((RegOffset) == XTE_RAF_OFFSET) ? "XTE_RAF_OFFSET": \
+	((RegOffset) == XTE_TPF_OFFSET) ? "XTE_TPF_OFFSET": \
+	((RegOffset) == XTE_IFGP_OFFSET) ? "XTE_IFGP_OFFSET": \
+	((RegOffset) == XTE_IS_OFFSET) ? "XTE_IS_OFFSET": \
+	((RegOffset) == XTE_IP_OFFSET) ? "XTE_IP_OFFSET": \
+	((RegOffset) == XTE_IE_OFFSET) ? "XTE_IE_OFFSET": \
+	((RegOffset) == XTE_MSW_OFFSET) ? "XTE_MSW_OFFSET": \
+	((RegOffset) == XTE_LSW_OFFSET) ? "XTE_LSW_OFFSET": \
+	((RegOffset) == XTE_CTL_OFFSET) ? "XTE_CTL_OFFSET": \
+	((RegOffset) == XTE_RDY_OFFSET) ? "XTE_RDY_OFFSET": \
+	((RegOffset) == XTE_RCW0_OFFSET) ? "XTE_RCW0_OFFSET": \
+	((RegOffset) == XTE_RCW1_OFFSET) ? "XTE_RCW1_OFFSET": \
+	((RegOffset) == XTE_TC_OFFSET) ? "XTE_TC_OFFSET": \
+	((RegOffset) == XTE_FCC_OFFSET) ? "XTE_FCC_OFFSET": \
+	((RegOffset) == XTE_EMMC_OFFSET) ? "XTE_EMMC_OFFSET": \
+	((RegOffset) == XTE_PHYC_OFFSET) ? "XTE_PHYC_OFFSET": \
+	((RegOffset) == XTE_MC_OFFSET) ? "XTE_MC_OFFSET": \
+	((RegOffset) == XTE_UAW0_OFFSET) ? "XTE_UAW0_OFFSET": \
+	((RegOffset) == XTE_UAW1_OFFSET) ? "XTE_UAW1_OFFSET": \
+	((RegOffset) == XTE_MAW0_OFFSET) ? "XTE_MAW0_OFFSET": \
+	((RegOffset) == XTE_MAW1_OFFSET) ? "XTE_MAW1_OFFSET": \
+	((RegOffset) == XTE_AFM_OFFSET) ? "XTE_AFM_OFFSET": \
+	((RegOffset) == XTE_TIS_OFFSET) ? "XTE_TIS_OFFSET": \
+	((RegOffset) == XTE_TIE_OFFSET) ? "XTE_TIE_OFFSET": \
+	((RegOffset) == XTE_MIIMWD_OFFSET) ? "XTE_MIIMWD_OFFSET": \
+	((RegOffset) == XTE_MIIMAI_OFFSET) ? "XTE_MIIMAI_OFFSET": \
+	"unknown")
+
+#define XLlTemac_print_reg_o(BaseAddress, RegOffset, Value) \
+	xdbg_printf(XDBG_DEBUG_TEMAC_REG, "%s0x%0x -> %s(0x%0x)\n", \
+			XLlTemac_indent(RegOffset), (Value), \
+			XLlTemac_reg_name(RegOffset), (RegOffset)) \
+
+#define XLlTemac_print_reg_i(BaseAddress, RegOffset, Value) \
+	xdbg_printf(XDBG_DEBUG_TEMAC_REG, "%s%s(0x%0x) -> 0x%0x\n", \
+			XLlTemac_indent(RegOffset), XLlTemac_reg_name(RegOffset), \
+			(RegOffset), (Value)) \
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_ReadReg returns the value read from the register specified by
+ * <i>RegOffset</i>.
+ *
+ * @param    BaseAddress is the base address of the TEMAC channel.
+ * @param    RegOffset is the offset of the register to be read.
+ *
+ * @return   XLlTemac_ReadReg returns the 32-bit value of the register.
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlTemac_mReadReg(u32 BaseAddress, u32 RegOffset)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_ReadReg(BaseAddress, RegOffset) \
+({ \
+	u32 value; \
+	if ((RegOffset) > 0x2c) { \
+		printf ("readreg: Woah! wrong reg addr: 0x%0x\n", (RegOffset)); \
+	} \
+	value = XIo_In32(((BaseAddress) + (RegOffset))); \
+	XLlTemac_print_reg_i((BaseAddress), (RegOffset), value); \
+	value; \
+})
+#else
+#define XLlTemac_ReadReg(BaseAddress, RegOffset) \
+	(XIo_In32(((BaseAddress) + (RegOffset))))
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_WriteReg, writes <i>Data</i> to the register specified by
+ * <i>RegOffset</i>.
+ *
+ * @param    BaseAddress is the base address of the TEMAC channel.
+ * @param    RegOffset is the offset of the register to be written.
+ * @param    Data is the 32-bit value to write to the register.
+ *
+ * @return   N/A
+ *
+ * @note
+ * C-style signature:
+ *    void XLlTemac_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_WriteReg(BaseAddress, RegOffset, Data) \
+({ \
+	if ((RegOffset) > 0x2c) { \
+		printf ("writereg: Woah! wrong reg addr: 0x%0x\n", (RegOffset)); \
+	} \
+	XLlTemac_print_reg_o((BaseAddress), (RegOffset), (Data)); \
+	XIo_Out32(((BaseAddress) + (RegOffset)), (Data)); \
+})
+#else
+#define XLlTemac_WriteReg(BaseAddress, RegOffset, Data) \
+	XIo_Out32(((BaseAddress) + (RegOffset)), (Data))
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_ReadIndirectReg returns the value read from the hard TEMAC register
+ * specified by <i>RegOffset</i>.
+ *
+ * @param    BaseAddress is the base address of the TEMAC channel.
+ * @param    RegOffset is the offset of the hard TEMAC register to be read.
+ *
+ * @return   XLlTemac_ReadIndirectReg returns the 32-bit value of the register.
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlTemac_mReadIndirectReg(u32 BaseAddress, u32 RegOffset)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+extern u32 _xlltemac_rir_value;
+
+#define XLlTemac_ReadIndirectReg(BaseAddress, RegOffset) \
+( \
+	indent_on = 1, \
+	(((RegOffset) < 0x200) ? \
+		xdbg_printf(XDBG_DEBUG_ERROR, \
+			"readindirect: Woah! wrong reg addr: 0x%0x\n", \
+			(RegOffset)) : 0), \
+	(((RegOffset) > 0x3b4) ? \
+		xdbg_printf(XDBG_DEBUG_ERROR, \
+			"readindirect: Woah! wrong reg addr: 0x%0x\n", \
+			(RegOffset)) : 0), \
+	XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, (RegOffset)), \
+	_xlltemac_rir_value = XLlTemac_ReadReg((BaseAddress), XTE_LSW_OFFSET), \
+	XLlTemac_print_reg_i((BaseAddress), (RegOffset), _xlltemac_rir_value), \
+	indent_on = 0, \
+	_xlltemac_rir_value \
+)
+#else
+#define XLlTemac_ReadIndirectReg(BaseAddress, RegOffset) \
+( \
+	XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, (RegOffset)), \
+	XLlTemac_ReadReg((BaseAddress), XTE_LSW_OFFSET) \
+)
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_WriteIndirectReg, writes <i>Data</i> to the hard TEMAC register
+ * specified by <i>RegOffset</i>.
+ *
+ * @param    BaseAddress is the base address of the TEMAC channel.
+ * @param    RegOffset is the offset of the hard TEMAC register to be written.
+ * @param    Data is the 32-bit value to write to the register.
+ *
+ * @return   N/A
+ *
+ * @note
+ * C-style signature:
+ *    void XLlTemac_WriteIndirectReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_WriteIndirectReg(BaseAddress, RegOffset, Data) \
+( \
+	indent_on = 1, \
+	(((RegOffset) < 0x200) ? \
+		xdbg_printf(XDBG_DEBUG_ERROR, \
+			"readindirect: Woah! wrong reg addr: 0x%0x\n", \
+			(RegOffset)) : 0), \
+	(((RegOffset) > 0x3b4) ? \
+		xdbg_printf(XDBG_DEBUG_ERROR, \
+			"readindirect: Woah! wrong reg addr: 0x%0x\n", \
+			(RegOffset)) : 0), \
+	XLlTemac_print_reg_o((BaseAddress), (RegOffset), (Data)), \
+	XLlTemac_WriteReg((BaseAddress), XTE_LSW_OFFSET, (Data)), \
+	XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, \
+		((RegOffset) | XTE_CTL_WEN_MASK)), \
+	((XLlTemac_ReadReg((BaseAddress), XTE_RDY_OFFSET) & \
+			XTE_RDY_HARD_ACS_RDY_MASK) ? \
+		((XLlTemac_ReadIndirectReg((BaseAddress), (RegOffset)) != (Data)) ? \
+			xdbg_printf(XDBG_DEBUG_ERROR, \
+				"data written is not read back: Reg: 0x%0x\n", \
+				(RegOffset)) \
+			: 0) \
+		: xdbg_printf(XDBG_DEBUG_ERROR, "(temac_wi) RDY reg not initially ready\n")), \
+	indent_on = 0 \
+)
+#else
+#define XLlTemac_WriteIndirectReg(BaseAddress, RegOffset, Data) \
+	XLlTemac_WriteReg((BaseAddress), XTE_LSW_OFFSET, (Data)), \
+	XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, \
+		((RegOffset) | XTE_CTL_WEN_MASK))
+#endif
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_main.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/net/ethernet/xilinx/xilinx_lltemac/xlltemac_main.c	2014-07-20 22:06:37.256290873 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Ethernet: Linux driver for the XPS_LLTEMAC core.
+ *
+ * Author: Xilinx, Inc.
+ *
+ * 2006-2007 (c) Xilinx, Inc. This file is licensed uner the terms of the GNU
+ * General Public License version 2.1. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  05/08/05 First release
+ * </pre>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <asm/io.h>
+#include <linux/ethtool.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_OF
+// For open firmware.
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_net.h>
+#endif
+
+#include "xbasic_types.h"
+#include "xlltemac.h"
+#include "xllfifo.h"
+#include "xlldma.h"
+#include "xlldma_bdring.h"
+
+#define LOCAL_FEATURE_RX_CSUM   0x01
+
+/*
+ * Default SEND and RECV buffer descriptors (BD) numbers.
+ * BD Space needed is (XTE_SEND_BD_CNT+XTE_RECV_BD_CNT)*Sizeof(XLlDma_Bd).
+ * Each XLlDma_Bd instance currently takes 40 bytes.
+ */
+#define XTE_SEND_BD_CNT 256
+#define XTE_RECV_BD_CNT 256
+
+/* Must be shorter than length of ethtool_drvinfo.driver field to fit */
+#define DRIVER_NAME         "xilinx_lltemac"
+#define DRIVER_DESCRIPTION  "Xilinx Tri-Mode Ethernet MAC driver"
+#define DRIVER_VERSION      "1.00a"
+
+#define TX_TIMEOUT   (3*HZ)	/* Transmission timeout is 3 seconds. */
+
+/*
+ * This version of the Xilinx TEMAC uses external DMA or FIFO cores.
+ * Currently neither the DMA or FIFO cores used require any memory alignment
+ * restrictions.
+ */
+/*
+ * ALIGNMENT_RECV = the alignement required to receive
+ * ALIGNMENT_SEND = the alignement required to send
+ * ALIGNMENT_SEND_PERF = tx alignment for better performance
+ *
+ * ALIGNMENT_SEND is used to see if we *need* to copy the data to re-align.
+ * ALIGNMENT_SEND_PERF is used if we've decided we need to copy anyway, we just
+ * copy to this alignment for better performance.
+ */
+
+#define ALIGNMENT_RECV          34
+#define ALIGNMENT_SEND          8
+#define ALIGNMENT_SEND_PERF     32
+
+#define XTE_SEND  1
+#define XTE_RECV  2
+
+/* SGDMA buffer descriptors must be aligned on a 8-byte boundary. */
+#define ALIGNMENT_BD            XLLDMA_BD_MINIMUM_ALIGNMENT
+
+/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
+#define BUFFER_ALIGNSEND(adr) ((ALIGNMENT_SEND - ((u32) adr)) % ALIGNMENT_SEND)
+#define BUFFER_ALIGNSEND_PERF(adr) ((ALIGNMENT_SEND_PERF - ((u32) adr)) % 32)
+#define BUFFER_ALIGNRECV(adr) ((ALIGNMENT_RECV - ((u32) adr)) % 32)
+
+/* Default TX/RX Threshold and waitbound values for SGDMA mode */
+#define DFT_TX_THRESHOLD  24
+#define DFT_TX_WAITBOUND  254
+#define DFT_RX_THRESHOLD  4
+#define DFT_RX_WAITBOUND  254
+
+#define XTE_AUTOSTRIPPING 1
+
+/* Put Buffer Descriptors in BRAM?
+ * NOTE:
+ *   Putting BDs in BRAM only works if there is only ONE instance of the TEMAC
+ *   in hardware.  The code does not handle multiple instances, e.g. it does
+ *   not manage the memory in BRAM.
+ */
+#define BD_IN_BRAM        0
+#define BRAM_BASEADDR     0xffff8000
+
+
+/*
+ * Checksum offload macros
+ */
+#define BdCsumEnable(BdPtr) \
+	XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET,             \
+		(XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) | 1 )
+
+/* Used for debugging */
+#define BdCsumEnabled(BdPtr) \
+	((XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) & 1)
+
+#define BdCsumDisable(BdPtr) \
+	XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET,             \
+		(XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) & 0xFFFFFFFE )
+
+#define BdCsumSetup(BdPtr, Start, Insert) \
+    XLlDma_mBdWrite((BdPtr), XLLDMA_BD_USR1_OFFSET, ((Start) << 16) | (Insert))
+
+/* Used for debugging */
+#define BdCsumInsert(BdPtr) \
+    (XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR1_OFFSET) & 0xffff)
+
+#define BdCsumSeed(BdPtr, Seed) \
+    XLlDma_mBdWrite((BdPtr), XLLDMA_BD_USR2_OFFSET, 0)
+
+#define BdCsumGet(BdPtr) \
+    (XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR3_OFFSET) & 0xffff)
+
+#define BdGetRxLen(BdPtr) \
+    (XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR4_OFFSET) & 0x3fff)
+
+/* LLTEMAC platform data */
+struct xlltemac_platform_data {
+	u8 tx_csum;
+	u8 rx_csum;
+	u8 phy_type;
+	u8 dcr_host;
+	u8 ll_dev_type;
+	u32 ll_dev_baseaddress;
+	u32 ll_dev_dma_rx_irq;
+	u32 ll_dev_dma_tx_irq;
+	u32 ll_dev_fifo_irq;
+
+	u8 mac_addr[6];
+};
+
+/*
+ * Our private per device data.  When a net_device is allocated we will
+ * ask for enough extra space for this.
+ */
+struct net_local {
+	struct list_head rcv;
+	struct list_head xmit;
+
+	struct net_device *ndev;	/* this device */
+	struct net_device *next_dev;	/* The next device in dev_list */
+	struct net_device_stats stats;	/* Statistics for this device */
+	struct timer_list phy_timer;	/* PHY monitoring timer */
+
+	u32 index;		/* Which interface is this */
+#if 0
+	XInterruptHandler Isr;	/* Pointer to the XLlTemac ISR routine */
+#endif
+	u8 gmii_addr;		/* The GMII address of the PHY */
+	u32 virt_dma_addr;	/* Virtual address to mapped dma */
+
+	/* The underlying OS independent code needs space as well.  A
+	 * pointer to the following XLlTemac structure will be passed to
+	 * any XLlTemac_ function that requires it.  However, we treat the
+	 * data as an opaque object in this file (meaning that we never
+	 * reference any of the fields inside of the structure). */
+	XLlFifo Fifo;
+	XLlDma Dma;
+	XLlTemac Emac;
+
+	unsigned int fifo_irq;	/* fifo irq */
+	unsigned int dma_irq_s;	/* send irq */
+	unsigned int dma_irq_r;	/* recv irq */
+	unsigned int frame_size; /* actual frame size = mtu + padding */
+
+	int cur_speed;
+
+	/* Buffer Descriptor space for both TX and RX BD ring */
+	void *desc_space;	/* virtual address of BD space */
+	dma_addr_t desc_space_handle;	/* physical address of BD space */
+	int desc_space_size;	/* size of BD space */
+
+	/* buffer for one skb in case no room is available for transmission */
+	struct sk_buff *deferred_skb;
+
+	/* send buffers for non tx-dre hw */
+	void **tx_orig_buffers;	/* Buffer addresses as returned by
+				   dma_alloc_coherent() */
+	void **tx_buffers;	/* Buffers addresses aligned for DMA */
+	dma_addr_t *tx_phys_buffers;	/* Buffer addresses in physical memory */
+	size_t tx_buffers_cur;	/* Index of current buffer used */
+
+	/* stats */
+	int max_frags_in_a_packet;
+	unsigned long realignments;
+	unsigned long tx_hw_csums;
+	unsigned long rx_hw_csums;
+	unsigned long local_features;
+#if ! XTE_AUTOSTRIPPING
+	unsigned long stripping;
+#endif
+};
+
+static u32 dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK;
+static u32 dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK;
+
+/* for exclusion of all program flows (processes, ISRs and BHs) */
+static spinlock_t XTE_spinlock; /* = SPIN_LOCK_UNLOCKED; */
+static spinlock_t XTE_tx_spinlock; /* = SPIN_LOCK_UNLOCKED; */
+static spinlock_t XTE_rx_spinlock; /* = SPIN_LOCK_UNLOCKED; */
+
+/*
+ * ethtool has a status reporting feature where we can report any sort of
+ * status information we'd like. This is the list of strings used for that
+ * status reporting. ETH_GSTRING_LEN is defined in ethtool.h
+ */
+static char xenet_ethtool_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"txpkts", "txdropped", "txerr", "txfifoerr",
+	"rxpkts", "rxdropped", "rxerr", "rxfifoerr",
+	"rxrejerr", "max_frags", "tx_hw_csums", "rx_hw_csums",
+};
+
+#define XENET_STATS_LEN sizeof(xenet_ethtool_gstrings_stats) / ETH_GSTRING_LEN
+
+/* Helper function to determine if a given XLlTemac error warrants a reset. */
+extern inline int status_requires_reset(int s)
+{
+	return (s == XST_FIFO_ERROR ||
+		s == XST_PFIFO_DEADLOCK ||
+		s == XST_DMA_ERROR || s == XST_IPIF_ERROR);
+}
+
+/* Queues with locks */
+static LIST_HEAD(receivedQueue);
+static spinlock_t receivedQueueSpin; // = SPIN_LOCK_UNLOCKED;
+
+static LIST_HEAD(sentQueue);
+static spinlock_t sentQueueSpin; // = SPIN_LOCK_UNLOCKED;
+
+
+/* from mii.h
+ *
+ * Items in mii.h but not in gmii.h
+ */
+#define ADVERTISE_100FULL       0x0100
+#define ADVERTISE_100HALF       0x0080
+#define ADVERTISE_10FULL        0x0040
+#define ADVERTISE_10HALF        0x0020
+#define ADVERTISE_CSMA          0x0001
+
+#define EX_ADVERTISE_1000FULL   0x0200
+#define EX_ADVERTISE_1000HALF   0x0100
+
+/*
+ * items not in mii.h nor gmii.h but should be
+ */
+#define MII_EXADVERTISE 0x09
+
+/*
+ * Wrap certain temac routines with a lock, so access to the shared hard temac
+ * interface is accessed mutually exclusive for dual channel temac support.
+ */
+
+static inline void _XLlTemac_Start(XLlTemac *InstancePtr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_Start(InstancePtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_Stop(XLlTemac *InstancePtr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_Stop(InstancePtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_Reset(InstancePtr, HardCoreAction);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_SetMacAddress(XLlTemac *InstancePtr,
+					  void *AddressPtr)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_SetMacAddress(InstancePtr, AddressPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline void _XLlTemac_GetMacAddress(XLlTemac *InstancePtr,
+					   void *AddressPtr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_GetMacAddress(InstancePtr, AddressPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_SetOptions(InstancePtr, Options);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline int _XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_ClearOptions(InstancePtr, Options);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline u16 _XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr)
+{
+	u16 speed;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	speed = XLlTemac_GetOperatingSpeed(InstancePtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return speed;
+}
+
+static inline void _XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_SetOperatingSpeed(InstancePtr, Speed);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	/* We need a delay after we set the speed. Otherwise the PHY will not be ready. */
+	udelay(10000);
+}
+
+static inline void _XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_PhySetMdioDivisor(InstancePtr, Divisor);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress,
+				     u32 RegisterNum, u16 *PhyDataPtr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_PhyRead(InstancePtr, PhyAddress, RegisterNum, PhyDataPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress,
+				      u32 RegisterNum, u16 PhyData)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_PhyWrite(InstancePtr, PhyAddress, RegisterNum, PhyData);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+
+static inline int _XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_MulticastClear(InstancePtr, Entry);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline int _XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_SetMacPauseAddress(InstancePtr, AddressPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline void _XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_GetMacPauseAddress(InstancePtr, AddressPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_GetSgmiiStatus(InstancePtr, SpeedPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+static inline int _XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr,
+					   u16 *SpeedPtr,
+					   int *IsFullDuplexPtr,
+					   int *IsLinkUpPtr)
+{
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	status = XLlTemac_GetRgmiiStatus(InstancePtr, SpeedPtr, IsFullDuplexPtr, IsLinkUpPtr);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+	return status;
+}
+
+
+#ifdef CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII
+#define MARVELL_88E1111_EXTENDED_PHY_CTL_REG_OFFSET  20
+#define MARVELL_88E1111_EXTENDED_PHY_STATUS_REG_OFFSET  27
+#endif
+
+#ifdef CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII
+# define NATIONAL_DP83865_CONTROL_INIT		0x9200
+# define NATIONAL_DP83865_CONTROL		0
+# define NATIONAL_DP83865_STATUS		1
+# define NATIONAL_DP83865_STATUS_LINK		0x04
+# define NATIONAL_DP83865_STATUS_AUTONEGEND	0x20
+# define NATIONAL_DP83865_STATUS_AUTONEG	0x11
+# define NATIONAL_DP83865_LINKSPEED_1000M	0x10
+# define NATIONAL_DP83865_LINKSPEED_100M	0x8
+# define NATIONAL_DP83865_LINKSPEED_MASK	0x18
+# define NATIONAL_DP83865_RETRIES		5
+#endif
+
+#define DEBUG_ERROR KERN_ERR
+#define DEBUG_LOG(level, ...) printk(level __VA_ARGS__)
+
+/*
+ * Perform any necessary special phy setup. In the gmii case, nothing needs to
+ * be done.
+ */
+static void phy_setup(struct net_local *lp)
+{
+#ifdef CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII
+	u16 RegValue;
+
+	printk(KERN_INFO "NATIONAL DP83865 PHY\n");
+	RegValue = NATIONAL_DP83865_CONTROL_INIT;
+	/*Do not reset phy*/
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr,
+		NATIONAL_DP83865_CONTROL, RegValue);
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+		NATIONAL_DP83865_STATUS, &RegValue);
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+		NATIONAL_DP83865_STATUS, &RegValue);
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII
+	u16 Register;
+
+	/*
+	 * Set up MAC interface
+	 *
+	 * Write 0x0cc3 to reg 20 in PHY
+	 *      5432 1098 7654 3210
+	 *      ---- ---- ---- ----
+	 * 0cc3=0000 1100 1100 0011
+	 *           downshift counter (bits 11-9): 110 = 7 times
+	 *              downshift enable (bit 8): 0 = enable
+	 *                RGMII timing control (bit 7): 1 = add delay to rx clk ro rxd
+	 *                outputs
+	 *                 Default Mac interface speed (bits 6-4): 100 = 10mbps 2.5 mhz
+	 *                 (between phy and temac - gets renegotiated)
+	 *                     reserved (bit 3)
+	 *                      DTE detect (bit 2): 0 disabled
+	 *                       RGMII transmit timing control (bit 1): 1 = add delay
+	 *                       to tx clk ro txd outputs
+	 *                        Transmitter Disable (bit 0): 1 = enabled
+	 */
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MARVELL_88E1111_EXTENDED_PHY_CTL_REG_OFFSET, 0x0cc3);
+
+	/*
+	 * Set RGMII to copper with correct hysterisis and correct mode
+	 * Disable fiber/copper auto sel, choose copper
+	 * RGMII /Modified MII to copper mode
+	 *
+	 * Write 0x848b to reg 27
+	 *      5432 1098 7654 3210
+	 *      ---- ---- ---- ----
+	 * 848b=1000 0100 1000 1011
+	 *      Fiber/Copper Auto Selection (bit 15): 1 = disable auto selection
+	 *            Interrupt Polarity (bit 10): 1 = int active low
+	 *              DTE detect status drop hysteresis (bts 8-5): 0100 = report 20s after DTE power status drop
+	 *                     HWCFG mode (bits 3-0): 1011 = RGMII/Modified MII to Copper
+	 */
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MARVELL_88E1111_EXTENDED_PHY_STATUS_REG_OFFSET, 0x848b);
+
+	/*
+	 * Reset the PHY
+	 */
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &Register);
+	Register |= BMCR_RESET;
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, Register);
+
+#endif /* CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_RGMII */
+
+#ifdef CONFIG_XILINX_LLTEMAC_XILINX_1000BASEX
+	u16 Register;
+
+	/*
+	 * Setup the PHY control register
+	 */
+	Register = BMCR_SPEED1000 | BMCR_FULLDPLX | BMCR_ANENABLE;
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, Register);
+
+#endif /* CONFIG_XILINX_LLTEMAC_XILINX_1000BASEX */
+}
+
+
+typedef enum DUPLEX { UNKNOWN_DUPLEX, HALF_DUPLEX, FULL_DUPLEX } DUPLEX;
+
+static int renegotiate_speed(struct net_device *dev, int speed, DUPLEX duplex)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	int retries = 2;
+	int wait_count;
+	u16 phy_reg0 = BMCR_ANENABLE | BMCR_ANRESTART;
+	u16 phy_reg1;
+	u16 phy_reg4;
+	u16 phy_reg9 = 0;
+
+
+	/*
+	 * It appears that the 10baset full and half duplex settings
+	 * are overloaded for gigabit ethernet
+	 */
+	if ((duplex == FULL_DUPLEX) && (speed == 10)) {
+		phy_reg4 = ADVERTISE_10FULL | ADVERTISE_CSMA;
+	}
+	else if ((duplex == FULL_DUPLEX) && (speed == 100)) {
+		phy_reg4 = ADVERTISE_100FULL | ADVERTISE_CSMA;
+	}
+	else if ((duplex == FULL_DUPLEX) && (speed == 1000)) {
+		phy_reg4 = ADVERTISE_CSMA;
+		phy_reg9 = EX_ADVERTISE_1000FULL;
+	}
+	else if (speed == 10) {
+		phy_reg4 = ADVERTISE_10HALF | ADVERTISE_CSMA;
+	}
+	else if (speed == 100) {
+		phy_reg4 = ADVERTISE_100HALF | ADVERTISE_CSMA;
+	}
+	else if (speed == 1000) {
+		phy_reg4 = ADVERTISE_CSMA;
+		phy_reg9 = EX_ADVERTISE_1000HALF;
+	}
+	else {
+		printk(KERN_ERR
+		       "%s: XLlTemac: unsupported speed requested: %d\n",
+		       dev->name, speed);
+		return -1;
+	}
+
+	/*
+	 * link status in register 1:
+	 * first read / second read:
+	 * 0               0           link is down
+	 * 0               1           link is up (but it was down earlier)
+	 * 1               0           link is down (but it was just up)
+	 * 1               1           link is up
+	 *
+	 */
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &phy_reg1);
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &phy_reg1);
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_ADVERTISE, phy_reg4);
+	_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_EXADVERTISE, phy_reg9);
+
+#ifndef CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII
+	while (retries--) {
+		/* initiate an autonegotiation of the speed */
+		_XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, phy_reg0);
+
+		wait_count = 10;	/* so we don't loop forever */
+		while (wait_count--) {
+			/* wait a bit for the negotiation to complete */
+			mdelay(500);
+			_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR,
+					  &phy_reg1);
+			_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR,
+					  &phy_reg1);
+
+			if ((phy_reg1 & BMSR_LSTATUS) &&
+			    (phy_reg1 & BMSR_ANEGCOMPLETE))
+				break;
+
+		}
+
+		if (phy_reg1 & BMSR_LSTATUS) {
+			printk(KERN_INFO
+			       "%s: XLlTemac: We renegotiated the speed to: %d\n",
+			       dev->name, speed);
+			return 0;
+		}
+		else {
+			printk(KERN_ERR
+			       "%s: XLlTemac: Not able to set the speed to %d (status: 0x%0x)\n",
+			       dev->name, speed, phy_reg1);
+			return -1;
+		}
+	}
+
+	printk(KERN_ERR
+	       "%s: XLlTemac: Not able to set the speed to %d\n", dev->name,
+	       speed);
+	return -1;
+#else
+	printk(KERN_INFO
+			       "%s: XLlTemac: We renegotiated the speed to: %d\n",
+			       dev->name, speed);
+	return 0;
+#endif
+}
+
+/*
+ * This function sets up MAC's speed according to link speed of PHY
+ */
+static void set_mac_speed(struct net_local *lp)
+{
+	u16 phylinkspeed;
+	struct net_device *dev = lp->ndev;
+
+#ifdef CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII
+    u16 RegValue;
+    int i;
+
+    for (i = 0; i < NATIONAL_DP83865_RETRIES*10; i++) {
+        _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+                 NATIONAL_DP83865_STATUS, &RegValue);
+        if (RegValue & (NATIONAL_DP83865_STATUS_AUTONEGEND
+                    |NATIONAL_DP83865_STATUS_LINK))
+            break;
+        udelay(1 * 100000);
+    }
+
+    _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+             NATIONAL_DP83865_STATUS_AUTONEG, &RegValue);
+    /* Get current link speed */
+    phylinkspeed = (RegValue & NATIONAL_DP83865_LINKSPEED_MASK);
+
+    /* Update TEMAC speed accordingly */
+    switch (phylinkspeed) {
+    case (NATIONAL_DP83865_LINKSPEED_1000M):
+        _XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+        printk(KERN_INFO "XLlTemac: speed set to 1000Mb/s\n");
+        break;
+    case (NATIONAL_DP83865_LINKSPEED_100M):
+        _XLlTemac_SetOperatingSpeed(&lp->Emac, 100);
+        printk(KERN_INFO "XLlTemac: speed set to 100Mb/s\n");
+        break;
+    default:
+        _XLlTemac_SetOperatingSpeed(&lp->Emac, 10);
+        printk(KERN_INFO "XLlTemac: speed set to 10Mb/s\n");
+        break;
+    }
+
+    return;
+
+#elif CONFIG_XILINX_LLTEMAC_MARVELL_88E1111_GMII
+	/*
+	 * This function is specific to MARVELL 88E1111 PHY chip on
+	 * many Xilinx boards and assumes GMII interface is being used
+	 * by the TEMAC.
+	 */
+
+#define MARVELL_88E1111_PHY_SPECIFIC_STATUS_REG_OFFSET  17
+#define MARVELL_88E1111_LINKSPEED_MARK                  0xC000
+#define MARVELL_88E1111_LINKSPEED_SHIFT                 14
+#define MARVELL_88E1111_LINKSPEED_1000M                 0x0002
+#define MARVELL_88E1111_LINKSPEED_100M                  0x0001
+#define MARVELL_88E1111_LINKSPEED_10M                   0x0000
+	u16 RegValue;
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+			MARVELL_88E1111_PHY_SPECIFIC_STATUS_REG_OFFSET,
+			&RegValue);
+	/* Get current link speed */
+	phylinkspeed = (RegValue & MARVELL_88E1111_LINKSPEED_MARK)
+		>> MARVELL_88E1111_LINKSPEED_SHIFT;
+
+	/* Update TEMAC speed accordingly */
+	switch (phylinkspeed) {
+	case (MARVELL_88E1111_LINKSPEED_1000M):
+		_XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+		printk(KERN_INFO "%s: XLlTemac: speed set to 1000Mb/s\n",
+		       dev->name);
+		lp->cur_speed = 1000;
+		break;
+	case (MARVELL_88E1111_LINKSPEED_100M):
+		_XLlTemac_SetOperatingSpeed(&lp->Emac, 100);
+		printk(KERN_INFO "%s: XLlTemac: speed set to 100Mb/s\n",
+		       dev->name);
+		lp->cur_speed = 100;
+		break;
+	case (MARVELL_88E1111_LINKSPEED_10M):
+		_XLlTemac_SetOperatingSpeed(&lp->Emac, 10);
+		printk(KERN_INFO "%s: XLlTemac: speed set to 10Mb/s\n",
+		       dev->name);
+		lp->cur_speed = 10;
+		break;
+	default:
+		_XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+		printk(KERN_INFO "%s: XLlTemac: speed defaults to 1000Mb/s\n",
+		       dev->name);
+		lp->cur_speed = 1000;
+		break;
+	}
+
+#elif defined CONFIG_XILINX_LLTEMAC_XILINX_1000BASEX
+	/*
+	 * This function is specific to Xilinx 1000Base-X PHY,
+	 * which only supports 1000Mbps, Full duplex links
+	 */
+
+	_XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+	printk(KERN_INFO "%s: XLlTemac: speed set to 1000Mb/s\n", dev->name);
+	lp->cur_speed = 1000;
+
+#else	/* generic PHY, there have been issues with 10Mbit with this code */
+	int ret;
+	int retry_count = 1;
+
+	if (XLlTemac_GetPhysicalInterface(&lp->Emac) == XTE_PHY_TYPE_MII) {
+		phylinkspeed = 100;
+	}
+	else {
+		phylinkspeed = 1000;
+	}
+
+	/*
+	 * Try to renegotiate the speed until something sticks
+	 */
+	while (phylinkspeed > 1) {
+		ret = renegotiate_speed(dev, phylinkspeed, FULL_DUPLEX);
+		/*
+		 * ret == 1 - try it again
+		 * ret == 0 - it worked
+		 * ret <  0 - there was some failure negotiating the speed
+		 */
+		if (ret == 0) {
+			/* it worked, get out of the loop */
+			break;
+		}
+
+		/* it didn't work this time, but it may work if we try again */
+		if ((ret == 1) && (retry_count)) {
+			retry_count--;
+			printk("trying again...\n");
+			continue;
+		}
+		/* reset the retry_count, becuase we're about to try a lower speed */
+		retry_count = 1;
+		phylinkspeed /= 10;
+	}
+	if (phylinkspeed == 1) {
+		printk(KERN_INFO "%s: XLlTemac: could not negotiate speed\n",
+		       dev->name);
+		lp->cur_speed = 0;
+
+		return;
+	}
+
+	_XLlTemac_SetOperatingSpeed(&lp->Emac, phylinkspeed);
+	printk(KERN_INFO "%s: XLlTemac: speed set to %dMb/s\n", dev->name,
+	       phylinkspeed);
+	lp->cur_speed = phylinkspeed;
+#endif
+}
+
+/*
+ * Helper function to reset the underlying hardware.  This is called
+ * when we get into such deep trouble that we don't know how to handle
+ * otherwise.
+ */
+static void reset(struct net_device *dev, u32 line_num)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	u32 TxThreshold, TxWaitBound, RxThreshold, RxWaitBound;
+	u32 Options;
+	static u32 reset_cnt = 0;
+	int status;
+
+	printk(KERN_INFO "%s: XLlTemac: resets (#%u) from adapter code line %d\n",
+	       dev->name, ++reset_cnt, line_num);
+
+	/* Shouldn't really be necessary, but shouldn't hurt. */
+	netif_stop_queue(dev);
+
+	/* Stop device */
+	_XLlTemac_Stop(&lp->Emac);
+
+	/*
+	 * XLlTemac_Reset puts the device back to the default state.  We need
+	 * to save all the settings we don't already know, reset, restore
+	 * the settings, and then restart the TEMAC.
+	 */
+	Options = XLlTemac_GetOptions(&lp->Emac);
+
+	/*
+	 * Capture the dma coalesce settings (if needed) and reset the
+	 * connected core, dma or fifo
+	 */
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		XLlDma_BdRingGetCoalesce(&XLlDma_mGetRxRing(&lp->Dma),
+					 &RxThreshold, &RxWaitBound);
+		XLlDma_BdRingGetCoalesce(&XLlDma_mGetTxRing(&lp->Dma),
+					 &TxThreshold, &TxWaitBound);
+
+		XLlDma_Reset(&lp->Dma);
+	} else {
+		XLlFifo_Reset(&lp->Fifo);
+	}
+
+	/* now we can reset the device */
+	_XLlTemac_Reset(&lp->Emac, XTE_NORESET_HARD);
+
+	/* Reset on TEMAC also resets PHY. Give it some time to finish negotiation
+	 * before we move on */
+	mdelay(2000);
+
+	/*
+	 * The following four functions will return an error if the
+	 * EMAC is already started.  We just stopped it by calling
+	 * _XLlTemac_Reset() so we can safely ignore the return values.
+	 */
+	(int) _XLlTemac_SetMacAddress(&lp->Emac, dev->dev_addr);
+	(int) _XLlTemac_SetOptions(&lp->Emac, Options);
+	(int) _XLlTemac_ClearOptions(&lp->Emac, ~Options);
+	Options = XLlTemac_GetOptions(&lp->Emac);
+	printk(KERN_INFO "%s: XLlTemac: Options: 0x%x\n", dev->name, Options);
+
+	phy_setup(lp);
+	set_mac_speed(lp);
+
+	if (XLlTemac_IsDma(&lp->Emac)) {	/* SG DMA mode */
+		status = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing,
+						  RxThreshold, RxWaitBound);
+		status |= XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing,
+						   TxThreshold, TxWaitBound);
+		if (status != XST_SUCCESS) {
+			/* Print the error, but keep on going as it's not a fatal error. */
+			printk(KERN_ERR "%s: XLlTemac: error setting coalesce values (probably out of range). status: %d\n",
+			       dev->name, status);
+		}
+		XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+		XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+	} else {			/* FIFO interrupt mode */
+		XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK |
+				XLLF_INT_RC_MASK | XLLF_INT_RXERROR_MASK |
+				XLLF_INT_TXERROR_MASK);
+	}
+	XLlTemac_IntDisable(&lp->Emac, XTE_INT_ALL_MASK);
+
+	if (lp->deferred_skb) {
+		dev_kfree_skb_any(lp->deferred_skb);
+		lp->deferred_skb = NULL;
+		lp->stats.tx_errors++;
+	}
+
+	/*
+	 * XLlTemac_Start returns an error when: if configured for
+	 * scatter-gather DMA and a descriptor list has not yet been created
+	 * for the send or receive channel, or if no receive buffer descriptors
+	 * have been initialized. Those are not happening. so ignore the returned
+	 * result checking.
+	 */
+	_XLlTemac_Start(&lp->Emac);
+
+	/* We're all ready to go.  Start the queue in case it was stopped. */
+	netif_wake_queue(dev);
+}
+
+/*
+ * The PHY registers read here should be standard registers in all PHY chips
+ */
+static int get_phy_status(struct net_device *dev, DUPLEX * duplex, int *linkup)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	u16 reg;
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &reg);
+	*duplex = FULL_DUPLEX;
+
+#ifdef CONFIG_XILINX_LLTEMAC_NATIONAL_DP83865_GMII
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+                 NATIONAL_DP83865_STATUS, &reg);
+	*linkup=(reg & NATIONAL_DP83865_STATUS_LINK) != 0;
+
+#else
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &reg);
+	*linkup = (reg & BMSR_LSTATUS) != 0;
+#endif
+
+	return 0;
+}
+
+/*
+ * This routine is used for two purposes.  The first is to keep the
+ * EMAC's duplex setting in sync with the PHY's.  The second is to keep
+ * the system apprised of the state of the link.  Note that this driver
+ * does not configure the PHY.  Either the PHY should be configured for
+ * auto-negotiation or it should be handled by something like mii-tool. */
+static void poll_gmii(unsigned long data)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	DUPLEX phy_duplex;
+	int phy_carrier;
+	int netif_carrier;
+
+	dev = (struct net_device *) data;
+	lp = (struct net_local *) netdev_priv(dev);
+
+	/* First, find out what's going on with the PHY. */
+	if (get_phy_status(dev, &phy_duplex, &phy_carrier)) {
+		printk(KERN_ERR "%s: XLlTemac: terminating link monitoring.\n",
+		       dev->name);
+		return;
+	}
+	netif_carrier = netif_carrier_ok(dev) != 0;
+	if (phy_carrier != netif_carrier) {
+		if (phy_carrier) {
+			set_mac_speed(lp);
+			printk(KERN_INFO
+			       "%s: XLlTemac: PHY Link carrier restored.\n",
+			       dev->name);
+			netif_carrier_on(dev);
+		}
+		else {
+			printk(KERN_INFO "%s: XLlTemac: PHY Link carrier lost.\n",
+			       dev->name);
+			netif_carrier_off(dev);
+		}
+	}
+
+	/* Set up the timer so we'll get called again in 2 seconds. */
+	lp->phy_timer.expires = jiffies + 2 * HZ;
+	add_timer(&lp->phy_timer);
+}
+
+static irqreturn_t xenet_temac_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	/*
+	 * All we care about here is the RxRject interrupts. Explanation below:
+	 *
+	 * Interrupt     Usage Description
+	 * ---------     -----------------
+	 * TxCmplt:      Fifo or DMA will have completion interrupts. We'll use
+	 *               those and not the TEMAC ones.
+	 * RxFifoOvr:    if the RX fifo is overflowing, the last thing we need
+	 *               is more interrupts to handle.
+	 * RxRJect:      We're keeping stats on rejected packets (we could
+	 *               choose not to).
+	 * RxCmplt:      Fifo or DMA will have completion interrupts. We'll use
+	 *               those and not the TEMAC ones.
+	 * AutoNeg:      This driver doesn't make use of the autonegotation
+	 *               completion interrupt.
+	 * HardAcsCmplt: This driver just polls the RDY register for this
+	 *               information instead of using an interrupt handler.
+	 * CfgWst, CfgRst,
+	 * AfWst, AfRst,
+	 * MiimWst, MiimRst,
+	 * FabrRst:      All of these registers indicate when access (read or
+	 *               write) to one or other of the Hard Temac Core
+	 *               registers is complete. Instead of relying on an
+	 *               interrupt context switch to be notified that the
+	 *               access is complete, this driver instead polls for the
+	 *               status, which, in most cases, should be faster.
+	 */
+	XLlTemac_IntClear(&lp->Emac, XTE_INT_ALL_MASK);
+
+	lp->stats.rx_errors++;
+	lp->stats.rx_crc_errors++;
+
+
+	return IRQ_HANDLED;
+}
+
+static void FifoSendHandler(struct net_device *dev);
+static void FifoRecvHandler(unsigned long p /*struct net_device *dev*/);
+
+static DECLARE_TASKLET(FifoRecvBH, FifoRecvHandler, 0);
+
+static irqreturn_t xenet_fifo_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	u32 irq_status;
+
+	unsigned long flags;
+
+	/*
+	 * Need to:
+	 * 1) Read the FIFO IS register
+	 * 2) clear all bits in the FIFO IS register
+	 * 3) loop on each bit in the IS register, and handle each interrupt event
+	 *
+	 */
+	irq_status = XLlFifo_IntPending(&lp->Fifo);
+	XLlFifo_IntClear(&lp->Fifo, irq_status);
+	while (irq_status) {
+		if (irq_status & XLLF_INT_RC_MASK) {
+			/* handle the receive completion */
+			struct list_head *cur_lp;
+			spin_lock_irqsave(&receivedQueueSpin, flags);
+			list_for_each(cur_lp, &receivedQueue) {
+				if (cur_lp == &(lp->rcv)) {
+					break;
+				}
+			}
+			if (cur_lp != &(lp->rcv)) {
+				list_add_tail(&lp->rcv, &receivedQueue);
+				XLlFifo_IntDisable(&lp->Fifo, XLLF_INT_ALL_MASK);
+				tasklet_schedule(&FifoRecvBH);
+			}
+			spin_unlock_irqrestore(&receivedQueueSpin, flags);
+			irq_status &= ~XLLF_INT_RC_MASK;
+		} else if (irq_status & XLLF_INT_TC_MASK) {
+			/* handle the transmit completion */
+			FifoSendHandler(dev);
+			irq_status &= ~XLLF_INT_TC_MASK;
+		} else if (irq_status & XLLF_INT_TXERROR_MASK) {
+			lp->stats.tx_errors++;
+			lp->stats.tx_fifo_errors++;
+			XLlFifo_Reset(&lp->Fifo);
+			irq_status &= ~XLLF_INT_TXERROR_MASK;
+		} else if (irq_status & XLLF_INT_RXERROR_MASK) {
+			lp->stats.rx_errors++;
+			XLlFifo_Reset(&lp->Fifo);
+			irq_status &= ~XLLF_INT_RXERROR_MASK;
+		} else {
+			/* debug
+			 * if (irq_status == 0) printk("Temac: spurious fifo int\n");
+			 */
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* The callback function for completed frames sent in SGDMA mode. */
+static void DmaSendHandlerBH(unsigned long p);
+static void DmaRecvHandlerBH(unsigned long p);
+
+static DECLARE_TASKLET(DmaSendBH, DmaSendHandlerBH, 0);
+static DECLARE_TASKLET(DmaRecvBH, DmaRecvHandlerBH, 0);
+
+static irqreturn_t xenet_dma_rx_interrupt(int irq, void *dev_id)
+{
+	u32 irq_status;
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct list_head *cur_lp;
+
+        unsigned long flags;
+
+	/* Read pending interrupts */
+	irq_status = XLlDma_mBdRingGetIrq(&lp->Dma.RxBdRing);
+
+	XLlDma_mBdRingAckIrq(&lp->Dma.RxBdRing, irq_status);
+
+	if ((irq_status & XLLDMA_IRQ_ALL_ERR_MASK)) {
+		XLlDma_Reset(&lp->Dma);
+		return IRQ_HANDLED;
+	}
+	if ((irq_status & (XLLDMA_IRQ_DELAY_MASK | XLLDMA_IRQ_COALESCE_MASK))) {
+		spin_lock_irqsave(&receivedQueueSpin, flags);
+		list_for_each(cur_lp, &receivedQueue) {
+			if (cur_lp == &(lp->rcv)) {
+				break;
+			}
+		}
+		if (cur_lp != &(lp->rcv)) {
+			list_add_tail(&lp->rcv, &receivedQueue);
+			XLlDma_mBdRingIntDisable(&lp->Dma.RxBdRing,
+						 XLLDMA_CR_IRQ_ALL_EN_MASK);
+			tasklet_schedule(&DmaRecvBH);
+		}
+		spin_unlock_irqrestore(&receivedQueueSpin, flags);
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t xenet_dma_tx_interrupt(int irq, void *dev_id)
+{
+	u32 irq_status;
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct list_head *cur_lp;
+
+	unsigned long flags;
+
+	/* Read pending interrupts */
+	irq_status = XLlDma_mBdRingGetIrq(&(lp->Dma.TxBdRing));
+
+	XLlDma_mBdRingAckIrq(&(lp->Dma.TxBdRing), irq_status);
+
+	if ((irq_status & XLLDMA_IRQ_ALL_ERR_MASK)) {
+		XLlDma_Reset(&lp->Dma);
+		return IRQ_HANDLED;
+	}
+
+	if ((irq_status & (XLLDMA_IRQ_DELAY_MASK | XLLDMA_IRQ_COALESCE_MASK))) {
+		spin_lock_irqsave(&sentQueueSpin, flags);
+		list_for_each(cur_lp, &sentQueue) {
+			if (cur_lp == &(lp->xmit)) {
+ 				break;
+			}
+		}
+		if (cur_lp != &(lp->xmit)) {
+			list_add_tail(&lp->xmit, &sentQueue);
+			XLlDma_mBdRingIntDisable(&lp->Dma.TxBdRing,
+						 XLLDMA_CR_IRQ_ALL_EN_MASK);
+			tasklet_schedule(&DmaSendBH);
+		}
+		spin_unlock_irqrestore(&sentQueueSpin, flags);
+	}
+	return IRQ_HANDLED;
+}
+
+/*
+ * Q:
+ * Why doesn't this linux driver use an interrupt handler for the TEMAC itself?
+ *
+ * A:
+ * Let's take a look at all the possible events that could be signaled by the
+ * TEMAC core.
+ *
+ * possible events:
+ *    Transmit Complete (TxCmplt) [not handled by this driver]
+ *        The TEMAC TxCmplt interrupt status is ignored by software in favor of
+ *        paying attention to the transmit complete status in the connected DMA
+ *        or FIFO core.
+ *    Receive Fifo Overflow (RxFifoOver) [not handled by this driver]
+ *        We have discovered that the overhead of an interrupt context switch
+ *        to attempt to handle this sort of event actually worsens the
+ *        condition, and cuases further dropped packets further increasing the
+ *        time spent in this interrupt handler.
+ *    Receive Frame Rejected (RxRject) [not handled by this driver]
+ *        We could possibly handle this interrupt and gather statistics
+ *        information based on these events that occur. However it is not that
+ *        critical.
+ *    Receive Complete (RxCmplt) [not handled by this driver]
+ *        The TEMAC RxCmplt interrupt status is ignored by software in favor of
+ *        paying attention to the receive complete status in the connected DMA
+ *        or FIFO core.
+ *    Autonegotiaion Complete (AutoNeg) [not handled by this driver]
+ *        Autonegotiation on the TEMAC is a bit complicated, and is handled in
+ *        a way that does not require the use of this interrupt event.
+ *    Hard Temac Core Access Complete (HardAcsCmplt) [not handled by this driver]
+ *        This event really just indicates if there are any events in the TIS
+ *        register. As can be seen below, none of the events from the TIS
+ *        register are handled, so there is no need to handle this event
+ *        either.
+ *    Configuration Write Complete (CfgWst) [not handled by this driver]
+ *    Configuration Read Complete (CfgRst) [not handled by this driver]
+ *    Address Filter Write Complete (AfWst) [not handled by this driver]
+ *    Address Filter Read Complete (AfRst) [not handled by this driver]
+ *    MII Management Write Complete (MiimWst) [not handled by this driver]
+ *    MII Management Read Complete (MiimRst) [not handled by this driver]
+ *    Fabric Read Complete (FabrRst) [not handled by this driver]
+ *        All of the above registers indicate when access (read or write) to
+ *        one or other of the Hard Temac Core registers is complete. Instead of
+ *        relying on an interrupt context switch to be notified that the access
+ *        is complete, this driver instead polls for the status, which, in most
+ *        cases, should be faster.
+ */
+
+static int xenet_open(struct net_device *dev)
+{
+	struct net_local *lp;
+	u32 Options;
+	int irqval = 0;
+
+	/*
+	 * Just to be safe, stop TX queue and the device first.  If the device is
+	 * already stopped, an error will be returned.  In this case, we don't
+	 * really care.
+	 */
+	netif_stop_queue(dev);
+	lp = (struct net_local *) netdev_priv(dev);
+	_XLlTemac_Stop(&lp->Emac);
+
+	INIT_LIST_HEAD(&(lp->rcv));
+	INIT_LIST_HEAD(&(lp->xmit));
+
+	/* Set the MAC address each time opened. */
+	if (_XLlTemac_SetMacAddress(&lp->Emac, dev->dev_addr) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: XLlTemac: could not set MAC address.\n",
+		       dev->name);
+		return -EIO;
+	}
+
+	/*
+	 * If the device is not configured for polled mode, connect to the
+	 * interrupt controller and enable interrupts.  Currently, there
+	 * isn't any code to set polled mode, so this check is probably
+	 * superfluous.
+	 */
+	Options = XLlTemac_GetOptions(&lp->Emac);
+	Options |= XTE_FLOW_CONTROL_OPTION;
+	/* Enabling jumbo packets shouldn't be a problem if MTU is smaller */
+	Options |= XTE_JUMBO_OPTION;
+	Options |= XTE_TRANSMITTER_ENABLE_OPTION;
+	Options |= XTE_RECEIVER_ENABLE_OPTION;
+#if XTE_AUTOSTRIPPING
+	Options |= XTE_FCS_STRIP_OPTION;
+#endif
+
+	(int) _XLlTemac_SetOptions(&lp->Emac, Options);
+	(int) _XLlTemac_ClearOptions(&lp->Emac, ~Options);
+	Options = XLlTemac_GetOptions(&lp->Emac);
+	printk(KERN_INFO "%s: XLlTemac: Options: 0x%x\n", dev->name, Options);
+
+	/* Just use interrupt driven methods - no polled mode */
+
+	irqval = request_irq(dev->irq, &xenet_temac_interrupt, 0, dev->name, dev);
+	if (irqval) {
+		printk(KERN_ERR
+		       "%s: XLlTemac: could not allocate interrupt %d.\n",
+		       dev->name, dev->irq);
+		return irqval;
+	}
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		printk(KERN_INFO
+		       "%s: XLlTemac: allocating interrupt %d for dma mode tx.\n",
+		       dev->name, lp->dma_irq_s);
+		irqval = request_irq(lp->dma_irq_s,
+			&xenet_dma_tx_interrupt, 0, "xilinx_dma_tx_int", dev);
+		if (irqval) {
+			printk(KERN_ERR
+			       "%s: XLlTemac: could not allocate interrupt %d.\n",
+			       dev->name, lp->dma_irq_s);
+			return irqval;
+		}
+		printk(KERN_INFO
+		       "%s: XLlTemac: allocating interrupt %d for dma mode rx.\n",
+		       dev->name, lp->dma_irq_r);
+		irqval = request_irq(lp->dma_irq_r,
+			&xenet_dma_rx_interrupt, 0, "xilinx_dma_rx_int", dev);
+		if (irqval) {
+			printk(KERN_ERR
+			       "%s: XLlTemac: could not allocate interrupt %d.\n",
+			       dev->name, lp->dma_irq_r);
+			return irqval;
+		}
+	} else {
+		printk(KERN_INFO
+		       "%s: XLlTemac: allocating interrupt %d for fifo mode.\n",
+		       dev->name, lp->fifo_irq);
+		/* With the way interrupts are issued on the fifo core, this needs to be
+		 * fast interrupt handler.
+		 */
+		irqval = request_irq(lp->fifo_irq,
+			&xenet_fifo_interrupt, 0, "xilinx_fifo_int", dev);
+		if (irqval) {
+			printk(KERN_ERR
+			       "%s: XLlTemac: could not allocate interrupt %d.\n",
+			       dev->name, lp->fifo_irq);
+			return irqval;
+		}
+	}
+
+	/* give the system enough time to establish a link */
+	mdelay(2000);
+
+	phy_setup(lp);
+	set_mac_speed(lp);
+
+	/* Enable interrupts  - no polled mode */
+	if (XLlTemac_IsFifo(&lp->Emac)) { /* fifo direct interrupt driver mode */
+		XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK |
+			XLLF_INT_RC_MASK | XLLF_INT_RXERROR_MASK |
+			XLLF_INT_TXERROR_MASK);
+	} else {		/* SG DMA mode */
+		XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+		XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+	}
+	/*
+	 * Make sure all temac interrupts are disabled. These
+	 * interrupts are not data flow releated.
+	 */
+	XLlTemac_IntDisable(&lp->Emac, XTE_INT_ALL_MASK);
+
+	/* Start TEMAC device */
+	_XLlTemac_Start(&lp->Emac);
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		u32 threshold_s, timer_s, threshold_r, timer_r;
+
+		XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold_s, &timer_s);
+		XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold_r, &timer_r);
+		printk(KERN_INFO
+		       "%s: XLlTemac: Send Threshold = %d, Receive Threshold = %d\n",
+		       dev->name, threshold_s, threshold_r);
+		printk(KERN_INFO
+		       "%s: XLlTemac: Send Wait bound = %d, Receive Wait bound = %d\n",
+		       dev->name, timer_s, timer_r);
+		if (XLlDma_BdRingStart(&lp->Dma.TxBdRing) == XST_FAILURE) {
+			printk(KERN_ERR "%s: XLlTemac: could not start dma tx channel\n", dev->name);
+			return -EIO;
+		}
+		if (XLlDma_BdRingStart(&lp->Dma.RxBdRing) == XST_FAILURE) {
+			printk(KERN_ERR "%s: XLlTemac: could not start dma rx channel\n", dev->name);
+			return -EIO;
+		}
+	}
+
+	/* We're ready to go. */
+	netif_start_queue(dev);
+
+	/* Set up the PHY monitoring timer. */
+	lp->phy_timer.expires = jiffies + 2 * HZ;
+	lp->phy_timer.data = (unsigned long) dev;
+	lp->phy_timer.function = &poll_gmii;
+	init_timer(&lp->phy_timer);
+	add_timer(&lp->phy_timer);
+	return 0;
+}
+
+static int xenet_close(struct net_device *dev)
+{
+	struct net_local *lp;
+	unsigned long flags;
+
+	lp = (struct net_local *) netdev_priv(dev);
+
+	/* Shut down the PHY monitoring timer. */
+	del_timer_sync(&lp->phy_timer);
+
+	/* Stop Send queue */
+	netif_stop_queue(dev);
+
+	/* Now we could stop the device */
+	_XLlTemac_Stop(&lp->Emac);
+
+	/*
+	 * Free the interrupt - not polled mode.
+	 */
+	free_irq(dev->irq, dev);
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		free_irq(lp->dma_irq_s, dev);
+		free_irq(lp->dma_irq_r, dev);
+	} else {
+		free_irq(lp->fifo_irq, dev);
+	}
+
+	spin_lock_irqsave(&receivedQueueSpin, flags);
+	list_del(&(lp->rcv));
+	spin_unlock_irqrestore(&receivedQueueSpin, flags);
+
+	spin_lock_irqsave(&sentQueueSpin, flags);
+	list_del(&(lp->xmit));
+	spin_unlock_irqrestore(&sentQueueSpin, flags);
+
+	return 0;
+}
+
+static struct net_device_stats *xenet_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	return &lp->stats;
+}
+
+static int descriptor_init(struct net_device *dev);
+static void free_descriptor_skb(struct net_device *dev);
+
+static void xenet_set_multicast_list(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	int i;
+	u32 Options;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_spinlock, flags);
+	XLlTemac_Stop(&lp->Emac);
+
+	Options = XLlTemac_GetOptions(&lp->Emac);
+	Options &= ~XTE_PROMISC_OPTION;
+	Options &= ~XTE_MULTICAST_OPTION;
+	for (i = 0; i < 4; i++)
+		XLlTemac_MulticastClear(&lp->Emac, i);
+
+	if ((dev->flags & IFF_PROMISC) ||
+			(dev->flags & IFF_ALLMULTI) ||
+			(netdev_mc_count(dev) > 4)) {
+		Options |= XTE_PROMISC_OPTION;
+		goto done;
+	}
+
+	if (dev->flags & IFF_MULTICAST) {
+		struct netdev_hw_addr *ha;
+		i = 0;
+		netdev_for_each_mc_addr(ha, dev) {
+			XLlTemac_MulticastAdd(&lp->Emac, ha->addr, i++);
+		}
+		Options |= XTE_MULTICAST_OPTION;
+	}
+
+done:
+	XLlTemac_SetOptions(&lp->Emac, Options);
+
+	XLlTemac_Start(&lp->Emac);
+	spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static int xenet_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int result;
+	int device_enable = 0;
+#ifdef CONFIG_XILINX_GIGE_VLAN
+	int head_size = XTE_HDR_VLAN_SIZE;
+#else
+	int head_size = XTE_HDR_SIZE;
+#endif
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	int max_frame = new_mtu + head_size + XTE_TRL_SIZE;
+	int min_frame = 1 + head_size + XTE_TRL_SIZE;
+
+#ifdef CONFIG_PPC
+        if (netif_running(dev)) {
+		printk("STOP device first!!!\n");
+                return -1;
+	}
+#endif
+	if (max_frame < min_frame)
+		return -EINVAL;
+
+	if (max_frame > XTE_MAX_JUMBO_FRAME_SIZE) {
+		printk(KERN_INFO "Wrong MTU packet size. Use %d size\n",
+							XTE_JUMBO_MTU);
+		new_mtu = XTE_JUMBO_MTU;
+	}
+
+	dev->mtu = new_mtu;	/* change mtu in net_device structure */
+
+	/* stop driver */
+	if (netif_running(dev)) {
+		device_enable = 1;
+		xenet_close(dev);
+	}
+	/* free all created descriptors for previous size */
+	free_descriptor_skb(dev);
+	/* setup new frame size */
+	lp->frame_size = dev->mtu + XTE_HDR_SIZE + XTE_TRL_SIZE;
+	XLlDma_Initialize(&lp->Dma, lp->virt_dma_addr); /* initialize dma */
+
+	result = descriptor_init(dev); /* create new skb with new size */
+	if (result) {
+		printk(KERN_ERR "Descriptor initialization failed.\n");
+		return -EINVAL;
+	}
+
+	if (device_enable)
+		xenet_open(dev); /* open the device */
+	return 0;
+}
+
+static int xenet_FifoSend(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *lp;
+	unsigned long flags, fifo_free_bytes;
+	int total_frags = skb_shinfo(skb)->nr_frags + 1;
+	unsigned int total_len;
+	skb_frag_t *frag;
+	int i;
+	void *virt_addr;
+
+	total_len = skb_headlen(skb);
+
+	frag = &skb_shinfo(skb)->frags[0];
+	for (i = 1; i < total_frags; i++, frag++) {
+		total_len += frag->size;
+	}
+
+	/* The following lock is used to protect TxVacancy, Write
+	 * and TxSetLen sequence which could happen from FifoSendHandler
+	 * or other processor in SMP case.
+	 */
+	spin_lock_irqsave(&XTE_tx_spinlock, flags);
+	lp = (struct net_local *) netdev_priv(dev);
+
+	fifo_free_bytes = XLlFifo_TxVacancy(&lp->Fifo) * 4;
+	if (fifo_free_bytes < total_len) {
+		netif_stop_queue(dev);	/* stop send queue */
+		lp->deferred_skb = skb;	/* buffer the sk_buffer and will send
+					   it in interrupt context */
+		spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+		return 0;
+	}
+
+	/* Write frame data to FIFO */
+	XLlFifo_Write(&lp->Fifo, (void *) skb->data, skb_headlen(skb));
+
+	frag = &skb_shinfo(skb)->frags[0];
+	for (i = 1; i < total_frags; i++, frag++) {
+		virt_addr = skb_frag_address(frag);
+		XLlFifo_Write(&lp->Fifo, virt_addr, frag->size);
+	}
+
+	/* Initiate transmit */
+	XLlFifo_TxSetLen(&lp->Fifo, total_len);
+	lp->stats.tx_bytes += total_len;
+	spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+
+	dev_kfree_skb(skb);	/* free skb */
+	dev->trans_start = jiffies;
+	return 0;
+}
+
+/* Callback function for completed frames sent in FIFO interrupt driven mode */
+static void FifoSendHandler(struct net_device *dev)
+{
+	struct net_local *lp;
+	struct sk_buff *skb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&XTE_tx_spinlock, flags);
+	lp = (struct net_local *) netdev_priv(dev);
+	lp->stats.tx_packets++;
+
+	/*Send out the deferred skb and wake up send queue if a deferred skb exists */
+	if (lp->deferred_skb) {
+		int total_frags;
+		unsigned int total_len;
+		unsigned long fifo_free_bytes;
+		skb_frag_t *frag;
+		int i;
+		void *virt_addr;
+
+		skb = lp->deferred_skb;
+		total_frags = skb_shinfo(skb)->nr_frags + 1;
+		total_len = skb_headlen(skb);
+
+		frag = &skb_shinfo(skb)->frags[0];
+		for (i = 1; i < total_frags; i++, frag++) {
+			total_len += frag->size;
+		}
+
+		fifo_free_bytes = XLlFifo_TxVacancy(&lp->Fifo) * 4;
+		if (fifo_free_bytes < total_len) {
+			/* If still no room for the deferred packet, return */
+			spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+			return;
+		}
+
+		/* Write frame data to FIFO */
+		XLlFifo_Write(&lp->Fifo, (void *) skb->data, skb_headlen(skb));
+
+		frag = &skb_shinfo(skb)->frags[0];
+		for (i = 1; i < total_frags; i++, frag++) {
+			virt_addr = skb_frag_address(frag);
+			XLlFifo_Write(&lp->Fifo, virt_addr, frag->size);
+		}
+
+		/* Initiate transmit */
+		XLlFifo_TxSetLen(&lp->Fifo, total_len);
+
+		dev_kfree_skb(skb);	/* free skb */
+		lp->deferred_skb = NULL;
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes += total_len;
+		dev->trans_start = jiffies;
+		netif_wake_queue(dev);	/* wake up send queue */
+	}
+	spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+}
+
+#if 0
+/*
+ * These are used for debugging purposes, left here in case they are useful
+ * for further debugging
+ */
+static unsigned int _xenet_tx_csum(struct sk_buff *skb)
+{
+	unsigned int csum = 0;
+	long csstart = skb_transport_header(skb) - skb->data;
+
+	if (csstart != skb->len) {
+		csum = skb_checksum(skb, csstart, skb->len - csstart, 0);
+	}
+
+	return csum;
+}
+
+static inline unsigned int _xenet_rx_csum(struct sk_buff *skb)
+{
+	return skb_checksum(skb, 0, skb->len, 0);
+}
+#endif
+
+/*
+ * xenet_DmaSend_internal is an internal use, send routine.
+ * Any locks that need to be acquired, should be acquired
+ * prior to calling this routine.
+ */
+static int xenet_DmaSend_internal(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *lp;
+	XLlDma_Bd *bd_ptr;
+	int result;
+	int total_frags;
+	int i;
+	void *virt_addr;
+	size_t len;
+	dma_addr_t phy_addr;
+	XLlDma_Bd *first_bd_ptr;
+	XLlDma_Bd *last_bd_ptr;
+	skb_frag_t *frag;
+
+	lp = (struct net_local *) netdev_priv(dev);
+
+	/* get skb_shinfo(skb)->nr_frags + 1 buffer descriptors */
+	total_frags = skb_shinfo(skb)->nr_frags + 1;
+
+	/* stats */
+	if (lp->max_frags_in_a_packet < total_frags) {
+		lp->max_frags_in_a_packet = total_frags;
+	}
+
+	if (total_frags < XTE_SEND_BD_CNT) {
+		result = XLlDma_BdRingAlloc(&lp->Dma.TxBdRing, total_frags,
+					    &bd_ptr);
+
+		if (result != XST_SUCCESS) {
+			netif_stop_queue(dev);	/* stop send queue */
+			lp->deferred_skb = skb;	/* buffer the sk_buffer and will send
+						   it in interrupt context */
+			return result;
+		}
+	} else {
+		dev_kfree_skb(skb);
+		lp->stats.tx_dropped++;
+		printk(KERN_ERR
+		       "%s: XLlTemac: could not send TX socket buffers (too many fragments).\n",
+		       dev->name);
+		return XST_FAILURE;
+	}
+
+	len = skb_headlen(skb);
+
+	/* get the physical address of the header */
+	phy_addr = (u32) dma_map_single(dev->dev.parent, skb->data, len,
+								DMA_TO_DEVICE);
+
+	/* get the header fragment, it's in the skb differently */
+	XLlDma_mBdSetBufAddr(bd_ptr, phy_addr);
+	XLlDma_mBdSetLength(bd_ptr, len);
+	XLlDma_mBdSetId(bd_ptr, skb);
+
+	/*
+	 * if tx checksum offloading is enabled, when the ethernet stack
+	 * wants us to perform the checksum in hardware,
+	 * skb->ip_summed is CHECKSUM_PARTIAL. Otherwise skb->ip_summed is
+	 * CHECKSUM_NONE, meaning the checksum is already done, or
+	 * CHECKSUM_UNNECESSARY, meaning checksumming is turned off (e.g.
+	 * loopback interface)
+	 *
+	 * skb->csum is an overloaded value. On send, skb->csum is the offset
+	 * into the buffer (skb_transport_header(skb)) to place the csum value.
+	 * On receive this feild gets set to the actual csum value, before it's
+	 * passed up the stack.
+	 *
+	 * When we get here, the ethernet stack above will have already
+	 * computed the pseudoheader csum value and have placed it in the
+	 * TCP/UDP header.
+	 *
+	 * The IP header csum has also already been computed and inserted.
+	 *
+	 * Since the IP header with it's own csum should compute to a null
+	 * csum, it should be ok to include it in the hw csum. If it is decided
+	 * to change this scheme, skb should be examined before dma_map_single()
+	 * is called, which flushes the page from the cpu's cache.
+	 *
+	 * skb->data points to the beginning of the whole packet
+	 * skb_transport_header(skb) points to the beginning of the ip header
+	 *
+	 */
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+
+		unsigned int csum_start_off = skb_transport_offset(skb);
+		unsigned int csum_index_off = csum_start_off + skb->csum_offset;
+
+#if 0
+		{
+			unsigned int csum = _xenet_tx_csum(skb);
+
+			*((unsigned short *) (raw + skb->csum)) =
+				csum_fold(csum);
+			BdCsumDisable(bd_ptr);
+		}
+#else
+		BdCsumEnable(bd_ptr);
+		BdCsumSetup(bd_ptr, csum_start_off, csum_index_off);
+
+#endif
+		lp->tx_hw_csums++;
+	}
+	else {
+		/*
+		 * This routine will do no harm even if hardware checksum capability is
+		 * off.
+		 */
+		BdCsumDisable(bd_ptr);
+	}
+
+	first_bd_ptr = bd_ptr;
+	last_bd_ptr = bd_ptr;
+
+	frag = &skb_shinfo(skb)->frags[0];
+
+	for (i = 1; i < total_frags; i++, frag++) {
+		bd_ptr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, bd_ptr);
+		last_bd_ptr = bd_ptr;
+
+		virt_addr = skb_frag_address(frag);
+		phy_addr =
+			(u32) dma_map_single(dev->dev.parent, virt_addr,
+					frag->size, DMA_TO_DEVICE);
+
+		XLlDma_mBdSetBufAddr(bd_ptr, phy_addr);
+		XLlDma_mBdSetLength(bd_ptr, frag->size);
+		XLlDma_mBdSetId(bd_ptr, NULL);
+		BdCsumDisable(bd_ptr);
+		XLlDma_mBdSetStsCtrl(bd_ptr, 0);
+	}
+
+	if (first_bd_ptr == last_bd_ptr) {
+		XLlDma_mBdSetStsCtrl(last_bd_ptr,
+				     XLLDMA_BD_STSCTRL_SOP_MASK |
+				     XLLDMA_BD_STSCTRL_EOP_MASK);
+	} else {
+		XLlDma_mBdSetStsCtrl(first_bd_ptr, XLLDMA_BD_STSCTRL_SOP_MASK);
+		XLlDma_mBdSetStsCtrl(last_bd_ptr, XLLDMA_BD_STSCTRL_EOP_MASK);
+	}
+
+
+	/* Enqueue to HW */
+	result = XLlDma_BdRingToHw(&lp->Dma.TxBdRing, total_frags,
+				   first_bd_ptr);
+	if (result != XST_SUCCESS) {
+		netif_stop_queue(dev);	/* stop send queue */
+		dev_kfree_skb(skb);
+		XLlDma_mBdSetId(first_bd_ptr, NULL);
+		lp->stats.tx_dropped++;
+		printk(KERN_ERR
+		       "%s: XLlTemac: could not send commit TX buffer descriptor (%d).\n",
+		       dev->name, result);
+		reset(dev, __LINE__);
+
+		return XST_FAILURE;
+	}
+
+	dev->trans_start = jiffies;
+
+	return XST_SUCCESS;
+}
+
+/* The send function for frames sent in DMA mode */
+static int xenet_DmaSend(struct sk_buff *skb, struct net_device *dev)
+{
+	/* The following spin_lock protects
+	 * SgAlloc, SgCommit sequence, which also exists in DmaSendHandlerBH Bottom
+	 * Half, or triggered by other processor in SMP case.
+	 */
+	spin_lock_bh(&XTE_tx_spinlock);
+
+	xenet_DmaSend_internal(skb, dev);
+
+	spin_unlock_bh(&XTE_tx_spinlock);
+
+	return 0;
+}
+
+
+static void DmaSendHandlerBH(unsigned long p)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	XLlDma_Bd *BdPtr, *BdCurPtr;
+	unsigned long len;
+	unsigned long flags;
+	struct sk_buff *skb;
+	dma_addr_t skb_dma_addr;
+	int result = XST_SUCCESS;
+	unsigned int bd_processed, bd_processed_save;
+
+	while (1) {
+		spin_lock_irqsave(&sentQueueSpin, flags);
+		if (list_empty(&sentQueue)) {
+			spin_unlock_irqrestore(&sentQueueSpin, flags);
+			break;
+		}
+
+		lp = list_entry(sentQueue.next, struct net_local, xmit);
+
+		list_del_init(&(lp->xmit));
+		spin_unlock_irqrestore(&sentQueueSpin, flags);
+
+		spin_lock_irqsave(&XTE_tx_spinlock, flags);
+		dev = lp->ndev;
+		bd_processed_save = 0;
+		while ((bd_processed =
+			XLlDma_BdRingFromHw(&lp->Dma.TxBdRing, XTE_SEND_BD_CNT,
+					    &BdPtr)) > 0) {
+
+			bd_processed_save = bd_processed;
+			BdCurPtr = BdPtr;
+			do {
+				len = XLlDma_mBdGetLength(BdCurPtr);
+				skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdCurPtr);
+				dma_unmap_single(dev->dev.parent, skb_dma_addr,
+						len, DMA_TO_DEVICE);
+
+				/* get ptr to skb */
+				skb = (struct sk_buff *)
+					XLlDma_mBdGetId(BdCurPtr);
+				if (skb)
+					dev_kfree_skb(skb);
+
+				/* reset BD id */
+				XLlDma_mBdSetId(BdCurPtr, NULL);
+
+				lp->stats.tx_bytes += len;
+				if (XLlDma_mBdGetStsCtrl(BdCurPtr) & XLLDMA_BD_STSCTRL_EOP_MASK) {
+					lp->stats.tx_packets++;
+				}
+
+				BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, BdCurPtr);
+				bd_processed--;
+			} while (bd_processed > 0);
+
+			result = XLlDma_BdRingFree(&lp->Dma.TxBdRing,
+						   bd_processed_save, BdPtr);
+			if (result != XST_SUCCESS) {
+				printk(KERN_ERR
+				       "%s: XLlDma: BdRingFree() error %d.\n",
+				       dev->name, result);
+				reset(dev, __LINE__);
+				spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+				return;
+			}
+		}
+		XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+		/* Send out the deferred skb if it exists */
+		if ((lp->deferred_skb) && bd_processed_save) {
+			skb = lp->deferred_skb;
+			lp->deferred_skb = NULL;
+
+			result = xenet_DmaSend_internal(skb, dev);
+		}
+
+		if (result == XST_SUCCESS) {
+			netif_wake_queue(dev);	/* wake up send queue */
+		}
+		spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+	}
+}
+
+static void xenet_tx_timeout(struct net_device *dev)
+{
+	struct net_local *lp;
+	unsigned long flags;
+
+	/*
+	 * Make sure that no interrupts come in that could cause reentrancy
+	 * problems in reset.
+	 */
+	spin_lock_irqsave(&XTE_tx_spinlock, flags);
+
+	lp = (struct net_local *) netdev_priv(dev);
+	printk(KERN_ERR
+	       "%s: XLlTemac: exceeded transmit timeout of %lu ms.  Resetting emac.\n",
+	       dev->name, TX_TIMEOUT * 1000UL / HZ);
+	lp->stats.tx_errors++;
+
+	reset(dev, __LINE__);
+
+	spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+}
+
+/* The callback function for frames received when in FIFO mode. */
+static void FifoRecvHandler(unsigned long p)
+{
+	struct net_local *lp;
+	struct sk_buff *skb;
+	u32 len;
+
+	struct net_device *dev;
+	unsigned long flags;
+	spin_lock_irqsave(&receivedQueueSpin, flags);
+	if (list_empty(&receivedQueue)) {
+		spin_unlock_irqrestore(&receivedQueueSpin, flags);
+		return;
+	}
+	lp = list_entry(receivedQueue.next, struct net_local, rcv);
+
+	list_del_init(&(lp->rcv));
+	spin_unlock_irqrestore(&receivedQueueSpin, flags);
+	dev = lp->ndev;
+
+	while (XLlFifo_RxOccupancy(&lp->Fifo) != 0) {
+
+		len = XLlFifo_RxGetLen(&lp->Fifo);
+
+		/*
+		 * TODO: Hm this is odd, if we can't allocate the skb, we throw away the next packet. Why?
+		 */
+		if (!(skb = /*dev_ */ alloc_skb(len + ALIGNMENT_RECV, GFP_ATOMIC))) {
+#define XTE_RX_SINK_BUFFER_SIZE 1024
+			static u32 rx_buffer_sink[XTE_RX_SINK_BUFFER_SIZE / sizeof(u32)];
+
+			/* Couldn't get memory. */
+			lp->stats.rx_dropped++;
+			printk(KERN_ERR
+			       "%s: XLlTemac: could not allocate receive buffer.\n",
+			       dev->name);
+
+			/* consume data in Xilinx TEMAC RX data fifo so it is sync with RX length fifo */
+			for (; len > XTE_RX_SINK_BUFFER_SIZE;
+					len -= XTE_RX_SINK_BUFFER_SIZE) {
+				XLlFifo_Read(&lp->Fifo, rx_buffer_sink,
+					       XTE_RX_SINK_BUFFER_SIZE);
+			}
+			XLlFifo_Read(&lp->Fifo, rx_buffer_sink, len);
+			break;
+		}
+
+		/* Read the packet data */
+		XLlFifo_Read(&lp->Fifo, skb->data, len);
+		lp->stats.rx_packets++;
+		lp->stats.rx_bytes += len;
+
+		skb_put(skb, len);	/* Tell the skb how much data we got. */
+		skb->dev = dev;		/* Fill out required meta-data. */
+		skb->protocol = eth_type_trans(skb, dev);
+		skb->ip_summed = CHECKSUM_NONE;
+		netif_rx(skb);		/* Send the packet upstream. */
+	}
+	XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK | XLLF_INT_RC_MASK |
+			XLLF_INT_RXERROR_MASK | XLLF_INT_TXERROR_MASK);
+
+}
+
+
+/*
+ * _xenet_DmaSetupRecvBuffers allocates as many socket buffers (sk_buff's) as it
+ * can up to the number of free RX buffer descriptors. Then it sets up the RX
+ * buffer descriptors to DMA into the socket_buffers.
+ *
+ * The net_device, dev, indcates on which device to operate for buffer
+ * descriptor allocation.
+ */
+static void _xenet_DmaSetupRecvBuffers(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	int free_bd_count = XLlDma_mBdRingGetFreeCnt(&lp->Dma.RxBdRing);
+	int num_sk_buffs;
+	struct sk_buff_head sk_buff_list;
+	struct sk_buff *new_skb;
+	u32 new_skb_baddr;
+	XLlDma_Bd *BdPtr, *BdCurPtr;
+	u32 align;
+	int result;
+
+#if 0
+	int align_max = ALIGNMENT_RECV;
+#else
+	int align_max = 0;
+#endif
+
+
+	skb_queue_head_init(&sk_buff_list);
+	for (num_sk_buffs = 0; num_sk_buffs < free_bd_count; num_sk_buffs++) {
+		new_skb = alloc_skb(lp->frame_size + align_max, GFP_ATOMIC);
+		if (new_skb == NULL) {
+			break;
+		}
+		/*
+		 * I think the XTE_spinlock, and Recv DMA int disabled will protect this
+		 * list as well, so we can use the __ version just fine
+		 */
+		__skb_queue_tail(&sk_buff_list, new_skb);
+	}
+	if (!num_sk_buffs) {
+		printk(KERN_ERR "%s: XLlTemac: alloc_skb unsuccessful\n",
+		       dev->name);
+		return;
+	}
+
+	/* now we got a bunch o' sk_buffs */
+	result = XLlDma_BdRingAlloc(&lp->Dma.RxBdRing, num_sk_buffs, &BdPtr);
+	if (result != XST_SUCCESS) {
+		/* we really shouldn't get this */
+		skb_queue_purge(&sk_buff_list);
+		printk(KERN_ERR "%s: XLlDma: BdRingAlloc unsuccessful (%d)\n",
+		       dev->name, result);
+		reset(dev, __LINE__);
+		return;
+	}
+
+	BdCurPtr = BdPtr;
+
+	new_skb = skb_dequeue(&sk_buff_list);
+	while (new_skb) {
+		/* make sure we're long-word aligned */
+		align = BUFFER_ALIGNRECV(new_skb->data);
+		if (align) {
+			skb_reserve(new_skb, align);
+		}
+
+		/* Get dma handle of skb->data */
+		new_skb_baddr = (u32) dma_map_single(dev->dev.parent,
+					new_skb->data, lp->frame_size,
+						     DMA_FROM_DEVICE);
+		XLlDma_mBdSetBufAddr(BdCurPtr, new_skb_baddr);
+		XLlDma_mBdSetLength(BdCurPtr, lp->frame_size);
+		XLlDma_mBdSetId(BdCurPtr, new_skb);
+		XLlDma_mBdSetStsCtrl(BdCurPtr,
+				     XLLDMA_BD_STSCTRL_SOP_MASK |
+				     XLLDMA_BD_STSCTRL_EOP_MASK);
+
+		BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing, BdCurPtr);
+
+		new_skb = skb_dequeue(&sk_buff_list);
+	}
+
+	/* enqueue RxBD with the attached skb buffers such that it is
+	 * ready for frame reception */
+	result = XLlDma_BdRingToHw(&lp->Dma.RxBdRing, num_sk_buffs, BdPtr);
+	if (result != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: XLlDma: (DmaSetupRecvBuffers) BdRingToHw unsuccessful (%d)\n",
+		       dev->name, result);
+		skb_queue_purge(&sk_buff_list);
+		BdCurPtr = BdPtr;
+		while (num_sk_buffs > 0) {
+			XLlDma_mBdSetId(BdCurPtr, NULL);
+			BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing,
+						      BdCurPtr);
+			num_sk_buffs--;
+		}
+		reset(dev, __LINE__);
+		return;
+	}
+}
+
+static void DmaRecvHandlerBH(unsigned long p)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	struct sk_buff *skb;
+	u32 len, skb_baddr;
+	int result;
+	unsigned long flags;
+	XLlDma_Bd *BdPtr, *BdCurPtr;
+	unsigned int bd_processed, bd_processed_saved;
+
+	while (1) {
+		spin_lock_irqsave(&receivedQueueSpin, flags);
+		if (list_empty(&receivedQueue)) {
+			spin_unlock_irqrestore(&receivedQueueSpin, flags);
+			break;
+		}
+		lp = list_entry(receivedQueue.next, struct net_local, rcv);
+
+		list_del_init(&(lp->rcv));
+		spin_unlock_irqrestore(&receivedQueueSpin, flags);
+		dev = lp->ndev;
+
+		spin_lock_irqsave(&XTE_rx_spinlock, flags);
+		if ((bd_processed =
+		     XLlDma_BdRingFromHw(&lp->Dma.RxBdRing, XTE_RECV_BD_CNT, &BdPtr)) > 0) {
+
+			bd_processed_saved = bd_processed;
+			BdCurPtr = BdPtr;
+			do {
+				/*
+				 * Regular length field not updated on rx,
+				 * USR4 updated instead.
+				 */
+				len = BdGetRxLen(BdCurPtr);
+
+				/* get ptr to skb */
+				skb = (struct sk_buff *)
+					XLlDma_mBdGetId(BdCurPtr);
+
+				/* get and free up dma handle used by skb->data */
+				skb_baddr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdCurPtr);
+				dma_unmap_single(dev->dev.parent, skb_baddr,
+						 lp->frame_size,
+						 DMA_FROM_DEVICE);
+
+				/* reset ID */
+				XLlDma_mBdSetId(BdCurPtr, NULL);
+
+				/* setup received skb and send it upstream */
+				skb_put(skb, len);	/* Tell the skb how much data we got. */
+				skb->dev = dev;
+
+				/* this routine adjusts skb->data to skip the header */
+				skb->protocol = eth_type_trans(skb, dev);
+
+				/* default the ip_summed value */
+				skb->ip_summed = CHECKSUM_NONE;
+
+				/* if we're doing rx csum offload, set it up */
+				if (((lp->local_features & LOCAL_FEATURE_RX_CSUM) != 0) &&
+				    (skb->protocol == __constant_htons(ETH_P_IP)) &&
+				    (skb->len > 64)) {
+					unsigned int csum;
+
+					/*
+					 * This hardware only supports proper checksum calculations
+					 * on TCP/UDP packets.
+					 *
+					 * skb->csum is an overloaded value. On send, skb->csum is
+					 * the offset into the buffer (skb_transport_header(skb))
+					 * to place the csum value. On receive this feild gets set
+					 * to the actual csum value, before it's passed up the stack.
+					 *
+					 * If we set skb->ip_summed to CHECKSUM_COMPLETE, the ethernet
+					 * stack above will compute the pseudoheader csum value and
+					 * add it to the partial checksum already computed (to be
+					 * placed in skb->csum) and verify it.
+					 *
+					 * Setting skb->ip_summed to CHECKSUM_NONE means that the
+					 * cheksum didn't verify and the stack will (re)check it.
+					 *
+					 * Setting skb->ip_summed to CHECKSUM_UNNECESSARY means
+					 * that the cheksum was verified/assumed to be good and the
+					 * stack does not need to (re)check it.
+					 *
+					 * The ethernet stack above will (re)compute the checksum
+					 * under the following conditions:
+					 * 1) skb->ip_summed was set to CHECKSUM_NONE
+					 * 2) skb->len does not match the length of the ethernet
+					 *    packet determined by parsing the packet. In this case
+					 *    the ethernet stack will assume any prior checksum
+					 *    value was miscomputed and throw it away.
+					 * 3) skb->ip_summed was set to CHECKSUM_COMPLETE, skb->csum was
+					 *    set, but the result does not check out ok by the
+					 *    ethernet stack.
+					 *
+					 * If the TEMAC hardware stripping feature is off, each
+					 * packet will contain an FCS feild which will have been
+					 * computed by the hardware checksum operation. This 4 byte
+					 * FCS value needs to be subtracted back out of the checksum
+					 * value computed by hardware as it's not included in a
+					 * normal ethernet packet checksum.
+					 *
+					 * The minimum transfer packet size over the wire is 64
+					 * bytes. If the packet is sent as exactly 64 bytes, then
+					 * it probably contains some random padding bytes. It's
+					 * somewhat difficult to determine the actual length of the
+					 * real packet data, so we just let the stack recheck the
+					 * checksum for us.
+					 *
+					 * After the call to eth_type_trans(), the following holds
+					 * true:
+					 *    skb->data points to the beginning of the ip header
+					 */
+					csum = BdCsumGet(BdCurPtr);
+
+#if ! XTE_AUTOSTRIPPING
+					if (!lp->stripping) {
+						/* take off the FCS */
+						u16 *data;
+
+						/* FCS is 4 bytes */
+						skb_put(skb, -4);
+
+						data = (u16 *) (&skb->
+								data[skb->len]);
+
+						/* subtract out the FCS from the csum value */
+						csum = csum_sub(csum, *data /* & 0xffff */);
+						data++;
+						csum = csum_sub(csum, *data /* & 0xffff */);
+					}
+#endif
+					skb->csum = csum;
+					skb->ip_summed = CHECKSUM_COMPLETE;
+
+					lp->rx_hw_csums++;
+				}
+
+				lp->stats.rx_packets++;
+				lp->stats.rx_bytes += len;
+				netif_rx(skb);	/* Send the packet upstream. */
+
+				BdCurPtr =
+					XLlDma_mBdRingNext(&lp->Dma.RxBdRing,
+							   BdCurPtr);
+				bd_processed--;
+			} while (bd_processed > 0);
+
+			/* give the descriptor back to the driver */
+			result = XLlDma_BdRingFree(&lp->Dma.RxBdRing,
+						   bd_processed_saved, BdPtr);
+			if (result != XST_SUCCESS) {
+				printk(KERN_ERR
+				       "%s: XLlDma: BdRingFree unsuccessful (%d)\n",
+				       dev->name, result);
+				reset(dev, __LINE__);
+				spin_unlock_irqrestore(&XTE_rx_spinlock, flags);
+				return;
+			}
+
+			_xenet_DmaSetupRecvBuffers(dev);
+		}
+		XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+		spin_unlock_irqrestore(&XTE_rx_spinlock, flags);
+	}
+}
+
+static int descriptor_init(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	int recvsize, sendsize;
+	int dftsize;
+	u32 *recvpoolptr, *sendpoolptr;
+	void *recvpoolphy, *sendpoolphy;
+	int result;
+
+/*
+ * Buffer Descriptr
+ * word	byte	description
+ * 0	0h	next ptr
+ * 1	4h	buffer addr
+ * 2	8h	buffer len
+ * 3	ch	sts/ctrl | app data (0) [tx csum enable (bit 31 LSB)]
+ * 4	10h	app data (1) [tx csum begin (bits 0-15 MSB) | csum insert (bits 16-31 LSB)]
+ * 5	14h	app data (2) [tx csum seed (bits 16-31 LSB)]
+ * 6	18h	app data (3) [rx raw csum (bits 16-31 LSB)]
+ * 7	1ch	app data (4) [rx recv length (bits 18-31 LSB)]
+ */
+#if 0
+	int XferType = XDMAV3_DMACR_TYPE_BFBURST_MASK;
+	int XferWidth = XDMAV3_DMACR_DSIZE_64_MASK;
+#endif
+
+	/* calc size of descriptor space pool; alloc from non-cached memory */
+	dftsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD,
+					XTE_RECV_BD_CNT + XTE_SEND_BD_CNT);
+	printk(KERN_INFO "XLlTemac: buffer descriptor size: %d (0x%0x)\n",
+	       dftsize, dftsize);
+
+#if BD_IN_BRAM == 0
+	/*
+	 * Allow buffer descriptors to be cached.
+	 * Old method w/cache on buffer descriptors disabled:
+	 *     lp->desc_space = dma_alloc_coherent(NULL, dftsize,
+	 *         &lp->desc_space_handle, GFP_KERNEL);
+	 * (note if going back to dma_alloc_coherent() the CACHE macros in
+	 * xenv_linux.h need to be disabled.
+	 */
+
+        printk(KERN_INFO "XLlTemac: Allocating DMA descriptors with kmalloc");
+        lp->desc_space = kmalloc(dftsize, GFP_KERNEL);
+	lp->desc_space_handle = (dma_addr_t) page_to_phys(virt_to_page(lp->desc_space));
+#else
+        printk(KERN_INFO "XLlTemac: Allocating DMA descriptors in Block Ram");
+	lp->desc_space_handle = BRAM_BASEADDR;
+	lp->desc_space = ioremap(lp->desc_space_handle, dftsize);
+#endif
+	if (lp->desc_space == NULL)
+		return -1;
+
+	lp->desc_space_size = dftsize;
+
+	printk(KERN_INFO
+	       "XLlTemac: (buffer_descriptor_init) phy: 0x%x, virt: 0x%x, size: 0x%x\n",
+	       lp->desc_space_handle, (unsigned int) lp->desc_space,
+	       lp->desc_space_size);
+
+	/* calc size of send and recv descriptor space */
+	recvsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD, XTE_RECV_BD_CNT);
+	sendsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD, XTE_SEND_BD_CNT);
+
+	recvpoolptr = lp->desc_space;
+	sendpoolptr = (void *) ((u32) lp->desc_space + recvsize);
+
+	recvpoolphy = (void *) lp->desc_space_handle;
+	sendpoolphy = (void *) ((u32) lp->desc_space_handle + recvsize);
+
+	result = XLlDma_BdRingCreate(&lp->Dma.RxBdRing, (u32) recvpoolphy,
+				     (u32) recvpoolptr, ALIGNMENT_BD,
+				     XTE_RECV_BD_CNT);
+	if (result != XST_SUCCESS) {
+		printk(KERN_ERR "XLlTemac: DMA Ring Create (RECV). Error: %d\n", result);
+		return -EIO;
+	}
+
+	result = XLlDma_BdRingCreate(&lp->Dma.TxBdRing, (u32) sendpoolphy,
+				     (u32) sendpoolptr, ALIGNMENT_BD,
+				     XTE_SEND_BD_CNT);
+	if (result != XST_SUCCESS) {
+		printk(KERN_ERR "XLlTemac: DMA Ring Create (SEND). Error: %d\n", result);
+		return -EIO;
+	}
+
+	_xenet_DmaSetupRecvBuffers(dev);
+	return 0;
+}
+
+static void free_descriptor_skb(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	XLlDma_Bd *BdPtr;
+	struct sk_buff *skb;
+	dma_addr_t skb_dma_addr;
+	u32 len, i;
+
+	/* Unmap and free skb's allocated and mapped in descriptor_init() */
+
+	/* Get the virtual address of the 1st BD in the DMA RX BD ring */
+	BdPtr = (XLlDma_Bd *) lp->Dma.RxBdRing.FirstBdAddr;
+
+	for (i = 0; i < XTE_RECV_BD_CNT; i++) {
+		skb = (struct sk_buff *) XLlDma_mBdGetId(BdPtr);
+		if (skb) {
+			skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdPtr);
+			dma_unmap_single(dev->dev.parent, skb_dma_addr,
+					lp->frame_size, DMA_FROM_DEVICE);
+			dev_kfree_skb(skb);
+		}
+		/* find the next BD in the DMA RX BD ring */
+		BdPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing, BdPtr);
+	}
+
+	/* Unmap and free TX skb's that have not had a chance to be freed
+	 * in DmaSendHandlerBH(). This could happen when TX Threshold is larger
+	 * than 1 and TX waitbound is 0
+	 */
+
+	/* Get the virtual address of the 1st BD in the DMA TX BD ring */
+	BdPtr = (XLlDma_Bd *) lp->Dma.TxBdRing.FirstBdAddr;
+
+	for (i = 0; i < XTE_SEND_BD_CNT; i++) {
+		skb = (struct sk_buff *) XLlDma_mBdGetId(BdPtr);
+		if (skb) {
+			skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdPtr);
+			len = XLlDma_mBdGetLength(BdPtr);
+			dma_unmap_single(dev->dev.parent, skb_dma_addr, len,
+					 DMA_TO_DEVICE);
+			dev_kfree_skb(skb);
+		}
+		/* find the next BD in the DMA TX BD ring */
+		BdPtr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, BdPtr);
+	}
+
+#if BD_IN_BRAM == 0
+	kfree(lp->desc_space);
+/* this is old approach which was removed */
+/*	dma_free_coherent(NULL,
+			  lp->desc_space_size,
+			  lp->desc_space, lp->desc_space_handle); */
+#else
+	iounmap(lp->desc_space);
+#endif
+}
+
+static int
+xenet_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	u32 mac_options;
+	u32 threshold, timer;
+	u16 gmii_cmd, gmii_status, gmii_advControl;
+
+	memset(ecmd, 0, sizeof(struct ethtool_cmd));
+
+	mac_options = XLlTemac_GetOptions(&(lp->Emac));
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &gmii_cmd);
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &gmii_status);
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_ADVERTISE, &gmii_advControl);
+
+	ecmd->duplex = DUPLEX_FULL;
+
+	ecmd->supported |= SUPPORTED_MII;
+
+	ecmd->port = PORT_MII;
+
+	ecmd->speed = lp->cur_speed;
+
+	if (gmii_status & BMSR_ANEGCAPABLE) {
+		ecmd->supported |= SUPPORTED_Autoneg;
+	}
+	if (gmii_status & BMSR_ANEGCOMPLETE) {
+		ecmd->autoneg = AUTONEG_ENABLE;
+		ecmd->advertising |= ADVERTISED_Autoneg;
+	}
+	else {
+		ecmd->autoneg = AUTONEG_DISABLE;
+	}
+	ecmd->phy_address = lp->Emac.Config.BaseAddress;
+	ecmd->transceiver = XCVR_INTERNAL;
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		/* get TX threshold */
+
+		XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold, &timer);
+		ecmd->maxtxpkt = threshold;
+
+		/* get RX threshold */
+		XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold, &timer);
+		ecmd->maxrxpkt = threshold;
+	}
+
+	ecmd->supported |= SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full |
+		SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
+
+	return 0;
+}
+
+static int
+xenet_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	if ((ecmd->duplex != DUPLEX_FULL) ||
+	    (ecmd->transceiver != XCVR_INTERNAL) ||
+	    (ecmd->phy_address &&
+	     (ecmd->phy_address != lp->Emac.Config.BaseAddress))) {
+		return -EOPNOTSUPP;
+	}
+
+	if ((ecmd->speed != 1000) && (ecmd->speed != 100) &&
+	    (ecmd->speed != 10)) {
+		printk(KERN_ERR
+		       "%s: XLlTemac: xenet_ethtool_set_settings speed not supported: %d\n",
+		       dev->name, ecmd->speed);
+		return -EOPNOTSUPP;
+	}
+
+	if (ecmd->speed != lp->cur_speed) {
+		renegotiate_speed(dev, ecmd->speed, FULL_DUPLEX);
+		_XLlTemac_SetOperatingSpeed(&lp->Emac, ecmd->speed);
+		lp->cur_speed = ecmd->speed;
+	}
+	return 0;
+}
+
+static int
+xenet_ethtool_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	u32 threshold, waitbound;
+
+	memset(ec, 0, sizeof(struct ethtool_coalesce));
+
+	if (!(XLlTemac_IsDma(&lp->Emac))) {
+		return -EIO;
+	}
+
+	XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold, &waitbound);
+	ec->rx_max_coalesced_frames = threshold;
+	ec->rx_coalesce_usecs = waitbound;
+
+	XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold, &waitbound);
+	ec->tx_max_coalesced_frames = threshold;
+	ec->tx_coalesce_usecs = waitbound;
+
+	return 0;
+}
+
+#if 0
+static void disp_bd_ring(XLlDma_BdRing *bd_ring)
+{
+	int num_bds = bd_ring->AllCnt;
+	u32 *cur_bd_ptr = (u32 *) bd_ring->FirstBdAddr;
+	int idx;
+
+	printk("ChanBase: %p\n", (void *) bd_ring->ChanBase);
+	printk("FirstBdPhysAddr: %p\n", (void *) bd_ring->FirstBdPhysAddr);
+	printk("FirstBdAddr: %p\n", (void *) bd_ring->FirstBdAddr);
+	printk("LastBdAddr: %p\n", (void *) bd_ring->LastBdAddr);
+	printk("Length: %d (0x%0x)\n", bd_ring->Length, bd_ring->Length);
+	printk("RunState: %d (0x%0x)\n", bd_ring->RunState, bd_ring->RunState);
+	printk("Separation: %d (0x%0x)\n", bd_ring->Separation,
+	       bd_ring->Separation);
+	printk("BD Count: %d\n", bd_ring->AllCnt);
+
+	printk("\n");
+
+	printk("FreeHead: %p\n", (void *) bd_ring->FreeHead);
+	printk("PreHead: %p\n", (void *) bd_ring->PreHead);
+	printk("HwHead: %p\n", (void *) bd_ring->HwHead);
+	printk("HwTail: %p\n", (void *) bd_ring->HwTail);
+	printk("PostHead: %p\n", (void *) bd_ring->PostHead);
+	printk("BdaRestart: %p\n", (void *) bd_ring->BdaRestart);
+
+	printk("Ring Contents:\n");
+/*
+ * Buffer Descriptr
+ * word	byte	description
+ * 0	0h	next ptr
+ * 1	4h	buffer addr
+ * 2	8h	buffer len
+ * 3	ch	sts/ctrl | app data (0) [tx csum enable (bit 31 LSB)]
+ * 4	10h	app data (1) [tx csum begin (bits 0-15 MSB) | csum insert (bits 16-31 LSB)]
+ * 5	14h	app data (2) [tx csum seed (bits 16-31 LSB)]
+ * 6	18h	app data (3) [rx raw csum (bits 16-31 LSB)]
+ * 7	1ch	app data (4) [rx recv length (bits 18-31 LSB)]
+ * 8	20h	sw app data (0) [id]
+ */
+	printk("Idx   NextBD BuffAddr   Length  CTL/CSE CSUM B/I CSUMSeed Raw CSUM  RecvLen       ID\n");
+	printk("--- -------- -------- -------- -------- -------- -------- -------- -------- --------\n");
+
+	for (idx = 0; idx < num_bds; idx++) {
+		printk("%3d %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
+		       idx,
+		       cur_bd_ptr[XLLDMA_BD_NDESC_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_BUFA_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_BUFL_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_STSCTRL_USR0_OFFSET /
+				  sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_USR1_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_USR2_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_USR3_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_USR4_OFFSET / sizeof(*cur_bd_ptr)],
+		       cur_bd_ptr[XLLDMA_BD_ID_OFFSET / sizeof(*cur_bd_ptr)]);
+
+		cur_bd_ptr += bd_ring->Separation / sizeof(int);
+	}
+	printk("--------------------------------------- Done ---------------------------------------\n");
+}
+#endif
+
+static int
+xenet_ethtool_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+	int ret;
+	struct net_local *lp;
+
+	lp = (struct net_local *) netdev_priv(dev);
+
+	if (!(XLlTemac_IsDma(&lp->Emac))) {
+		return -EIO;
+	}
+
+	if (ec->rx_coalesce_usecs == 0) {
+		ec->rx_coalesce_usecs = 1;
+		dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+	}
+	if ((ret = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing,
+			(u16) (ec->rx_max_coalesced_frames),
+			(u16) (ec->rx_coalesce_usecs))) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: XLlDma: BdRingSetCoalesce error %d\n",
+		       dev->name, ret);
+		return -EIO;
+	}
+	XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+
+	if (ec->tx_coalesce_usecs == 0) {
+		ec->tx_coalesce_usecs = 1;
+		dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+	}
+	if ((ret = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing,
+			(u16) (ec->tx_max_coalesced_frames),
+			(u16) (ec->tx_coalesce_usecs))) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: XLlDma: BdRingSetCoalesce error %d\n",
+		       dev->name, ret);
+		return -EIO;
+	}
+	XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+	return 0;
+}
+
+static void
+xenet_ethtool_get_ringparam(struct net_device *dev,
+			    struct ethtool_ringparam *erp)
+{
+	memset(erp, 0, sizeof(struct ethtool_ringparam));
+
+	erp->rx_max_pending = XTE_RECV_BD_CNT;
+	erp->tx_max_pending = XTE_SEND_BD_CNT;
+	erp->rx_pending = XTE_RECV_BD_CNT;
+	erp->tx_pending = XTE_SEND_BD_CNT;
+}
+
+static void
+xenet_ethtool_get_pauseparam(struct net_device *dev,
+			     struct ethtool_pauseparam *epp)
+{
+	u32 Options;
+	u16 gmii_status;
+	struct net_local *lp = netdev_priv(dev);
+
+	_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &gmii_status);
+
+	/* I suspect that the expected value is that autonegotiation is
+	 * enabled,  not completed.
+	 * As seen in xenet_do_ethtool_ioctl() */
+        if (gmii_status & BMSR_ANEGCOMPLETE) {
+                epp->autoneg = AUTONEG_ENABLE;
+        }
+        else {
+                epp->autoneg = AUTONEG_DISABLE;
+        }
+
+	Options = XLlTemac_GetOptions(&lp->Emac);
+	if (Options & XTE_FLOW_CONTROL_OPTION) {
+		epp->rx_pause = 1;
+		epp->tx_pause = 1;
+	}
+	else {
+		epp->rx_pause = 0;
+		epp->tx_pause = 0;
+	}
+}
+
+#if 0
+static u32
+xenet_ethtool_get_rx_csum(struct net_device *dev)
+{
+	struct net_local *lp = netdev_priv(dev);
+	u32 retval;
+
+ 	retval = (lp->local_features & LOCAL_FEATURE_RX_CSUM) != 0;
+
+ 	return retval;
+}
+
+static int
+xenet_ethtool_set_rx_csum(struct net_device *dev, u32 onoff)
+{
+	struct net_local *lp = netdev_priv(dev);
+
+	if (onoff) {
+		if (XLlTemac_IsRxCsum(&lp->Emac) == TRUE) {
+			lp->local_features |=
+				LOCAL_FEATURE_RX_CSUM;
+		}
+	}
+	else {
+		lp->local_features &= ~LOCAL_FEATURE_RX_CSUM;
+	}
+
+	return 0;
+}
+
+static u32
+xenet_ethtool_get_tx_csum(struct net_device *dev)
+{
+	u32 retval;
+
+	retval = (dev->features & NETIF_F_IP_CSUM) != 0;
+	return retval;
+}
+
+static int
+xenet_ethtool_set_tx_csum(struct net_device *dev, u32 onoff)
+{
+	struct net_local *lp = netdev_priv(dev);
+
+	if (onoff) {
+		if (XLlTemac_IsTxCsum(&lp->Emac) == TRUE) {
+			dev->features |= NETIF_F_IP_CSUM;
+		}
+	}
+	else {
+		dev->features &= ~NETIF_F_IP_CSUM;
+	}
+
+	return 0;
+}
+
+static u32
+xenet_ethtool_get_sg(struct net_device *dev)
+{
+	u32 retval;
+
+	retval = (dev->features & NETIF_F_SG) != 0;
+
+	return retval;
+}
+
+static int
+xenet_ethtool_set_sg(struct net_device *dev, u32 onoff)
+{
+	struct net_local *lp = netdev_priv(dev);
+
+	if (onoff) {
+		if (XLlTemac_IsDma(&lp->Emac)) {
+			dev->features |=
+				NETIF_F_SG | NETIF_F_FRAGLIST;
+		}
+	}
+	else {
+		dev->features &=
+			~(NETIF_F_SG | NETIF_F_FRAGLIST);
+	}
+
+	return 0;
+}
+#endif
+static void
+xenet_ethtool_get_strings(struct net_device *dev, u32 stringset, u8 *strings)
+{
+	*strings = 0;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(strings,
+			&xenet_ethtool_gstrings_stats,
+			sizeof(xenet_ethtool_gstrings_stats));
+
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void
+xenet_ethtool_get_ethtool_stats(struct net_device *dev,
+	struct ethtool_stats *stats, u64 *data)
+{
+	struct net_local *lp = netdev_priv(dev);
+
+	data[0] = lp->stats.tx_packets;
+	data[1] = lp->stats.tx_dropped;
+	data[2] = lp->stats.tx_errors;
+	data[3] = lp->stats.tx_fifo_errors;
+	data[4] = lp->stats.rx_packets;
+	data[5] = lp->stats.rx_dropped;
+	data[6] = lp->stats.rx_errors;
+	data[7] = lp->stats.rx_fifo_errors;
+	data[8] = lp->stats.rx_crc_errors;
+	data[9] = lp->max_frags_in_a_packet;
+	data[10] = lp->tx_hw_csums;
+	data[11] = lp->rx_hw_csums;
+}
+
+static int
+xenet_ethtool_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return XENET_STATS_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+
+#define EMAC_REGS_N 32
+struct mac_regsDump {
+	struct ethtool_regs hd;
+	u16 data[EMAC_REGS_N];
+};
+
+static int
+xenet_ethtool_get_regs_len(struct net_device *dev)
+{
+	return (sizeof(u16) * EMAC_REGS_N);
+}
+
+static void
+xenet_ethtool_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+		       void *ret)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct mac_regsDump *dump = (struct mac_regsDump *) regs;
+	int i;
+
+	dump->hd.version = 0;
+	dump->hd.len = sizeof(dump->data);
+	memset(dump->data, 0, sizeof(dump->data));
+
+	for (i = 0; i < EMAC_REGS_N; i++) {
+		_XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, i, &(dump->data[i]));
+	}
+
+	*(int *) ret = 0;
+}
+
+static void
+xenet_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *ed)
+{
+	memset(ed, 0, sizeof(struct ethtool_drvinfo));
+	strncpy(ed->driver, DRIVER_NAME, sizeof(ed->driver) - 1);
+	strncpy(ed->version, DRIVER_VERSION, sizeof(ed->version) - 1);
+	/* Also tell how much memory is needed for dumping register values */
+	ed->regdump_len = sizeof(u16) * EMAC_REGS_N;
+	ed->n_stats = XENET_STATS_LEN;
+}
+
+/*
+ * xenet_do_ethtool_ioctl:
+ * DEPRECATED
+ */
+static int xenet_do_ethtool_ioctl(struct net_device *dev, struct ifreq *rq)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct ethtool_cmd ecmd;
+	struct ethtool_coalesce eco;
+	struct ethtool_drvinfo edrv;
+	struct ethtool_ringparam erp;
+	struct ethtool_pauseparam epp;
+	struct mac_regsDump regs;
+	int ret = -EOPNOTSUPP;
+	u32 Options;
+
+	if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+		return -EFAULT;
+	switch (ecmd.cmd) {
+	case ETHTOOL_GSET:	/* Get setting. No command option needed w/ ethtool */
+		ret = xenet_ethtool_get_settings(dev, &ecmd);
+		if (ret < 0)
+			return -EIO;
+		if (copy_to_user(rq->ifr_data, &ecmd, sizeof(ecmd)))
+			return -EFAULT;
+		ret = 0;
+		break;
+	case ETHTOOL_SSET:	/* Change setting. Use "-s" command option w/ ethtool */
+		ret = xenet_ethtool_set_settings(dev, &ecmd);
+		break;
+	case ETHTOOL_GPAUSEPARAM:	/* Get pause parameter information. Use "-a" w/ ethtool */
+		ret = xenet_ethtool_get_settings(dev, &ecmd);
+		if (ret < 0)
+			return ret;
+		epp.cmd = ecmd.cmd;
+		epp.autoneg = ecmd.autoneg;
+		Options = XLlTemac_GetOptions(&lp->Emac);
+		if (Options & XTE_FCS_INSERT_OPTION) {
+			epp.rx_pause = 1;
+			epp.tx_pause = 1;
+		}
+		else {
+			epp.rx_pause = 0;
+			epp.tx_pause = 0;
+		}
+		if (copy_to_user
+		    (rq->ifr_data, &epp, sizeof(struct ethtool_pauseparam)))
+			return -EFAULT;
+		ret = 0;
+		break;
+	case ETHTOOL_SPAUSEPARAM:	/* Set pause parameter. Use "-A" w/ ethtool */
+		return -EOPNOTSUPP;	/* TODO: To support in next version */
+	case ETHTOOL_GRXCSUM:{	/* Get rx csum offload info. Use "-k" w/ ethtool */
+			struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+
+			edata.data =
+				(lp->local_features & LOCAL_FEATURE_RX_CSUM) !=
+				0;
+			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+				return -EFAULT;
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_SRXCSUM:{	/* Set rx csum offload info. Use "-K" w/ ethtool */
+			struct ethtool_value edata;
+
+			if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+				return -EFAULT;
+
+			if (edata.data) {
+				if (XLlTemac_IsRxCsum(&lp->Emac) == TRUE) {
+					lp->local_features |=
+						LOCAL_FEATURE_RX_CSUM;
+				}
+			}
+			else {
+				lp->local_features &= ~LOCAL_FEATURE_RX_CSUM;
+			}
+
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_GTXCSUM:{	/* Get tx csum offload info. Use "-k" w/ ethtool */
+			struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+			edata.data = (dev->features & NETIF_F_IP_CSUM) != 0;
+			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+				return -EFAULT;
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_STXCSUM:{	/* Set tx csum offload info. Use "-K" w/ ethtool */
+			struct ethtool_value edata;
+
+			if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+				return -EFAULT;
+
+			if (edata.data) {
+				if (XLlTemac_IsTxCsum(&lp->Emac) == TRUE) {
+					dev->features |= NETIF_F_IP_CSUM;
+				}
+			}
+			else {
+				dev->features &= ~NETIF_F_IP_CSUM;
+			}
+
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_GSG:{	/* Get ScatterGather info. Use "-k" w/ ethtool */
+			struct ethtool_value edata = { ETHTOOL_GSG };
+
+			edata.data = (dev->features & NETIF_F_SG) != 0;
+			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+				return -EFAULT;
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_SSG:{	/* Set ScatterGather info. Use "-K" w/ ethtool */
+			struct ethtool_value edata;
+
+			if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+				return -EFAULT;
+
+			if (edata.data) {
+				if (XLlTemac_IsDma(&lp->Emac)) {
+					dev->features |=
+						NETIF_F_SG | NETIF_F_FRAGLIST;
+				}
+			}
+			else {
+				dev->features &=
+					~(NETIF_F_SG | NETIF_F_FRAGLIST);
+			}
+
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_GCOALESCE:	/* Get coalescing info. Use "-c" w/ ethtool */
+		if (!(XLlTemac_IsDma(&lp->Emac)))
+			break;
+		eco.cmd = ecmd.cmd;
+		ret = xenet_ethtool_get_coalesce(dev, &eco);
+		if (ret < 0) {
+			return -EIO;
+		}
+		if (copy_to_user
+		    (rq->ifr_data, &eco, sizeof(struct ethtool_coalesce))) {
+			return -EFAULT;
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_SCOALESCE:	/* Set coalescing info. Use "-C" w/ ethtool */
+		if (!(XLlTemac_IsDma(&lp->Emac)))
+			break;
+		if (copy_from_user
+		    (&eco, rq->ifr_data, sizeof(struct ethtool_coalesce)))
+			return -EFAULT;
+		ret = xenet_ethtool_set_coalesce(dev, &eco);
+		break;
+	case ETHTOOL_GDRVINFO:	/* Get driver information. Use "-i" w/ ethtool */
+		edrv.cmd = edrv.cmd;
+		xenet_ethtool_get_drvinfo(dev, &edrv);
+		edrv.n_stats = XENET_STATS_LEN;
+		if (copy_to_user
+		    (rq->ifr_data, &edrv, sizeof(struct ethtool_drvinfo))) {
+			return -EFAULT;
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_GREGS:	/* Get register values. Use "-d" with ethtool */
+		regs.hd.cmd = edrv.cmd;
+		xenet_ethtool_get_regs(dev, &(regs.hd), &ret);
+		if (ret < 0) {
+			return ret;
+		}
+		if (copy_to_user
+		    (rq->ifr_data, &regs, sizeof(struct mac_regsDump))) {
+			return -EFAULT;
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_GRINGPARAM:	/* Get RX/TX ring parameters. Use "-g" w/ ethtool */
+		erp.cmd = edrv.cmd;
+		xenet_ethtool_get_ringparam(dev, &(erp));
+		if (copy_to_user
+		    (rq->ifr_data, &erp, sizeof(struct ethtool_ringparam))) {
+			return -EFAULT;
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_NWAY_RST:	/* Restart auto negotiation if enabled. Use "-r" w/ ethtool */
+		return -EOPNOTSUPP;	/* TODO: To support in next version */
+	case ETHTOOL_GSTRINGS:{
+			struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
+			void __user *addr = rq->ifr_data;
+			char *strings = NULL;
+
+			if (copy_from_user(&gstrings, addr, sizeof(gstrings))) {
+				return -EFAULT;
+			}
+			switch (gstrings.string_set) {
+			case ETH_SS_STATS:
+				gstrings.len = XENET_STATS_LEN;
+				strings = *xenet_ethtool_gstrings_stats;
+				break;
+			default:
+				return -EOPNOTSUPP;
+			}
+			if (copy_to_user(addr, &gstrings, sizeof(gstrings))) {
+				return -EFAULT;
+			}
+			addr += offsetof(struct ethtool_gstrings, data);
+			if (copy_to_user
+			    (addr, strings, gstrings.len * ETH_GSTRING_LEN)) {
+				return -EFAULT;
+			}
+			ret = 0;
+			break;
+		}
+	case ETHTOOL_GSTATS:{
+			struct {
+				struct ethtool_stats cmd;
+				uint64_t data[XENET_STATS_LEN];
+			} stats = { {
+			ETHTOOL_GSTATS, XENET_STATS_LEN}};
+
+			stats.data[0] = lp->stats.tx_packets;
+			stats.data[1] = lp->stats.tx_dropped;
+			stats.data[2] = lp->stats.tx_errors;
+			stats.data[3] = lp->stats.tx_fifo_errors;
+			stats.data[4] = lp->stats.rx_packets;
+			stats.data[5] = lp->stats.rx_dropped;
+			stats.data[6] = lp->stats.rx_errors;
+			stats.data[7] = lp->stats.rx_fifo_errors;
+			stats.data[8] = lp->stats.rx_crc_errors;
+			stats.data[9] = lp->max_frags_in_a_packet;
+			stats.data[10] = lp->tx_hw_csums;
+			stats.data[11] = lp->rx_hw_csums;
+
+			if (copy_to_user(rq->ifr_data, &stats, sizeof(stats))) {
+				return -EFAULT;
+			}
+			ret = 0;
+			break;
+		}
+	default:
+		return -EOPNOTSUPP;	/* All other operations not supported */
+	}
+	return ret;
+}
+
+static int xenet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	/* gmii_ioctl_data has 4 u16 fields: phy_id, reg_num, val_in & val_out */
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *) &rq->ifr_data;
+	struct {
+		__u16 threshold;
+		__u32 direction;
+	} thr_arg;
+	struct {
+		__u16 waitbound;
+		__u32 direction;
+	} wbnd_arg;
+
+	int ret;
+	u32 threshold, timer;
+	XLlDma_BdRing *RingPtr;
+	u32 *dma_int_mask_ptr;
+
+	switch (cmd) {
+	case SIOCETHTOOL:
+		/* DEPRECATED */
+		return xenet_do_ethtool_ioctl(dev, rq);
+	case SIOCGMIIPHY:	/* Get address of GMII PHY in use. */
+	case SIOCDEVPRIVATE:	/* for binary compat, remove in 2.5 */
+		data->phy_id = lp->gmii_addr;
+		/* Fall Through */
+
+	case SIOCGMIIREG:	/* Read GMII PHY register. */
+	case SIOCDEVPRIVATE + 1:	/* for binary compat, remove in 2.5 */
+		if (data->phy_id > 31 || data->reg_num > 31)
+			return -ENXIO;
+
+		/* Stop the PHY timer to prevent reentrancy. */
+		del_timer_sync(&lp->phy_timer);
+
+		_XLlTemac_PhyRead(&lp->Emac, data->phy_id, data->reg_num,
+				  &data->val_out);
+
+		/* Start the PHY timer up again. */
+		lp->phy_timer.expires = jiffies + 2 * HZ;
+		add_timer(&lp->phy_timer);
+		return 0;
+
+	case SIOCSMIIREG:	/* Write GMII PHY register. */
+	case SIOCDEVPRIVATE + 2:	/* for binary compat, remove in 2.5 */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		if (data->phy_id > 31 || data->reg_num > 31)
+			return -ENXIO;
+
+		/* Stop the PHY timer to prevent reentrancy. */
+		del_timer_sync(&lp->phy_timer);
+
+		_XLlTemac_PhyWrite(&lp->Emac, data->phy_id, data->reg_num,
+				   data->val_in);
+
+		/* Start the PHY timer up again. */
+		lp->phy_timer.expires = jiffies + 2 * HZ;
+		add_timer(&lp->phy_timer);
+		return 0;
+
+	case SIOCDEVPRIVATE + 3:	/* set THRESHOLD */
+		if (XLlTemac_IsFifo(&lp->Emac))
+			return -EFAULT;
+
+		if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg)))
+			return -EFAULT;
+
+		if (thr_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+		}
+		XLlDma_BdRingGetCoalesce(RingPtr, &threshold, &timer);
+		if (thr_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+		}
+		if ((ret = XLlDma_BdRingSetCoalesce(RingPtr, thr_arg.threshold,
+						    timer)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		return 0;
+
+	case SIOCDEVPRIVATE + 4:	/* set WAITBOUND */
+		if (!(XLlTemac_IsDma(&lp->Emac)))
+			return -EFAULT;
+
+		if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg)))
+			return -EFAULT;
+
+		if (wbnd_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+		}
+		XLlDma_BdRingGetCoalesce(RingPtr, &threshold, &timer);
+		if (wbnd_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+			dma_int_mask_ptr = &dma_tx_int_mask;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+			dma_int_mask_ptr = &dma_rx_int_mask;
+		}
+		if (wbnd_arg.waitbound == 0) {
+			wbnd_arg.waitbound = 1;
+			*dma_int_mask_ptr = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+		}
+		if ((ret = XLlDma_BdRingSetCoalesce(RingPtr, threshold,
+					wbnd_arg.waitbound)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		XLlDma_mBdRingIntEnable(RingPtr, *dma_int_mask_ptr);
+
+		return 0;
+
+	case SIOCDEVPRIVATE + 5:	/* get THRESHOLD */
+		if (!(XLlTemac_IsDma(&lp->Emac)))
+			return -EFAULT;
+
+		if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg)))
+			return -EFAULT;
+
+		if (thr_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+		}
+		XLlDma_BdRingGetCoalesce(RingPtr,
+				(u32 *) &(thr_arg.threshold), &timer);
+		if (copy_to_user(rq->ifr_data, &thr_arg, sizeof(thr_arg))) {
+			return -EFAULT;
+		}
+		return 0;
+
+	case SIOCDEVPRIVATE + 6:	/* get WAITBOUND */
+		if (!(XLlTemac_IsDma(&lp->Emac)))
+			return -EFAULT;
+
+		if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg))) {
+			return -EFAULT;
+		}
+		if (thr_arg.direction == XTE_SEND) {
+			RingPtr = &lp->Dma.TxBdRing;
+		} else {
+			RingPtr = &lp->Dma.RxBdRing;
+		}
+		XLlDma_BdRingGetCoalesce(RingPtr, &threshold,
+					 (u32 *) &(wbnd_arg.waitbound));
+		if (copy_to_user(rq->ifr_data, &wbnd_arg, sizeof(wbnd_arg))) {
+			return -EFAULT;
+		}
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
+/******************************************************************************
+ *
+ * NEW FUNCTIONS FROM LINUX 2.6
+ *
+ ******************************************************************************/
+
+static void xtenet_remove_ndev(struct net_device *ndev)
+{
+	if (ndev) {
+		struct net_local *lp = netdev_priv(ndev);
+
+		if (XLlTemac_IsDma(&lp->Emac) && (lp->desc_space))
+			free_descriptor_skb(ndev);
+
+		iounmap((__force void __iomem *) (lp->Emac.Config.BaseAddress));
+		free_netdev(ndev);
+	}
+}
+
+static int xtenet_remove(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+
+	unregister_netdev(ndev);
+	xtenet_remove_ndev(ndev);
+
+	return 0;		/* success */
+}
+
+/* Detect the PHY address by scanning addresses 0 to 31 and
+ * looking at the MII status register (register 1) and assuming
+ * the PHY supports 10Mbps full/half duplex. Feel free to change
+ * this code to match your PHY, or hardcode the address if needed.
+ */
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG  1
+
+#ifdef CONFIG_XILINX_LLTEMAC_XILINX_1000BASEX
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ *  0x0100: Extended register support
+ *  0x0180: Unidirectional support
+ *  0x0040: MF Preamble suppression support
+ *  0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x01C8
+#else
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ *  0x1000: 10Mbps full duplex support
+ *  0x0800: 10Mbps half duplex support
+ *  0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x1808
+#endif
+
+static int detect_phy(struct net_local *lp, char *dev_name)
+{
+	u16 phy_reg;
+	u32 phy_addr;
+
+	for (phy_addr = 31; phy_addr > 0; phy_addr--) {
+		_XLlTemac_PhyRead(&lp->Emac, phy_addr, PHY_DETECT_REG, &phy_reg);
+
+		if ((phy_reg != 0xFFFF) &&
+		    ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+			/* Found a valid PHY address */
+			printk(KERN_INFO "XTemac: PHY detected at address %d.\n", phy_addr);
+			return phy_addr;
+		}
+	}
+
+	printk(KERN_WARNING "XTemac: No PHY detected.  Assuming a PHY at address 0\n");
+	return 0;		/* default to zero */
+}
+
+static struct net_device_ops xilinx_netdev_ops;
+
+/* From include/linux/ethtool.h */
+static struct ethtool_ops ethtool_ops = {
+	.get_settings = xenet_ethtool_get_settings,
+	.set_settings = xenet_ethtool_set_settings,
+	.get_drvinfo  = xenet_ethtool_get_drvinfo,
+	.get_regs_len = xenet_ethtool_get_regs_len,
+	.get_regs     = xenet_ethtool_get_regs,
+	.get_coalesce = xenet_ethtool_get_coalesce,
+	.set_coalesce = xenet_ethtool_set_coalesce,
+	.get_ringparam  = xenet_ethtool_get_ringparam,
+	.get_pauseparam = xenet_ethtool_get_pauseparam,
+/*	.get_rx_csum  = xenet_ethtool_get_rx_csum,
+	.set_rx_csum  = xenet_ethtool_set_rx_csum,
+	.get_tx_csum  = xenet_ethtool_get_tx_csum,
+	.set_tx_csum  = xenet_ethtool_set_tx_csum,
+	.get_sg       = xenet_ethtool_get_sg,
+	.set_sg       = xenet_ethtool_set_sg, */
+	.get_strings  = xenet_ethtool_get_strings,
+	.get_ethtool_stats = xenet_ethtool_get_ethtool_stats,
+	.get_sset_count    = xenet_ethtool_get_sset_count,
+};
+
+/** Shared device initialization code */
+static int xtenet_setup(
+		struct device *dev,
+		struct resource *r_mem,
+		struct resource *r_irq,
+		struct xlltemac_platform_data *pdata) {
+	int xs;
+	u32 virt_baddr;		/* virtual base address of TEMAC */
+
+	XLlTemac_Config Temac_Config;
+
+	struct net_device *ndev = NULL;
+	struct net_local *lp = NULL;
+
+	int rc = 0;
+
+	/* Create an ethernet device instance */
+	ndev = alloc_etherdev(sizeof(struct net_local));
+	if (!ndev) {
+		dev_err(dev, "Could not allocate net device.\n");
+		rc = -ENOMEM;
+		goto error;
+	}
+	dev_set_drvdata(dev, ndev);
+
+	SET_NETDEV_DEV(ndev, dev);
+	ndev->irq = r_irq->start;
+
+	/* Initialize the private data used by XEmac_LookupConfig().
+	 * The private data are zeroed out by alloc_etherdev() already.
+	 */
+	lp = netdev_priv(ndev);
+	lp->ndev = ndev;
+	lp->dma_irq_r = pdata->ll_dev_dma_rx_irq;
+	lp->dma_irq_s = pdata->ll_dev_dma_tx_irq;
+	lp->fifo_irq = pdata->ll_dev_fifo_irq;
+
+	/* Setup the Config structure for the XLlTemac_CfgInitialize() call. */
+	Temac_Config.BaseAddress = r_mem->start;
+#if 0
+	Config.RxPktFifoDepth = pdata->rx_pkt_fifo_depth;
+	Config.TxPktFifoDepth = pdata->tx_pkt_fifo_depth;
+	Config.MacFifoDepth = pdata->mac_fifo_depth;
+	Config.IpIfDmaConfig = pdata->dma_mode;
+#endif
+	Temac_Config.TxCsum = pdata->tx_csum;
+	Temac_Config.RxCsum = pdata->rx_csum;
+	Temac_Config.LLDevType = pdata->ll_dev_type;
+	Temac_Config.LLDevBaseAddress = pdata->ll_dev_baseaddress;
+	Temac_Config.PhyType = pdata->phy_type;
+
+	/* Get the virtual base address for the device */
+	virt_baddr = (__force u32) ioremap(r_mem->start,
+					   r_mem->end - r_mem->start + 1);
+	if (0 == virt_baddr) {
+		dev_err(dev, "XLlTemac: Could not allocate iomem.\n");
+		rc = -EIO;
+		goto error;
+	}
+
+	if (XLlTemac_CfgInitialize(&lp->Emac, &Temac_Config, virt_baddr) !=
+	    XST_SUCCESS) {
+		dev_err(dev, "XLlTemac: Could not initialize device.\n");
+
+		rc = -ENODEV;
+		goto error;
+	}
+
+	/* Set the MAC address from platform data */
+        memcpy(ndev->dev_addr, pdata->mac_addr, 6);
+
+	if (_XLlTemac_SetMacAddress(&lp->Emac, ndev->dev_addr) != XST_SUCCESS) {
+		/* should not fail right after an initialize */
+		dev_err(dev, "XLlTemac: could not set MAC address.\n");
+		rc = -EIO;
+		goto error;
+	}
+
+	dev_info(dev,
+			"MAC address is now %2x:%2x:%2x:%2x:%2x:%2x\n",
+			pdata->mac_addr[0], pdata->mac_addr[1],
+			pdata->mac_addr[2], pdata->mac_addr[3],
+			pdata->mac_addr[4], pdata->mac_addr[5]);
+
+	if (ndev->mtu > XTE_JUMBO_MTU)
+		ndev->mtu = XTE_JUMBO_MTU;
+
+	lp->frame_size = ndev->mtu + XTE_HDR_SIZE + XTE_TRL_SIZE;
+
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		int result;
+
+		dev_err(dev, "XLlTemac: using DMA mode.\n");
+
+		if (pdata->dcr_host) {
+			printk("XLlTemac: DCR address: 0x%0x\n", pdata->ll_dev_baseaddress);
+			XLlDma_Initialize(&lp->Dma, pdata->ll_dev_baseaddress);
+			lp->virt_dma_addr = pdata->ll_dev_baseaddress;
+		} else {
+			virt_baddr = (__force u32) ioremap(pdata->ll_dev_baseaddress, 4096);
+			lp->virt_dma_addr = virt_baddr;
+			if (0 == virt_baddr) {
+				dev_err(dev,
+					"XLlTemac: Could not allocate iomem for local link connected device.\n");
+				rc = -EIO;
+				goto error;
+			}
+			printk("XLlTemac: Dma base address: phy: 0x%x, virt: 0x%x\n", pdata->ll_dev_baseaddress, virt_baddr);
+			XLlDma_Initialize(&lp->Dma, virt_baddr);
+		}
+
+		xilinx_netdev_ops.ndo_start_xmit = xenet_DmaSend;
+
+		result = descriptor_init(ndev);
+		if (result) {
+			rc = -EIO;
+			goto error;
+		}
+
+		/* set the packet threshold and wait bound for both TX/RX directions */
+		if (DFT_TX_WAITBOUND == 0) {
+			dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+			xs = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing, DFT_TX_THRESHOLD, 1);
+		} else {
+			xs = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing, DFT_TX_THRESHOLD, DFT_TX_WAITBOUND);
+		}
+		if (xs != XST_SUCCESS) {
+			dev_err(dev,
+			       "XLlTemac: could not set SEND pkt threshold/waitbound, ERROR %d",
+			       xs);
+		}
+		XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+		if (DFT_RX_WAITBOUND == 0) {
+			dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+			xs = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing, DFT_RX_THRESHOLD, 1);
+		} else {
+			xs = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing, DFT_RX_THRESHOLD, DFT_RX_WAITBOUND);
+		}
+		if (xs != XST_SUCCESS) {
+			dev_err(dev,
+			       "XLlTemac: Could not set RECV pkt threshold/waitbound ERROR %d",
+			       xs);
+		}
+		XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+	}
+	else {
+		dev_err(dev,
+		       "XLlTemac: using FIFO direct interrupt driven mode.\n");
+
+		virt_baddr = (__force u32) ioremap(pdata->ll_dev_baseaddress,
+						   4096);
+		if (0 == virt_baddr) {
+			dev_err(dev,
+			       "XLlTemac: Could not allocate iomem for local link connected device.\n");
+			rc = -EIO;
+			goto error;
+		}
+		printk("XLlTemac: Fifo base address: 0x%0x\n", virt_baddr);
+		XLlFifo_Initialize(&lp->Fifo, virt_baddr);
+
+		xilinx_netdev_ops.ndo_start_xmit = xenet_FifoSend;
+	}
+
+	/** Scan to find the PHY */
+	lp->gmii_addr = detect_phy(lp, ndev->name);
+
+
+	/* initialize the netdev structure */
+
+	ndev->netdev_ops = &xilinx_netdev_ops;
+
+	if (XLlTemac_IsDma(&lp->Emac)) {
+		ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+
+		if (XLlTemac_IsTxCsum(&lp->Emac) == TRUE) {
+			/*
+			 * This hardware only supports proper checksum calculations
+			 * on TCP/UDP packets.
+			 */
+			ndev->features |= NETIF_F_IP_CSUM;
+		}
+		if (XLlTemac_IsRxCsum(&lp->Emac) == TRUE) {
+			lp->local_features |= LOCAL_FEATURE_RX_CSUM;
+		}
+	}
+
+	ndev->watchdog_timeo = TX_TIMEOUT;
+
+	/* init the stats */
+	lp->max_frags_in_a_packet = 0;
+	lp->tx_hw_csums = 0;
+	lp->rx_hw_csums = 0;
+
+#if ! XTE_AUTOSTRIPPING
+	lp->stripping =
+		(XLlTemac_GetOptions(&(lp->Emac)) & XTE_FCS_STRIP_OPTION) != 0;
+#endif
+
+	/* Set ethtool IOCTL handler vectors.
+	 * xenet_do_ethtool_ioctl() is deprecated.
+	 */
+	SET_ETHTOOL_OPS(ndev, &ethtool_ops);
+
+	rc = register_netdev(ndev);
+	if (rc) {
+		dev_err(dev,
+		       "%s: Cannot register net device, aborting.\n",
+		       ndev->name);
+		goto error;	/* rc is already set here... */
+	}
+
+	dev_info(dev,
+		"%s: Xilinx TEMAC at 0x%08X mapped to 0x%08X, irq=%d\n",
+		ndev->name,
+		(unsigned int)r_mem->start,
+		lp->Emac.Config.BaseAddress,
+		ndev->irq);
+
+	return 0;
+
+error:
+	if (ndev) {
+		xtenet_remove_ndev(ndev);
+	}
+	return rc;
+}
+
+#if 0
+static int xtenet_probe(struct device *dev)
+{
+	struct resource *r_irq = NULL;	/* Interrupt resources */
+	struct resource *r_mem = NULL;	/* IO mem resources */
+	struct xlltemac_platform_data *pdata;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	/* param check */
+	if (!pdev) {
+		dev_err(dev, "Probe called with NULL param.\n");
+		return -ENODEV;
+	}
+
+	pdata = (struct xlltemac_platform_data *) pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(dev, "Couldn't find platform data.\n");
+
+		return -ENODEV;
+	}
+
+	/* Get iospace and an irq for the device */
+	r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r_irq || !r_mem) {
+		dev_err(dev, "IO resource(s) not found.\n");
+		return -ENODEV;
+	}
+
+        return xtenet_setup(dev, r_mem, r_irq, pdata);
+}
+#endif
+
+
+#ifdef CONFIG_OF
+static u32 get_u32(struct platform_device *op, const char *s) {
+	u32 *p = (u32 *)of_get_property(op->dev.of_node, s, NULL);
+	if(p) {
+		return *p;
+	} else {
+		dev_warn(&op->dev, "Parameter %s not found, defaulting to false.\n", s);
+		return FALSE;
+	}
+}
+
+static struct net_device_ops xilinx_netdev_ops = {
+	.ndo_open 	= xenet_open,
+	.ndo_stop	= xenet_close,
+	.ndo_start_xmit	= NULL,
+	.ndo_do_ioctl	= xenet_ioctl,
+	.ndo_change_mtu	= xenet_change_mtu,
+	.ndo_tx_timeout	= xenet_tx_timeout,
+	.ndo_get_stats	= xenet_get_stats,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_set_rx_mode	= xenet_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+static struct of_device_id xtenet_fifo_of_match[] = {
+	{ .compatible = "xlnx,xps-ll-fifo-1.00.a", },
+	{ .compatible = "xlnx,xps-ll-fifo-1.00.b", },
+	{ .compatible = "xlnx,xps-ll-fifo-1.01.a", },
+	{ /* end of list */ },
+};
+
+static struct of_device_id xtenet_sdma_of_match[] = {
+	{ .compatible = "xlnx,ll-dma-1.00.a", },
+	{ /* end of list */ },
+};
+
+static int xtenet_of_probe(struct platform_device *op)
+{
+	struct resource r_irq_struct;
+	struct resource r_mem_struct;
+	struct resource r_connected_mem_struct;
+	struct resource r_connected_irq_struct;
+	struct xlltemac_platform_data pdata_struct;
+
+	struct resource *r_irq = &r_irq_struct;	/* Interrupt resources */
+	struct resource *r_mem = &r_mem_struct;	/* IO mem resources */
+	struct xlltemac_platform_data *pdata = &pdata_struct;
+        const void *mac_address;
+	int rc = 0;
+	const phandle *llink_connected_handle;
+	struct device_node *llink_connected_node;
+	u32 *dcrreg_property;
+
+	/*
+	 * Make sure the locks are initialized
+	 */
+	spin_lock_init(&XTE_spinlock);
+	spin_lock_init(&XTE_tx_spinlock);
+	spin_lock_init(&XTE_rx_spinlock);
+
+	INIT_LIST_HEAD(&sentQueue);
+	INIT_LIST_HEAD(&receivedQueue);
+
+	spin_lock_init(&sentQueueSpin);
+	spin_lock_init(&receivedQueueSpin);
+
+	printk(KERN_INFO "Device Tree Probing \'%s\'\n",
+                        op->dev.of_node->name);
+
+	/* Get iospace for the device */
+	rc = of_address_to_resource(op->dev.of_node, 0, r_mem);
+	if(rc) {
+		dev_warn(&op->dev, "invalid address\n");
+		return rc;
+	}
+
+	/* Get IRQ for the device */
+	rc = of_irq_to_resource(op->dev.of_node, 0, r_irq);
+	if(!rc) {
+		dev_warn(&op->dev, "no IRQ found.\n");
+		return rc;
+	}
+
+	pdata_struct.tx_csum = get_u32(op, "xlnx,txcsum");
+	pdata_struct.rx_csum = get_u32(op, "xlnx,rxcsum");
+	pdata_struct.phy_type = get_u32(op, "xlnx,phy-type");
+        llink_connected_handle =
+		of_get_property(op->dev.of_node, "llink-connected", NULL);
+        if(!llink_connected_handle) {
+            dev_warn(&op->dev, "no Locallink connection found.\n");
+            return rc;
+        }
+
+	llink_connected_node =
+		of_find_node_by_phandle(*llink_connected_handle);
+	rc = of_address_to_resource(
+			llink_connected_node,
+			0,
+			&r_connected_mem_struct);
+
+        /** Get the right information from whatever the locallink is
+	    connected to. */
+	if(of_match_node(xtenet_fifo_of_match, llink_connected_node)) {
+		/** Connected to a fifo. */
+
+		if(rc) {
+			dev_warn(&op->dev, "invalid address\n");
+			return rc;
+		}
+
+	        pdata_struct.ll_dev_baseaddress	= r_connected_mem_struct.start;
+		pdata_struct.ll_dev_type = XPAR_LL_FIFO;
+		pdata_struct.ll_dev_dma_rx_irq	= 0;
+		pdata_struct.ll_dev_dma_tx_irq	= 0;
+
+		rc = of_irq_to_resource(
+				llink_connected_node,
+				0,
+				&r_connected_irq_struct);
+		if(!rc) {
+			dev_warn(&op->dev, "no IRQ found.\n");
+			return rc;
+		}
+		pdata_struct.ll_dev_fifo_irq	= r_connected_irq_struct.start;
+		pdata_struct.dcr_host = 0x0;
+        } else if(of_match_node(xtenet_sdma_of_match, llink_connected_node)) {
+		/** Connected to a dma port, default to 405 type dma */
+		pdata->dcr_host = 0;
+		if(rc) {
+			/* no address was found, might be 440, check for dcr reg */
+
+			dcrreg_property = (u32 *)of_get_property(llink_connected_node, "dcr-reg", 									NULL);
+			if(dcrreg_property) {
+			        r_connected_mem_struct.start = *dcrreg_property;
+				pdata->dcr_host = 0xFF;
+			} else {
+				dev_warn(&op->dev, "invalid address\n");
+				return rc;
+			}
+		}
+
+        	pdata_struct.ll_dev_baseaddress	= r_connected_mem_struct.start;
+		pdata_struct.ll_dev_type = XPAR_LL_DMA;
+
+		rc = of_irq_to_resource(
+				llink_connected_node,
+				0,
+				&r_connected_irq_struct);
+		if(!rc) {
+			dev_warn(&op->dev, "First IRQ not found.\n");
+			return rc;
+		}
+		pdata_struct.ll_dev_dma_rx_irq	= r_connected_irq_struct.start;
+		rc = of_irq_to_resource(
+				llink_connected_node,
+				1,
+				&r_connected_irq_struct);
+		if(!rc) {
+			dev_warn(&op->dev, "Second IRQ not found.\n");
+			return rc;
+		}
+		pdata_struct.ll_dev_dma_tx_irq	= r_connected_irq_struct.start;
+
+		pdata_struct.ll_dev_fifo_irq	= 0;
+        } else {
+		dev_warn(&op->dev, "Locallink connection not matched.\n");
+		return rc;
+        }
+
+	of_node_put(llink_connected_node);
+        mac_address = of_get_mac_address(op->dev.of_node);
+        if(mac_address) {
+            memcpy(pdata_struct.mac_addr, mac_address, 6);
+        } else {
+            dev_warn(&op->dev, "No MAC address found.\n");
+        }
+
+	return xtenet_setup(&op->dev, r_mem, r_irq, pdata);
+}
+
+static int xtenet_of_remove(struct platform_device *op)
+{
+	return xtenet_remove(&op->dev);
+}
+
+static struct of_device_id xtenet_of_match[] = {
+	{ .compatible = "xlnx,xps-ll-temac-1.00.a", },
+	{ .compatible = "xlnx,xps-ll-temac-1.00.b", },
+	{ .compatible = "xlnx,xps-ll-temac-1.01.a", },
+	{ .compatible = "xlnx,xps-ll-temac-1.01.b", },
+	{ /* end of list */ },
+};
+
+MODULE_DEVICE_TABLE(of, xtenet_of_match);
+#endif
+
+static struct platform_driver xtenet_of_driver = {
+	.probe		= xtenet_of_probe,
+	.remove		= xtenet_of_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(xtenet_of_match),
+	},
+};
+
+module_platform_driver(xtenet_of_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/remoteproc/Kconfig	2014-07-20 22:05:50.264066159 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/Kconfig	2014-07-20 22:06:37.270290642 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:67 @
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ZYNQ_REMOTEPROC
+	tristate "Support ZYNQ remoteproc"
+	depends on ARCH_ZYNQ && SMP && !DEBUG_SG
+	select REMOTEPROC
+	select RPMSG
+	select HOTPLUG_CPU
+	default m
+	help
+	  Say y here to support Xilinx ZynQ remote processors (the second
+	  ARM CORTEX-A9 cpu) via the remote processor framework.
+
+config MB_REMOTEPROC
+	tristate "Support Microblaze remoteproc"
+	depends on ARCH_ZYNQ && !DEBUG_SG
+	select GPIO_XILINX
+	select REMOTEPROC
+	select RPMSG
+	default m
+	help
+	  Say y here to support Xilinx Microblaze remote processors
+	  on the Xilinx Zynq.
+
 endmenu
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/remoteproc/Makefile	2014-07-20 22:05:50.263066176 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/Makefile	2014-07-20 22:06:37.279290493 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:13 @
 obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ZYNQ_REMOTEPROC)		+= zynq_remoteproc.o
+obj-$(CONFIG_MB_REMOTEPROC)		+= mb_remoteproc.o
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/mb_remoteproc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/mb_remoteproc.c	2014-07-20 22:06:37.290290312 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Microblaze Remote Processor driver
+ *
+ * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2012 PetaLogix
+ *
+ * Based on origin OMAP Remote Processor driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/smp.h>
+#include <linux/irqchip/arm-gic.h>
+#include <asm/outercache.h>
+#include <asm/cacheflush.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include "remoteproc_internal.h"
+
+/* Module parameter */
+static char *firmware;
+
+/* Private data */
+struct mb_rproc_pdata {
+	struct rproc *rproc;
+	u32 mem_start;
+	u32 mem_end;
+	int reset_gpio;
+	int mb_debug_gpio;
+	int ipi;
+	int vring0;
+	int vring1;
+	void __iomem *vbase;
+	const unsigned char *bootloader;
+};
+
+/* Store rproc for IPI handler */
+static struct platform_device *remoteprocdev;
+static struct work_struct workqueue;
+
+static void handle_event(struct work_struct *work)
+{
+	struct mb_rproc_pdata *local = platform_get_drvdata(remoteprocdev);
+
+	flush_cache_all();
+	outer_flush_range(local->mem_start, local->mem_end);
+
+	if (rproc_vq_interrupt(local->rproc, 0) == IRQ_NONE)
+		dev_info(&remoteprocdev->dev, "no message found in vqid 0\n");
+}
+
+static irqreturn_t ipi_kick(int irq, void *dev_id)
+{
+	dev_dbg(&remoteprocdev->dev, "KICK Linux because of pending message\n");
+	schedule_work(&workqueue);
+	dev_dbg(&remoteprocdev->dev, "KICK Linux handled\n");
+
+	return IRQ_HANDLED;
+}
+
+static int mb_rproc_start(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev.parent;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mb_rproc_pdata *local = platform_get_drvdata(pdev);
+	const struct firmware *fw;
+	int ret;
+
+	dev_info(dev, "%s\n", __func__);
+	INIT_WORK(&workqueue, handle_event);
+
+	flush_cache_all();
+	outer_flush_range(local->mem_start, local->mem_end);
+
+	remoteprocdev = pdev;
+
+	ret = request_firmware(&fw, local->bootloader, &pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "request_firmware failed\n");
+		return ret;
+	}
+	/* Copy bootloader to memory */
+	memcpy(local->vbase, fw->data, fw->size);
+	release_firmware(fw);
+
+	/* Just for sure synchronize memories */
+	dsb();
+
+	/* Release Microblaze from reset */
+	gpio_set_value(local->reset_gpio, 0);
+
+	return 0;
+}
+
+/* kick a firmware */
+static void mb_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct device *dev = rproc->dev.parent;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mb_rproc_pdata *local = platform_get_drvdata(pdev);
+
+	dev_dbg(dev, "KICK Firmware to start send messages vqid %d\n", vqid);
+
+	flush_cache_all();
+	outer_flush_all();
+
+	/* Send swirq to firmware */
+	gpio_set_value(local->vring0, 0);
+	gpio_set_value(local->vring1, 0);
+	dsb();
+
+	if (!vqid) {
+		udelay(500);
+		gpio_set_value(local->vring0, 1);
+		dsb();
+	} else {
+		udelay(100);
+		gpio_set_value(local->vring1, 1);
+		dsb();
+	}
+}
+
+/* power off the remote processor */
+static int mb_rproc_stop(struct rproc *rproc)
+{
+  	struct device *dev = rproc->dev.parent;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mb_rproc_pdata *local = platform_get_drvdata(pdev);
+
+	/* Setup MB to the state where all memory transactions are done */
+	gpio_set_value(local->mb_debug_gpio, 1);
+	dsb(); /* Be sure that this write has been done */
+	/*
+	 * This should be enough to ensure one CLK as
+	 * it is written in MB ref guide
+	 */
+	gpio_set_value(local->mb_debug_gpio, 0);
+
+	udelay(1000); /* Wait some time to finish all mem transactions */
+
+	/* Add Microblaze to reset state */
+	gpio_set_value(local->reset_gpio, 1);
+
+	/* No reason to wait that operations where done */
+	return 0;
+}
+
+static struct rproc_ops mb_rproc_ops = {
+	.start		= mb_rproc_start,
+	.stop		= mb_rproc_stop,
+	.kick		= mb_rproc_kick,
+};
+
+/* Just to detect bug if interrupt forwarding is broken */
+static irqreturn_t mb_remoteproc_interrupt(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+
+	dev_err(dev, "GIC IRQ %d is not forwarded correctly\n", irq);
+
+	return IRQ_HANDLED;
+}
+
+static int mb_remoteproc_probe(struct platform_device *pdev)
+{
+	const unsigned char *prop;
+	struct platform_device *bram_pdev;
+	struct device_node *bram_dev;
+	struct resource *res; /* IO mem resources */
+	int ret = 0;
+	int count = 0;
+	struct mb_rproc_pdata *local;
+
+	local = devm_kzalloc(&pdev->dev, sizeof(*local), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, local);
+
+	/* Declare memory for firmware */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "invalid address\n");
+		return -ENODEV;
+	}
+
+	local->mem_start = res->start;
+	local->mem_end = res->end;
+
+	/* Alloc phys addr from 0 to max_addr for firmware */
+	ret = dma_declare_coherent_memory(&pdev->dev, local->mem_start,
+		local->mem_start, local->mem_end - local->mem_start + 1,
+		DMA_MEMORY_IO);
+	if (!ret) {
+		dev_err(&pdev->dev, "dma_declare_coherent_memory failed\n");
+		return ret;
+	}
+
+	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
+		return ret;
+	}
+
+	/* Alloc IRQ based on DTS to be sure that no other driver will use it */
+	while (1) {
+		int irq;
+		/* Allocating shared IRQs will ensure that any module will
+		 * use these IRQs */
+		irq = platform_get_irq(pdev, count++);
+		if (irq == -ENXIO)
+			break;
+		ret = devm_request_irq(&pdev->dev, irq, mb_remoteproc_interrupt,
+				       0, dev_name(&pdev->dev), &pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "IRQ %d already allocated\n", irq);
+			return ret;
+		}
+
+		dev_info(&pdev->dev, "%d: Alloc irq: %d\n", count, irq);
+	}
+
+	/* Find out reset gpio and keep microblaze in reset */
+	local->reset_gpio = of_get_named_gpio(pdev->dev.of_node, "reset", 0);
+	if (local->reset_gpio < 0) {
+		dev_err(&pdev->dev, "reset-gpio property not found\n");
+		return local->reset_gpio;
+	}
+	ret = devm_gpio_request_one(&pdev->dev, local->reset_gpio,
+				    GPIOF_OUT_INIT_HIGH, "mb_reset");
+	if (ret) {
+		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
+		return ret;
+	}
+
+	/* Find out reset gpio and keep microblaze in reset */
+	local->mb_debug_gpio = of_get_named_gpio(pdev->dev.of_node, "debug", 0);
+	if (local->mb_debug_gpio < 0) {
+		dev_err(&pdev->dev, "mb-debug-gpio property not found\n");
+		return local->mb_debug_gpio;
+	}
+	ret = devm_gpio_request_one(&pdev->dev, local->mb_debug_gpio,
+				    GPIOF_OUT_INIT_LOW, "mb_debug");
+	if (ret) {
+		dev_err(&pdev->dev, "Please specify gpio debug pin\n");
+		return ret;
+	}
+
+	/* IPI number for getting irq from firmware */
+	local->ipi = of_get_named_gpio(pdev->dev.of_node, "ipino", 0);
+	if (local->ipi < 0) {
+		dev_err(&pdev->dev, "ipi-gpio property not found\n");
+		return local->ipi;
+	}
+	ret = devm_gpio_request_one(&pdev->dev, local->ipi, GPIOF_IN, "mb_ipi");
+	if (ret) {
+		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
+		return ret;
+	}
+	ret = devm_request_irq(&pdev->dev, gpio_to_irq(local->ipi),
+			       ipi_kick, IRQF_SHARED|IRQF_TRIGGER_RISING,
+			       dev_name(&pdev->dev), local);
+	if (ret) {
+		dev_err(&pdev->dev, "IRQ %d already allocated\n", local->ipi);
+		return ret;
+	}
+
+	/* Find out vring0 pin */
+	local->vring0 = of_get_named_gpio(pdev->dev.of_node, "vring0", 0);
+	if (local->vring0 < 0) {
+		dev_err(&pdev->dev, "reset-gpio property not found\n");
+		return local->vring0;
+	}
+	ret = devm_gpio_request_one(&pdev->dev, local->vring0,
+				    GPIOF_DIR_OUT, "mb_vring0");
+	if (ret) {
+		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
+		return ret;
+	}
+
+	/* Find out vring1 pin */
+	local->vring1 = of_get_named_gpio(pdev->dev.of_node, "vring1", 0);
+	if (local->vring1 < 0) {
+		dev_err(&pdev->dev, "reset-gpio property not found\n");
+		return local->vring1;
+	}
+	ret = devm_gpio_request_one(&pdev->dev, local->vring1,
+				    GPIOF_DIR_OUT, "mb_vring1");
+	if (ret) {
+		dev_err(&pdev->dev, "Please specify gpio reset addr\n");
+		return ret;
+	}
+
+	/* Allocate bram device */
+	bram_dev = of_parse_phandle(pdev->dev.of_node, "bram", 0);
+	if (!bram_dev) {
+		dev_err(&pdev->dev, "Please specify bram connection\n");
+		return -ENODEV;
+	}
+	bram_pdev = of_find_device_by_node(bram_dev);
+	if (!bram_pdev) {
+		dev_err(&pdev->dev, "BRAM device hasn't found\n");
+		return -ENODEV;
+	}
+	res = platform_get_resource(bram_pdev, IORESOURCE_MEM, 0);
+	local->vbase = devm_ioremap_resource(&pdev->dev, res);
+	if (!local->vbase)
+		return -ENODEV;
+
+	/* Load simple bootloader to bram */
+	local->bootloader = of_get_property(pdev->dev.of_node,
+					    "bram-firmware", NULL);
+	if (!local->bootloader) {
+		dev_err(&pdev->dev, "Please specify BRAM firmware\n");
+		return -ENODEV;
+	}
+
+	dev_info(&pdev->dev, "Using microblaze BRAM bootloader: %s\n",
+		 local->bootloader);
+
+	/* Module param firmware first */
+	if (firmware)
+		prop = firmware;
+	else
+		prop = of_get_property(pdev->dev.of_node, "firmware", NULL);
+
+	if (prop) {
+		dev_info(&pdev->dev, "Using firmware: %s\n", prop);
+		local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
+				&mb_rproc_ops, prop, sizeof(struct rproc));
+		if (!local->rproc) {
+			dev_err(&pdev->dev, "rproc allocation failed\n");
+			return -ENOMEM;
+		}
+
+		ret = rproc_add(local->rproc);
+		if (ret) {
+			dev_err(&pdev->dev, "rproc registration failed\n");
+			rproc_put(local->rproc);
+			return ret;
+		}
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+static int mb_remoteproc_remove(struct platform_device *pdev)
+{
+	struct mb_rproc_pdata *local = platform_get_drvdata(pdev);
+
+	dev_info(&pdev->dev, "%s\n", __func__);
+
+	dma_release_declared_memory(&pdev->dev);
+
+	rproc_del(local->rproc);
+	rproc_put(local->rproc);
+
+	return 0;
+}
+
+/* Match table for OF platform binding */
+static struct of_device_id mb_remoteproc_match[] = {
+	{ .compatible = "xlnx,mb_remoteproc", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, mb_remoteproc_match);
+
+static struct platform_driver mb_remoteproc_driver = {
+	.probe = mb_remoteproc_probe,
+	.remove = mb_remoteproc_remove,
+	.driver = {
+		.name = "mb_remoteproc",
+		.owner = THIS_MODULE,
+		.of_match_table = mb_remoteproc_match,
+	},
+};
+module_platform_driver(mb_remoteproc_driver);
+
+module_param(firmware, charp, 0);
+MODULE_PARM_DESC(firmware, "Override the firmware image name. Default value in DTS.");
+
+MODULE_AUTHOR("Michal Simek <monstr@monstr.eu");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Microblaze remote processor control driver");
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/remoteproc_core.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/remoteproc/remoteproc_core.c	2014-07-20 22:05:50.262066192 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/remoteproc_core.c	2014-07-20 22:06:37.304290081 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:692 @
  * enum fw_resource_type.
  */
 static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
-	[RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
+	[RSC_CARVEOUT] = NULL, /* Register carveouts separately */
 	[RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
 	[RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
 	[RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */
+	[RSC_MMU] = NULL, /* For firmware purpose */
+};
+
+static rproc_handle_resource_t rproc_carveout_handlers[RSC_LAST] = {
+	[RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
 };
 
 static rproc_handle_resource_t rproc_vdev_handler[RSC_LAST] = {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:930 @
 
 	/* count the number of notify-ids */
 	rproc->max_notifyid = -1;
+
+	/* look for carveout areas and register them first */
+	ret = rproc_handle_resources(rproc, tablesz, rproc_carveout_handlers);
+	if (ret)
+		goto out;
+
 	ret = rproc_handle_resources(rproc, tablesz, rproc_count_vrings_handler);
 	if (ret)
 		goto out;
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/remoteproc_elf_loader.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/remoteproc/remoteproc_elf_loader.c	2014-07-20 22:05:50.265066142 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/remoteproc_elf_loader.c	2014-07-20 22:06:37.317289867 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:323 @
 {
 	struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data;
 	struct elf32_shdr *shdr;
+	const u8 *elf_data = fw->data;
+	struct elf32_phdr *phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff);
 
 	shdr = find_table(&rproc->dev, ehdr, fw->size);
 	if (!shdr)
 		return NULL;
 
-	return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size);
+	return rproc_da_to_va(rproc, shdr->sh_addr - phdr->p_vaddr + phdr->p_paddr, shdr->sh_size);
 }
 
 const struct rproc_fw_ops rproc_elf_fw_ops = {
Index: linux-3.12.24-rt38-xilinx/drivers/remoteproc/zynq_remoteproc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/remoteproc/zynq_remoteproc.c	2014-07-20 22:06:37.328289685 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Zynq Remote Processor driver
+ *
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 PetaLogix
+ *
+ * Based on origin OMAP Remote Processor driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/smp.h>
+#include <linux/irqchip/arm-gic.h>
+#include <asm/outercache.h>
+#include <asm/cacheflush.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+
+#include "remoteproc_internal.h"
+
+extern int __cpuinit zynq_cpun_start(u32 address, int cpu);
+
+/* Module parameter */
+static char *firmware;
+
+/* Structure for storing IRQs */
+struct irq_list {
+	int irq;
+	struct list_head list;
+};
+
+/* Private data */
+struct zynq_rproc_pdata {
+	struct irq_list mylist;
+	struct rproc *rproc;
+	u32 ipino;
+	u32 vring0;
+	u32 vring1;
+	u32 mem_start;
+	u32 mem_end;
+};
+
+/* Store rproc for IPI handler */
+static struct platform_device *remoteprocdev;
+static struct work_struct workqueue;
+
+static void handle_event(struct work_struct *work)
+{
+	struct zynq_rproc_pdata *local = platform_get_drvdata(remoteprocdev);
+
+	flush_cache_all();
+	outer_flush_range(local->mem_start, local->mem_end);
+
+	if (rproc_vq_interrupt(local->rproc, 0) == IRQ_NONE)
+		dev_dbg(&remoteprocdev->dev, "no message found in vqid 0\n");
+}
+
+static void ipi_kick(void)
+{
+	dev_dbg(&remoteprocdev->dev, "KICK Linux because of pending message\n");
+	schedule_work(&workqueue);
+}
+
+static int zynq_rproc_start(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev.parent;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_rproc_pdata *local = platform_get_drvdata(pdev);
+	int ret;
+
+	dev_dbg(dev, "%s\n", __func__);
+	INIT_WORK(&workqueue, handle_event);
+
+	flush_cache_all();
+	outer_flush_range(local->mem_start, local->mem_end);
+
+	remoteprocdev = pdev;
+	ret = zynq_cpun_start(0, 1);
+
+	return ret;
+}
+
+/* kick a firmware */
+static void zynq_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct device *dev = rproc->dev.parent;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct zynq_rproc_pdata *local = platform_get_drvdata(pdev);
+
+	dev_dbg(dev, "KICK Firmware to start send messages vqid %d\n", vqid);
+
+	/* Send swirq to firmware */
+	if (!vqid)
+		gic_raise_softirq(cpumask_of(1), local->vring0);
+	else
+		gic_raise_softirq(cpumask_of(1), local->vring1);
+}
+
+/* power off the remote processor */
+static int zynq_rproc_stop(struct rproc *rproc)
+{
+	dev_dbg(rproc->dev.parent, "%s\n", __func__);
+
+	/* FIXME missing reset option */
+	return 0;
+}
+
+static struct rproc_ops zynq_rproc_ops = {
+	.start		= zynq_rproc_start,
+	.stop		= zynq_rproc_stop,
+	.kick		= zynq_rproc_kick,
+};
+
+/* Just to detect bug if interrupt forwarding is broken */
+static irqreturn_t zynq_remoteproc_interrupt(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+
+	dev_err(dev, "GIC IRQ %d is not forwarded correctly\n", irq);
+
+	/*
+	 *  MS: Calling this function doesn't need to be BUG
+	 * especially for cases where firmware doesn't disable
+	 * interrupts. In next probing can be som interrupts pending.
+	 * The next scenario is for cases when you want to monitor
+	 * non frequent interrupt through Linux kernel. Interrupt happen
+	 * and it is forwarded to Linux which update own statistic
+	 * in (/proc/interrupt) and forward it to firmware.
+	 *
+	 * gic_set_cpu(1, irq);	- setup cpu1 as destination cpu
+	 * gic_raise_softirq(cpumask_of(1), irq); - forward irq to firmware
+	 */
+
+	gic_set_cpu(1, irq);
+	return IRQ_HANDLED;
+}
+
+static void clear_irq(struct platform_device *pdev)
+{
+	struct list_head *pos, *q;
+	struct irq_list *tmp;
+	struct zynq_rproc_pdata *local = platform_get_drvdata(pdev);
+
+	dev_info(&pdev->dev, "Deleting the irq_list\n");
+	list_for_each_safe(pos, q, &local->mylist.list) {
+		tmp = list_entry(pos, struct irq_list, list);
+		free_irq(tmp->irq, &pdev->dev);
+		gic_set_cpu(0, tmp->irq);
+		list_del(pos);
+		kfree(tmp);
+	}
+}
+
+static int zynq_remoteproc_probe(struct platform_device *pdev)
+{
+	const unsigned char *prop;
+	struct resource *res; /* IO mem resources */
+	int ret = 0;
+	struct irq_list *tmp;
+	int count = 0;
+	struct zynq_rproc_pdata *local;
+
+	ret = cpu_down(1);
+	/* EBUSY means CPU is already released */
+	if (ret && (ret != -EBUSY)) {
+		dev_err(&pdev->dev, "Can't release cpu1\n");
+		return -ENOMEM;
+	}
+
+	local = devm_kzalloc(&pdev->dev, sizeof(struct zynq_rproc_pdata),
+			     GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, local);
+
+	/* Declare memory for firmware */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "invalid address\n");
+		return -ENODEV;
+	}
+
+	local->mem_start = res->start;
+	local->mem_end = res->end;
+
+	/* Alloc phys addr from 0 to max_addr for firmware */
+	ret = dma_declare_coherent_memory(&pdev->dev, local->mem_start,
+		local->mem_start, local->mem_end - local->mem_start + 1,
+		DMA_MEMORY_IO);
+	if (!ret) {
+		dev_err(&pdev->dev, "dma_declare_coherent_memory failed\n");
+		goto dma_fault;
+	}
+
+	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
+		goto dma_fault;
+	}
+
+	/* Init list for IRQs - it can be long list */
+	INIT_LIST_HEAD(&local->mylist.list);
+
+	/* Alloc IRQ based on DTS to be sure that no other driver will use it */
+	while (1) {
+		int irq;
+
+		irq = platform_get_irq(pdev, count++);
+		if (irq == -ENXIO)
+			break;
+
+		tmp = kzalloc(sizeof(struct irq_list), GFP_KERNEL);
+		if (!tmp) {
+			dev_err(&pdev->dev, "Unable to alloc irq list\n");
+			ret = -ENOMEM;
+			goto irq_fault;
+		}
+
+		tmp->irq = irq;
+
+		dev_dbg(&pdev->dev, "%d: Alloc irq: %d\n", count, tmp->irq);
+
+		/* Allocating shared IRQs will ensure that any module will
+		 * use these IRQs */
+		ret = request_irq(tmp->irq, zynq_remoteproc_interrupt, 0,
+					dev_name(&pdev->dev), &pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "IRQ %d already allocated\n",
+								tmp->irq);
+			goto irq_fault;
+		}
+
+		/*
+		 * MS: Here is place for detecting problem with firmware
+		 * which doesn't work correctly with interrupts
+		 *
+		 * MS: Comment if you want to count IRQs on Linux
+		 */
+		gic_set_cpu(1, tmp->irq);
+		list_add(&(tmp->list), &(local->mylist.list));
+	}
+
+	/* Allocate free IPI number */
+	ret = of_property_read_u32(pdev->dev.of_node, "ipino", &local->ipino);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to read property");
+		goto irq_fault;
+	}
+
+	ret = set_ipi_handler(local->ipino, ipi_kick, "Firmware kick");
+	if (ret) {
+		dev_err(&pdev->dev, "IPI handler already registered\n");
+		goto irq_fault;
+	}
+
+	/* Read vring0 ipi number */
+	ret = of_property_read_u32(pdev->dev.of_node, "vring0", &local->vring0);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to read property");
+		goto ipi_fault;
+	}
+
+	/* Read vring1 ipi number */
+	ret = of_property_read_u32(pdev->dev.of_node, "vring1", &local->vring1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to read property");
+		goto ipi_fault;
+	}
+
+	/* Module param firmware first */
+	if (firmware)
+		prop = firmware;
+	else
+		prop = of_get_property(pdev->dev.of_node, "firmware", NULL);
+
+	if (prop) {
+		dev_dbg(&pdev->dev, "Using firmware: %s\n", prop);
+		local->rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
+				&zynq_rproc_ops, prop, sizeof(struct rproc));
+		if (!local->rproc) {
+			dev_err(&pdev->dev, "rproc allocation failed\n");
+			goto ipi_fault;
+		}
+
+		ret = rproc_add(local->rproc);
+		if (ret) {
+			dev_err(&pdev->dev, "rproc registration failed\n");
+			goto rproc_fault;
+		}
+
+		return ret;
+	} else
+		ret = -ENODEV;
+
+rproc_fault:
+	rproc_put(local->rproc);
+ipi_fault:
+	clear_ipi_handler(local->ipino);
+
+irq_fault:
+	clear_irq(pdev);
+
+dma_fault:
+	/* Cpu can't be power on - for example in nosmp mode */
+	ret |= cpu_up(1);
+	if (ret)
+		dev_err(&pdev->dev, "Can't power on cpu1 %d\n", ret);
+
+	return ret;
+}
+
+static int zynq_remoteproc_remove(struct platform_device *pdev)
+{
+	struct zynq_rproc_pdata *local = platform_get_drvdata(pdev);
+	u32 ret;
+
+	dev_info(&pdev->dev, "%s\n", __func__);
+
+	dma_release_declared_memory(&pdev->dev);
+
+	clear_ipi_handler(local->ipino);
+	clear_irq(pdev);
+
+	rproc_del(local->rproc);
+	rproc_put(local->rproc);
+
+	/* Cpu can't be power on - for example in nosmp mode */
+	ret = cpu_up(1);
+	if (ret)
+		dev_err(&pdev->dev, "Can't power on cpu1 %d\n", ret);
+
+	return 0;
+}
+
+/* Match table for OF platform binding */
+static struct of_device_id zynq_remoteproc_match[] = {
+	{ .compatible = "xlnx,zynq_remoteproc", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, zynq_remoteproc_match);
+
+static struct platform_driver zynq_remoteproc_driver = {
+	.probe = zynq_remoteproc_probe,
+	.remove = zynq_remoteproc_remove,
+	.driver = {
+		.name = "zynq_remoteproc",
+		.owner = THIS_MODULE,
+		.of_match_table = zynq_remoteproc_match,
+	},
+};
+module_platform_driver(zynq_remoteproc_driver);
+
+module_param(firmware, charp, 0);
+MODULE_PARM_DESC(firmware, "Override the firmware image name. Default value in DTS.");
+
+MODULE_AUTHOR("Michal Simek <monstr@monstr.eu");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Zynq remote processor control driver");
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/Kconfig	2014-07-20 22:06:37.339289504 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+config OMAP_RPMSG
+	tristate "OMAP virtio-based remote processor messaging support"
+	depends on ARCH_OMAP4 && OMAP_REMOTE_PROC
+	select CONFIG_OMAP_MBOX_FWK
+	select RPMSG
+	help
+	  Say Y if you want to enable OMAP's virtio-based remote-processor
+	  messaging, currently only available on OMAP4. This is required
+	  for offloading cpu-intensive and/or latency-sensitive tasks to
+	  the remote on-chip M3s or C64x+ dsp, usually used by multimedia
+	  frameworks.
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/Makefile	2014-07-20 22:06:37.345289405 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+obj-$(CONFIG_OMAP_RPMSG) += omap_rpmsg.o
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/omap_rpmsg.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/omap_rpmsg.c	2014-07-20 22:06:37.355289240 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Remote processor messaging transport (OMAP platform-specific bits)
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/notifier.h>
+#include <linux/remoteproc.h>
+
+#include <plat/mailbox.h>
+#include <plat/dsp.h>
+
+#include "omap_rpmsg.h"
+
+/**
+ * struct omap_rpmsg_vproc - omap's virtio remote processor state
+ * @vdev: virtio device
+ * @vring: phys address of two vrings; first one used for rx, 2nd one for tx
+ * @buf_paddr: physical address of the IPC buffer region
+ * @buf_size: size of IPC buffer region
+ * @buf_mapped: kernel (ioremap'ed) address of IPC buffer region
+ * @mbox_name: name of omap mailbox device to use with this vproc
+ * @rproc_name: name of remote proc device to use with this vproc
+ * @mbox: omap mailbox handle
+ * @rproc: remoteproc handle
+ * @nb: notifier block that will be invoked on inbound mailbox messages
+ * @vq: virtio's virtqueues
+ * @base_vq_id: index of first virtqueue that belongs to this vproc
+ * @num_of_vqs: number of virtqueues this vproc owns
+ * @static_chnls: table of static channels for this vproc
+ */
+struct omap_rpmsg_vproc {
+	struct virtio_device vdev;
+	unsigned int vring[2]; /* mpu owns first vring, ipu owns the 2nd */
+	unsigned int buf_paddr;
+	unsigned int buf_size; /* size must be page-aligned */
+	void *buf_mapped;
+	char *mbox_name;
+	char *rproc_name;
+	struct omap_mbox *mbox;
+	struct rproc *rproc;
+	struct notifier_block nb;
+	struct virtqueue *vq[2];
+	int base_vq_id;
+	int num_of_vqs;
+	struct rpmsg_channel_info *static_chnls;
+};
+
+#define to_omap_vproc(vd) container_of(vd, struct omap_rpmsg_vproc, vdev)
+
+/**
+ * struct omap_rpmsg_vq_info - virtqueue state
+ * @num: number of buffers supported by the vring
+ * @vq_id: a unique index of this virtqueue
+ * @addr: address where the vring is mapped onto
+ * @vproc: the virtual remote processor state
+ *
+ * Such a struct will be maintained for every virtqueue we're
+ * using to communicate with the remote processor
+ */
+struct omap_rpmsg_vq_info {
+	__u16 num;
+	__u16 vq_id;
+	void *addr;
+	struct omap_rpmsg_vproc *vproc;
+};
+
+/*
+ * For now, allocate 256 buffers of 512 bytes for each side. each buffer
+ * will then have 16B for the msg header and 496B for the payload.
+ * This will require a total space of 256KB for the buffers themselves, and
+ * 3 pages for every vring (the size of the vring depends on the number of
+ * buffers it supports).
+ */
+#define RPMSG_NUM_BUFS		(512)
+#define RPMSG_BUF_SIZE		(512)
+#define RPMSG_BUFS_SPACE	(RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+/*
+ * The alignment between the consumer and producer parts of the vring.
+ * Note: this is part of the "wire" protocol. If you change this, you need
+ * to update your BIOS image as well
+ */
+#define RPMSG_VRING_ALIGN	(4096)
+
+/* With 256 buffers, our vring will occupy 3 pages */
+#define RPMSG_RING_SIZE	((DIV_ROUND_UP(vring_size(RPMSG_NUM_BUFS / 2, \
+				RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)
+
+/* The total IPC space needed to communicate with a remote processor */
+#define RPMSG_IPC_MEM	(RPMSG_BUFS_SPACE + 2 * RPMSG_RING_SIZE)
+
+/*
+ * Provide rpmsg core with platform-specific configuration.
+ * Since user data is at stake here, bugs can't be tolerated. hence
+ * the BUG_ON approach on invalid lengths.
+ *
+ * For more info on these configuration requests, see enum
+ * rpmsg_platform_requests.
+ */
+static void omap_rpmsg_get(struct virtio_device *vdev, unsigned int request,
+		   void *buf, unsigned len)
+{
+	struct omap_rpmsg_vproc *vproc = to_omap_vproc(vdev);
+	int tmp;
+
+	switch (request) {
+	case VPROC_BUF_ADDR:
+		BUG_ON(len != sizeof(vproc->buf_mapped));
+		memcpy(buf, &vproc->buf_mapped, len);
+		break;
+	case VPROC_BUF_PADDR:
+		BUG_ON(len != sizeof(vproc->buf_paddr));
+		memcpy(buf, &vproc->buf_paddr, len);
+		break;
+	case VPROC_BUF_NUM:
+		BUG_ON(len != sizeof(tmp));
+		tmp = RPMSG_NUM_BUFS;
+		memcpy(buf, &tmp, len);
+		break;
+	case VPROC_BUF_SZ:
+		BUG_ON(len != sizeof(tmp));
+		tmp = RPMSG_BUF_SIZE;
+		memcpy(buf, &tmp, len);
+		break;
+	case VPROC_STATIC_CHANNELS:
+		BUG_ON(len != sizeof(vproc->static_chnls));
+		memcpy(buf, &vproc->static_chnls, len);
+		break;
+	default:
+		dev_err(&vdev->dev, "invalid request: %d\n", request);
+	}
+}
+
+/* kick the remote processor, and let it know which virtqueue to poke at */
+static void omap_rpmsg_notify(struct virtqueue *vq)
+{
+	struct omap_rpmsg_vq_info *rpvq = vq->priv;
+	int ret;
+
+	pr_debug("sending mailbox msg: %d\n", rpvq->vq_id);
+	/* send the index of the triggered virtqueue in the mailbox payload */
+	ret = omap_mbox_msg_send(rpvq->vproc->mbox, rpvq->vq_id);
+	if (ret)
+		pr_err("ugh, omap_mbox_msg_send() failed: %d\n", ret);
+}
+
+/**
+ * omap_rpmsg_mbox_callback() - inbound mailbox message handler
+ * @this: notifier block
+ * @index: unused
+ * @data: mailbox payload
+ *
+ * This handler is invoked by omap's mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let virtio handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicates different events. Those values are deliberately very
+ * big so they don't coincide with virtqueue indices. Moreover,
+ * they are rarely used, if used at all, and their necessity should
+ * be revisited.
+ */
+static int omap_rpmsg_mbox_callback(struct notifier_block *this,
+					unsigned long index, void *data)
+{
+	mbox_msg_t msg = (mbox_msg_t) data;
+	struct omap_rpmsg_vproc *vproc;
+
+	vproc = container_of(this, struct omap_rpmsg_vproc, nb);
+
+	pr_debug("mbox msg: 0x%x\n", msg);
+
+	switch (msg) {
+	case RP_MBOX_CRASH:
+		pr_err("%s has just crashed !\n", vproc->rproc_name);
+		/* todo: smarter error handling here */
+		break;
+	case RP_MBOX_ECHO_REPLY:
+		pr_info("received echo reply from %s !\n", vproc->rproc_name);
+		break;
+	case RP_MBOX_PENDING_MSG:
+		/*
+		 * a new inbound message is waiting in our rx vring (1st vring).
+		 * Let's pretend the message explicitly contained the rx vring
+		 * index number and handle it generically.
+		 */
+		msg = vproc->base_vq_id;
+		/* intentional fall-through */
+	default:
+		/* ignore vq indices which are clearly not for us */
+		if (msg < vproc->base_vq_id)
+			break;
+
+		msg -= vproc->base_vq_id;
+
+		/*
+		 * Currently both PENDING_MSG and explicit-virtqueue-index
+		 * messaging are supported.
+		 * Whatever approach is taken, at this point 'msg' contains
+		 * the index of the vring which was just triggered.
+		 */
+		if (msg < vproc->num_of_vqs)
+			vring_interrupt(msg, vproc->vq[msg]);
+	}
+
+	return NOTIFY_DONE;
+}
+
+/* prepare a virtqueue */
+static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
+				    unsigned index,
+				    void (*callback)(struct virtqueue *vq),
+				    const char *name)
+{
+	struct omap_rpmsg_vproc *vproc = to_omap_vproc(vdev);
+	struct omap_rpmsg_vq_info *rpvq;
+	struct virtqueue *vq;
+	int err;
+
+	rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL);
+	if (!rpvq)
+		return ERR_PTR(-ENOMEM);
+
+	/* ioremap'ing normal memory, so we cast away sparse's complaints */
+	rpvq->addr = (__force void *) ioremap_nocache(vproc->vring[index],
+							RPMSG_RING_SIZE);
+	if (!rpvq->addr) {
+		err = -ENOMEM;
+		goto free_rpvq;
+	}
+
+	memset(rpvq->addr, 0, RPMSG_RING_SIZE);
+
+	pr_debug("vring%d: phys 0x%x, virt 0x%x\n", index, vproc->vring[index],
+					(unsigned int) rpvq->addr);
+
+	vq = vring_new_virtqueue(RPMSG_NUM_BUFS / 2, RPMSG_VRING_ALIGN, vdev,
+				rpvq->addr, omap_rpmsg_notify, callback, name);
+	if (!vq) {
+		pr_err("vring_new_virtqueue failed\n");
+		err = -ENOMEM;
+		goto unmap_vring;
+	}
+
+	vproc->vq[index] = vq;
+	vq->priv = rpvq;
+	/* unique id for this virtqueue */
+	rpvq->vq_id = vproc->base_vq_id + index;
+	rpvq->vproc = vproc;
+
+	return vq;
+
+unmap_vring:
+	/* iounmap normal memory, so make sparse happy */
+	iounmap((__force void __iomem *) rpvq->addr);
+free_rpvq:
+	kfree(rpvq);
+	return ERR_PTR(err);
+}
+
+static void omap_rpmsg_del_vqs(struct virtio_device *vdev)
+{
+	struct virtqueue *vq, *n;
+	struct omap_rpmsg_vproc *vproc = to_omap_vproc(vdev);
+
+	if (vproc->rproc)
+		rproc_put(vproc->rproc);
+
+	if (vproc->mbox)
+		omap_mbox_put(vproc->mbox, &vproc->nb);
+
+	if (vproc->buf_mapped)
+		/* iounmap normal memory, so make sparse happy */
+		iounmap((__force void __iomem *)vproc->buf_mapped);
+
+	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
+		struct omap_rpmsg_vq_info *rpvq = vq->priv;
+		vring_del_virtqueue(vq);
+		/* iounmap normal memory, so make sparse happy */
+		iounmap((__force void __iomem *) rpvq->addr);
+		kfree(rpvq);
+	}
+}
+
+static int omap_rpmsg_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+		       struct virtqueue *vqs[],
+		       vq_callback_t *callbacks[],
+		       const char *names[])
+{
+	struct omap_rpmsg_vproc *vproc = to_omap_vproc(vdev);
+	int i, err;
+
+	/* we maintain two virtqueues per remote processor (for RX and TX) */
+	if (nvqs != 2)
+		return -EINVAL;
+
+	for (i = 0; i < nvqs; ++i) {
+		vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]);
+		if (IS_ERR(vqs[i])) {
+			err = PTR_ERR(vqs[i]);
+			goto error;
+		}
+	}
+
+	vproc->num_of_vqs = nvqs;
+
+	/* ioremap'ing normal memory, so we cast away sparse's complaints */
+	vproc->buf_mapped = (__force void *) ioremap_nocache(vproc->buf_paddr,
+							vproc->buf_size);
+	if (!vproc->buf_mapped) {
+		pr_err("ioremap failed\n");
+		err = -ENOMEM;
+		goto error;
+	}
+
+	/* for now, use mailbox's notifiers. later that can be optimized */
+	vproc->nb.notifier_call = omap_rpmsg_mbox_callback;
+	vproc->mbox = omap_mbox_get(vproc->mbox_name, &vproc->nb);
+	if (IS_ERR(vproc->mbox)) {
+		pr_err("failed to get mailbox %s\n", vproc->mbox_name);
+		err = -EINVAL;
+		goto error;
+	}
+
+	pr_debug("buf: phys 0x%x, virt 0x%x\n", vproc->buf_paddr,
+					(unsigned int) vproc->buf_mapped);
+
+	/* tell the M3 we're ready (so M3 will know we're sane) */
+	err = omap_mbox_msg_send(vproc->mbox, RP_MBOX_READY);
+	if (err) {
+		pr_err("ugh, omap_mbox_msg_send() failed: %d\n", err);
+		goto error;
+	}
+
+	/* send it the physical address of the vrings + IPC buffer */
+	err = omap_mbox_msg_send(vproc->mbox, (mbox_msg_t) vproc->buf_paddr);
+	if (err) {
+		pr_err("ugh, omap_mbox_msg_send() failed: %d\n", err);
+		goto error;
+	}
+
+	/* ping the remote processor. this is only for sanity-sake;
+	 * there is no functional effect whatsoever */
+	err = omap_mbox_msg_send(vproc->mbox, RP_MBOX_ECHO_REQUEST);
+	if (err) {
+		pr_err("ugh, omap_mbox_msg_send() failed: %d\n", err);
+		goto error;
+	}
+
+	/* now load the firmware, and boot the M3 */
+	vproc->rproc = rproc_get(vproc->rproc_name);
+	if (!vproc->rproc) {
+		pr_err("failed to get rproc %s\n", vproc->rproc_name);
+		err = -EINVAL;
+		goto error;
+	}
+
+	return 0;
+
+error:
+	omap_rpmsg_del_vqs(vdev);
+	return err;
+}
+
+/*
+ * should be nice to add firmware support for these handlers.
+ * for now provide them so virtio doesn't crash
+ */
+static u8 omap_rpmsg_get_status(struct virtio_device *vdev)
+{
+	return 0;
+}
+
+static void omap_rpmsg_set_status(struct virtio_device *vdev, u8 status)
+{
+	dev_dbg(&vdev->dev, "new status: %d\n", status);
+}
+
+static void omap_rpmsg_reset(struct virtio_device *vdev)
+{
+	dev_dbg(&vdev->dev, "reset !\n");
+}
+
+static u32 omap_rpmsg_get_features(struct virtio_device *vdev)
+{
+	/* for now, use hardcoded bitmap. later this should be provided
+	 * by the firmware itself */
+	return 1 << VIRTIO_RPMSG_F_NS;
+}
+
+static void omap_rpmsg_finalize_features(struct virtio_device *vdev)
+{
+	/* Give virtio_ring a chance to accept features */
+	vring_transport_features(vdev);
+}
+
+static void omap_rpmsg_vproc_release(struct device *dev)
+{
+	/* this handler is provided so driver core doesn't yell at us */
+}
+
+static struct virtio_config_ops omap_rpmsg_config_ops = {
+	.get_features	= omap_rpmsg_get_features,
+	.finalize_features = omap_rpmsg_finalize_features,
+	.get		= omap_rpmsg_get,
+	.find_vqs	= omap_rpmsg_find_vqs,
+	.del_vqs	= omap_rpmsg_del_vqs,
+	.reset		= omap_rpmsg_reset,
+	.set_status	= omap_rpmsg_set_status,
+	.get_status	= omap_rpmsg_get_status,
+};
+
+/*
+ * Populating the static channels table.
+ *
+ * This is not always required, and the example below just demonstrates
+ * how to populate it with a static server channel.
+ *
+ * This example should be moved to Documentation/rpmsh.h before merging.
+ *
+ * For more info, see 'struct rpmsg_channel_info'.
+ */
+static struct rpmsg_channel_info omap_ipuc0_static_chnls[] = {
+	RMSG_SERVER_CHNL("rpmsg-server-sample", 137),
+	{ },
+};
+
+static struct rpmsg_channel_info omap_ipuc1_static_chnls[] = {
+	{ },
+};
+
+static struct omap_rpmsg_vproc omap_rpmsg_vprocs[] = {
+	/* ipu_c0's rpmsg backend */
+	{
+		.vdev.id.device	= VIRTIO_ID_RPMSG,
+		.vdev.config	= &omap_rpmsg_config_ops,
+		.mbox_name	= "mailbox-1",
+		.rproc_name	= "ipu",
+		/* core 0 is using indices 0 + 1 for its vqs */
+		.base_vq_id	= 0,
+		.static_chnls = omap_ipuc0_static_chnls,
+	},
+	/* ipu_c1's rpmsg backend */
+	{
+		.vdev.id.device	= VIRTIO_ID_RPMSG,
+		.vdev.config	= &omap_rpmsg_config_ops,
+		.mbox_name	= "mailbox-1",
+		.rproc_name	= "ipu",
+		/* core 1 is using indices 2 + 3 for its vqs */
+		.base_vq_id	= 2,
+		.static_chnls = omap_ipuc1_static_chnls,
+	},
+};
+
+static int __init omap_rpmsg_ini(void)
+{
+	int i, ret = 0;
+	/*
+	 * This whole area generally needs some rework.
+	 * E.g, consider using dma_alloc_coherent for the IPC buffers and
+	 * vrings, use CMA, etc...
+	 */
+	phys_addr_t paddr = omap_dsp_get_mempool_base();
+	phys_addr_t psize = omap_dsp_get_mempool_size();
+
+	/*
+	 * allocate carverout memory for the buffers and vring, and
+	 * then register the vproc virtio device
+	 */
+	for (i = 0; i < ARRAY_SIZE(omap_rpmsg_vprocs); i++) {
+		struct omap_rpmsg_vproc *vproc = &omap_rpmsg_vprocs[i];
+
+		if (psize < RPMSG_IPC_MEM) {
+			pr_err("out of carveout memory: %d (%d)\n", psize, i);
+			return -ENOMEM;
+		}
+
+		vproc->buf_paddr = paddr;
+		vproc->buf_size = RPMSG_BUFS_SPACE;
+		vproc->vring[0] = paddr + RPMSG_BUFS_SPACE;
+		vproc->vring[1] = paddr + RPMSG_BUFS_SPACE + RPMSG_RING_SIZE;
+
+		paddr += RPMSG_IPC_MEM;
+		psize -= RPMSG_IPC_MEM;
+
+		pr_debug("vproc%d: buf 0x%x, vring0 0x%x, vring1 0x%x\n", i,
+			vproc->buf_paddr, vproc->vring[0], vproc->vring[1]);
+
+		vproc->vdev.dev.release = omap_rpmsg_vproc_release;
+
+		ret = register_virtio_device(&vproc->vdev);
+		if (ret) {
+			pr_err("failed to register vproc: %d\n", ret);
+			break;
+		}
+	}
+
+	return ret;
+}
+module_init(omap_rpmsg_ini);
+
+static void __exit omap_rpmsg_fini(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(omap_rpmsg_vprocs); i++) {
+		struct omap_rpmsg_vproc *vproc = &omap_rpmsg_vprocs[i];
+
+		unregister_virtio_device(&vproc->vdev);
+	}
+}
+module_exit(omap_rpmsg_fini);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OMAP Remote processor messaging virtio device");
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/omap_rpmsg.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/host/omap_rpmsg.h	2014-07-20 22:06:37.366289058 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Remote processor messaging
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OMAP_RPMSG_H
+#define _OMAP_RPMSG_H
+
+/*
+ * enum - Predefined Mailbox Messages
+ *
+ * @RP_MBOX_READY: informs the M3's that we're up and running. this is
+ * part of the init sequence sent that the M3 expects to see immediately
+ * after it is booted.
+ *
+ * @RP_MBOX_PENDING_MSG: informs the receiver that there is an inbound
+ * message waiting in its own receive-side vring. please note that currently
+ * this message is optional: alternatively, one can explicitly send the index
+ * of the triggered virtqueue itself. the preferred approach will be decided
+ * as we progress and experiment with those two different approaches.
+ *
+ * @RP_MBOX_CRASH: this message is sent if BIOS crashes
+ *
+ * @RP_MBOX_ECHO_REQUEST: a mailbox-level "ping" message.
+ *
+ * @RP_MBOX_ECHO_REPLY: a mailbox-level reply to a "ping"
+ *
+ * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the
+ * recovery mechanism (to some extent).
+ */
+enum omap_rp_mbox_messages {
+	RP_MBOX_READY		= 0xFFFFFF00,
+	RP_MBOX_PENDING_MSG	= 0xFFFFFF01,
+	RP_MBOX_CRASH		= 0xFFFFFF02,
+	RP_MBOX_ECHO_REQUEST	= 0xFFFFFF03,
+	RP_MBOX_ECHO_REPLY	= 0xFFFFFF04,
+	RP_MBOX_ABORT_REQUEST	= 0xFFFFFF05,
+};
+
+#endif /* _OMAP_RPMSG_H */
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/rpmsg/Kconfig	2014-07-20 22:05:50.206067116 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/Kconfig	2014-07-20 22:06:37.373288943 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:9 @
 	select VIRTIO
 	select VIRTUALIZATION
 
+config RPMSG_SERVER_SAMPLE
+	tristate "An rpmsg server sample"
+	depends on RPMSG
+	---help---
+	  This is just a sample server driver for the rpmsg bus.
+	  Say either Y or M. You know you want to.
+
+config RPMSG_OMX
+	tristate "rpmsg OMX driver"
+	depends on RPMSG
+	---help---
+	  An rpmsg driver that exposes OMX API to user space, in order to
+	  allow multimedia applications to offload OMX processing to
+	  remote processors.
+
+	  If unsure, say N.
+
+config RPMSG_FREERTOS_STAT
+	tristate "An FreeRTOS statistic"
+	depends on RPMSG
+	---help---
+	  This is just a sample to get statistic from FreeRTOS.
+	  Say either Y or M. You know you want to.
+
+source "drivers/rpmsg/host/Kconfig"
+
 endmenu
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/rpmsg/Makefile	2014-07-20 22:05:50.205067133 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/Makefile	2014-07-20 22:06:37.382288794 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2 @
 obj-$(CONFIG_RPMSG)	+= virtio_rpmsg_bus.o
+obj-$(CONFIG_RPMSG_SERVER_SAMPLE) += rpmsg_server_sample.o
+obj-$(CONFIG_RPMSG_FREERTOS_STAT) += rpmsg_freertos_statistic.o
+obj-$(CONFIG_RPMSG_OMX) += rpmsg_omx.o
+obj-$(CONFIG_RPMSG)            += host/
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_freertos_statistic.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_freertos_statistic.c	2014-07-20 22:06:37.392288629 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Remote processor messaging transport - sample server driver
+ *
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 PetaLogix
+ *
+ * Based on original OMX driver made by:
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/scatterlist.h>
+#include <linux/idr.h>
+#include <linux/poll.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/skbuff.h>
+
+struct rpmsg_service {
+	struct cdev cdev;
+	struct rpmsg_channel *rpdev;
+	struct device *dev;
+	int major;
+	int minor;
+};
+
+struct rpmsg_instance {
+	struct rpmsg_endpoint *ept;
+	struct rpmsg_service *service;
+	struct sk_buff_head queue;
+	struct mutex lock;
+	wait_queue_head_t readq;
+};
+
+static void rpmsg_cb(struct rpmsg_channel *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	static int rx_count;
+	struct sk_buff *skb;
+	char *skbdata;
+	/* priv is setup only for new endpoints */
+	struct rpmsg_instance *instance = priv;
+
+	dev_dbg(&rpdev->dev, "incoming msg %d (src: 0x%x) len %d\n",
+						++rx_count, src, len);
+
+	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 32, 1,
+		       data, len,  true);
+
+	skb = alloc_skb(len, GFP_KERNEL);
+	if (!skb) {
+		dev_err(&rpdev->dev, "alloc_skb err: %u\n", len);
+		return;
+	}
+
+	skbdata = skb_put(skb, len);
+	memcpy(skbdata, data, len);
+	mutex_lock(&instance->lock);
+	skb_queue_tail(&instance->queue, skb);
+	mutex_unlock(&instance->lock);
+	/* wake up any blocking processes, waiting for new data */
+	wake_up_interruptible(&instance->readq);
+}
+
+static ssize_t rpmsg_read(struct file *filp, char __user *buf,
+						size_t len, loff_t *offp)
+{
+	struct rpmsg_instance *instance = filp->private_data;
+	struct sk_buff *skb;
+	int use;
+
+	if (mutex_lock_interruptible(&instance->lock))
+		return -ERESTARTSYS;
+
+	/* nothing to read ? */
+	if (skb_queue_empty(&instance->queue)) {
+		mutex_unlock(&instance->lock);
+		/* non-blocking requested ? return now */
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		/* otherwise block, and wait for data */
+		if (wait_event_interruptible(instance->readq,
+				!skb_queue_empty(&instance->queue)))
+			return -ERESTARTSYS;
+		if (mutex_lock_interruptible(&instance->lock))
+			return -ERESTARTSYS;
+	}
+
+	skb = skb_dequeue(&instance->queue);
+	if (!skb) {
+		printk("err is rmpsg_omx racy ?\n");
+		return -EFAULT;
+	}
+
+	mutex_unlock(&instance->lock);
+
+	use = min(len, skb->len);
+	if (copy_to_user(buf, skb->data, use))
+		use = -EFAULT;
+
+	kfree_skb(skb);
+	return use;
+}
+
+/* MAX number of bytes in one packet - depend on resource table */
+#define CHANNEL_SIZE	512
+
+static ssize_t rpmsg_write(struct file *filp, const char __user *ubuf,
+						size_t len, loff_t *offp)
+{
+	struct rpmsg_instance *instance = filp->private_data;
+	struct rpmsg_service *service = instance->service;
+	int err;
+	char kbuf[CHANNEL_SIZE];
+
+	len = len < CHANNEL_SIZE ? len : CHANNEL_SIZE;
+	if (copy_from_user(kbuf, ubuf, len))
+		return -EMSGSIZE;
+
+	err = rpmsg_send_offchannel(service->rpdev, instance->ept->addr,
+					service->rpdev->dst, kbuf, len);
+	if (err) {
+		dev_err(service->dev, "rpmsg_send failed: %d\n", err);
+		return err;
+	}
+
+	return len;
+}
+
+static int rpmsg_open(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_instance *instance;
+	struct rpmsg_service *service;
+
+	service = container_of(inode->i_cdev, struct rpmsg_service, cdev);
+
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+	if (!instance)
+		return -ENOMEM;
+
+	instance->service = service;
+
+	mutex_init(&instance->lock);
+	skb_queue_head_init(&instance->queue);
+	init_waitqueue_head(&instance->readq);
+
+	filp->private_data = instance;
+
+	/* assign a new, unique, local address and associate omx with it */
+	instance->ept = rpmsg_create_ept(service->rpdev, rpmsg_cb, instance,
+							RPMSG_ADDR_ANY);
+	if (!instance->ept) {
+		dev_err(service->dev, "create ept failed\n");
+		kfree(instance);
+		return -ENOMEM;
+	}
+
+	dev_dbg(service->dev, "New endpoint at %d\n", instance->ept->addr);
+	return 0;
+}
+
+typedef enum {
+	CLEAR = 0,
+	START,
+	STOP,
+	CLONE,
+	GET,
+	QUIT,
+	STATE_MASK = 0xF,
+} message_state;
+
+static int rpmsg_release(struct inode *inode, struct file *filp)
+{
+	int err, temp;
+	struct rpmsg_instance *instance = filp->private_data;
+	struct rpmsg_service *service = instance->service;
+
+	/* Place for sending any STOP message or announce driver
+	 * that connection from user-space is lost */
+	temp = QUIT;
+	err = rpmsg_send_offchannel(service->rpdev, instance->ept->addr,
+				service->rpdev->dst, &temp, sizeof(temp));
+	if (err) {
+		dev_err(service->dev, "rpmsg_send failed: %d\n", err);
+		/* No return here because driver wants to quit */
+	}
+
+	/* Discard all SKBs */
+	while (!skb_queue_empty(&instance->queue)) {
+		struct sk_buff *skb;
+		skb = skb_dequeue(&instance->queue);
+		kfree_skb(skb);
+	}
+
+	rpmsg_destroy_ept(instance->ept); /* Also endpoint */
+	kfree(instance);
+	return 0;
+}
+
+
+static const struct file_operations rpmsg_fops = {
+	.open		= rpmsg_open,
+	.release	= rpmsg_release,
+	.read		= rpmsg_read,
+	.write		= rpmsg_write,
+	.owner		= THIS_MODULE,
+};
+
+static struct class *rpmsg_class;
+static dev_t rpmsg_dev;
+static u32 minor;
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+	int ret;
+	struct rpmsg_service *service;
+
+	service = kzalloc(sizeof(*service), GFP_KERNEL);
+	if (!service) {
+		dev_err(&rpdev->dev, "kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	service->rpdev = rpdev;
+	service->major = MAJOR(rpmsg_dev);
+	service->minor = minor++;
+
+	cdev_init(&service->cdev, &rpmsg_fops);
+	service->cdev.owner = THIS_MODULE;
+	ret = cdev_add(&service->cdev,
+				MKDEV(service->major, service->minor), 1);
+	if (ret) {
+		dev_err(&rpdev->dev, "cdev_add failed: %d\n", ret);
+		goto free;
+	}
+
+	service->dev = device_create(rpmsg_class, &rpdev->dev,
+			MKDEV(service->major, service->minor), NULL,
+			"rpmsg%d", service->minor);
+	if (IS_ERR(service->dev)) {
+		dev_err(&rpdev->dev, "device_create failed: %d\n", ret);
+		goto clean_cdev;
+	}
+	dev_set_drvdata(&rpdev->dev, service);
+
+	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+					rpdev->src, rpdev->dst);
+	return 0;
+
+clean_cdev:
+	cdev_del(&service->cdev);
+free:
+	kfree(service);
+	return ret;
+}
+
+static void rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+	struct rpmsg_service *service = dev_get_drvdata(&rpdev->dev);
+	int major = MAJOR(rpmsg_dev);
+
+	device_destroy(rpmsg_class, MKDEV(major, service->minor));
+	cdev_del(&service->cdev);
+	kfree(service);
+}
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data,
+					int len, void *priv, u32 src)
+{
+	dev_info(&rpdev->dev, "ORIGIN callback function without priv\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+	{ .name	= "rpmsg-timer-statistic" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_server = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_driver_sample_id_table,
+	.probe		= rpmsg_sample_probe,
+	.callback	= rpmsg_sample_cb,
+	.remove		= rpmsg_sample_remove,
+};
+
+#define MAX_DEVICES	8
+
+static int __init init(void)
+{
+	int ret;
+
+	/* Allocate 0-8 char devices */
+	ret = alloc_chrdev_region(&rpmsg_dev, 0, MAX_DEVICES,
+						KBUILD_MODNAME);
+	if (ret) {
+		pr_err("alloc_chrdev_region failed: %d\n", ret);
+		goto out;
+	}
+
+	/* Create class for this device */
+	rpmsg_class = class_create(THIS_MODULE, KBUILD_MODNAME);
+	if (IS_ERR(rpmsg_class)) {
+		ret = PTR_ERR(rpmsg_class);
+		pr_err("class_create failed: %d\n", ret);
+		goto unreg_region;
+	}
+
+	return register_rpmsg_driver(&rpmsg_sample_server);
+
+unreg_region:
+	unregister_chrdev_region(rpmsg_dev, MAX_DEVICES);
+out:
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	unregister_rpmsg_driver(&rpmsg_sample_server);
+	class_destroy(rpmsg_class);
+	unregister_chrdev_region(rpmsg_dev, MAX_DEVICES);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DESCRIPTION("Virtio remote processor messaging sample driver");
+MODULE_AUTHOR("Michal Simek <monstr@monstr.eu");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_omx.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_omx.c	2014-07-20 22:06:37.401288481 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * OMX offloading remote processor driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/cdev.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/skbuff.h>
+#include <linux/sched.h>
+#include <linux/rpmsg.h>
+#include <linux/rpmsg_omx.h>
+
+/* maximum OMX devices this driver can handle */
+#define MAX_OMX_DEVICES		8
+
+struct rpmsg_omx_service {
+	struct cdev cdev;
+	struct device *dev;
+	struct rpmsg_channel *rpdev;
+	int minor;
+};
+
+struct rpmsg_omx_instance {
+	struct rpmsg_omx_service *omxserv;
+	struct sk_buff_head queue;
+	struct mutex lock;
+	wait_queue_head_t readq;
+	struct completion reply_arrived;
+	struct rpmsg_endpoint *ept;
+	u32 dst;
+	int state;
+};
+
+static struct class *rpmsg_omx_class;
+static dev_t rpmsg_omx_dev;
+
+/* store all remote omx connection services (usually one per remoteproc) */
+static DEFINE_IDR(rpmsg_omx_services);
+static DEFINE_SPINLOCK(rpmsg_omx_services_lock);
+
+static void rpmsg_omx_cb(struct rpmsg_channel *rpdev, void *data, int len,
+							void *priv, u32 src)
+{
+	struct omx_msg_hdr *hdr = data;
+	struct rpmsg_omx_instance *omx = priv;
+	struct omx_conn_rsp *rsp;
+	struct sk_buff *skb;
+	char *skbdata;
+
+	if (len < sizeof(*hdr) || hdr->len < len - sizeof(*hdr)) {
+		dev_warn(&rpdev->dev, "%s: truncated message\n", __func__);
+		return;
+	}
+
+	dev_dbg(&rpdev->dev, "%s: incoming msg src 0x%x type %d len %d\n",
+					__func__, src, hdr->type, hdr->len);
+	print_hex_dump(KERN_DEBUG, "rpmsg_omx RX: ", DUMP_PREFIX_NONE, 16, 1,
+		       data, len,  true);
+
+	switch (hdr->type) {
+	case OMX_CONN_RSP:
+		if (hdr->len < sizeof(*rsp)) {
+			dev_warn(&rpdev->dev, "incoming empty response msg\n");
+			break;
+		}
+		rsp = (struct omx_conn_rsp *) hdr->data;
+		dev_info(&rpdev->dev, "conn rsp: status %d addr %d\n",
+			       rsp->status, rsp->addr);
+		omx->dst = rsp->addr;
+		if (rsp->status)
+			omx->state = OMX_FAIL;
+		else
+			omx->state = OMX_CONNECTED;
+		complete(&omx->reply_arrived);
+		break;
+	case OMX_RAW_MSG:
+		skb = alloc_skb(hdr->len, GFP_KERNEL);
+		if (!skb) {
+			dev_err(&rpdev->dev, "alloc_skb err: %u\n", hdr->len);
+			break;
+		}
+		skbdata = skb_put(skb, hdr->len);
+		memcpy(skbdata, hdr->data, hdr->len);
+
+		mutex_lock(&omx->lock);
+		skb_queue_tail(&omx->queue, skb);
+		mutex_unlock(&omx->lock);
+		/* wake up any blocking processes, waiting for new data */
+		wake_up_interruptible(&omx->readq);
+		break;
+	default:
+		dev_warn(&rpdev->dev, "unexpected msg type: %d\n", hdr->type);
+		break;
+	}
+}
+
+static int rpmsg_omx_connect(struct rpmsg_omx_instance *omx, char *omxname)
+{
+	struct omx_msg_hdr *hdr;
+	struct omx_conn_req *payload;
+	struct rpmsg_omx_service *omxserv = omx->omxserv;
+	char connect_msg[sizeof(*hdr) + sizeof(*payload)] = { 0 };
+	int ret;
+
+	if (omx->state == OMX_CONNECTED) {
+		dev_dbg(omxserv->dev, "endpoint already connected\n");
+		return -EISCONN;
+	}
+
+	hdr = (struct omx_msg_hdr *)connect_msg;
+	hdr->type = OMX_CONN_REQ;
+	hdr->flags = 0;
+	hdr->len = strlen(omxname) + 1;
+	payload = (struct omx_conn_req *)hdr->data;
+	strcpy(payload->name, omxname);
+
+	init_completion(&omx->reply_arrived);
+
+	/* send a conn req to the remote OMX connection service. use
+	 * the new local address that was just allocated by ->open */
+	ret = rpmsg_send_offchannel(omxserv->rpdev, omx->ept->addr,
+			omxserv->rpdev->dst, connect_msg, sizeof(connect_msg));
+	if (ret) {
+		dev_err(omxserv->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	/* wait until a connection reply arrives or 5 seconds elapse */
+	ret = wait_for_completion_interruptible_timeout(&omx->reply_arrived,
+						msecs_to_jiffies(5000));
+	if (omx->state == OMX_CONNECTED)
+		return 0;
+
+	if (omx->state == OMX_FAIL)
+		return -ENXIO;
+
+	if (ret) {
+		dev_err(omxserv->dev, "premature wakeup: %d\n", ret);
+		return -EIO;
+	}
+
+	return -ETIMEDOUT;
+}
+
+static
+long rpmsg_omx_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct rpmsg_omx_instance *omx = filp->private_data;
+	struct rpmsg_omx_service *omxserv = omx->omxserv;
+	char buf[48];
+	int ret = 0;
+
+	dev_dbg(omxserv->dev, "%s: cmd %d, arg 0x%lx\n", __func__, cmd, arg);
+
+	if (_IOC_TYPE(cmd) != OMX_IOC_MAGIC)
+		return -ENOTTY;
+	if (_IOC_NR(cmd) > OMX_IOC_MAXNR)
+		return -ENOTTY;
+
+	switch (cmd) {
+	case OMX_IOCCONNECT:
+		ret = copy_from_user(buf, (char __user *) arg, sizeof(buf));
+		if (ret) {
+			dev_err(omxserv->dev, "copy_from_user fail: %d\n", ret);
+			ret = -EFAULT;
+			break;
+		}
+		/* make sure user input is null terminated */
+		buf[sizeof(buf) - 1] = '\0';
+		ret = rpmsg_omx_connect(omx, buf);
+		break;
+	default:
+		dev_warn(omxserv->dev, "unhandled ioctl cmd: %d\n", cmd);
+		break;
+	}
+
+	return ret;
+}
+
+static int rpmsg_omx_open(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_omx_service *omxserv;
+	struct rpmsg_omx_instance *omx;
+
+	omxserv = container_of(inode->i_cdev, struct rpmsg_omx_service, cdev);
+
+	omx = kzalloc(sizeof(*omx), GFP_KERNEL);
+	if (!omx)
+		return -ENOMEM;
+
+	mutex_init(&omx->lock);
+	skb_queue_head_init(&omx->queue);
+	init_waitqueue_head(&omx->readq);
+	omx->omxserv = omxserv;
+	omx->state = OMX_UNCONNECTED;
+
+	/* assign a new, unique, local address and associate omx with it */
+	omx->ept = rpmsg_create_ept(omxserv->rpdev, rpmsg_omx_cb, omx,
+							RPMSG_ADDR_ANY);
+	if (!omx->ept) {
+		dev_err(omxserv->dev, "create ept failed\n");
+		kfree(omx);
+		return -ENOMEM;
+	}
+
+	/* associate filp with the new omx instance */
+	filp->private_data = omx;
+
+	dev_info(omxserv->dev, "local addr assigned: 0x%x\n", omx->ept->addr);
+
+	return 0;
+}
+
+static int rpmsg_omx_release(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_omx_instance *omx = filp->private_data;
+	struct rpmsg_omx_service *omxserv = omx->omxserv;
+	char kbuf[512];
+	struct omx_msg_hdr *hdr = (struct omx_msg_hdr *) kbuf;
+	struct omx_disc_req *disc_req = (struct omx_disc_req *)hdr->data;
+	int use, ret;
+
+	/* todo: release resources here */
+
+	/* send a disconnect msg with the OMX instance addr */
+	hdr->type = OMX_DISCONNECT;
+	hdr->flags = 0;
+	hdr->len = sizeof(struct omx_disc_req);
+	disc_req->addr = omx->dst;
+	use = sizeof(*hdr) + hdr->len;
+
+	dev_info(omxserv->dev, "Disconnecting from OMX service at %d\n",
+		omx->dst);
+
+	/* send the msg to the remote OMX connection service */
+	ret = rpmsg_send_offchannel(omxserv->rpdev, omx->ept->addr,
+					omxserv->rpdev->dst, kbuf, use);
+	if (ret) {
+		dev_err(omxserv->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	rpmsg_destroy_ept(omx->ept);
+	kfree(omx);
+
+	return 0;
+}
+
+static ssize_t rpmsg_omx_read(struct file *filp, char __user *buf,
+						size_t len, loff_t *offp)
+{
+	struct rpmsg_omx_instance *omx = filp->private_data;
+	struct sk_buff *skb;
+	int use;
+
+	if (omx->state != OMX_CONNECTED)
+		return -ENOTCONN;
+
+	if (mutex_lock_interruptible(&omx->lock))
+		return -ERESTARTSYS;
+
+	/* nothing to read ? */
+	if (skb_queue_empty(&omx->queue)) {
+		mutex_unlock(&omx->lock);
+		/* non-blocking requested ? return now */
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		/* otherwise block, and wait for data */
+		if (wait_event_interruptible(omx->readq,
+				!skb_queue_empty(&omx->queue)))
+			return -ERESTARTSYS;
+		if (mutex_lock_interruptible(&omx->lock))
+			return -ERESTARTSYS;
+	}
+
+	skb = skb_dequeue(&omx->queue);
+	if (!skb) {
+		dev_err(omx->omxserv->dev, "err is rmpsg_omx racy ?\n");
+		return -EFAULT;
+	}
+
+	mutex_unlock(&omx->lock);
+
+	use = min(len, skb->len);
+
+	if (copy_to_user(buf, skb->data, use))
+		use = -EFAULT;
+
+	kfree_skb(skb);
+	return use;
+}
+
+static ssize_t rpmsg_omx_write(struct file *filp, const char __user *ubuf,
+						size_t len, loff_t *offp)
+{
+	struct rpmsg_omx_instance *omx = filp->private_data;
+	struct rpmsg_omx_service *omxserv = omx->omxserv;
+	char kbuf[512];
+	struct omx_msg_hdr *hdr = (struct omx_msg_hdr *) kbuf;
+	int use, ret;
+
+	if (omx->state != OMX_CONNECTED)
+		return -ENOTCONN;
+
+	/*
+	 * for now, limit msg size to 512 bytes (incl. header).
+	 * (note: rpmsg's limit is even tighter. this whole thing needs fixing)
+	 */
+	use = min(sizeof(kbuf) - sizeof(*hdr), len);
+
+	/*
+	 * copy the data. Later, number of copies can be optimized if found to
+	 * be significant in real use cases
+	 */
+	if (copy_from_user(hdr->data, ubuf, use))
+		return -EMSGSIZE;
+
+	hdr->type = OMX_RAW_MSG;
+	hdr->flags = 0;
+	hdr->len = use;
+
+	use += sizeof(*hdr);
+
+	ret = rpmsg_send_offchannel(omxserv->rpdev, omx->ept->addr,
+						omx->dst, kbuf, use);
+	if (ret) {
+		dev_err(omxserv->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	return use;
+}
+
+static
+unsigned int rpmsg_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	struct rpmsg_omx_instance *omx = filp->private_data;
+	unsigned int mask = 0;
+
+	if (mutex_lock_interruptible(&omx->lock))
+		return -ERESTARTSYS;
+
+	poll_wait(filp, &omx->readq, wait);
+
+	if (!skb_queue_empty(&omx->queue))
+		mask |= POLLIN | POLLRDNORM;
+
+	/* implement missing rpmsg virtio functionality here */
+	if (true)
+		mask |= POLLOUT | POLLWRNORM;
+
+	mutex_unlock(&omx->lock);
+
+	return mask;
+}
+
+static const struct file_operations rpmsg_omx_fops = {
+	.open		= rpmsg_omx_open,
+	.release	= rpmsg_omx_release,
+	.unlocked_ioctl	= rpmsg_omx_ioctl,
+	.read		= rpmsg_omx_read,
+	.write		= rpmsg_omx_write,
+	.poll		= rpmsg_poll,
+	.owner		= THIS_MODULE,
+};
+
+static int rpmsg_omx_probe(struct rpmsg_channel *rpdev)
+{
+	int ret, major, minor;
+	struct rpmsg_omx_service *omxserv;
+
+	if (!idr_pre_get(&rpmsg_omx_services, GFP_KERNEL)) {
+		dev_err(&rpdev->dev, "idr_pre_get failes\n");
+		return -ENOMEM;
+	}
+
+	omxserv = kzalloc(sizeof(*omxserv), GFP_KERNEL);
+	if (!omxserv) {
+		dev_err(&rpdev->dev, "kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	/* dynamically assign a new minor number */
+	spin_lock(&rpmsg_omx_services_lock);
+	ret = idr_get_new(&rpmsg_omx_services, omxserv, &minor);
+	spin_unlock(&rpmsg_omx_services_lock);
+
+	if (ret) {
+		dev_err(&rpdev->dev, "failed to idr_get_new: %d\n", ret);
+		goto free_omx;
+	}
+
+	major = MAJOR(rpmsg_omx_dev);
+
+	omxserv->rpdev = rpdev;
+	omxserv->minor = minor;
+
+	cdev_init(&omxserv->cdev, &rpmsg_omx_fops);
+	omxserv->cdev.owner = THIS_MODULE;
+	ret = cdev_add(&omxserv->cdev, MKDEV(major, minor), 1);
+	if (ret) {
+		dev_err(&rpdev->dev, "cdev_add failed: %d\n", ret);
+		goto rem_idr;
+	}
+
+	omxserv->dev = device_create(rpmsg_omx_class, &rpdev->dev,
+			MKDEV(major, minor), NULL,
+			"rpmsg-omx%d", minor);
+	if (IS_ERR(omxserv->dev)) {
+		ret = PTR_ERR(omxserv->dev);
+		dev_err(&rpdev->dev, "device_create failed: %d\n", ret);
+		goto clean_cdev;
+	}
+
+	dev_set_drvdata(&rpdev->dev, omxserv);
+
+	dev_info(omxserv->dev, "new OMX connection srv channel: %u -> %u!\n",
+						rpdev->src, rpdev->dst);
+	return 0;
+
+clean_cdev:
+	cdev_del(&omxserv->cdev);
+rem_idr:
+	spin_lock(&rpmsg_omx_services_lock);
+	idr_remove(&rpmsg_omx_services, minor);
+	spin_unlock(&rpmsg_omx_services_lock);
+free_omx:
+	kfree(omxserv);
+	return ret;
+}
+
+static void rpmsg_omx_remove(struct rpmsg_channel *rpdev)
+{
+	struct rpmsg_omx_service *omxserv = dev_get_drvdata(&rpdev->dev);
+	int major = MAJOR(rpmsg_omx_dev);
+
+	dev_info(omxserv->dev, "rpmsg omx driver is removed\n");
+
+	device_destroy(rpmsg_omx_class, MKDEV(major, omxserv->minor));
+	cdev_del(&omxserv->cdev);
+	spin_lock(&rpmsg_omx_services_lock);
+	idr_remove(&rpmsg_omx_services, omxserv->minor);
+	spin_unlock(&rpmsg_omx_services_lock);
+	kfree(omxserv);
+}
+
+static void rpmsg_omx_driver_cb(struct rpmsg_channel *rpdev, void *data,
+						int len, void *priv, u32 src)
+{
+	dev_warn(&rpdev->dev, "uhm, unexpected message\n");
+
+	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+		       data, len,  true);
+}
+
+static struct rpmsg_device_id rpmsg_omx_id_table[] = {
+	{ .name	= "rpmsg-omx" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_omx_id_table);
+
+static struct rpmsg_driver rpmsg_omx_driver = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_omx_id_table,
+	.probe		= rpmsg_omx_probe,
+	.callback	= rpmsg_omx_driver_cb,
+	.remove		= rpmsg_omx_remove,
+};
+
+static int __init init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&rpmsg_omx_dev, 0, MAX_OMX_DEVICES,
+							KBUILD_MODNAME);
+	if (ret) {
+		pr_err("alloc_chrdev_region failed: %d\n", ret);
+		goto out;
+	}
+
+	rpmsg_omx_class = class_create(THIS_MODULE, KBUILD_MODNAME);
+	if (IS_ERR(rpmsg_omx_class)) {
+		ret = PTR_ERR(rpmsg_omx_class);
+		pr_err("class_create failed: %d\n", ret);
+		goto unreg_region;
+	}
+
+	return register_rpmsg_driver(&rpmsg_omx_driver);
+
+unreg_region:
+	unregister_chrdev_region(rpmsg_omx_dev, MAX_OMX_DEVICES);
+out:
+	return ret;
+}
+module_init(init);
+
+static void __exit fini(void)
+{
+	unregister_rpmsg_driver(&rpmsg_omx_driver);
+	class_destroy(rpmsg_omx_class);
+	unregister_chrdev_region(rpmsg_omx_dev, MAX_OMX_DEVICES);
+}
+module_exit(fini);
+
+MODULE_DESCRIPTION("OMX offloading rpmsg driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_server_sample.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/rpmsg_server_sample.c	2014-07-20 22:06:37.408288365 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Remote processor messaging transport - sample server driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/io.h>
+
+#define MSG		("hello world!")
+#define MSG_LIMIT	100
+
+#define MSG_LAT		("12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"12345678901234567890123456789012345678901234567890"\
+			"123456789012345678901234567890123456789012345")
+#define MSG_LAT_LIMIT	100000
+
+u64 start; /* variable for storing jiffies */
+
+/* TTC runs on 133 MHz - (1 / 133000000 = 8 ns) */
+#define TTC_HZ	8
+
+/* ttc ioremap pointer */
+u8 *ttc_base;
+
+/* Enable/disable latency measuring */
+static int latency;
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	int err;
+	static int rx_count;
+
+	if (latency) {
+		static u32 min = 0x10000000;
+		static u32 max;
+		static u32 average;
+
+		u32 value = __raw_readl(ttc_base + 0x1c); /* Read value */
+		__raw_writel(0x11, ttc_base + 0x10); /* Stop TTC */
+
+		if (value < min)
+			min = value;
+		if (value > max)
+			max = value;
+
+		average += value;
+		/* count messages */
+		++rx_count;
+
+		if (rx_count >= MSG_LAT_LIMIT) {
+			u64 end = get_jiffies_64();
+			u32 time = end - start;
+			u32 timeps = ((1000000 / MSG_LAT_LIMIT) * time) / HZ;
+
+			printk(KERN_INFO "actual value %d ns, min %d ns, max %d"
+				" ns, average %d ns\n", value * TTC_HZ,
+						min * TTC_HZ, max * TTC_HZ,
+						(average/rx_count) * TTC_HZ);
+			printk(KERN_INFO "Start/end jiffies %llx/%llx, "
+				"messages %d. Time: %d s, "
+				"Messages per second %d\n", end, start,
+				rx_count, time/HZ,
+				1000000 / timeps);
+
+			dev_info(&rpdev->dev, "goodbye!\n");
+			return;
+		}
+
+		__raw_writel(0x10, ttc_base + 0x10); /* Start TTC */
+		/* reply */
+		err = rpmsg_sendto(rpdev, MSG_LAT, strlen(MSG_LAT), src);
+	} else {
+		dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n",
+							++rx_count, src);
+		print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+			data, len,  true);
+
+		/* samples should not live forever */
+		if (rx_count >= MSG_LIMIT) {
+			dev_info(&rpdev->dev, "goodbye!\n");
+			return;
+		}
+
+		err = rpmsg_sendto(rpdev, MSG, strlen(MSG), src); /* reply */
+	}
+
+	if (err)
+		pr_err("rpmsg_send failed: %d\n", err);
+}
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+	int err;
+
+	if (latency) {
+		dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!, len %d\n",
+				rpdev->src, rpdev->dst, strlen(MSG_LAT));
+
+		ttc_base = ioremap(0xf8002000, PAGE_SIZE); /* TTC base addr */
+		if (!ttc_base) {
+			pr_err("TTC Ioremap failed\n");
+			return -1;
+		}
+		start = get_jiffies_64();
+		__raw_writel(0x10, ttc_base + 0x10); /* Start TTC */
+
+		err = rpmsg_sendto(rpdev, MSG_LAT, strlen(MSG_LAT), 50);
+	} else {
+		dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!, len %d\n",
+				rpdev->src, rpdev->dst, strlen(MSG));
+
+		err = rpmsg_sendto(rpdev, MSG, strlen(MSG), 50);
+	}
+
+	if (err) {
+		pr_err("rpmsg_send failed: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+	dev_info(&rpdev->dev, "rpmsg sample driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+	{ .name	= "rpmsg-server-sample" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_server = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_driver_sample_id_table,
+	.probe		= rpmsg_sample_probe,
+	.callback	= rpmsg_sample_cb,
+	.remove		= rpmsg_sample_remove,
+};
+
+static int __init init(void)
+{
+	return register_rpmsg_driver(&rpmsg_sample_server);
+}
+
+static void __exit fini(void)
+{
+	unregister_rpmsg_driver(&rpmsg_sample_server);
+}
+module_init(init);
+module_exit(fini);
+
+module_param(latency, int, 0);
+MODULE_PARM_DESC(latency, "Enable latency measuring code.");
+
+MODULE_DESCRIPTION("Virtio remote processor messaging sample driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/rpmsg/virtio_rpmsg_bus.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/rpmsg/virtio_rpmsg_bus.c	2014-07-20 22:05:50.207067099 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/rpmsg/virtio_rpmsg_bus.c	2014-07-20 22:06:37.424288102 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:54 @
  * @sendq:	wait queue of sending contexts waiting for a tx buffers
  * @sleepers:	number of senders that are waiting for a tx buffer
  * @ns_ept:	the bus's name service endpoint
+ * @id:		unique system-wide index id for this vproc
  *
  * This structure stores the rpmsg state of a given virtio remote processor
  * device (there might be several virtio proc devices for each physical
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:72 @
 	wait_queue_head_t sendq;
 	atomic_t sleepers;
 	struct rpmsg_endpoint *ns_ept;
+	int id;
 };
 
+int get_virtproc_id(struct virtproc_info *vrp)
+{
+	return vrp->id;
+}
+EXPORT_SYMBOL(get_virtproc_id);
+
 /**
  * struct rpmsg_channel_info - internal channel info representation
  * @name: name of service
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:145 @
 rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
 
 /*
+ * The virtio devices we are probed with represent remote processors
+ * on the system. We call them _virtual_ processors, because every physical
+ * remote processor might actually have several virtio devices.
+ *
+ * The idr below is used to assign each vproc a unique, system-wide, index id.
+ */
+static struct idr vprocs;
+static DEFINE_MUTEX(vprocs_mutex);
+
+/*
  * Unique (and free running) index for rpmsg devices.
  *
  * Yeah, we're not recycling those numbers (yet?). will be easy
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:514 @
  * this function will be used to create both static and dynamic
  * channels.
  */
-static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
+static struct rpmsg_channel *__rpmsg_create_channel(struct virtproc_info *vrp,
 				struct rpmsg_channel_info *chinfo)
 {
 	struct rpmsg_channel *rpdev;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:570 @
  * find an existing channel using its name + address properties,
  * and destroy it
  */
-static int rpmsg_destroy_channel(struct virtproc_info *vrp,
+static int __rpmsg_destroy_channel(struct virtproc_info *vrp,
 					struct rpmsg_channel_info *chinfo)
 {
 	struct virtio_device *vdev = vrp->vdev;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:908 @
 	wake_up_interruptible(&vrp->sendq);
 }
 
+struct rpmsg_channel *rpmsg_create_channel(int vrp_id, const char *name,
+							int src, int dst)
+{
+	struct rpmsg_channel_info chinfo;
+	struct virtproc_info *vrp;
+
+	strncpy(chinfo.name, name, sizeof(chinfo.name));
+	chinfo.src = src;
+	chinfo.dst = dst;
+
+	/* TODO we probably want radix tree and fw-induced id numbers ? */
+	vrp = idr_find(&vprocs, vrp_id);
+	if (!vrp)
+		return NULL;
+
+	return __rpmsg_create_channel(vrp, &chinfo);
+}
+EXPORT_SYMBOL(rpmsg_create_channel);
+
 /* invoked when a name service announcement arrives */
 static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
 							void *priv, u32 src)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:970 @
 	chinfo.dst = msg->addr;
 
 	if (msg->flags & RPMSG_NS_DESTROY) {
-		ret = rpmsg_destroy_channel(vrp, &chinfo);
+		ret = __rpmsg_destroy_channel(vrp, &chinfo);
 		if (ret)
-			dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
+			dev_err(dev, "__rpmsg_destroy_channel err: %d\n", ret);
 	} else {
-		newch = rpmsg_create_channel(vrp, &chinfo);
+		newch = __rpmsg_create_channel(vrp, &chinfo);
 		if (!newch)
-			dev_err(dev, "rpmsg_create_channel failed\n");
+			dev_err(dev, "__rpmsg_create_channel failed\n");
 	}
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:987 @
 	struct virtqueue *vqs[2];
 	struct virtproc_info *vrp;
 	void *bufs_va;
-	int err = 0, i;
+	int err = 0, i, vproc_id;
 
 	vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
 	if (!vrp)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1000 @
 	mutex_init(&vrp->tx_lock);
 	init_waitqueue_head(&vrp->sendq);
 
+	if (!idr_pre_get(&vprocs, GFP_KERNEL))
+		goto free_vrp;
+
+	mutex_lock(&vprocs_mutex);
+
+	err = idr_get_new(&vprocs, vrp, &vproc_id);
+
+	mutex_unlock(&vprocs_mutex);
+
+	if (err) {
+		dev_err(&vdev->dev, "idr_get_new failed: %d\n", err);
+		goto free_vrp;
+	}
+
+	vrp->id = vproc_id;
+
 	/* We expect two virtqueues, rx and tx (and in this order) */
 	err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names);
 	if (err)
-		goto free_vrp;
+		goto rem_idr;
 
 	vrp->rvq = vqs[0];
 	vrp->svq = vqs[1];
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1083 @
 					bufs_va, vrp->bufs_dma);
 vqs_del:
 	vdev->config->del_vqs(vrp->vdev);
+rem_idr:
+	mutex_lock(&vprocs_mutex);
+	idr_remove(&vprocs, vproc_id);
+	mutex_unlock(&vprocs_mutex);
 free_vrp:
 	kfree(vrp);
 	return err;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1117 @
 
 	vdev->config->del_vqs(vrp->vdev);
 
+	/* FIXME del_vqs is calling rproc_shutdown which switch loaded resource
+	 * table back to cached table but without any synchronization.
+	 * That's why vdev->config->reset(vdev) above is called on loaded table
+	 * and this one is called on cached resource table which ensure
+	 * that WARN_ON_ONCE(dev->config->get_status(dev)); in
+	 * virtio_dev_remove() won't show bug because cached table wasn't
+	 * synchronized with loaded one.
+	 */
+	vdev->config->reset(vdev);
+
 	dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE,
 					vrp->rbufs, vrp->bufs_dma);
 
+	mutex_lock(&vprocs_mutex);
+	idr_remove(&vprocs, vrp->id);
+	mutex_unlock(&vprocs_mutex);
+
 	kfree(vrp);
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1160 @
 {
 	int ret;
 
+	idr_init(&vprocs);
+
 	ret = bus_register(&rpmsg_bus);
 	if (ret) {
 		pr_err("failed to register rpmsg bus: %d\n", ret);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1182 @
 {
 	unregister_virtio_driver(&virtio_ipc_driver);
 	bus_unregister(&rpmsg_bus);
+
+	idr_remove_all(&vprocs);
+	idr_destroy(&vprocs);
 }
 module_exit(rpmsg_fini);
 
Index: linux-3.12.24-rt38-xilinx/drivers/spi/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/spi/Kconfig	2014-07-20 22:05:50.169067727 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/spi/Kconfig	2014-07-20 22:06:37.450287673 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:508 @
 
 	  See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
 	  Product Specification document (DS464) for hardware details.
-
 	  Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)"
 
+config SPI_ZYNQ_QSPI
+	tristate "Xilinx PS QSPI controller"
+	depends on ARCH_ZYNQ
+	depends on SPI_MASTER
+	help
+	  This selects the Xilinx ZYNQ Quad SPI controller master driver.
+
+config SPI_ZYNQ_QSPI_DUAL_STACKED
+	bool "Xilinx PS QSPI Dual stacked configuration"
+	depends on SPI_ZYNQ_QSPI
+	help
+	  This selects the Xilinx ZYNQ Quad SPI controller in dual stacked mode.
+	  Enable this option if your hw design is using dual stacked
+	  configuration.
+
+config SPI_ZYNQ
+	tristate "Xilinx ZYNQ SPI controller"
+	depends on ARCH_ZYNQ
+	depends on SPI_MASTER
+	help
+	  This selects the Xilinx ZYNQ SPI controller master driver.
+
 config SPI_NUC900
 	tristate "Nuvoton NUC900 series SPI"
 	depends on ARCH_W90X900
Index: linux-3.12.24-rt38-xilinx/drivers/spi/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/spi/Makefile	2014-07-20 22:05:50.168067743 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/spi/Makefile	2014-07-20 22:06:37.463287458 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:81 @
 obj-$(CONFIG_SPI_TXX9)			+= spi-txx9.o
 obj-$(CONFIG_SPI_XCOMM)		+= spi-xcomm.o
 obj-$(CONFIG_SPI_XILINX)		+= spi-xilinx.o
+obj-$(CONFIG_SPI_ZYNQ)			+= spi-zynq.o
+obj-$(CONFIG_SPI_ZYNQ_QSPI)		+= spi-zynq-qspi.o
Index: linux-3.12.24-rt38-xilinx/drivers/spi/spi-xilinx.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/spi/spi-xilinx.c	2014-07-20 22:05:50.166067776 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/spi/spi-xilinx.c	2014-07-20 22:06:37.474287277 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:371 @
 	if (!master)
 		return -ENODEV;
 
+	/* clear the dma_mask, to try to disable use of dma */
+	master->dev.dma_mask = 0;
+
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 
Index: linux-3.12.24-rt38-xilinx/drivers/spi/spi-zynq.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/spi/spi-zynq.c	2014-07-20 22:06:37.490287013 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ *
+ * Xilinx PS SPI controller driver (master mode only)
+ *
+ * (c) 2008-2011 Xilinx, Inc.
+ *
+ * based on Blackfin On-Chip SPI Driver (spi_bfin5xx.c)
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+/*
+ * Name of this driver
+ */
+#define XSPIPS_NAME		"xspips"
+
+/*
+ * Register offset definitions
+ */
+#define XSPIPS_CR_OFFSET	0x00 /* Configuration  Register, RW */
+#define XSPIPS_ISR_OFFSET	0x04 /* Interrupt Status Register, RO */
+#define XSPIPS_IER_OFFSET	0x08 /* Interrupt Enable Register, WO */
+#define XSPIPS_IDR_OFFSET	0x0c /* Interrupt Disable Register, WO */
+#define XSPIPS_IMR_OFFSET	0x10 /* Interrupt Enabled Mask Register, RO */
+#define XSPIPS_ER_OFFSET	0x14 /* Enable/Disable Register, RW */
+#define XSPIPS_DR_OFFSET	0x18 /* Delay Register, RW */
+#define XSPIPS_TXD_OFFSET	0x1C /* Data Transmit Register, WO */
+#define XSPIPS_RXD_OFFSET	0x20 /* Data Receive Register, RO */
+#define XSPIPS_SICR_OFFSET	0x24 /* Slave Idle Count Register, RW */
+#define XSPIPS_THLD_OFFSET	0x28 /* Transmit FIFO Watermark Register,RW */
+
+/*
+ * SPI Configuration Register bit Masks
+ *
+ * This register contains various control bits that affect the operation
+ * of the SPI controller
+ */
+#define XSPIPS_CR_MANSTRT_MASK	0x00010000 /* Manual TX Start */
+#define XSPIPS_CR_CPHA_MASK	0x00000004 /* Clock Phase Control */
+#define XSPIPS_CR_CPOL_MASK	0x00000002 /* Clock Polarity Control */
+#define XSPIPS_CR_SSCTRL_MASK	0x00003C00 /* Slave Select Mask */
+
+/*
+ * SPI Interrupt Registers bit Masks
+ *
+ * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
+ * bit definitions.
+ */
+#define XSPIPS_IXR_TXOW_MASK	0x00000004 /* SPI TX FIFO Overwater */
+#define XSPIPS_IXR_MODF_MASK	0x00000002 /* SPI Mode Fault */
+#define XSPIPS_IXR_RXNEMTY_MASK 0x00000010 /* SPI RX FIFO Not Empty */
+#define XSPIPS_IXR_ALL_MASK	(XSPIPS_IXR_TXOW_MASK | XSPIPS_IXR_MODF_MASK)
+
+/*
+ * SPI Enable Register bit Masks
+ *
+ * This register is used to enable or disable the SPI controller
+ */
+#define XSPIPS_ER_ENABLE_MASK	0x00000001 /* SPI Enable Bit Mask */
+
+/*
+ * Definitions for the status of queue
+ */
+#define XSPIPS_QUEUE_STOPPED	0
+#define XSPIPS_QUEUE_RUNNING	1
+
+/*
+ * Macros for the SPI controller read/write
+ */
+#define xspips_read(addr)	__raw_readl(addr)
+#define xspips_write(addr, val)	__raw_writel((val), (addr))
+
+
+/**
+ * struct xspips - This definition defines spi driver instance
+ * @workqueue:		Queue of all the transfers
+ * @work:		Information about current transfer
+ * @queue:		Head of the queue
+ * @queue_state:	Queue status
+ * @regs:		Virtual address of the SPI controller registers
+ * @devclk:		Pointer to the peripheral clock
+ * @aperclk:		Pointer to the APER clock
+ * @clk_rate_change_nb:	Notifier block for clock frequency change callback
+ * @irq:		IRQ number
+ * @speed_hz:		Current SPI bus clock speed in Hz
+ * @trans_queue_lock:	Lock used for accessing transfer queue
+ * @ctrl_reg_lock:	Lock used for accessing configuration register
+ * @txbuf:		Pointer	to the TX buffer
+ * @rxbuf:		Pointer to the RX buffer
+ * @remaining_bytes:	Number of bytes left to transfer
+ * @dev_busy:		Device busy flag
+ * @done:		Transfer complete status
+ */
+struct xspips {
+	struct workqueue_struct *workqueue;
+	struct work_struct work;
+	struct list_head queue;
+	int queue_state;
+	void __iomem *regs;
+	struct clk *devclk;
+	struct clk *aperclk;
+	struct notifier_block clk_rate_change_nb;
+	int irq;
+	u32 speed_hz;
+	spinlock_t trans_queue_lock;
+	spinlock_t ctrl_reg_lock;
+	const u8 *txbuf;
+	u8 *rxbuf;
+	int remaining_bytes;
+	u8 dev_busy;
+	struct completion done;
+};
+
+
+/**
+ * xspips_init_hw - Initialize the hardware and configure the SPI controller
+ * @regs_base:		Base address of SPI controller
+ *
+ * On reset the SPI controller is configured to be in master mode, baud rate
+ * divisor is set to 2, threshold value for TX FIFO not full interrupt is set
+ * to 1 and size of the word to be transferred as 8 bit.
+ * This function initializes the SPI controller to disable and clear all the
+ * interrupts, enable manual slave select and manual start, deselect all the
+ * chip select lines, and enable the SPI controller.
+ */
+static void xspips_init_hw(void __iomem *regs_base)
+{
+	xspips_write(regs_base + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
+	xspips_write(regs_base + XSPIPS_IDR_OFFSET, 0x7F);
+
+	/* Clear the RX FIFO */
+	while (xspips_read(regs_base + XSPIPS_ISR_OFFSET) &
+			XSPIPS_IXR_RXNEMTY_MASK)
+		xspips_read(regs_base + XSPIPS_RXD_OFFSET);
+
+	xspips_write(regs_base + XSPIPS_ISR_OFFSET, 0x7F);
+	xspips_write(regs_base + XSPIPS_CR_OFFSET, 0x0000FC01);
+	xspips_write(regs_base + XSPIPS_ER_OFFSET, XSPIPS_ER_ENABLE_MASK);
+}
+
+/**
+ * xspips_chipselect - Select or deselect the chip select line
+ * @spi:	Pointer to the spi_device structure
+ * @is_on:	Select(1) or deselect (0) the chip select line
+ */
+static void xspips_chipselect(struct spi_device *spi, int is_on)
+{
+	struct xspips *xspi = spi_master_get_devdata(spi->master);
+	u32 ctrl_reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&xspi->ctrl_reg_lock, flags);
+
+	ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
+
+	if (is_on) {
+		/* Select the slave */
+		ctrl_reg &= ~XSPIPS_CR_SSCTRL_MASK;
+		ctrl_reg |= (((~(0x0001 << spi->chip_select)) << 10) &
+				XSPIPS_CR_SSCTRL_MASK);
+	} else {
+		/* Deselect the slave */
+		ctrl_reg |= XSPIPS_CR_SSCTRL_MASK;
+	}
+
+	xspips_write(xspi->regs + XSPIPS_CR_OFFSET, ctrl_reg);
+
+	spin_unlock_irqrestore(&xspi->ctrl_reg_lock, flags);
+}
+
+/**
+ * xspips_setup_transfer - Configure SPI controller for specified transfer
+ * @spi:	Pointer to the spi_device structure
+ * @transfer:	Pointer to the spi_transfer structure which provides information
+ *		about next transfer setup parameters
+ *
+ * Sets the operational mode of SPI controller for the next SPI transfer and
+ * sets the requested clock frequency.
+ *
+ * returns:	0 on success and error value on error
+ *
+ * Note: If the requested frequency is not an exact match with what can be
+ * obtained using the prescalar value the driver sets the clock frequency which
+ * is lower than the requested frequency (maximum lower) for the transfer. If
+ * the requested frequency is higher or lower than that is supported by the SPI
+ * controller the driver will set the highest or lowest frequency supported by
+ * controller.
+ */
+static int xspips_setup_transfer(struct spi_device *spi,
+		struct spi_transfer *transfer)
+{
+	struct xspips *xspi = spi_master_get_devdata(spi->master);
+	u8 bits_per_word;
+	u32 ctrl_reg;
+	u32 req_hz;
+	u32 baud_rate_val;
+	unsigned long flags, frequency;
+
+	bits_per_word = (transfer) ?
+			transfer->bits_per_word : spi->bits_per_word;
+	req_hz = (transfer) ? transfer->speed_hz : spi->max_speed_hz;
+
+	if (bits_per_word != 8) {
+		dev_err(&spi->dev, "%s, unsupported bits per word %x\n",
+			__func__, spi->bits_per_word);
+		return -EINVAL;
+	}
+
+	frequency = clk_get_rate(xspi->devclk);
+
+	spin_lock_irqsave(&xspi->ctrl_reg_lock, flags);
+
+	xspips_write(xspi->regs + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
+	ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
+
+	/* Set the SPI clock phase and clock polarity */
+	ctrl_reg &= (~XSPIPS_CR_CPHA_MASK) & (~XSPIPS_CR_CPOL_MASK);
+	if (spi->mode & SPI_CPHA)
+		ctrl_reg |= XSPIPS_CR_CPHA_MASK;
+	if (spi->mode & SPI_CPOL)
+		ctrl_reg |= XSPIPS_CR_CPOL_MASK;
+
+	/* Set the clock frequency */
+	if (xspi->speed_hz != req_hz) {
+		baud_rate_val = 1;	/* first valid value is 1 */
+		while ((baud_rate_val < 8) && (frequency /
+					(2 << baud_rate_val)) > req_hz)
+			baud_rate_val++;
+
+		ctrl_reg &= 0xFFFFFFC7;
+		ctrl_reg |= (baud_rate_val << 3);
+
+		xspi->speed_hz = (frequency / (2 << baud_rate_val));
+	}
+
+	xspips_write(xspi->regs + XSPIPS_CR_OFFSET, ctrl_reg);
+	xspips_write(xspi->regs + XSPIPS_ER_OFFSET, XSPIPS_ER_ENABLE_MASK);
+
+	spin_unlock_irqrestore(&xspi->ctrl_reg_lock, flags);
+
+	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u clock speed\n",
+		__func__, spi->mode, spi->bits_per_word,
+		xspi->speed_hz);
+
+	return 0;
+}
+
+/**
+ * xspips_setup - Configure the SPI controller
+ * @spi:	Pointer to the spi_device structure
+ *
+ * Sets the operational mode of SPI controller for the next SPI transfer, sets
+ * the baud rate and divisor value to setup the requested spi clock.
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_setup(struct spi_device *spi)
+{
+	if (!spi->max_speed_hz)
+		return -EINVAL;
+
+	if (!spi->bits_per_word)
+		spi->bits_per_word = 8;
+
+	return xspips_setup_transfer(spi, NULL);
+}
+
+/**
+ * xspips_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
+ * @xspi:	Pointer to the xspips structure
+ */
+static void xspips_fill_tx_fifo(struct xspips *xspi)
+{
+	while ((xspips_read(xspi->regs + XSPIPS_ISR_OFFSET) & 0x00000008) == 0
+		&& (xspi->remaining_bytes > 0)) {
+		if (xspi->txbuf)
+			xspips_write(xspi->regs + XSPIPS_TXD_OFFSET,
+					*xspi->txbuf++);
+		else
+			xspips_write(xspi->regs + XSPIPS_TXD_OFFSET, 0);
+
+		xspi->remaining_bytes--;
+	}
+}
+
+/**
+ * xspips_irq - Interrupt service routine of the SPI controller
+ * @irq:	IRQ number
+ * @dev_id:	Pointer to the xspi structure
+ *
+ * This function handles TX empty and Mode Fault interrupts only.
+ * On TX empty interrupt this function reads the received data from RX FIFO and
+ * fills the TX FIFO if there is any data remaining to be transferred.
+ * On Mode Fault interrupt this function indicates that transfer is completed,
+ * the SPI subsystem will identify the error as the remaining bytes to be
+ * transferred is non-zero.
+ *
+ * returns:	IRQ_HANDLED always
+ */
+static irqreturn_t xspips_irq(int irq, void *dev_id)
+{
+	struct xspips *xspi = dev_id;
+	u32 intr_status;
+
+	intr_status = xspips_read(xspi->regs + XSPIPS_ISR_OFFSET);
+	xspips_write(xspi->regs + XSPIPS_ISR_OFFSET, intr_status);
+	xspips_write(xspi->regs + XSPIPS_IDR_OFFSET, XSPIPS_IXR_ALL_MASK);
+
+	if (intr_status & XSPIPS_IXR_MODF_MASK) {
+		/* Indicate that transfer is completed, the SPI subsystem will
+		 * identify the error as the remaining bytes to be
+		 * transferred is non-zero */
+		complete(&xspi->done);
+	} else if (intr_status & XSPIPS_IXR_TXOW_MASK) {
+		u32 ctrl_reg;
+
+		/* Read out the data from the RX FIFO */
+		while (xspips_read(xspi->regs + XSPIPS_ISR_OFFSET) &
+				XSPIPS_IXR_RXNEMTY_MASK) {
+			u8 data;
+
+			data = xspips_read(xspi->regs + XSPIPS_RXD_OFFSET);
+			if (xspi->rxbuf)
+				*xspi->rxbuf++ = data;
+
+			/* Data memory barrier is placed here to ensure that
+			 * data read operation is completed before the status
+			 * read is initiated. Without dmb, there are chances
+			 * that data and status reads will appear at the SPI
+			 * peripheral back-to-back which results in an
+			 * incorrect status read.
+			 */
+			dmb();
+		}
+
+		if (xspi->remaining_bytes) {
+			/* There is more data to send */
+			xspips_fill_tx_fifo(xspi);
+
+			xspips_write(xspi->regs + XSPIPS_IER_OFFSET,
+					XSPIPS_IXR_ALL_MASK);
+
+			spin_lock(&xspi->ctrl_reg_lock);
+
+			ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
+			ctrl_reg |= XSPIPS_CR_MANSTRT_MASK;
+			xspips_write(xspi->regs + XSPIPS_CR_OFFSET, ctrl_reg);
+
+			spin_unlock(&xspi->ctrl_reg_lock);
+		} else {
+			/* Transfer is completed */
+			complete(&xspi->done);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xspips_start_transfer - Initiates the SPI transfer
+ * @spi:	Pointer to the spi_device structure
+ * @transfer:	Pointer to the spi_transfer structure which provide information
+ *		about next transfer parameters
+ *
+ * This function fills the TX FIFO, starts the SPI transfer, and waits for the
+ * transfer to be completed.
+ *
+ * returns:	Number of bytes transferred in the last transfer
+ */
+static int xspips_start_transfer(struct spi_device *spi,
+			struct spi_transfer *transfer)
+{
+	struct xspips *xspi = spi_master_get_devdata(spi->master);
+	u32 ctrl_reg;
+	unsigned long flags;
+
+	xspi->txbuf = transfer->tx_buf;
+	xspi->rxbuf = transfer->rx_buf;
+	xspi->remaining_bytes = transfer->len;
+	INIT_COMPLETION(xspi->done);
+
+	xspips_fill_tx_fifo(xspi);
+
+	xspips_write(xspi->regs + XSPIPS_IER_OFFSET, XSPIPS_IXR_ALL_MASK);
+
+	spin_lock_irqsave(&xspi->ctrl_reg_lock, flags);
+
+	/* Start the transfer by enabling manual start bit */
+	ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
+	ctrl_reg |= XSPIPS_CR_MANSTRT_MASK;
+	xspips_write(xspi->regs + XSPIPS_CR_OFFSET, ctrl_reg);
+
+	spin_unlock_irqrestore(&xspi->ctrl_reg_lock, flags);
+
+	wait_for_completion(&xspi->done);
+
+	return (transfer->len) - (xspi->remaining_bytes);
+}
+
+/**
+ * xspips_work_queue - Get the transfer request from queue to perform transfers
+ * @work:	Pointer to the work_struct structure
+ */
+static void xspips_work_queue(struct work_struct *work)
+{
+	struct xspips *xspi = container_of(work, struct xspips, work);
+	unsigned long flags;
+
+	spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+	xspi->dev_busy = 1;
+
+	if (list_empty(&xspi->queue) ||
+		xspi->queue_state == XSPIPS_QUEUE_STOPPED) {
+		xspi->dev_busy = 0;
+		spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+		return;
+	}
+
+	while (!list_empty(&xspi->queue)) {
+		struct spi_message *msg;
+		struct spi_device *spi;
+		struct spi_transfer *transfer = NULL;
+		unsigned cs_change = 1;
+		int status = 0;
+
+		msg = container_of(xspi->queue.next, struct spi_message, queue);
+		list_del_init(&msg->queue);
+		spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+		spi = msg->spi;
+
+		list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+			if ((transfer->bits_per_word || transfer->speed_hz) &&
+								cs_change) {
+				status = xspips_setup_transfer(spi, transfer);
+				if (status < 0)
+					break;
+			}
+
+			if (cs_change)
+				xspips_chipselect(spi, 1);
+
+			cs_change = transfer->cs_change;
+
+			if (!transfer->tx_buf && !transfer->rx_buf &&
+				transfer->len) {
+				status = -EINVAL;
+				break;
+			}
+
+			if (transfer->len)
+				status = xspips_start_transfer(spi, transfer);
+
+			if (status != transfer->len) {
+				if (status > 0)
+					status = -EMSGSIZE;
+				break;
+			}
+			msg->actual_length += status;
+			status = 0;
+
+			if (transfer->delay_usecs)
+				udelay(transfer->delay_usecs);
+
+			if (!cs_change)
+				continue;
+			if (transfer->transfer_list.next == &msg->transfers)
+				break;
+
+			xspips_chipselect(spi, 0);
+		}
+
+		msg->status = status;
+		msg->complete(msg->context);
+
+		if (!(status == 0 && cs_change))
+			xspips_chipselect(spi, 0);
+
+		spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+	}
+	xspi->dev_busy = 0;
+	spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+}
+
+/**
+ * xspips_transfer - Add a new transfer request at the tail of work queue
+ * @spi:	Pointer to the spi_device structure
+ * @message:	Pointer to the spi_transfer structure which provide information
+ *		about next transfer parameters
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_transfer(struct spi_device *spi, struct spi_message *message)
+{
+	struct xspips *xspi = spi_master_get_devdata(spi->master);
+	struct spi_transfer *transfer;
+	unsigned long flags;
+
+	if (xspi->queue_state == XSPIPS_QUEUE_STOPPED)
+		return -ESHUTDOWN;
+
+	message->actual_length = 0;
+	message->status = -EINPROGRESS;
+
+	/* Check each transfer's parameters */
+	list_for_each_entry(transfer, &message->transfers, transfer_list) {
+		u8 bits_per_word =
+			transfer->bits_per_word ? : spi->bits_per_word;
+
+		bits_per_word = bits_per_word ? : 8;
+		if (!transfer->tx_buf && !transfer->rx_buf && transfer->len)
+			return -EINVAL;
+		if (bits_per_word != 8)
+			return -EINVAL;
+	}
+
+	spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+	list_add_tail(&message->queue, &xspi->queue);
+	if (!xspi->dev_busy)
+		queue_work(xspi->workqueue, &xspi->work);
+	spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xspips_start_queue - Starts the queue of the SPI driver
+ * @xspi:	Pointer to the xspips structure
+ *
+ * returns:	0 on success and error value on error
+ */
+static inline int xspips_start_queue(struct xspips *xspi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+
+	if (xspi->queue_state == XSPIPS_QUEUE_RUNNING || xspi->dev_busy) {
+		spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+		return -EBUSY;
+	}
+
+	xspi->queue_state = XSPIPS_QUEUE_RUNNING;
+	spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xspips_stop_queue - Stops the queue of the SPI driver
+ * @xspi:	Pointer to the xspips structure
+ *
+ * This function waits till queue is empty and then stops the queue.
+ * Maximum time out is set to 5 seconds.
+ *
+ * returns:	0 on success and error value on error
+ */
+static inline int xspips_stop_queue(struct xspips *xspi)
+{
+	unsigned long flags;
+	unsigned limit = 500;
+	int ret = 0;
+
+	if (xspi->queue_state != XSPIPS_QUEUE_RUNNING)
+		return ret;
+
+	spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+
+	while ((!list_empty(&xspi->queue) || xspi->dev_busy) && limit--) {
+		spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+		msleep(10);
+		spin_lock_irqsave(&xspi->trans_queue_lock, flags);
+	}
+
+	if (!list_empty(&xspi->queue) || xspi->dev_busy)
+		ret = -EBUSY;
+
+	if (ret == 0)
+		xspi->queue_state = XSPIPS_QUEUE_STOPPED;
+
+	spin_unlock_irqrestore(&xspi->trans_queue_lock, flags);
+
+	return ret;
+}
+
+/**
+ * xspips_destroy_queue - Destroys the queue of the SPI driver
+ * @xspi:	Pointer to the xspips structure
+ *
+ * returns:	0 on success and error value on error
+ */
+static inline int xspips_destroy_queue(struct xspips *xspi)
+{
+	int ret;
+
+	ret = xspips_stop_queue(xspi);
+	if (ret != 0)
+		return ret;
+
+	destroy_workqueue(xspi->workqueue);
+
+	return 0;
+}
+
+static int xspips_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers. And we may have to suspend operation and return
+		 * after the rate change or its abort
+		 */
+		return NOTIFY_OK;
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+/**
+ * xspips_probe - Probe method for the SPI driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function initializes the driver data structures and the hardware.
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct spi_master *master;
+	struct xspips *xspi;
+	struct resource *res;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*xspi));
+	if (master == NULL)
+		return -ENOMEM;
+
+	xspi = spi_master_get_devdata(master);
+	master->dev.of_node = pdev->dev.of_node;
+	platform_set_drvdata(pdev, master);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xspi->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xspi->regs)) {
+		ret = PTR_ERR(xspi->regs);
+		goto remove_master;
+	}
+
+	xspi->irq = platform_get_irq(pdev, 0);
+	if (xspi->irq < 0) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "irq number is negative\n");
+		goto remove_master;
+	}
+
+	ret = devm_request_irq(&pdev->dev, xspi->irq, xspips_irq,
+			       0, pdev->name, xspi);
+	if (ret != 0) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "request_irq failed\n");
+		goto remove_master;
+	}
+
+	xspi->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+	if (IS_ERR(xspi->aperclk)) {
+		dev_err(&pdev->dev, "aper_clk clock not found.\n");
+		ret = PTR_ERR(xspi->aperclk);
+		goto remove_master;
+	}
+
+	xspi->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(xspi->devclk)) {
+		dev_err(&pdev->dev, "ref_clk clock not found.\n");
+		ret = PTR_ERR(xspi->devclk);
+		goto remove_master;
+	}
+
+	ret = clk_prepare_enable(xspi->aperclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto remove_master;
+	}
+
+	ret = clk_prepare_enable(xspi->devclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable device clock.\n");
+		goto clk_dis_aper;
+	}
+
+	xspi->clk_rate_change_nb.notifier_call = xspips_clk_notifier_cb;
+	xspi->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(xspi->devclk, &xspi->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+	/* SPI controller initializations */
+	xspips_init_hw(xspi->regs);
+
+	init_completion(&xspi->done);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "num-chip-select",
+				   (u32 *)&master->num_chipselect);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "couldn't determine num-chip-select\n");
+		goto clk_notif_unreg;
+	}
+	master->setup = xspips_setup;
+	master->transfer = xspips_transfer;
+	master->mode_bits = SPI_CPOL | SPI_CPHA;
+
+	xspi->speed_hz = clk_get_rate(xspi->devclk) / 2;
+
+	xspi->dev_busy = 0;
+
+	INIT_LIST_HEAD(&xspi->queue);
+	spin_lock_init(&xspi->trans_queue_lock);
+	spin_lock_init(&xspi->ctrl_reg_lock);
+
+	xspi->queue_state = XSPIPS_QUEUE_STOPPED;
+	xspi->dev_busy = 0;
+
+	INIT_WORK(&xspi->work, xspips_work_queue);
+	xspi->workqueue =
+		create_singlethread_workqueue(dev_name(&pdev->dev));
+	if (!xspi->workqueue) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "problem initializing queue\n");
+		goto clk_notif_unreg;
+	}
+
+	ret = xspips_start_queue(xspi);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "problem starting queue\n");
+		goto remove_queue;
+	}
+
+	ret = spi_register_master(master);
+	if (ret) {
+		dev_err(&pdev->dev, "spi_register_master failed\n");
+		goto remove_queue;
+	}
+
+	dev_info(&pdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", res->start,
+			(u32 __force)xspi->regs, xspi->irq);
+
+	return ret;
+
+remove_queue:
+	(void)xspips_destroy_queue(xspi);
+clk_notif_unreg:
+	clk_notifier_unregister(xspi->devclk, &xspi->clk_rate_change_nb);
+	clk_disable_unprepare(xspi->devclk);
+clk_dis_aper:
+	clk_disable_unprepare(xspi->aperclk);
+remove_master:
+	spi_master_put(master);
+	return ret;
+}
+
+/**
+ * xspips_remove - Remove method for the SPI driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function is called if a device is physically removed from the system or
+ * if the driver module is being unloaded. It frees all resources allocated to
+ * the device.
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xspips *xspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = xspips_destroy_queue(xspi);
+	if (ret != 0)
+		return ret;
+
+	xspips_write(xspi->regs + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
+
+	clk_notifier_unregister(xspi->devclk, &xspi->clk_rate_change_nb);
+	clk_disable_unprepare(xspi->devclk);
+	clk_disable_unprepare(xspi->aperclk);
+
+	spi_unregister_master(master);
+	spi_master_put(master);
+
+	dev_dbg(&pdev->dev, "remove succeeded\n");
+	return 0;
+
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xspips_suspend - Suspend method for the SPI driver
+ * @dev:	Address of the platform_device structure
+ *
+ * This function stops the SPI driver queue and disables the SPI controller
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_suspend(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev,
+			struct platform_device, dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xspips *xspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = xspips_stop_queue(xspi);
+	if (ret != 0)
+		return ret;
+
+	xspips_write(xspi->regs + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
+
+	clk_disable(xspi->devclk);
+	clk_disable(xspi->aperclk);
+
+	dev_dbg(&pdev->dev, "suspend succeeded\n");
+	return 0;
+}
+
+/**
+ * xspips_resume - Resume method for the SPI driver
+ * @dev:	Address of the platform_device structure
+ *
+ * This function starts the SPI driver queue and initializes the SPI controller
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xspips_resume(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev,
+			struct platform_device, dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xspips *xspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = clk_enable(xspi->aperclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable APER clock.\n");
+		return ret;
+	}
+
+	ret = clk_enable(xspi->devclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable device clock.\n");
+		clk_disable(xspi->aperclk);
+		return ret;
+	}
+
+	xspips_init_hw(xspi->regs);
+
+	ret = xspips_start_queue(xspi);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "problem starting queue (%d)\n", ret);
+		return ret;
+	}
+
+	dev_dbg(&pdev->dev, "resume succeeded\n");
+	return 0;
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(xspips_dev_pm_ops, xspips_suspend, xspips_resume);
+
+/* Work with hotplug and coldplug */
+MODULE_ALIAS("platform:" XSPIPS_NAME);
+
+static struct of_device_id xspips_of_match[] = {
+	{ .compatible = "xlnx,ps7-spi-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xspips_of_match);
+
+/*
+ * xspips_driver - This structure defines the SPI subsystem platform driver
+ */
+static struct platform_driver xspips_driver = {
+	.probe	= xspips_probe,
+	.remove	= xspips_remove,
+	.driver = {
+		.name = XSPIPS_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = xspips_of_match,
+		.pm = &xspips_dev_pm_ops,
+	},
+};
+
+module_platform_driver(xspips_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx PS SPI driver");
+MODULE_LICENSE("GPL");
+
Index: linux-3.12.24-rt38-xilinx/drivers/spi/spi-zynq-qspi.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/spi/spi-zynq-qspi.c	2014-07-20 22:06:37.506286749 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ *
+ * Xilinx PS Quad-SPI (QSPI) controller driver (master mode only)
+ *
+ * (c) 2009-2011 Xilinx, Inc.
+ *
+ * based on Xilinx PS SPI Driver (xspips.c)
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+/*
+ * Name of this driver
+ */
+#define DRIVER_NAME			"xqspips"
+
+/*
+ * Register offset definitions
+ */
+#define XQSPIPS_CONFIG_OFFSET		0x00 /* Configuration  Register, RW */
+#define XQSPIPS_STATUS_OFFSET		0x04 /* Interrupt Status Register, RO */
+#define XQSPIPS_IEN_OFFSET		0x08 /* Interrupt Enable Register, WO */
+#define XQSPIPS_IDIS_OFFSET		0x0C /* Interrupt Disable Reg, WO */
+#define XQSPIPS_IMASK_OFFSET		0x10 /* Interrupt Enabled Mask Reg,RO */
+#define XQSPIPS_ENABLE_OFFSET		0x14 /* Enable/Disable Register, RW */
+#define XQSPIPS_DELAY_OFFSET		0x18 /* Delay Register, RW */
+#define XQSPIPS_TXD_00_00_OFFSET	0x1C /* Transmit 4-byte inst, WO */
+#define XQSPIPS_TXD_00_01_OFFSET	0x80 /* Transmit 1-byte inst, WO */
+#define XQSPIPS_TXD_00_10_OFFSET	0x84 /* Transmit 2-byte inst, WO */
+#define XQSPIPS_TXD_00_11_OFFSET	0x88 /* Transmit 3-byte inst, WO */
+#define XQSPIPS_RXD_OFFSET		0x20 /* Data Receive Register, RO */
+#define XQSPIPS_SIC_OFFSET		0x24 /* Slave Idle Count Register, RW */
+#define XQSPIPS_TX_THRESH_OFFSET	0x28 /* TX FIFO Watermark Reg, RW */
+#define XQSPIPS_RX_THRESH_OFFSET	0x2C /* RX FIFO Watermark Reg, RW */
+#define XQSPIPS_GPIO_OFFSET		0x30 /* GPIO Register, RW */
+#define XQSPIPS_LINEAR_CFG_OFFSET	0xA0 /* Linear Adapter Config Ref, RW */
+#define XQSPIPS_MOD_ID_OFFSET		0xFC /* Module ID Register, RO */
+
+/*
+ * QSPI Configuration Register bit Masks
+ *
+ * This register contains various control bits that effect the operation
+ * of the QSPI controller
+ */
+#define XQSPIPS_CONFIG_IFMODE_MASK	0x80000000 /* Flash Memory Interface */
+#define XQSPIPS_CONFIG_MANSRT_MASK	0x00010000 /* Manual TX Start */
+#define XQSPIPS_CONFIG_MANSRTEN_MASK	0x00008000 /* Enable Manual TX Mode */
+#define XQSPIPS_CONFIG_SSFORCE_MASK	0x00004000 /* Manual Chip Select */
+#define XQSPIPS_CONFIG_BDRATE_MASK	0x00000038 /* Baud Rate Divisor Mask */
+#define XQSPIPS_CONFIG_CPHA_MASK	0x00000004 /* Clock Phase Control */
+#define XQSPIPS_CONFIG_CPOL_MASK	0x00000002 /* Clock Polarity Control */
+#define XQSPIPS_CONFIG_SSCTRL_MASK	0x00003C00 /* Slave Select Mask */
+#define XQSPIPS_CONFIG_MSTREN_MASK	0x00000001 /* Master Mode */
+
+/*
+ * QSPI Interrupt Registers bit Masks
+ *
+ * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
+ * bit definitions.
+ */
+#define XQSPIPS_IXR_TXNFULL_MASK	0x00000004 /* QSPI TX FIFO Overflow */
+#define XQSPIPS_IXR_TXFULL_MASK		0x00000008 /* QSPI TX FIFO is full */
+#define XQSPIPS_IXR_RXNEMTY_MASK	0x00000010 /* QSPI RX FIFO Not Empty */
+#define XQSPIPS_IXR_ALL_MASK		(XQSPIPS_IXR_TXNFULL_MASK | \
+					XQSPIPS_IXR_RXNEMTY_MASK)
+
+/*
+ * QSPI Enable Register bit Masks
+ *
+ * This register is used to enable or disable the QSPI controller
+ */
+#define XQSPIPS_ENABLE_ENABLE_MASK	0x00000001 /* QSPI Enable Bit Mask */
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define XQSPIPS_LCFG_TWO_MEM_MASK	0x40000000 /* LQSPI Two memories Mask */
+#define XQSPIPS_LCFG_SEP_BUS_MASK	0x20000000 /* LQSPI Separate bus Mask */
+#define XQSPIPS_LCFG_U_PAGE_MASK	0x10000000 /* LQSPI Upper Page Mask */
+
+#define XQSPIPS_LCFG_DUMMY_SHIFT	8
+
+#define XQSPIPS_FAST_READ_QOUT_CODE	0x6B	/* read instruction code */
+#define XQSPIPS_FIFO_DEPTH		63	/* FIFO depth in words */
+#define XQSPIPS_RX_THRESHOLD		32	/* Rx FIFO threshold level */
+
+/*
+ * The modebits configurable by the driver to make the SPI support different
+ * data formats
+ */
+#define MODEBITS			(SPI_CPOL | SPI_CPHA)
+
+/*
+ * Definitions for the status of queue
+ */
+#define XQSPIPS_QUEUE_STOPPED		0
+#define XQSPIPS_QUEUE_RUNNING		1
+
+/*
+ * Definitions of the flash commands
+ */
+/* Flash opcodes in ascending order */
+#define	XQSPIPS_FLASH_OPCODE_WRSR	0x01	/* Write status register */
+#define	XQSPIPS_FLASH_OPCODE_PP		0x02	/* Page program */
+#define	XQSPIPS_FLASH_OPCODE_NORM_READ	0x03	/* Normal read data bytes */
+#define	XQSPIPS_FLASH_OPCODE_WRDS	0x04	/* Write disable */
+#define	XQSPIPS_FLASH_OPCODE_RDSR1	0x05	/* Read status register 1 */
+#define	XQSPIPS_FLASH_OPCODE_WREN	0x06	/* Write enable */
+#define	XQSPIPS_FLASH_OPCODE_BRRD	0x16	/* Bank Register Read */
+#define	XQSPIPS_FLASH_OPCODE_BRWR	0x17	/* Bank Register Write */
+#define	XQSPIPS_FLASH_OPCODE_EXTADRD	0xC8	/* Micron - Bank Reg Read */
+#define	XQSPIPS_FLASH_OPCODE_EXTADWR	0xC5	/* Micron - Bank Reg Write */
+#define	XQSPIPS_FLASH_OPCODE_FAST_READ	0x0B	/* Fast read data bytes */
+#define	XQSPIPS_FLASH_OPCODE_BE_4K	0x20	/* Erase 4KiB block */
+#define	XQSPIPS_FLASH_OPCODE_RDSR2	0x35	/* Read status register 2 */
+#define	XQSPIPS_FLASH_OPCODE_RDFSR	0x70	/* Read flag status register */
+#define	XQSPIPS_FLASH_OPCODE_DUAL_READ	0x3B	/* Dual read data bytes */
+#define	XQSPIPS_FLASH_OPCODE_BE_32K	0x52	/* Erase 32KiB block */
+#define	XQSPIPS_FLASH_OPCODE_QUAD_READ	0x6B	/* Quad read data bytes */
+#define	XQSPIPS_FLASH_OPCODE_ERASE_SUS	0x75	/* Erase suspend */
+#define	XQSPIPS_FLASH_OPCODE_ERASE_RES	0x7A	/* Erase resume */
+#define	XQSPIPS_FLASH_OPCODE_RDID	0x9F	/* Read JEDEC ID */
+#define	XQSPIPS_FLASH_OPCODE_BE		0xC7	/* Erase whole flash block */
+#define	XQSPIPS_FLASH_OPCODE_SE		0xD8	/* Sector erase (usually 64KB)*/
+#define XQSPIPS_FLASH_OPCODE_QPP	0x32	/* Quad page program */
+
+/*
+ * Macros for the QSPI controller read/write
+ */
+#define xqspips_read(addr)		readl_relaxed(addr)
+#define xqspips_write(addr, val)	writel_relaxed((val), (addr))
+
+/**
+ * struct xqspips - Defines qspi driver instance
+ * @workqueue:		Queue of all the transfers
+ * @work:		Information about current transfer
+ * @queue:		Head of the queue
+ * @queue_state:	Queue status
+ * @regs:		Virtual address of the QSPI controller registers
+ * @devclk:		Pointer to the peripheral clock
+ * @aperclk:		Pointer to the APER clock
+ * @clk_rate_change_nb:	Notifier block for clock frequency change callback
+ * @irq:		IRQ number
+ * @speed_hz:		Current QSPI bus clock speed in Hz
+ * @trans_queue_lock:	Lock used for accessing transfer queue
+ * @config_reg_lock:	Lock used for accessing configuration register
+ * @txbuf:		Pointer	to the TX buffer
+ * @rxbuf:		Pointer to the RX buffer
+ * @bytes_to_transfer:	Number of bytes left to transfer
+ * @bytes_to_receive:	Number of bytes left to receive
+ * @dev_busy:		Device busy flag
+ * @done:		Transfer complete status
+ * @is_inst:		Flag to indicate the first message in a Transfer request
+ * @is_dual:		Flag to indicate whether dual flash memories are used
+ */
+struct xqspips {
+	struct workqueue_struct *workqueue;
+	struct work_struct work;
+	struct list_head queue;
+	u8 queue_state;
+	void __iomem *regs;
+	struct clk *devclk;
+	struct clk *aperclk;
+	struct notifier_block clk_rate_change_nb;
+	int irq;
+	u32 speed_hz;
+	spinlock_t trans_queue_lock;
+	spinlock_t config_reg_lock;
+	const void *txbuf;
+	void *rxbuf;
+	int bytes_to_transfer;
+	int bytes_to_receive;
+	u8 dev_busy;
+	struct completion done;
+	bool is_inst;
+	u32 is_dual;
+};
+
+/**
+ * struct xqspips_inst_format - Defines qspi flash instruction format
+ * @opcode:		Operational code of instruction
+ * @inst_size:		Size of the instruction including address bytes
+ * @offset:		Register address where instruction has to be written
+ */
+struct xqspips_inst_format {
+	u8 opcode;
+	u8 inst_size;
+	u8 offset;
+};
+
+/*
+ * List of all the QSPI instructions and its format
+ */
+static struct xqspips_inst_format flash_inst[] = {
+	{ XQSPIPS_FLASH_OPCODE_WREN, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_WRDS, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_RDSR1, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_RDSR2, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_WRSR, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_RDFSR, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_PP, 4, XQSPIPS_TXD_00_00_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_SE, 4, XQSPIPS_TXD_00_00_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_BE_32K, 4, XQSPIPS_TXD_00_00_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_BE_4K, 4, XQSPIPS_TXD_00_00_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_BE, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_RDID, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_NORM_READ, 4, XQSPIPS_TXD_00_00_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_FAST_READ, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_DUAL_READ, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_QUAD_READ, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_BRRD, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_BRWR, 2, XQSPIPS_TXD_00_10_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_EXTADRD, 1, XQSPIPS_TXD_00_01_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_EXTADWR, 2, XQSPIPS_TXD_00_10_OFFSET },
+	{ XQSPIPS_FLASH_OPCODE_QPP, 4, XQSPIPS_TXD_00_00_OFFSET },
+	/* Add all the instructions supported by the flash device */
+};
+
+/**
+ * xqspips_init_hw - Initialize the hardware
+ * @regs_base:	Base address of QSPI controller
+ * @is_dual:	Indicates whether dual memories are used
+ *
+ * The default settings of the QSPI controller's configurable parameters on
+ * reset are
+ *	- Master mode
+ *	- Baud rate divisor is set to 2
+ *	- Threshold value for TX FIFO not full interrupt is set to 1
+ *	- Flash memory interface mode enabled
+ *	- Size of the word to be transferred as 8 bit
+ * This function performs the following actions
+ *	- Disable and clear all the interrupts
+ *	- Enable manual slave select
+ *	- Enable manual start
+ *	- Deselect all the chip select lines
+ *	- Set the size of the word to be transferred as 32 bit
+ *	- Set the little endian mode of TX FIFO and
+ *	- Enable the QSPI controller
+ */
+static void xqspips_init_hw(void __iomem *regs_base, int is_dual)
+{
+	u32 config_reg;
+
+	xqspips_write(regs_base + XQSPIPS_ENABLE_OFFSET,
+		~XQSPIPS_ENABLE_ENABLE_MASK);
+	xqspips_write(regs_base + XQSPIPS_IDIS_OFFSET, 0x7F);
+
+	/* Disable linear mode as the boot loader may have used it */
+	xqspips_write(regs_base + XQSPIPS_LINEAR_CFG_OFFSET, 0);
+
+	/* Clear the RX FIFO */
+	while (xqspips_read(regs_base + XQSPIPS_STATUS_OFFSET) &
+			XQSPIPS_IXR_RXNEMTY_MASK)
+		xqspips_read(regs_base + XQSPIPS_RXD_OFFSET);
+
+	xqspips_write(regs_base + XQSPIPS_STATUS_OFFSET , 0x7F);
+	config_reg = xqspips_read(regs_base + XQSPIPS_CONFIG_OFFSET);
+	config_reg &= ~(XQSPIPS_CONFIG_MSTREN_MASK |
+			XQSPIPS_CONFIG_CPOL_MASK |
+			XQSPIPS_CONFIG_CPHA_MASK |
+			XQSPIPS_CONFIG_BDRATE_MASK |
+			XQSPIPS_CONFIG_SSFORCE_MASK |
+			XQSPIPS_CONFIG_MANSRTEN_MASK |
+			XQSPIPS_CONFIG_MANSRT_MASK);
+	config_reg |= (XQSPIPS_CONFIG_MSTREN_MASK |
+			XQSPIPS_CONFIG_SSFORCE_MASK |
+			XQSPIPS_CONFIG_IFMODE_MASK);
+	xqspips_write(regs_base + XQSPIPS_CONFIG_OFFSET, config_reg);
+
+	xqspips_write(regs_base + XQSPIPS_RX_THRESH_OFFSET,
+				XQSPIPS_RX_THRESHOLD);
+	if (is_dual == 1)
+		/* Enable two memories on seperate buses */
+		xqspips_write(regs_base + XQSPIPS_LINEAR_CFG_OFFSET,
+			(XQSPIPS_LCFG_TWO_MEM_MASK |
+			 XQSPIPS_LCFG_SEP_BUS_MASK |
+			 (1 << XQSPIPS_LCFG_DUMMY_SHIFT) |
+			 XQSPIPS_FAST_READ_QOUT_CODE));
+#ifdef CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED
+	/* Enable two memories on shared bus */
+	xqspips_write(regs_base + XQSPIPS_LINEAR_CFG_OFFSET,
+		 (XQSPIPS_LCFG_TWO_MEM_MASK |
+		 (1 << XQSPIPS_LCFG_DUMMY_SHIFT) |
+		 XQSPIPS_FAST_READ_QOUT_CODE));
+#endif
+	xqspips_write(regs_base + XQSPIPS_ENABLE_OFFSET,
+			XQSPIPS_ENABLE_ENABLE_MASK);
+}
+
+/**
+ * xqspips_copy_read_data - Copy data to RX buffer
+ * @xqspi:	Pointer to the xqspips structure
+ * @data:	The 32 bit variable where data is stored
+ * @size:	Number of bytes to be copied from data to RX buffer
+ */
+static void xqspips_copy_read_data(struct xqspips *xqspi, u32 data, u8 size)
+{
+	if (xqspi->rxbuf) {
+		data >>= (4 - size) * 8;
+		data = le32_to_cpu(data);
+		memcpy((u8 *)xqspi->rxbuf, &data, size);
+		xqspi->rxbuf += size;
+	}
+	xqspi->bytes_to_receive -= size;
+	if (xqspi->bytes_to_receive < 0)
+		xqspi->bytes_to_receive = 0;
+}
+
+/**
+ * xqspips_copy_write_data - Copy data from TX buffer
+ * @xqspi:	Pointer to the xqspips structure
+ * @data:	Pointer to the 32 bit variable where data is to be copied
+ * @size:	Number of bytes to be copied from TX buffer to data
+ */
+static void xqspips_copy_write_data(struct xqspips *xqspi, u32 *data, u8 size)
+{
+
+	if (xqspi->txbuf) {
+		switch (size) {
+		case 1:
+			*data = *((u8 *)xqspi->txbuf);
+			xqspi->txbuf += 1;
+			*data |= 0xFFFFFF00;
+			break;
+		case 2:
+			*data = *((u16 *)xqspi->txbuf);
+			xqspi->txbuf += 2;
+			*data |= 0xFFFF0000;
+			break;
+		case 3:
+			*data = *((u16 *)xqspi->txbuf);
+			xqspi->txbuf += 2;
+			*data |= (*((u8 *)xqspi->txbuf) << 16);
+			xqspi->txbuf += 1;
+			*data |= 0xFF000000;
+			break;
+		case 4:
+			*data = *((u32 *)xqspi->txbuf);
+			xqspi->txbuf += 4;
+			break;
+		default:
+			/* This will never execute */
+			break;
+		}
+	} else {
+		*data = 0;
+	}
+
+	xqspi->bytes_to_transfer -= size;
+	if (xqspi->bytes_to_transfer < 0)
+		xqspi->bytes_to_transfer = 0;
+}
+
+/**
+ * xqspips_chipselect - Select or deselect the chip select line
+ * @qspi:	Pointer to the spi_device structure
+ * @is_on:	Select(1) or deselect (0) the chip select line
+ */
+static void xqspips_chipselect(struct spi_device *qspi, int is_on)
+{
+	struct xqspips *xqspi = spi_master_get_devdata(qspi->master);
+	u32 config_reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&xqspi->config_reg_lock, flags);
+
+	config_reg = xqspips_read(xqspi->regs + XQSPIPS_CONFIG_OFFSET);
+
+	if (is_on) {
+		/* Select the slave */
+		config_reg &= ~XQSPIPS_CONFIG_SSCTRL_MASK;
+		config_reg |= (((~(0x0001 << qspi->chip_select)) << 10) &
+				XQSPIPS_CONFIG_SSCTRL_MASK);
+	} else {
+		/* Deselect the slave */
+		config_reg |= XQSPIPS_CONFIG_SSCTRL_MASK;
+	}
+
+	xqspips_write(xqspi->regs + XQSPIPS_CONFIG_OFFSET, config_reg);
+
+	spin_unlock_irqrestore(&xqspi->config_reg_lock, flags);
+}
+
+/**
+ * xqspips_setup_transfer - Configure QSPI controller for specified transfer
+ * @qspi:	Pointer to the spi_device structure
+ * @transfer:	Pointer to the spi_transfer structure which provides information
+ *		about next transfer setup parameters
+ *
+ * Sets the operational mode of QSPI controller for the next QSPI transfer and
+ * sets the requested clock frequency.
+ *
+ * returns:	0 on success and -EINVAL on invalid input parameter
+ *
+ * Note: If the requested frequency is not an exact match with what can be
+ * obtained using the prescalar value, the driver sets the clock frequency which
+ * is lower than the requested frequency (maximum lower) for the transfer. If
+ * the requested frequency is higher or lower than that is supported by the QSPI
+ * controller the driver will set the highest or lowest frequency supported by
+ * controller.
+ */
+static int xqspips_setup_transfer(struct spi_device *qspi,
+		struct spi_transfer *transfer)
+{
+	struct xqspips *xqspi = spi_master_get_devdata(qspi->master);
+	u32 config_reg;
+	u32 req_hz;
+	u32 baud_rate_val = 0;
+	unsigned long flags;
+	int update_baud = 0;
+
+	req_hz = (transfer) ? transfer->speed_hz : qspi->max_speed_hz;
+
+	if (qspi->mode & ~MODEBITS) {
+		dev_err(&qspi->dev, "%s, unsupported mode bits %x\n",
+			__func__, qspi->mode & ~MODEBITS);
+		return -EINVAL;
+	}
+
+	if (transfer && (transfer->speed_hz == 0))
+		req_hz = qspi->max_speed_hz;
+
+	/* Set the clock frequency */
+	if (xqspi->speed_hz != req_hz) {
+		while ((baud_rate_val < 8)  &&
+			(clk_get_rate(xqspi->devclk) / (2 << baud_rate_val)) >
+			req_hz)
+				baud_rate_val++;
+		xqspi->speed_hz = req_hz;
+		update_baud = 1;
+	}
+
+	spin_lock_irqsave(&xqspi->config_reg_lock, flags);
+
+	config_reg = xqspips_read(xqspi->regs + XQSPIPS_CONFIG_OFFSET);
+
+	/* Set the QSPI clock phase and clock polarity */
+	config_reg &= (~XQSPIPS_CONFIG_CPHA_MASK) &
+				(~XQSPIPS_CONFIG_CPOL_MASK);
+	if (qspi->mode & SPI_CPHA)
+		config_reg |= XQSPIPS_CONFIG_CPHA_MASK;
+	if (qspi->mode & SPI_CPOL)
+		config_reg |= XQSPIPS_CONFIG_CPOL_MASK;
+
+	if (update_baud) {
+		config_reg &= 0xFFFFFFC7;
+		config_reg |= (baud_rate_val << 3);
+	}
+
+	xqspips_write(xqspi->regs + XQSPIPS_CONFIG_OFFSET, config_reg);
+
+	spin_unlock_irqrestore(&xqspi->config_reg_lock, flags);
+
+	dev_dbg(&qspi->dev, "%s, mode %d, %u bits/w, %u clock speed\n",
+		__func__, qspi->mode & MODEBITS, qspi->bits_per_word,
+		xqspi->speed_hz);
+
+	return 0;
+}
+
+/**
+ * xqspips_setup - Configure the QSPI controller
+ * @qspi:	Pointer to the spi_device structure
+ *
+ * Sets the operational mode of QSPI controller for the next QSPI transfer, baud
+ * rate and divisor value to setup the requested qspi clock.
+ *
+ * returns:	0 on success and error value on failure
+ */
+static int xqspips_setup(struct spi_device *qspi)
+{
+
+	if (qspi->mode & SPI_LSB_FIRST)
+		return -EINVAL;
+
+	if (!qspi->max_speed_hz)
+		return -EINVAL;
+
+	if (!qspi->bits_per_word)
+		qspi->bits_per_word = 32;
+
+	return xqspips_setup_transfer(qspi, NULL);
+}
+
+/**
+ * xqspips_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
+ * @xqspi:	Pointer to the xqspips structure
+ * @size:	Size of the fifo to be filled
+ */
+static void xqspips_fill_tx_fifo(struct xqspips *xqspi, u32 size)
+{
+	u32 fifocount;
+
+	for (fifocount = 0; (fifocount < size) &&
+			(xqspi->bytes_to_transfer >= 4); fifocount++) {
+		if (xqspi->txbuf) {
+			xqspips_write(xqspi->regs + XQSPIPS_TXD_00_00_OFFSET,
+						*((u32 *)xqspi->txbuf));
+			xqspi->txbuf += 4;
+		} else {
+			xqspips_write(xqspi->regs + XQSPIPS_TXD_00_00_OFFSET,
+						0x00);
+		}
+		xqspi->bytes_to_transfer -= 4;
+		if (xqspi->bytes_to_transfer < 0)
+			xqspi->bytes_to_transfer = 0;
+	}
+}
+
+/**
+ * xqspips_irq - Interrupt service routine of the QSPI controller
+ * @irq:	IRQ number
+ * @dev_id:	Pointer to the xqspi structure
+ *
+ * This function handles TX empty only.
+ * On TX empty interrupt this function reads the received data from RX FIFO and
+ * fills the TX FIFO if there is any data remaining to be transferred.
+ *
+ * returns:	IRQ_HANDLED always
+ */
+static irqreturn_t xqspips_irq(int irq, void *dev_id)
+{
+	struct xqspips *xqspi = dev_id;
+	u32 intr_status;
+	u8 offset[3] =	{XQSPIPS_TXD_00_01_OFFSET, XQSPIPS_TXD_00_10_OFFSET,
+		XQSPIPS_TXD_00_11_OFFSET};
+	u32 rxcount;
+	u32 rxindex = 0;
+
+	intr_status = xqspips_read(xqspi->regs + XQSPIPS_STATUS_OFFSET);
+	xqspips_write(xqspi->regs + XQSPIPS_STATUS_OFFSET , intr_status);
+	xqspips_write(xqspi->regs + XQSPIPS_IDIS_OFFSET,
+			XQSPIPS_IXR_ALL_MASK);
+
+	if ((intr_status & XQSPIPS_IXR_TXNFULL_MASK) ||
+		   (intr_status & XQSPIPS_IXR_RXNEMTY_MASK)) {
+		/* This bit is set when Tx FIFO has < THRESHOLD entries. We have
+		   the THRESHOLD value set to 1, so this bit indicates Tx FIFO
+		   is empty */
+		u32 data;
+
+		rxcount = xqspi->bytes_to_receive - xqspi->bytes_to_transfer;
+		rxcount = (rxcount % 4) ? ((rxcount/4) + 1) : (rxcount/4);
+
+		/* Read out the data from the RX FIFO */
+		while ((rxindex < rxcount) &&
+				(rxindex < XQSPIPS_RX_THRESHOLD)) {
+
+			if (xqspi->bytes_to_receive < 4 && !xqspi->is_dual) {
+				data = xqspips_read(xqspi->regs +
+						XQSPIPS_RXD_OFFSET);
+				xqspips_copy_read_data(xqspi, data,
+					xqspi->bytes_to_receive);
+			} else {
+				if (xqspi->rxbuf) {
+					(*(u32 *)xqspi->rxbuf) =
+					xqspips_read(xqspi->regs +
+						XQSPIPS_RXD_OFFSET);
+					xqspi->rxbuf += 4;
+				} else {
+					data = xqspips_read(xqspi->regs +
+							XQSPIPS_RXD_OFFSET);
+				}
+				xqspi->bytes_to_receive -= 4;
+				if (xqspi->bytes_to_receive < 0)
+					xqspi->bytes_to_receive = 0;
+			}
+			rxindex++;
+		}
+
+		if (xqspi->bytes_to_transfer) {
+			if (xqspi->bytes_to_transfer >= 4) {
+				/* There is more data to send */
+				xqspips_fill_tx_fifo(xqspi,
+						XQSPIPS_RX_THRESHOLD);
+			} else {
+				int tmp;
+				tmp = xqspi->bytes_to_transfer;
+				xqspips_copy_write_data(xqspi, &data,
+					xqspi->bytes_to_transfer);
+				if (xqspi->is_dual)
+					xqspips_write(xqspi->regs +
+						XQSPIPS_TXD_00_00_OFFSET, data);
+				else
+					xqspips_write(xqspi->regs +
+						offset[tmp - 1], data);
+			}
+			xqspips_write(xqspi->regs + XQSPIPS_IEN_OFFSET,
+					XQSPIPS_IXR_ALL_MASK);
+		} else {
+			/* If transfer and receive is completed then only send
+			 * complete signal */
+			if (xqspi->bytes_to_receive) {
+				/* There is still some data to be received.
+				   Enable Rx not empty interrupt */
+				xqspips_write(xqspi->regs + XQSPIPS_IEN_OFFSET,
+						XQSPIPS_IXR_ALL_MASK);
+			} else {
+				xqspips_write(xqspi->regs + XQSPIPS_IDIS_OFFSET,
+						XQSPIPS_IXR_ALL_MASK);
+				complete(&xqspi->done);
+			}
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xqspips_start_transfer - Initiates the QSPI transfer
+ * @qspi:	Pointer to the spi_device structure
+ * @transfer:	Pointer to the spi_transfer structure which provide information
+ *		about next transfer parameters
+ *
+ * This function fills the TX FIFO, starts the QSPI transfer, and waits for the
+ * transfer to be completed.
+ *
+ * returns:	Number of bytes transferred in the last transfer
+ */
+static int xqspips_start_transfer(struct spi_device *qspi,
+			struct spi_transfer *transfer)
+{
+	struct xqspips *xqspi = spi_master_get_devdata(qspi->master);
+	u32 data = 0;
+	u8 instruction = 0;
+	u8 index;
+	struct xqspips_inst_format *curr_inst;
+
+	xqspi->txbuf = transfer->tx_buf;
+	xqspi->rxbuf = transfer->rx_buf;
+	xqspi->bytes_to_transfer = transfer->len;
+	xqspi->bytes_to_receive = transfer->len;
+
+	if (xqspi->txbuf)
+		instruction = *(u8 *)xqspi->txbuf;
+
+	INIT_COMPLETION(xqspi->done);
+	if (instruction && xqspi->is_inst) {
+		for (index = 0 ; index < ARRAY_SIZE(flash_inst); index++)
+			if (instruction == flash_inst[index].opcode)
+				break;
+
+		/* Instruction might have already been transmitted. This is a
+		 * 'data only' transfer */
+		if (index == ARRAY_SIZE(flash_inst))
+			goto xfer_data;
+
+		curr_inst = &flash_inst[index];
+
+		/* Get the instruction */
+		data = 0;
+		xqspips_copy_write_data(xqspi, &data,
+					curr_inst->inst_size);
+
+		/* Write the instruction to LSB of the FIFO. The core is
+		 * designed such that it is not necessary to check whether the
+		 * write FIFO is full before writing. However, write would be
+		 * delayed if the user tries to write when write FIFO is full
+		 */
+		xqspips_write(xqspi->regs + curr_inst->offset, data);
+		goto xfer_start;
+	}
+
+xfer_data:
+	/* In case of Fast, Dual and Quad reads, transmit the instruction first.
+	 * Address and dummy byte will be transmitted in interrupt handler,
+	 * after instruction is transmitted */
+	if (((xqspi->is_inst == 0) && (xqspi->bytes_to_transfer >= 4)) ||
+	     ((xqspi->bytes_to_transfer >= 4) &&
+	      (instruction != XQSPIPS_FLASH_OPCODE_FAST_READ) &&
+	      (instruction != XQSPIPS_FLASH_OPCODE_DUAL_READ) &&
+	      (instruction != XQSPIPS_FLASH_OPCODE_QUAD_READ)))
+		xqspips_fill_tx_fifo(xqspi, XQSPIPS_FIFO_DEPTH);
+
+xfer_start:
+	xqspips_write(xqspi->regs + XQSPIPS_IEN_OFFSET,
+			XQSPIPS_IXR_ALL_MASK);
+
+	wait_for_completion(&xqspi->done);
+
+	return (transfer->len) - (xqspi->bytes_to_transfer);
+}
+
+/**
+ * xqspips_work_queue - Get the request from queue to perform transfers
+ * @work:	Pointer to the work_struct structure
+ */
+static void xqspips_work_queue(struct work_struct *work)
+{
+	struct xqspips *xqspi = container_of(work, struct xqspips, work);
+	unsigned long flags;
+#ifdef CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED
+	u32 lqspi_cfg_reg;
+#endif
+
+	spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+	xqspi->dev_busy = 1;
+
+	/* Check if list is empty or queue is stoped */
+	if (list_empty(&xqspi->queue) ||
+		xqspi->queue_state == XQSPIPS_QUEUE_STOPPED) {
+		xqspi->dev_busy = 0;
+		spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+		return;
+	}
+
+	/* Keep requesting transfer till list is empty */
+	while (!list_empty(&xqspi->queue)) {
+		struct spi_message *msg;
+		struct spi_device *qspi;
+		struct spi_transfer *transfer = NULL;
+		unsigned cs_change = 1;
+		int status = 0;
+
+		msg = container_of(xqspi->queue.next, struct spi_message,
+					queue);
+		list_del_init(&msg->queue);
+		spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+		qspi = msg->spi;
+
+#ifdef CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED
+		lqspi_cfg_reg = xqspips_read(xqspi->regs +
+					XQSPIPS_LINEAR_CFG_OFFSET);
+		if (qspi->master->flags & SPI_MASTER_U_PAGE)
+			lqspi_cfg_reg |= XQSPIPS_LCFG_U_PAGE_MASK;
+		else
+			lqspi_cfg_reg &= ~XQSPIPS_LCFG_U_PAGE_MASK;
+		xqspips_write(xqspi->regs + XQSPIPS_LINEAR_CFG_OFFSET,
+			      lqspi_cfg_reg);
+#endif
+
+		list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+			if (transfer->bits_per_word || transfer->speed_hz) {
+				status = xqspips_setup_transfer(qspi, transfer);
+				if (status < 0)
+					break;
+			}
+
+			/* Select the chip if required */
+			if (cs_change) {
+				xqspips_chipselect(qspi, 1);
+				xqspi->is_inst = 1;
+			}
+
+			cs_change = transfer->cs_change;
+
+			if (!transfer->tx_buf && !transfer->rx_buf &&
+				transfer->len) {
+				status = -EINVAL;
+				break;
+			}
+
+			/* Request the transfer */
+			if (transfer->len) {
+				status = xqspips_start_transfer(qspi, transfer);
+				xqspi->is_inst = 0;
+			}
+
+			if (status != transfer->len) {
+				if (status > 0)
+					status = -EMSGSIZE;
+				break;
+			}
+			msg->actual_length += status;
+			status = 0;
+
+			if (transfer->delay_usecs)
+				udelay(transfer->delay_usecs);
+
+			if (cs_change)
+				/* Deselect the chip */
+				xqspips_chipselect(qspi, 0);
+
+			if (transfer->transfer_list.next == &msg->transfers)
+				break;
+		}
+
+		msg->status = status;
+		msg->complete(msg->context);
+
+		xqspips_setup_transfer(qspi, NULL);
+
+		if (!(status == 0 && cs_change))
+			xqspips_chipselect(qspi, 0);
+
+		spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+	}
+	xqspi->dev_busy = 0;
+	spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+}
+
+/**
+ * xqspips_transfer - Add a new transfer request at the tail of work queue
+ * @qspi:	Pointer to the spi_device structure
+ * @message:	Pointer to the spi_transfer structure which provides information
+ *		about next transfer parameters
+ *
+ * returns:	0 on success, -EINVAL on invalid input parameter and
+ *		-ESHUTDOWN if queue is stopped by module unload function
+ */
+static int xqspips_transfer(struct spi_device *qspi,
+			    struct spi_message *message)
+{
+	struct xqspips *xqspi = spi_master_get_devdata(qspi->master);
+	struct spi_transfer *transfer;
+	unsigned long flags;
+
+	if (xqspi->queue_state == XQSPIPS_QUEUE_STOPPED)
+		return -ESHUTDOWN;
+
+	message->actual_length = 0;
+	message->status = -EINPROGRESS;
+
+	/* Check each transfer's parameters */
+	list_for_each_entry(transfer, &message->transfers, transfer_list) {
+		if (!transfer->tx_buf && !transfer->rx_buf && transfer->len)
+			return -EINVAL;
+		/* QSPI controller supports only 32 bit transfers whereas higher
+		 * layer drivers request 8 bit transfers. Re-visit at a later
+		 * time */
+		/* if (bits_per_word != 32)
+			return -EINVAL; */
+	}
+
+	spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+	list_add_tail(&message->queue, &xqspi->queue);
+	if (!xqspi->dev_busy)
+		queue_work(xqspi->workqueue, &xqspi->work);
+	spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xqspips_start_queue - Starts the queue of the QSPI driver
+ * @xqspi:	Pointer to the xqspips structure
+ *
+ * returns:	0 on success and -EBUSY if queue is already running or device is
+ *		busy
+ */
+static inline int xqspips_start_queue(struct xqspips *xqspi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+
+	if (xqspi->queue_state == XQSPIPS_QUEUE_RUNNING || xqspi->dev_busy) {
+		spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+		return -EBUSY;
+	}
+
+	xqspi->queue_state = XQSPIPS_QUEUE_RUNNING;
+	spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+
+	return 0;
+}
+
+/**
+ * xqspips_stop_queue - Stops the queue of the QSPI driver
+ * @xqspi:	Pointer to the xqspips structure
+ *
+ * This function waits till queue is empty and then stops the queue.
+ * Maximum time out is set to 5 seconds.
+ *
+ * returns:	0 on success and -EBUSY if queue is not empty or device is busy
+ */
+static inline int xqspips_stop_queue(struct xqspips *xqspi)
+{
+	unsigned long flags;
+	unsigned limit = 500;
+	int ret = 0;
+
+	if (xqspi->queue_state != XQSPIPS_QUEUE_RUNNING)
+		return ret;
+
+	spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+
+	while ((!list_empty(&xqspi->queue) || xqspi->dev_busy) && limit--) {
+		spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+		msleep(10);
+		spin_lock_irqsave(&xqspi->trans_queue_lock, flags);
+	}
+
+	if (!list_empty(&xqspi->queue) || xqspi->dev_busy)
+		ret = -EBUSY;
+
+	if (ret == 0)
+		xqspi->queue_state = XQSPIPS_QUEUE_STOPPED;
+
+	spin_unlock_irqrestore(&xqspi->trans_queue_lock, flags);
+
+	return ret;
+}
+
+/**
+ * xqspips_destroy_queue - Destroys the queue of the QSPI driver
+ * @xqspi:	Pointer to the xqspips structure
+ *
+ * returns:	0 on success and error value on failure
+ */
+static inline int xqspips_destroy_queue(struct xqspips *xqspi)
+{
+	int ret;
+
+	ret = xqspips_stop_queue(xqspi);
+	if (ret != 0)
+		return ret;
+
+	destroy_workqueue(xqspi->workqueue);
+
+	return 0;
+}
+
+static int xqspips_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers. And we may have to suspend operation and return
+		 * after the rate change or its abort
+		 */
+		return NOTIFY_OK;
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xqspips_suspend - Suspend method for the QSPI driver
+ * @_dev:	Address of the platform_device structure
+ *
+ * This function stops the QSPI driver queue and disables the QSPI controller
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xqspips_suspend(struct device *_dev)
+{
+	struct platform_device *pdev = container_of(_dev,
+			struct platform_device, dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xqspips *xqspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = xqspips_stop_queue(xqspi);
+	if (ret != 0)
+		return ret;
+
+	xqspips_write(xqspi->regs + XQSPIPS_ENABLE_OFFSET,
+			~XQSPIPS_ENABLE_ENABLE_MASK);
+
+	clk_disable(xqspi->devclk);
+	clk_disable(xqspi->aperclk);
+
+	dev_dbg(&pdev->dev, "suspend succeeded\n");
+	return 0;
+}
+
+/**
+ * xqspips_resume - Resume method for the QSPI driver
+ * @dev:	Address of the platform_device structure
+ *
+ * The function starts the QSPI driver queue and initializes the QSPI controller
+ *
+ * returns:	0 on success and error value on error
+ */
+static int xqspips_resume(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev,
+			struct platform_device, dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xqspips *xqspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = clk_enable(xqspi->aperclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable APER clock.\n");
+		return ret;
+	}
+
+	ret = clk_enable(xqspi->devclk);
+	if (ret) {
+		dev_err(dev, "Cannot enable device clock.\n");
+		clk_disable(xqspi->aperclk);
+		return ret;
+	}
+
+	xqspips_init_hw(xqspi->regs, xqspi->is_dual);
+
+	ret = xqspips_start_queue(xqspi);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "problem starting queue (%d)\n", ret);
+		return ret;
+	}
+
+	dev_dbg(&pdev->dev, "resume succeeded\n");
+	return 0;
+}
+#endif /* ! CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(xqspips_dev_pm_ops, xqspips_suspend, xqspips_resume);
+
+/**
+ * xqspips_probe - Probe method for the QSPI driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function initializes the driver data structures and the hardware.
+ *
+ * returns:	0 on success and error value on failure
+ */
+static int xqspips_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct spi_master *master;
+	struct xqspips *xqspi;
+	struct resource *res;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
+	if (master == NULL)
+		return -ENOMEM;
+
+	xqspi = spi_master_get_devdata(master);
+	master->dev.of_node = pdev->dev.of_node;
+	platform_set_drvdata(pdev, master);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xqspi->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xqspi->regs)) {
+		ret = PTR_ERR(xqspi->regs);
+		goto remove_master;
+	}
+
+	xqspi->irq = platform_get_irq(pdev, 0);
+	if (xqspi->irq < 0) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "irq resource not found\n");
+		goto remove_master;
+	}
+	ret = devm_request_irq(&pdev->dev, xqspi->irq, xqspips_irq,
+			       0, pdev->name, xqspi);
+	if (ret != 0) {
+		ret = -ENXIO;
+		dev_err(&pdev->dev, "request_irq failed\n");
+		goto remove_master;
+	}
+
+	if (of_property_read_u32(pdev->dev.of_node, "is-dual", &xqspi->is_dual))
+		dev_warn(&pdev->dev, "couldn't determine configuration info "
+			 "about dual memories. defaulting to single memory\n");
+
+	xqspi->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+	if (IS_ERR(xqspi->aperclk)) {
+		dev_err(&pdev->dev, "aper_clk clock not found.\n");
+		ret = PTR_ERR(xqspi->aperclk);
+		goto remove_master;
+	}
+
+	xqspi->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(xqspi->devclk)) {
+		dev_err(&pdev->dev, "ref_clk clock not found.\n");
+		ret = PTR_ERR(xqspi->devclk);
+		goto remove_master;
+	}
+
+	ret = clk_prepare_enable(xqspi->aperclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto remove_master;
+	}
+
+	ret = clk_prepare_enable(xqspi->devclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable device clock.\n");
+		goto clk_dis_aper;
+	}
+
+	xqspi->clk_rate_change_nb.notifier_call = xqspips_clk_notifier_cb;
+	xqspi->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(xqspi->devclk, &xqspi->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+
+	/* QSPI controller initializations */
+	xqspips_init_hw(xqspi->regs, xqspi->is_dual);
+
+	init_completion(&xqspi->done);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "num-chip-select",
+				   (u32 *)&master->num_chipselect);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "couldn't determine num-chip-select\n");
+		goto clk_unreg_notif;
+	}
+
+	master->setup = xqspips_setup;
+	master->transfer = xqspips_transfer;
+	master->flags = SPI_MASTER_QUAD_MODE;
+
+	xqspi->speed_hz = clk_get_rate(xqspi->devclk) / 2;
+
+	xqspi->dev_busy = 0;
+
+	INIT_LIST_HEAD(&xqspi->queue);
+	spin_lock_init(&xqspi->trans_queue_lock);
+	spin_lock_init(&xqspi->config_reg_lock);
+
+	xqspi->queue_state = XQSPIPS_QUEUE_STOPPED;
+	xqspi->dev_busy = 0;
+
+	INIT_WORK(&xqspi->work, xqspips_work_queue);
+	xqspi->workqueue =
+		create_singlethread_workqueue(dev_name(&pdev->dev));
+	if (!xqspi->workqueue) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "problem initializing queue\n");
+		goto clk_unreg_notif;
+	}
+
+	ret = xqspips_start_queue(xqspi);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "problem starting queue\n");
+		goto remove_queue;
+	}
+
+	ret = spi_register_master(master);
+	if (ret) {
+		dev_err(&pdev->dev, "spi_register_master failed\n");
+		goto remove_queue;
+	}
+
+	dev_info(&pdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", res->start,
+		 (u32 __force)xqspi->regs, xqspi->irq);
+
+	return ret;
+
+remove_queue:
+	(void)xqspips_destroy_queue(xqspi);
+clk_unreg_notif:
+	clk_notifier_unregister(xqspi->devclk, &xqspi->clk_rate_change_nb);
+	clk_disable_unprepare(xqspi->devclk);
+clk_dis_aper:
+	clk_disable_unprepare(xqspi->aperclk);
+remove_master:
+	spi_master_put(master);
+	return ret;
+}
+
+/**
+ * xqspips_remove - Remove method for the QSPI driver
+ * @pdev:	Pointer to the platform_device structure
+ *
+ * This function is called if a device is physically removed from the system or
+ * if the driver module is being unloaded. It frees all resources allocated to
+ * the device.
+ *
+ * returns:	0 on success and error value on failure
+ */
+static int xqspips_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct xqspips *xqspi = spi_master_get_devdata(master);
+	int ret = 0;
+
+	ret = xqspips_destroy_queue(xqspi);
+	if (ret != 0)
+		return ret;
+
+	xqspips_write(xqspi->regs + XQSPIPS_ENABLE_OFFSET,
+			~XQSPIPS_ENABLE_ENABLE_MASK);
+
+	clk_notifier_unregister(xqspi->devclk, &xqspi->clk_rate_change_nb);
+	clk_disable_unprepare(xqspi->devclk);
+	clk_disable_unprepare(xqspi->aperclk);
+
+	spi_unregister_master(master);
+	spi_master_put(master);
+
+
+	dev_dbg(&pdev->dev, "remove succeeded\n");
+	return 0;
+}
+
+/* Work with hotplug and coldplug */
+MODULE_ALIAS("platform:" DRIVER_NAME);
+
+static struct of_device_id xqspips_of_match[] = {
+	{ .compatible = "xlnx,ps7-qspi-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, xqspips_of_match);
+
+/*
+ * xqspips_driver - This structure defines the QSPI platform driver
+ */
+static struct platform_driver xqspips_driver = {
+	.probe	= xqspips_probe,
+	.remove	= xqspips_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = xqspips_of_match,
+		.pm = &xqspips_dev_pm_ops,
+	},
+};
+
+module_platform_driver(xqspips_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx PS QSPI driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/Kconfig	2014-07-20 22:06:37.518286551 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# APF driver configuration
+#
+
+menuconfig XILINX_APF
+	tristate "Xilinx APF Accelerator driver"
+	depends on ARCH_ZYNQ
+	default n
+	help
+	  Select if you want to include APF accelerator driver
+
+config XILINX_DMA_APF
+	bool "Xilinx APF DMA engines support"
+	depends on XILINX_APF
+	select DMA_ENGINE
+	help
+	  Enable support for the Xilinx APF DMA controllers.
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/Makefile	2014-07-20 22:06:37.523286469 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+# gpio support: dedicated expander chips, etc
+
+ccflags-$(CONFIG_DEBUG_XILINX_APF) += -DDEBUG
+ccflags-$(CONFIG_XILINX_APF) += -Idrivers/dma
+
+obj-$(CONFIG_XILINX_APF) += xlnk.o
+obj-$(CONFIG_XILINX_APF) += xlnk-eng.o
+obj-$(CONFIG_XILINX_DMA_APF) += xilinx-dma-apf.o
+
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xilinx-dma-apf.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xilinx-dma-apf.c	2014-07-20 22:06:37.537286238 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI DMA Engine support
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ * Description:
+ * This driver supports Xilinx AXI DMA engine:
+ *  . Axi DMA engine, it does transfers between memory and device. It can be
+ *    configured to have one channel or two channels. If configured as two
+ *    channels, one is for transmit to device and another is for receive from
+ *    device.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/dmapool.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-attrs.h>
+#include <linux/pagemap.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/pm.h>
+#include <linux/fs.h>
+#include <linux/gfp.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/sched.h>
+
+#include "xilinx-dma-apf.h"
+
+#include "xlnk-event-tracer-type.h"
+#include "xlnk.h"
+
+static DEFINE_MUTEX(dma_list_mutex);
+static LIST_HEAD(dma_device_list);
+/* IO accessors */
+#define DMA_OUT(addr, val)      (iowrite32(val, addr))
+#define DMA_IN(addr)            (ioread32(addr))
+
+static int unpin_user_pages(struct scatterlist *sglist, unsigned int cnt);
+/* Driver functions */
+static void xdma_clean_bd(struct xdma_desc_hw *bd)
+{
+	bd->src_addr = 0x0;
+	bd->control = 0x0;
+	bd->status = 0x0;
+	bd->app[0] = 0x0;
+	bd->app[1] = 0x0;
+	bd->app[2] = 0x0;
+	bd->app[3] = 0x0;
+	bd->app[4] = 0x0;
+	bd->dmahead = 0x0;
+	bd->sw_flag = 0x0;
+}
+
+static int dma_is_running(struct xdma_chan *chan)
+{
+	return !(DMA_IN(&chan->regs->sr) & XDMA_SR_HALTED_MASK) &&
+		(DMA_IN(&chan->regs->cr) & XDMA_CR_RUNSTOP_MASK);
+}
+
+static int dma_is_idle(struct xdma_chan *chan)
+{
+	return DMA_IN(&chan->regs->sr) & XDMA_SR_IDLE_MASK;
+}
+
+static void dma_halt(struct xdma_chan *chan)
+{
+	DMA_OUT(&chan->regs->cr,
+		(DMA_IN(&chan->regs->cr)  & ~XDMA_CR_RUNSTOP_MASK));
+}
+
+static void dma_start(struct xdma_chan *chan)
+{
+	DMA_OUT(&chan->regs->cr,
+		(DMA_IN(&chan->regs->cr) | XDMA_CR_RUNSTOP_MASK));
+}
+
+static int dma_init(struct xdma_chan *chan)
+{
+	int loop = XDMA_RESET_LOOP;
+
+	DMA_OUT(&chan->regs->cr,
+		(DMA_IN(&chan->regs->cr) | XDMA_CR_RESET_MASK));
+
+	/* Wait for the hardware to finish reset
+	 */
+	while (loop) {
+		if (!(DMA_IN(&chan->regs->cr) & XDMA_CR_RESET_MASK))
+			break;
+
+		loop -= 1;
+	}
+
+	if (!loop)
+		return 1;
+
+	return 0;
+}
+
+static int xdma_alloc_chan_descriptors(struct xdma_chan *chan)
+{
+	int i;
+	u8 *ptr;
+
+	/*
+	 * We need the descriptor to be aligned to 64bytes
+	 * for meeting Xilinx DMA specification requirement.
+	 */
+	ptr = (u8 *)dma_alloc_coherent(chan->dev,
+				(sizeof(struct xdma_desc_hw) * XDMA_MAX_BD_CNT),
+				&chan->bd_phys_addr,
+				GFP_KERNEL);
+
+	if (!ptr) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptor pool\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	memset(ptr, 0, (sizeof(struct xdma_desc_hw) * XDMA_MAX_BD_CNT));
+	chan->bd_cur = 0;
+	chan->bd_tail = 0;
+	chan->bd_used = 0;
+	chan->bd_chain_size = sizeof(struct xdma_desc_hw) * XDMA_MAX_BD_CNT;
+
+	/*
+	 * Pre allocate all the channels.
+	 */
+	for (i = 0; i < XDMA_MAX_BD_CNT; i++) {
+		chan->bds[i] = (struct xdma_desc_hw *)
+				(ptr + (sizeof(struct xdma_desc_hw) * i));
+		chan->bds[i]->next_desc = chan->bd_phys_addr +
+					(sizeof(struct xdma_desc_hw) *
+						((i + 1) % XDMA_MAX_BD_CNT));
+	}
+
+	/* there is at least one descriptor free to be allocated */
+	return 0;
+}
+
+static void xdma_free_chan_resources(struct xdma_chan *chan)
+{
+	dev_dbg(chan->dev, "Free all channel resources.\n");
+	dma_free_coherent(chan->dev, (sizeof(struct xdma_desc_hw) *
+			XDMA_MAX_BD_CNT), chan->bds[0], chan->bd_phys_addr);
+}
+
+static void xilinx_chan_desc_reinit(struct xdma_chan *chan)
+{
+	struct xdma_desc_hw *desc;
+	unsigned int start, end;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	start = 0;
+	end = XDMA_MAX_BD_CNT;
+
+	while (start < end) {
+		desc = chan->bds[start];
+		xdma_clean_bd(desc);
+		start++;
+	}
+	/* Re-initialize bd_cur and bd_tail values */
+	chan->bd_cur = 0;
+	chan->bd_tail = 0;
+	chan->bd_used = 0;
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static void xilinx_chan_desc_cleanup(struct xdma_chan *chan)
+{
+	struct xdma_head *dmahead;
+	struct xdma_desc_hw *desc;
+	struct completion *cmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+#define XDMA_BD_STS_RXEOF_MASK 0x04000000
+	desc = chan->bds[chan->bd_cur];
+	while ((desc->status & XDMA_BD_STS_ALL_MASK)) {
+		if ((desc->status & XDMA_BD_STS_RXEOF_MASK) &&
+		    !(desc->dmahead)) {
+			pr_info("ERROR: premature EOF on DMA\n");
+			dma_init(chan); /* reset the dma HW */
+			while (!(desc->dmahead)) {
+				xdma_clean_bd(desc);
+				chan->bd_used--;
+				chan->bd_cur++;
+				if (chan->bd_cur >= XDMA_MAX_BD_CNT)
+					chan->bd_cur = 0;
+				desc = chan->bds[chan->bd_cur];
+			}
+		}
+		if (desc->dmahead) {
+
+			if ((desc->sw_flag & XDMA_BD_SF_POLL_MODE_MASK))
+				if (!(desc->sw_flag & XDMA_BD_SF_SW_DONE_MASK))
+					break;
+
+			dmahead = (struct xdma_head *)desc->dmahead;
+			cmp = (struct completion *)&dmahead->cmp;
+			if (dmahead->nappwords_o)
+				memcpy(dmahead->appwords_o, desc->app,
+					dmahead->nappwords_o * sizeof(u32));
+
+			if (chan->poll_mode)
+				cmp->done = 1;
+			else
+				complete(cmp);
+		}
+		xdma_clean_bd(desc);
+		chan->bd_used--;
+		chan->bd_cur++;
+		if (chan->bd_cur >= XDMA_MAX_BD_CNT)
+			chan->bd_cur = 0;
+		desc = chan->bds[chan->bd_cur];
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static void xdma_err_tasklet(unsigned long data)
+{
+	struct xdma_chan *chan = (struct xdma_chan *)data;
+
+	if (chan->err) {
+		/* If reset failed, need to hard reset
+		 * Channel is no longer functional
+		 */
+		if (!dma_init(chan))
+			chan->err = 0;
+		else
+			dev_err(chan->dev,
+			    "DMA channel reset failed, please reset system\n");
+	}
+
+	rmb();
+	xilinx_chan_desc_cleanup(chan);
+
+	xilinx_chan_desc_reinit(chan);
+}
+
+static void xdma_tasklet(unsigned long data)
+{
+	struct xdma_chan *chan = (struct xdma_chan *)data;
+
+	rmb();
+	xilinx_chan_desc_cleanup(chan);
+}
+
+static void dump_cur_bd(struct xdma_chan *chan)
+{
+	u32 index;
+
+	index = (((u32)DMA_IN(&chan->regs->cdr)) - chan->bd_phys_addr) /
+			sizeof(struct xdma_desc_hw);
+
+	dev_err(chan->dev, "cur bd @ %08x\n",   (u32)DMA_IN(&chan->regs->cdr));
+	dev_err(chan->dev, "  buf  = 0x%08x\n", chan->bds[index]->src_addr);
+	dev_err(chan->dev, "  ctrl = 0x%08x\n", chan->bds[index]->control);
+	dev_err(chan->dev, "  sts  = 0x%08x\n", chan->bds[index]->status);
+	dev_err(chan->dev, "  next = 0x%08x\n", chan->bds[index]->next_desc);
+}
+
+static irqreturn_t xdma_rx_intr_handler(int irq, void *data)
+{
+	struct xdma_chan *chan = data;
+	u32 stat;
+
+	stat = DMA_IN(&chan->regs->sr);
+
+	if (!(stat & XDMA_XR_IRQ_ALL_MASK)) {
+		return IRQ_NONE;
+	}
+
+	/* Ack the interrupts */
+	DMA_OUT(&chan->regs->sr, (stat & XDMA_XR_IRQ_ALL_MASK));
+
+	if (stat & XDMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev, "Channel %s has errors %x, cdr %x tdr %x\n",
+			chan->name, (unsigned int)stat,
+			(unsigned int)DMA_IN(&chan->regs->cdr),
+			(unsigned int)DMA_IN(&chan->regs->tdr));
+
+		dump_cur_bd(chan);
+
+		chan->err = 1;
+		tasklet_schedule(&chan->dma_err_tasklet);
+	}
+
+	if (!(chan->poll_mode) && ((stat & XDMA_XR_IRQ_DELAY_MASK) ||
+			(stat & XDMA_XR_IRQ_IOC_MASK)))
+		tasklet_schedule(&chan->tasklet);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t xdma_tx_intr_handler(int irq, void *data)
+{
+	struct xdma_chan *chan = data;
+	u32 stat;
+
+	stat = DMA_IN(&chan->regs->sr);
+
+	if (!(stat & XDMA_XR_IRQ_ALL_MASK)) {
+		return IRQ_NONE;
+	}
+
+	/* Ack the interrupts */
+	DMA_OUT(&chan->regs->sr, (stat & XDMA_XR_IRQ_ALL_MASK));
+
+	if (stat & XDMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev, "Channel %s has errors %x, cdr %x tdr %x\n",
+			chan->name, (unsigned int)stat,
+			(unsigned int)DMA_IN(&chan->regs->cdr),
+			(unsigned int)DMA_IN(&chan->regs->tdr));
+
+		dump_cur_bd(chan);
+
+		chan->err = 1;
+		tasklet_schedule(&chan->dma_err_tasklet);
+	}
+
+	if (!(chan->poll_mode) && ((stat & XDMA_XR_IRQ_DELAY_MASK) ||
+			(stat & XDMA_XR_IRQ_IOC_MASK)))
+		tasklet_schedule(&chan->tasklet);
+
+	return IRQ_HANDLED;
+}
+
+static void xdma_chan_remove(struct xdma_chan *chan)
+{
+	dma_halt(chan);
+	xdma_free_chan_resources(chan);
+	free_irq(chan->irq, chan);
+	kfree(chan);
+}
+
+static void xdma_start_transfer(struct xdma_chan *chan,
+				int start_index,
+				int end_index)
+{
+	dma_addr_t cur_phys;
+	dma_addr_t tail_phys;
+	u32 regval;
+
+	if (chan->err)
+		return;
+
+	cur_phys = chan->bd_phys_addr + (start_index *
+					sizeof(struct xdma_desc_hw));
+	tail_phys = chan->bd_phys_addr + (end_index *
+					sizeof(struct xdma_desc_hw));
+	/* If hardware is busy, move the tail & return */
+	if (dma_is_running(chan) || dma_is_idle(chan)) {
+		/* Update tail ptr register and start the transfer */
+		DMA_OUT(&chan->regs->tdr, tail_phys);
+		xlnk_record_event(XLNK_ET_KERNEL_AFTER_DMA_KICKOFF);
+		return;
+	}
+
+	DMA_OUT(&chan->regs->cdr, cur_phys);
+
+	dma_start(chan);
+
+	/* Enable interrupts */
+	regval = DMA_IN(&chan->regs->cr);
+	regval |= (chan->poll_mode ? XDMA_XR_IRQ_ERROR_MASK
+					: XDMA_XR_IRQ_ALL_MASK);
+	DMA_OUT(&chan->regs->cr, regval);
+
+	/* Update tail ptr register and start the transfer */
+	DMA_OUT(&chan->regs->tdr, tail_phys);
+	xlnk_record_event(XLNK_ET_KERNEL_AFTER_DMA_KICKOFF);
+}
+
+static int xdma_setup_hw_desc(struct xdma_chan *chan,
+				struct xdma_head *dmahead,
+				struct scatterlist *sgl,
+				unsigned int sg_len,
+				enum dma_data_direction direction,
+				unsigned int nappwords_i,
+				u32 *appwords_i)
+{
+	struct xdma_desc_hw *bd = NULL;
+	size_t copy;
+	struct scatterlist *sg;
+	size_t sg_used;
+	dma_addr_t dma_src;
+	int i, start_index = -1, end_index1 = 0, end_index2 = -1;
+	int status;
+	unsigned long flags;
+	unsigned int bd_used_saved;
+
+	if (!chan)
+		return -ENODEV;
+
+	/* if we almost run out of bd, try to recycle some */
+	if ((chan->poll_mode) && (chan->bd_used >= XDMA_BD_CLEANUP_THRESHOLD))
+		xilinx_chan_desc_cleanup(chan);
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	bd_used_saved = chan->bd_used;
+	/*
+	 * Build transactions using information in the scatter gather list
+	 */
+	for_each_sg(sgl, sg, sg_len, i) {
+		sg_used = 0;
+
+		/* Loop until the entire scatterlist entry is used */
+		while (sg_used < sg_dma_len(sg)) {
+			/* Allocate the link descriptor from DMA pool */
+			bd = chan->bds[chan->bd_tail];
+			if ((bd->control) & (XDMA_BD_STS_ACTUAL_LEN_MASK)) {
+				end_index2 = chan->bd_tail;
+				status = -ENOMEM;
+				/* If first was not set, then we failed to
+				 * allocate the very first descriptor,
+				 * and we're done */
+				if (start_index == -1)
+					goto out_unlock;
+				else
+					goto out_clean;
+			}
+			/*
+			 * Calculate the maximum number of bytes to transfer,
+			 * making sure it is less than the DMA controller limit
+			 */
+			copy = min((size_t)(sg_dma_len(sg) - sg_used),
+				   (size_t)chan->max_len);
+			/*
+			 * Only the src address for DMA
+			 */
+			dma_src = sg_dma_address(sg) + sg_used;
+			bd->src_addr = dma_src;
+
+			/* Fill in the descriptor */
+			bd->control = copy;
+
+			/*
+			 * If this is not the first descriptor, chain the
+			 * current descriptor after the previous descriptor
+			 *
+			 * For the first DMA_TO_DEVICE transfer, set SOP
+			 */
+			if (start_index == -1) {
+				start_index = chan->bd_tail;
+
+				if (nappwords_i)
+					memcpy(bd->app, appwords_i,
+						nappwords_i * sizeof(u32));
+
+				if (direction == DMA_TO_DEVICE)
+					bd->control |= XDMA_BD_SOP;
+			}
+
+			sg_used += copy;
+			end_index2 = chan->bd_tail;
+			chan->bd_tail++;
+			chan->bd_used++;
+			if (chan->bd_tail >= XDMA_MAX_BD_CNT) {
+				end_index1 = XDMA_MAX_BD_CNT;
+				chan->bd_tail = 0;
+			}
+		}
+	}
+
+	if (start_index == -1) {
+		status = -EINVAL;
+		goto out_unlock;
+	}
+
+	bd->dmahead = (u32) dmahead;
+	bd->sw_flag = chan->poll_mode ? XDMA_BD_SF_POLL_MODE_MASK : 0;
+	dmahead->last_bd_index = end_index2;
+
+	if (direction == DMA_TO_DEVICE)
+		bd->control |= XDMA_BD_EOP;
+
+	wmb();
+
+	xdma_start_transfer(chan, start_index, end_index2);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return 0;
+
+out_clean:
+	if (!end_index1) {
+		for (i = start_index; i < end_index2; i++)
+			xdma_clean_bd(chan->bds[i]);
+	} else {
+		/* clean till the end of bd list first, and then 2nd end */
+		for (i = start_index; i < end_index1; i++)
+			xdma_clean_bd(chan->bds[i]);
+
+		end_index1 = 0;
+		for (i = end_index1; i < end_index2; i++)
+			xdma_clean_bd(chan->bds[i]);
+	}
+	/* Move the bd_tail back */
+	chan->bd_tail = start_index;
+	chan->bd_used = bd_used_saved;
+
+out_unlock:
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return status;
+}
+
+#define XDMA_SGL_MAX_LEN	XDMA_MAX_BD_CNT
+static struct scatterlist sglist_array[XDMA_SGL_MAX_LEN];
+
+/*
+ *  create minimal length scatter gather list for physically contiguous buffer
+ *  that starts at phy_buf and has length phy_buf_len bytes
+ */
+static unsigned int phy_buf_to_sgl(void *phy_buf, unsigned int phy_buf_len,
+			struct scatterlist **sgl)
+{
+	unsigned int sgl_cnt = 0;
+	struct scatterlist *sgl_head;
+	unsigned int dma_len;
+
+	if (!phy_buf || !phy_buf_len) {
+		pr_err("phy_buf is NULL or phy_buf_len = 0\n");
+		return sgl_cnt;
+	}
+
+	*sgl = sglist_array;
+	sgl_head = *sgl;
+
+	while (phy_buf_len > 0) {
+
+		sgl_cnt++;
+		if (sgl_cnt > XDMA_SGL_MAX_LEN)
+			return 0;
+
+		dma_len = (phy_buf_len > XDMA_MAX_TRANS_LEN) ?
+				XDMA_MAX_TRANS_LEN : phy_buf_len;
+
+		sg_dma_address(sgl_head) = (dma_addr_t)phy_buf;
+		sg_dma_len(sgl_head) = dma_len;
+		sgl_head = sg_next(sgl_head);
+
+		phy_buf += dma_len;
+		phy_buf_len -= dma_len;
+
+	}
+	return sgl_cnt;
+}
+
+/*  merge sg list, sgl, with length sgl_len, to sgl_merged, to save dma bds */
+static unsigned int sgl_merge(struct scatterlist *sgl, unsigned int sgl_len,
+			struct scatterlist **sgl_merged)
+{
+	struct scatterlist *sghead, *sgend, *sgnext, *sg_merged_head;
+	unsigned int sg_visited_cnt = 0, sg_merged_num = 0;
+	unsigned int dma_len = 0;
+
+	*sgl_merged = sglist_array;
+	sg_merged_head = *sgl_merged;
+	sghead = sgl;
+
+	while (sghead && (sg_visited_cnt < sgl_len)) {
+
+		dma_len = sg_dma_len(sghead);
+		sgend = sghead;
+		sg_visited_cnt++;
+		sgnext = sg_next(sgend);
+
+		while (sgnext && (sg_visited_cnt < sgl_len)) {
+
+			if ((sg_dma_address(sgend) + sg_dma_len(sgend)) !=
+				sg_dma_address(sgnext))
+				break;
+
+			if (dma_len + sg_dma_len(sgnext) >= XDMA_MAX_TRANS_LEN)
+				break;
+
+			sgend = sgnext;
+			dma_len += sg_dma_len(sgend);
+			sg_visited_cnt++;
+			sgnext = sg_next(sgnext);
+
+		}
+
+		sg_merged_num++;
+		if (sg_merged_num > XDMA_SGL_MAX_LEN)
+			return 0;
+
+		memcpy(sg_merged_head, sghead, sizeof(struct scatterlist));
+
+		sg_dma_len(sg_merged_head) = dma_len;
+
+		sg_merged_head = sg_next(sg_merged_head);
+		sghead = sg_next(sgend);
+	}
+
+	return sg_merged_num;
+}
+
+static struct page *mapped_pages[XDMA_MAX_BD_CNT];
+static int pin_user_pages(unsigned long uaddr,
+			   unsigned int ulen,
+			   int write,
+			   struct scatterlist **scatterpp,
+			   unsigned int *cntp,
+			   unsigned int user_flags)
+{
+	int status;
+	struct mm_struct *mm = current->mm;
+	struct task_struct *curr_task = current;
+	unsigned int first_page;
+	unsigned int last_page;
+	unsigned int num_pages;
+	struct scatterlist *sglist;
+
+	unsigned int pgidx;
+	unsigned int pglen;
+	unsigned int pgoff;
+	unsigned int sublen;
+
+	first_page = uaddr / PAGE_SIZE;
+	last_page = (uaddr + ulen - 1) / PAGE_SIZE;
+	num_pages = last_page - first_page + 1;
+	xlnk_record_event(XLNK_ET_KERNEL_BEFORE_GET_USER_PAGES);
+	down_read(&mm->mmap_sem);
+	status = get_user_pages(curr_task, mm, uaddr, num_pages, write, 1,
+				mapped_pages, NULL);
+	up_read(&mm->mmap_sem);
+	xlnk_record_event(XLNK_ET_KERNEL_AFTER_GET_USER_PAGES);
+
+	if (status == num_pages) {
+		sglist = kcalloc(num_pages,
+				 sizeof(struct scatterlist),
+				 GFP_KERNEL);
+		if (sglist == NULL) {
+			pr_err("%s: kcalloc failed to create sg list\n",
+			       __func__);
+			return -ENOMEM;
+		}
+		sg_init_table(sglist, num_pages);
+		sublen = 0;
+		for (pgidx = 0; pgidx < status; pgidx++) {
+			if (pgidx == 0 && num_pages != 1) {
+				pgoff = uaddr & (~PAGE_MASK);
+				pglen = PAGE_SIZE - pgoff;
+			} else if (pgidx == 0 && num_pages == 1) {
+				pgoff = uaddr & (~PAGE_MASK);
+				pglen = ulen;
+			} else if (pgidx == num_pages - 1) {
+				pgoff = 0;
+				pglen = ulen - sublen;
+			} else {
+				pgoff = 0;
+				pglen = PAGE_SIZE;
+			}
+
+			sublen += pglen;
+
+			sg_set_page(&sglist[pgidx],
+				    mapped_pages[pgidx],
+				    pglen, pgoff);
+
+			sg_dma_len(&sglist[pgidx]) = pglen;
+		}
+
+		*scatterpp = sglist;
+		*cntp = num_pages;
+
+		return 0;
+	} else {
+
+		for (pgidx = 0; pgidx < status; pgidx++) {
+			page_cache_release(mapped_pages[pgidx]);
+		}
+		return -ENOMEM;
+	}
+}
+
+static int unpin_user_pages(struct scatterlist *sglist, unsigned int cnt)
+{
+	struct page *pg;
+	unsigned int i;
+
+	if (!sglist)
+		return 0;
+
+	for (i = 0; i < cnt; i++) {
+		pg = sg_page(sglist + i);
+		if (pg) {
+			page_cache_release(pg);
+		}
+	}
+
+	kfree(sglist);
+	return 0;
+}
+
+struct xdma_chan *xdma_request_channel(char *name)
+{
+	int i;
+	struct xdma_device *device, *tmp;
+
+	mutex_lock(&dma_list_mutex);
+	list_for_each_entry_safe(device, tmp, &dma_device_list, node) {
+		for (i = 0; i < device->channel_count; i++) {
+			if (device->chan[i]->client_count)
+				continue;
+			if (!strcmp(device->chan[i]->name, name)) {
+				device->chan[i]->client_count++;
+				mutex_unlock(&dma_list_mutex);
+				return device->chan[i];
+			}
+		}
+	}
+	mutex_unlock(&dma_list_mutex);
+	return NULL;
+}
+EXPORT_SYMBOL(xdma_request_channel);
+
+void xdma_release_channel(struct xdma_chan *chan)
+{
+	mutex_lock(&dma_list_mutex);
+	if (!chan->client_count) {
+		mutex_unlock(&dma_list_mutex);
+		return;
+	}
+	chan->client_count--;
+	dma_halt(chan);
+	xilinx_chan_desc_reinit(chan);
+	mutex_unlock(&dma_list_mutex);
+}
+EXPORT_SYMBOL(xdma_release_channel);
+
+void xdma_release_all_channels(void)
+{
+	int i;
+	struct xdma_device *device, *tmp;
+
+	list_for_each_entry_safe(device, tmp, &dma_device_list, node) {
+		for (i = 0; i < device->channel_count; i++) {
+			if (device->chan[i]->client_count) {
+				dma_halt(device->chan[i]);
+				xilinx_chan_desc_reinit(device->chan[i]);
+				device->chan[i]->client_count = 0;
+				pr_info("%s: chan %s freed\n",
+						__func__,
+						device->chan[i]->name);
+			}
+		}
+	}
+}
+EXPORT_SYMBOL(xdma_release_all_channels);
+
+int xdma_submit(struct xdma_chan *chan,
+			void *userbuf,
+			unsigned int size,
+			unsigned int nappwords_i,
+			u32 *appwords_i,
+			unsigned int nappwords_o,
+			unsigned int user_flags,
+			struct xdma_head **dmaheadpp)
+{
+	struct xdma_head *dmahead;
+	struct scatterlist *sglist, *sglist_dma;
+	unsigned int sgcnt, sgcnt_dma;
+	enum dma_data_direction dmadir;
+	int status;
+	void *kaddr;
+	DEFINE_DMA_ATTRS(attrs);
+
+
+	xlnk_record_event(XLNK_ET_KERNEL_ENTER_DMA_SUBMIT);
+	dmahead = kmalloc(sizeof(struct xdma_head), GFP_KERNEL);
+	if (!dmahead)
+		return -ENOMEM;
+
+	memset(dmahead, 0, sizeof(struct xdma_head));
+
+	dmahead->chan = chan;
+	dmahead->userbuf = userbuf;
+	dmahead->size = size;
+	dmahead->dmadir = chan->direction;
+	dmahead->userflag = user_flags;
+	dmadir = chan->direction;
+	if (user_flags & CF_FLAG_PHYSICALLY_CONTIGUOUS) {
+		/*
+		 * convert physically contiguous buffer into
+		 * minimal length sg list
+		 */
+		sgcnt = phy_buf_to_sgl(userbuf, size, &sglist);
+		if (!sgcnt)
+			return -ENOMEM;
+
+		sglist_dma = sglist;
+		sgcnt_dma = sgcnt;
+		if (user_flags & CF_FLAG_CACHE_FLUSH_INVALIDATE) {
+			kaddr = phys_to_virt((phys_addr_t)userbuf);
+			dmac_map_area(kaddr, size, DMA_TO_DEVICE);
+			outer_clean_range((phys_addr_t)userbuf,
+						(u32)userbuf + size);
+		}
+	} else {
+		/* pin user pages is monitored separately */
+		xlnk_record_event(XLNK_ET_KERNEL_BEFORE_PIN_USER_PAGE);
+		status = pin_user_pages((unsigned long)userbuf, size,
+					dmadir != DMA_TO_DEVICE,
+					&sglist, &sgcnt, user_flags);
+		if (status < 0) {
+			pr_err("pin_user_pages failed\n");
+			return status;
+		}
+		xlnk_record_event(XLNK_ET_KERNEL_AFTER_PIN_USER_PAGE);
+		xlnk_record_event(XLNK_ET_KERNEL_BEFORE_DMA_MAP_SG);
+		if (!(user_flags & CF_FLAG_CACHE_FLUSH_INVALIDATE))
+			dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
+
+		status = get_dma_ops(chan->dev)->map_sg(chan->dev, sglist,
+							sgcnt, dmadir, &attrs);
+		if (!status) {
+			pr_err("dma_map_sg failed\n");
+			unpin_user_pages(sglist, sgcnt);
+			return -ENOMEM;
+		}
+		xlnk_record_event(XLNK_ET_KERNEL_AFTER_DMA_MAP_SG);
+
+		/* merge sg list to save dma bds */
+		sgcnt_dma = sgl_merge(sglist, sgcnt, &sglist_dma);
+		if (!sgcnt_dma) {
+			get_dma_ops(chan->dev)->unmap_sg(chan->dev, sglist,
+							 sgcnt, dmadir, &attrs);
+			unpin_user_pages(sglist, sgcnt);
+			return -ENOMEM;
+		}
+	}
+	dmahead->sglist = sglist;
+	dmahead->sgcnt = sgcnt;
+
+	/* skipping config */
+	init_completion(&dmahead->cmp);
+
+	if (nappwords_i > XDMA_MAX_APPWORDS)
+		nappwords_i = XDMA_MAX_APPWORDS;
+
+	if (nappwords_o > XDMA_MAX_APPWORDS)
+		nappwords_o = XDMA_MAX_APPWORDS;
+
+	dmahead->nappwords_o = nappwords_o;
+
+	xlnk_record_event(XLNK_ET_KERNEL_BEFORE_DMA_SETUP_BD);
+	status = xdma_setup_hw_desc(chan, dmahead, sglist_dma, sgcnt_dma,
+				    dmadir, nappwords_i, appwords_i);
+	xlnk_record_event(XLNK_ET_KERNEL_AFTER_DMA_SETUP_BD);
+	if (status) {
+		pr_err("setup hw desc failed\n");
+		if (!(user_flags & CF_FLAG_PHYSICALLY_CONTIGUOUS)) {
+			get_dma_ops(chan->dev)->unmap_sg(chan->dev, sglist,
+							 sgcnt, dmadir, &attrs);
+			unpin_user_pages(sglist, sgcnt);
+		}
+
+		return -ENOMEM;
+	}
+
+	*dmaheadpp = dmahead;
+
+	xlnk_record_event(XLNK_ET_KERNEL_LEAVE_DMA_SUBMIT);
+	return 0;
+}
+EXPORT_SYMBOL(xdma_submit);
+
+int xdma_wait(struct xdma_head *dmahead, unsigned int user_flags)
+{
+	struct xdma_chan *chan = dmahead->chan;
+	void *kaddr, *paddr;
+	int size;
+	DEFINE_DMA_ATTRS(attrs);
+	xlnk_record_event(XLNK_ET_KERNEL_ENTER_DMA_WAIT);
+
+	if (chan->poll_mode) {
+		xilinx_chan_desc_cleanup(chan);
+	} else
+		wait_for_completion(&dmahead->cmp);
+
+	if (!(user_flags & CF_FLAG_PHYSICALLY_CONTIGUOUS)) {
+		xlnk_record_event(XLNK_ET_KERNEL_BEFORE_DMA_UNMAP_SG);
+		if (!(user_flags & CF_FLAG_CACHE_FLUSH_INVALIDATE))
+			dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
+
+		get_dma_ops(chan->dev)->unmap_sg(chan->dev, dmahead->sglist,
+						 dmahead->sgcnt,
+						 dmahead->dmadir, &attrs);
+		xlnk_record_event(XLNK_ET_KERNEL_AFTER_DMA_UNMAP_SG);
+
+		unpin_user_pages(dmahead->sglist, dmahead->sgcnt);
+	} else {
+		if (user_flags & CF_FLAG_CACHE_FLUSH_INVALIDATE) {
+			paddr = dmahead->userbuf;
+			size = dmahead->size;
+			kaddr = phys_to_virt((phys_addr_t)paddr);
+			outer_inv_range((phys_addr_t)paddr, (u32)paddr + size);
+			dmac_unmap_area(kaddr, size, DMA_FROM_DEVICE);
+		}
+	}
+	xlnk_record_event(XLNK_ET_KERNEL_LEAVE_DMA_WAIT);
+	return 0;
+}
+EXPORT_SYMBOL(xdma_wait);
+
+int xdma_getconfig(struct xdma_chan *chan,
+				unsigned char *irq_thresh,
+				unsigned char *irq_delay)
+{
+	*irq_thresh = (DMA_IN(&chan->regs->cr) >> XDMA_COALESCE_SHIFT) & 0xff;
+	*irq_delay = (DMA_IN(&chan->regs->cr) >> XDMA_DELAY_SHIFT) & 0xff;
+	return 0;
+}
+EXPORT_SYMBOL(xdma_getconfig);
+
+int xdma_setconfig(struct xdma_chan *chan,
+				unsigned char irq_thresh,
+				unsigned char irq_delay)
+{
+	unsigned long val;
+
+	if (dma_is_running(chan))
+		return -EBUSY;
+
+	val = DMA_IN(&chan->regs->cr);
+	val &= ~((0xff << XDMA_COALESCE_SHIFT) |
+				(0xff << XDMA_DELAY_SHIFT));
+	val |= ((irq_thresh << XDMA_COALESCE_SHIFT) |
+				(irq_delay << XDMA_DELAY_SHIFT));
+
+	DMA_OUT(&chan->regs->cr, val);
+	return 0;
+}
+EXPORT_SYMBOL(xdma_setconfig);
+
+/* Brute-force probing for xilinx DMA
+ */
+static int xdma_probe(struct platform_device *pdev)
+{
+	struct xdma_device *xdev;
+	struct resource *res;
+	int err, i, j;
+	struct xdma_chan *chan;
+	struct dma_device_config *dma_config;
+	int dma_chan_dir;
+	int dma_chan_reg_offset;
+
+	pr_info("%s: probe dma %x, nres %d, id %d\n", __func__,
+		 (unsigned int)&pdev->dev,
+		 pdev->num_resources, pdev->id);
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(struct xdma_device), GFP_KERNEL);
+	if (!xdev) {
+		dev_err(&pdev->dev, "Not enough memory for device\n");
+		return -ENOMEM;
+	}
+	xdev->dev = &(pdev->dev);
+
+	dma_config = (struct dma_device_config *)xdev->dev->platform_data;
+	if (dma_config->channel_count < 1 || dma_config->channel_count > 2)
+		return -EFAULT;
+
+	/* Get the memory resource */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (!xdev->regs) {
+		dev_err(&pdev->dev, "unable to iomap registers\n");
+		return -EFAULT;
+	}
+
+	dev_info(&pdev->dev, "AXIDMA device %d physical base address=%pa\n",
+		 pdev->id, &res->start);
+	dev_info(&pdev->dev, "AXIDMA device %d remapped to %pa\n",
+		 pdev->id, &xdev->regs);
+
+	/* Allocate the channels */
+
+	dev_info(&pdev->dev, "has %d channel(s)\n", dma_config->channel_count);
+	for (i = 0; i < dma_config->channel_count; i++) {
+		chan = devm_kzalloc(&pdev->dev, sizeof(*chan), GFP_KERNEL);
+		if (!chan) {
+			dev_err(&pdev->dev, "no free memory for DMA channel\n");
+			return -ENOMEM;
+		}
+
+		dma_chan_dir = strcmp(dma_config->channel_config[i].type,
+					"axi-dma-mm2s-channel") ?
+				DMA_FROM_DEVICE : DMA_TO_DEVICE;
+		dma_chan_reg_offset = dma_chan_dir == DMA_TO_DEVICE ? 0 : 0x30;
+
+		/* Initialize channel parameters */
+		chan->id = i;
+		chan->regs = xdev->regs + dma_chan_reg_offset;
+		/* chan->regs = xdev->regs; */
+		chan->dev = xdev->dev;
+		chan->max_len = XDMA_MAX_TRANS_LEN;
+		chan->direction = dma_chan_dir;
+		sprintf(chan->name, "%schan%d", dev_name(&pdev->dev), chan->id);
+		pr_info("  chan%d name: %s\n", chan->id, chan->name);
+		pr_info("  chan%d direction: %s\n", chan->id,
+			dma_chan_dir == DMA_FROM_DEVICE ?
+				"FROM_DEVICE" : "TO_DEVICE");
+
+		spin_lock_init(&chan->lock);
+		tasklet_init(&chan->tasklet, xdma_tasklet, (unsigned long)chan);
+		tasklet_init(&chan->dma_err_tasklet, xdma_err_tasklet,
+						(unsigned long)chan);
+
+		xdev->chan[chan->id] = chan;
+
+		/* The IRQ resource */
+		chan->irq = dma_config->channel_config[i].irq;
+		if (chan->irq <= 0) {
+			pr_err("get_resource for IRQ for dev %d failed\n",
+				pdev->id);
+			return -ENODEV;
+		}
+
+		err = devm_request_irq(&pdev->dev,
+			chan->irq,
+			dma_chan_dir == DMA_TO_DEVICE ?
+				xdma_tx_intr_handler : xdma_rx_intr_handler,
+			IRQF_SHARED,
+			pdev->name,
+			chan);
+		if (err) {
+			dev_err(&pdev->dev, "unable to request IRQ\n");
+			return err;
+		}
+		pr_info("  chan%d irq: %d\n", chan->id, chan->irq);
+
+		chan->poll_mode = dma_config->channel_config[i].poll_mode;
+		pr_info("  chan%d poll mode: %s\n", chan->id,
+				chan->poll_mode ? "on" : "off");
+
+		/* Allocate channel BD's */
+		err = xdma_alloc_chan_descriptors(xdev->chan[chan->id]);
+		if (err) {
+			dev_err(&pdev->dev, "unable to allocate BD's\n");
+			return -ENOMEM;
+		}
+		pr_info("  chan%d bd ring @ 0x%08x (size: 0x%08x bytes)\n",
+				chan->id, chan->bd_phys_addr,
+				chan->bd_chain_size);
+
+		err = dma_init(xdev->chan[chan->id]);
+		if (err) {
+			dev_err(&pdev->dev, "DMA init failed\n");
+			/* FIXME Check this - unregister all chan resources */
+			for (j = 0; j <= i; j++)
+				xdma_free_chan_resources(xdev->chan[j]);
+			return -EIO;
+		}
+	}
+	xdev->channel_count = dma_config->channel_count;
+
+	/* Add the DMA device to the global list */
+	mutex_lock(&dma_list_mutex);
+	list_add_tail(&xdev->node, &dma_device_list);
+	mutex_unlock(&dma_list_mutex);
+
+	platform_set_drvdata(pdev, xdev);
+
+	return 0;
+}
+
+static int xdma_remove(struct platform_device *pdev)
+{
+	int i;
+	struct xdma_device *xdev = platform_get_drvdata(pdev);
+
+	/* Remove the DMA device from the global list */
+	mutex_lock(&dma_list_mutex);
+	list_del(&xdev->node);
+	mutex_unlock(&dma_list_mutex);
+
+	for (i = 0; i < XDMA_MAX_CHANS_PER_DEVICE; i++) {
+		if (xdev->chan[i])
+			xdma_chan_remove(xdev->chan[i]);
+	}
+
+	return 0;
+}
+
+static struct platform_driver xdma_driver = {
+	.probe = xdma_probe,
+	.remove = xdma_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "xilinx-axidma",
+	},
+};
+
+module_platform_driver(xdma_driver);
+
+MODULE_DESCRIPTION("Xilinx DMA driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xilinx-dma-apf.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xilinx-dma-apf.h	2014-07-20 22:06:37.545286106 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI DMA Engine support
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __XILINX_DMA_APF_H
+#define __XILINX_DMA_APF_H
+
+/* ioctls */
+#include <linux/ioctl.h>
+
+/* tasklet */
+#include <linux/interrupt.h>
+
+/* dma stuff */
+#include <linux/dma-mapping.h>
+
+#define XDMA_IOC_MAGIC 'X'
+#define XDMA_IOCRESET		_IO(XDMA_IOC_MAGIC, 0)
+#define XDMA_IOCREQUEST		_IOWR(XDMA_IOC_MAGIC, 1, unsigned long)
+#define XDMA_IOCRELEASE		_IOWR(XDMA_IOC_MAGIC, 2, unsigned long)
+#define XDMA_IOCSUBMIT		_IOWR(XDMA_IOC_MAGIC, 3, unsigned long)
+#define XDMA_IOCWAIT		_IOWR(XDMA_IOC_MAGIC, 4, unsigned long)
+#define XDMA_IOCGETCONFIG	_IOWR(XDMA_IOC_MAGIC, 5, unsigned long)
+#define XDMA_IOCSETCONFIG	_IOWR(XDMA_IOC_MAGIC, 6, unsigned long)
+#define XDMA_IOC_MAXNR		6
+
+/* Specific hardware configuration-related constants
+ */
+#define XDMA_RESET_LOOP            1000000
+#define XDMA_HALT_LOOP             1000000
+#define XDMA_NO_CHANGE             0xFFFF;
+
+/* General register bits definitions
+ */
+#define XDMA_CR_RESET_MASK    0x00000004  /* Reset DMA engine */
+#define XDMA_CR_RUNSTOP_MASK  0x00000001  /* Start/stop DMA engine */
+
+#define XDMA_SR_HALTED_MASK   0x00000001  /* DMA channel halted */
+#define XDMA_SR_IDLE_MASK     0x00000002  /* DMA channel idle */
+
+#define XDMA_SR_ERR_INTERNAL_MASK 0x00000010/* Datamover internal err */
+#define XDMA_SR_ERR_SLAVE_MASK    0x00000020 /* Datamover slave err */
+#define XDMA_SR_ERR_DECODE_MASK   0x00000040 /* Datamover decode err */
+#define XDMA_SR_ERR_SG_INT_MASK   0x00000100 /* SG internal err */
+#define XDMA_SR_ERR_SG_SLV_MASK   0x00000200 /* SG slave err */
+#define XDMA_SR_ERR_SG_DEC_MASK   0x00000400 /* SG decode err */
+#define XDMA_SR_ERR_ALL_MASK      0x00000770 /* All errors */
+
+#define XDMA_XR_IRQ_IOC_MASK	0x00001000 /* Completion interrupt */
+#define XDMA_XR_IRQ_DELAY_MASK	0x00002000 /* Delay interrupt */
+#define XDMA_XR_IRQ_ERROR_MASK	0x00004000 /* Error interrupt */
+#define XDMA_XR_IRQ_ALL_MASK	    0x00007000 /* All interrupts */
+
+#define XDMA_XR_DELAY_MASK    0xFF000000 /* Delay timeout counter */
+#define XDMA_XR_COALESCE_MASK 0x00FF0000 /* Coalesce counter */
+
+#define XDMA_DELAY_SHIFT    24
+#define XDMA_COALESCE_SHIFT 16
+
+#define XDMA_DELAY_MAX     0xFF /**< Maximum delay counter value */
+#define XDMA_COALESCE_MAX  0xFF /**< Maximum coalescing counter value */
+
+/* BD definitions for Axi DMA
+ */
+#define XDMA_BD_STS_ACTUAL_LEN_MASK	0x007FFFFF
+#define XDMA_BD_STS_COMPL_MASK 0x80000000
+#define XDMA_BD_STS_ERR_MASK   0x70000000
+#define XDMA_BD_STS_ALL_MASK   0xF0000000
+
+/* DMA BD special bits definitions
+ */
+#define XDMA_BD_SOP       0x08000000    /* Start of packet bit */
+#define XDMA_BD_EOP       0x04000000    /* End of packet bit */
+
+/* BD Software Flag definitions for Axi DMA
+ */
+#define XDMA_BD_SF_POLL_MODE_MASK	0x00000002
+#define XDMA_BD_SF_SW_DONE_MASK		0x00000001
+
+/* driver defines */
+#define XDMA_MAX_BD_CNT			2048
+#define XDMA_MAX_CHANS_PER_DEVICE	2
+#define XDMA_MAX_TRANS_LEN		0x7FF000
+#define XDMA_MAX_APPWORDS		5
+#define XDMA_BD_CLEANUP_THRESHOLD	((XDMA_MAX_BD_CNT * 8) / 10)
+
+/* Platform data definition until ARM supports device tree */
+struct dma_channel_config {
+	char *type;
+	unsigned int include_dre;
+	unsigned int datawidth;
+	unsigned int max_burst_len;
+	unsigned int irq;
+	unsigned int poll_mode;
+	unsigned int lite_mode;
+};
+struct dma_device_config {
+	char *type;
+	unsigned int include_sg;
+	unsigned int sg_include_stscntrl_strm;  /* dma only */
+	unsigned int channel_count;
+	struct dma_channel_config *channel_config;
+};
+
+struct xdma_desc_hw {
+	u32 next_desc;	/* 0x00 */
+	u32 pad1;       /* 0x04 */
+	u32 src_addr;   /* 0x08 */
+	u32 pad2;       /* 0x0c */
+	u32 addr_vsize; /* 0x10 */
+	u32 hsize;       /* 0x14 */
+	u32 control;    /* 0x18 */
+	u32 status;     /* 0x1c */
+	u32 app[5];      /* 0x20 */
+	u32 dmahead;
+	u32 sw_flag;	/* 0x38 */
+	u32 Reserved0;
+} __aligned(64);
+
+/* shared by all Xilinx DMA engines */
+struct xdma_regs {
+	u32 cr;        /* 0x00 Control Register */
+	u32 sr;        /* 0x04 Status Register */
+	u32 cdr;       /* 0x08 Current Descriptor Register */
+	u32 pad1;
+	u32 tdr;       /* 0x10 Tail Descriptor Register */
+	u32 pad2;
+	u32 src;       /* 0x18 Source Address Register (cdma) */
+	u32 pad3;
+	u32 dst;       /* 0x20 Destination Address Register (cdma) */
+	u32 pad4;
+	u32 btt_ref;   /* 0x28 Bytes To Transfer (cdma) or
+					park_ref (vdma) */
+	u32 version;   /* 0x2c version (vdma) */
+};
+
+/* Per DMA specific operations should be embedded in the channel structure */
+struct xdma_chan {
+	char name[64];
+	struct xdma_regs __iomem *regs;
+	struct device *dev;			/* The dma device */
+	struct xdma_desc_hw *bds[XDMA_MAX_BD_CNT];
+	dma_addr_t bd_phys_addr;
+	u32 bd_chain_size;
+	int bd_cur;
+	int bd_tail;
+	unsigned int bd_used;			/* # of BDs passed to hw chan */
+	enum dma_data_direction direction;	/* Transfer direction */
+	int id;					/* Channel ID */
+	int irq;				/* Channel IRQ */
+	int poll_mode;				/* Poll mode turned on? */
+	spinlock_t lock;			/* Descriptor operation lock */
+	struct tasklet_struct tasklet;		/* Cleanup work after irq */
+	struct tasklet_struct dma_err_tasklet;	/* Cleanup work after irq */
+	int    max_len;				/* Maximum len per transfer */
+	int    err;				/* Channel has errors */
+	int    client_count;
+};
+
+struct xdma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct list_head node;
+	struct xdma_chan *chan[XDMA_MAX_CHANS_PER_DEVICE];
+	u8 channel_count;
+};
+
+struct xdma_head {
+	void *userbuf;
+	unsigned int size;
+	unsigned int dmaflag;
+	enum dma_data_direction dmadir;
+	void *sglist;
+	unsigned int sgcnt;
+	struct completion cmp;
+	struct xdma_chan *chan;
+	unsigned int nappwords_o;
+	u32 appwords_o[XDMA_MAX_APPWORDS];
+	unsigned int userflag;
+	u32 last_bd_index;
+};
+
+struct xdma_chan *xdma_request_channel(char *name);
+void xdma_release_channel(struct xdma_chan *chan);
+void xdma_release_all_channels(void);
+int xdma_submit(struct xdma_chan *chan,
+		void *userbuf,
+		unsigned int size,
+		unsigned int nappwords_i,
+		u32 *appwords_i,
+		unsigned int nappwords_o,
+		unsigned int user_flags,
+		struct xdma_head **dmaheadpp);
+int xdma_wait(struct xdma_head *dmahead, unsigned int user_flags);
+int xdma_getconfig(struct xdma_chan *chan,
+		   unsigned char *irq_thresh,
+		   unsigned char *irq_delay);
+int xdma_setconfig(struct xdma_chan *chan,
+		   unsigned char irq_thresh,
+		   unsigned char irq_delay);
+
+#endif
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk.c	2014-07-20 22:06:37.559285875 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * xlnk.c
+ *
+ * Xilinx Accelerator driver support.
+ *
+ * Copyright (C) 2010 Xilinx Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <linux/string.h>
+
+#include <linux/uaccess.h>
+
+#include <linux/dmaengine.h>
+#include <linux/completion.h>
+#include <linux/wait.h>
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/errno.h>	/* error codes */
+#include <linux/dma-mapping.h>  /* dma */
+
+
+#include "xlnk-ioctl.h"
+#include "xlnk-event-tracer-type.h"
+#include "xlnk.h"
+
+#ifdef CONFIG_XILINX_DMA_APF
+#include "xilinx-dma-apf.h"
+#endif
+
+#ifdef CONFIG_XILINX_MCDMA
+#include "xdma-if.h"
+#include "xdma.h"
+
+static void xdma_if_device_release(struct device *op)
+{
+}
+
+#endif
+
+#define DRIVER_NAME  "xlnk"
+#define DRIVER_VERSION  "0.2"
+
+static struct platform_device *xlnk_pdev;
+static struct device *xlnk_dev;
+
+static struct cdev xlnk_cdev;
+
+static struct class *xlnk_class;
+
+static s32 driver_major;
+
+static char *driver_name = DRIVER_NAME;
+
+static void *xlnk_dev_buf;
+static ssize_t xlnk_dev_size;
+static int xlnk_dev_vmas;
+
+#define XLNK_BUF_POOL_SIZE	256
+static void **xlnk_bufpool;
+static unsigned int xlnk_bufpool_size = XLNK_BUF_POOL_SIZE;
+static dma_addr_t xlnk_phyaddr[XLNK_BUF_POOL_SIZE];
+static size_t xlnk_buflen[XLNK_BUF_POOL_SIZE];
+static unsigned int  xlnk_bufcacheable[XLNK_BUF_POOL_SIZE];
+
+
+static int xlnk_open(struct inode *ip, struct file *filp);  /* Open */
+static int xlnk_release(struct inode *ip, struct file *filp);   /* Release */
+static long xlnk_ioctl(struct file *filp, unsigned int code,
+				unsigned long args);
+static ssize_t xlnk_read(struct file *filp, char __user *buf,
+			  size_t count, loff_t *offp);
+static ssize_t xlnk_write(struct file *filp, const char __user *buf,
+			  size_t count, loff_t *offp);
+static int xlnk_mmap(struct file *filp, struct vm_area_struct *vma);
+static void xlnk_vma_open(struct vm_area_struct *vma);
+static void xlnk_vma_close(struct vm_area_struct *vma);
+
+static int xlnk_init_bufpool(void);
+
+static void xlnk_start_benchmark_counter(void);
+static int xlnk_dump_events(unsigned long buf);
+static int xlnk_get_event_size(unsigned long buf);
+
+static int xlnk_shutdown(unsigned long buf);
+static int xlnk_recover_resource(unsigned long buf);
+
+static const struct file_operations xlnk_fops = {
+	.open = xlnk_open,
+	.release = xlnk_release,
+	.read = xlnk_read,
+	.write = xlnk_write,
+	.unlocked_ioctl = xlnk_ioctl,
+	.mmap = xlnk_mmap,
+};
+
+#define MAX_XLNK_DMAS 16
+
+struct xlnk_device_pack {
+	char name[64];
+	struct platform_device pdev;
+	struct resource res[8];
+
+#ifdef CONFIG_XILINX_DMA_APF
+	struct dma_channel_config dma_chan_cfg[4];  /* for xidane dma only */
+	struct dma_device_config dma_dev_cfg;	   /* for xidane dma only */
+#endif
+
+#ifdef CONFIG_XILINX_MCDMA
+	struct xdma_device_info mcdma_dev_cfg;	 /* for mcdma only */
+#endif
+
+};
+
+static struct xlnk_device_pack *xlnk_devpacks[16];
+static void xlnk_devpacks_init(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i++)
+		xlnk_devpacks[0] = NULL;
+
+}
+
+static void xlnk_devpacks_delete(struct xlnk_device_pack *devpack)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i++) {
+		if (xlnk_devpacks[i] == devpack)
+			xlnk_devpacks[i] = NULL;
+	}
+}
+
+static void xlnk_devpacks_add(struct xlnk_device_pack *devpack)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i++) {
+		if (xlnk_devpacks[i] == NULL) {
+			xlnk_devpacks[i] = devpack;
+			break;
+		}
+	}
+}
+
+static struct xlnk_device_pack *xlnk_devpacks_find(unsigned long base)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i++) {
+		if (xlnk_devpacks[i]
+			&& xlnk_devpacks[i]->res[0].start == base)
+			return xlnk_devpacks[i];
+	}
+	return NULL;
+}
+
+static void xlnk_devpacks_free(unsigned long base)
+{
+	struct xlnk_device_pack *devpack;
+
+	devpack = xlnk_devpacks_find(base);
+	if (devpack) {
+		platform_device_unregister(&devpack->pdev);
+		kfree(devpack);
+		xlnk_devpacks_delete(devpack);
+	}
+}
+
+static void xlnk_devpacks_free_all(void)
+{
+	struct xlnk_device_pack *devpack;
+	unsigned int i;
+
+	for (i = 0; i < 16; i++) {
+		devpack = xlnk_devpacks[i];
+		if (devpack) {
+			platform_device_unregister(&devpack->pdev);
+			kfree(devpack);
+			xlnk_devpacks_delete(devpack);
+		}
+	}
+}
+
+static int xlnk_probe(struct platform_device *pdev)
+{
+	int err;
+	dev_t dev = 0;
+
+	/* use 2.6 device model */
+	err = alloc_chrdev_region(&dev, 0, 1, driver_name);
+	if (err) {
+		pr_err("%s: Can't get major %d\n", __func__, driver_major);
+		goto err1;
+	}
+
+	cdev_init(&xlnk_cdev, &xlnk_fops);
+
+	xlnk_cdev.owner = THIS_MODULE;
+
+	err = cdev_add(&xlnk_cdev, dev, 1);
+
+	if (err) {
+		pr_err("%s: Failed to add XLNK device\n", __func__);
+		goto err3;
+	}
+
+	/* udev support */
+	xlnk_class = class_create(THIS_MODULE, "xlnk");
+	if (IS_ERR(xlnk_class)) {
+		pr_err("%s: Error creating xlnk class\n", __func__);
+		goto err3;
+	}
+
+	driver_major = MAJOR(dev);
+
+	pr_info("xlnk major %d\n", driver_major);
+
+	device_create(xlnk_class, NULL, MKDEV(driver_major, 0),
+			  NULL, "xlnk");
+
+	xlnk_init_bufpool();
+
+	pr_info("%s driver loaded\n", DRIVER_NAME);
+
+	xlnk_pdev = pdev;
+	xlnk_dev = &pdev->dev;
+
+	if (xlnk_pdev)
+		pr_info("xlnk_pdev is not null\n");
+	else
+		pr_info("xlnk_pdev is null\n");
+
+	xlnk_devpacks_init();
+
+#ifdef CONFIG_ARCH_ZYNQ
+	xlnk_start_benchmark_counter();
+#endif
+
+	return 0;
+
+err3:
+	cdev_del(&xlnk_cdev);
+	unregister_chrdev_region(dev, 1);
+err1:
+	return err;
+}
+
+static int xlnk_buf_findnull(void)
+{
+	int i;
+
+	for (i = 1; i < xlnk_bufpool_size; i++) {
+		if (!xlnk_bufpool[i])
+			return i;
+	}
+
+	return 0;
+}
+
+/**
+ * allocate and return an id
+ * id must be a positve number
+ */
+static int xlnk_allocbuf(unsigned int len, unsigned int cacheable)
+{
+	int id;
+
+	id = xlnk_buf_findnull();
+
+	if (id <= 0)
+		return -ENOMEM;
+
+	xlnk_bufpool[id] = dma_alloc_coherent(xlnk_dev, len,
+					      &xlnk_phyaddr[id],
+					      GFP_KERNEL | GFP_DMA);
+	xlnk_buflen[id] = len;
+	xlnk_bufcacheable[id] = cacheable;
+
+	if (!xlnk_bufpool[id]) {
+		pr_err("%s: dma_alloc_coherent of %d byte buffer failed\n",
+		       __func__, len);
+		return -ENOMEM;
+	}
+
+	return id;
+}
+
+static int xlnk_init_bufpool(void)
+{
+	unsigned int i;
+
+	xlnk_dev_buf = kmalloc(8192, GFP_KERNEL | __GFP_DMA);
+	*((char *)xlnk_dev_buf) = '\0';
+
+	if (!xlnk_dev_buf) {
+		pr_err("%s: malloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	xlnk_bufpool = kmalloc(sizeof(void *) * xlnk_bufpool_size,
+				   GFP_KERNEL);
+
+	xlnk_bufpool[0] = xlnk_dev_buf;
+	for (i = 1; i < xlnk_bufpool_size; i++)
+		xlnk_bufpool[i] = NULL;
+
+	return 0;
+}
+
+#define XLNK_SUSPEND NULL
+#define XLNK_RESUME NULL
+
+static int xlnk_remove(struct platform_device *pdev)
+{
+	dev_t devno;
+
+	kfree(xlnk_dev_buf);
+	xlnk_dev_buf = NULL;
+
+	kfree(xlnk_bufpool);
+	xlnk_bufpool = NULL;
+
+	devno = MKDEV(driver_major, 0);
+	cdev_del(&xlnk_cdev);
+	unregister_chrdev_region(devno, 1);
+	if (xlnk_class) {
+		/* remove the device from sysfs */
+		device_destroy(xlnk_class, MKDEV(driver_major, 0));
+		class_destroy(xlnk_class);
+	}
+
+	xlnk_devpacks_free_all();
+
+	return 0;
+}
+
+
+static struct platform_driver xlnk_driver = {
+	.driver = {
+		   .name = DRIVER_NAME,
+		   },
+	.probe = xlnk_probe,
+	.remove = xlnk_remove,
+	.suspend = XLNK_SUSPEND,
+	.resume = XLNK_RESUME,
+};
+
+static u64 dma_mask = 0xFFFFFFFFUL;
+
+static struct platform_device xlnk_device = {
+	.name = "xlnk",
+	.id = 0,
+	.dev = {
+		.platform_data = NULL,
+		.dma_mask = &dma_mask,
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+	.resource = NULL,
+	.num_resources = 0,
+};
+
+/*
+ * This function is called when an application opens handle to the
+ * bridge driver.
+ */
+static int xlnk_open(struct inode *ip, struct file *filp)
+{
+	int status = 0;
+
+	if ((filp->f_flags & O_ACCMODE) == O_WRONLY)
+		xlnk_dev_size = 0;
+
+	return status;
+}
+
+static ssize_t xlnk_read(struct file *filp, char __user *buf,
+			  size_t count, loff_t *offp)
+{
+	ssize_t retval = 0;
+
+	/* todo: need semi for critical section */
+
+	if (*offp >= xlnk_dev_size)
+		goto out;
+
+	if (*offp + count > xlnk_dev_size)
+		count = xlnk_dev_size - *offp;
+
+	if (copy_to_user(buf, xlnk_dev_buf + *offp, count)) {
+		retval = -EFAULT;
+		goto out;
+	}
+	*offp += count;
+	retval = count;
+
+ out:
+	return retval;
+}
+
+static ssize_t xlnk_write(struct file *filp, const char __user *buf,
+			  size_t count, loff_t *offp)
+{
+	ssize_t retval = 0;
+
+	/* todo: need to setup semi for critical section */
+
+	if (copy_from_user(xlnk_dev_buf + *offp, buf, count)) {
+		retval = -EFAULT;
+		goto out;
+	}
+	*offp += count;
+	retval = count;
+
+	if (xlnk_dev_size < *offp)
+		xlnk_dev_size = *offp;
+
+ out:
+	return retval;
+}
+
+/*
+ * This function is called when an application closes handle to the bridge
+ * driver.
+ */
+static int xlnk_release(struct inode *ip, struct file *filp)
+{
+	int status = 0;
+	return status;
+}
+
+
+static int xlnk_devregister(char *name, unsigned int id,
+				unsigned long base, unsigned int size,
+				unsigned int *irqs,
+				u32 *handle)
+{
+	unsigned int nres;
+	unsigned int nirq;
+	unsigned int *irqptr;
+	struct xlnk_device_pack *devpack;
+	unsigned int i;
+	int status;
+
+	devpack = xlnk_devpacks_find(base);
+	if (devpack) {
+		*handle = (u32)devpack;
+		return 0;
+	}
+	nirq = 0;
+	irqptr = irqs;
+
+	while (*irqptr) {
+		nirq++;
+		irqptr++;
+	}
+
+	if (nirq > 7)
+		return -ENOMEM;
+
+	nres = nirq + 1;
+
+	devpack = kzalloc(sizeof(struct xlnk_device_pack),
+			  GFP_KERNEL);
+	strcpy(devpack->name, name);
+	devpack->pdev.name = devpack->name;
+
+	devpack->pdev.id = id;
+
+	devpack->pdev.dev.dma_mask = &dma_mask;
+	devpack->pdev.dev.coherent_dma_mask = 0xFFFFFFFF;
+
+	devpack->res[0].start = base;
+	devpack->res[0].end = base + size - 1;
+	devpack->res[0].flags = IORESOURCE_MEM;
+
+	for (i = 0; i < nirq; i++) {
+		devpack->res[i+1].start = irqs[i];
+		devpack->res[i+1].end = irqs[i];
+		devpack->res[i+1].flags = IORESOURCE_IRQ;
+	}
+
+	devpack->pdev.resource = devpack->res;
+	devpack->pdev.num_resources = nres;
+
+	status = platform_device_register(&devpack->pdev);
+	if (status) {
+		kfree(devpack);
+		*handle = 0;
+	} else {
+		xlnk_devpacks_add(devpack);
+		*handle = (u32)devpack;
+	}
+	return status;
+}
+
+static int xlnk_dmaregister(char *name, unsigned int id,
+				unsigned long base, unsigned int size,
+				unsigned int chan_num,
+				unsigned int chan0_dir,
+				unsigned int chan0_irq,
+				unsigned int chan0_poll_mode,
+				unsigned int chan0_include_dre,
+				unsigned int chan0_data_width,
+				unsigned int chan1_dir,
+				unsigned int chan1_irq,
+				unsigned int chan1_poll_mode,
+				unsigned int chan1_include_dre,
+				unsigned int chan1_data_width,
+				u32 *handle)
+{
+	int status = -1;
+
+#ifdef CONFIG_XILINX_DMA_APF
+
+	struct xlnk_device_pack *devpack;
+
+	if (strcmp(name, "xilinx-axidma"))
+		return -EINVAL;
+
+	if (chan_num < 1 || chan_num > 2)
+		return -EINVAL;
+
+	devpack = xlnk_devpacks_find(base);
+	if (devpack) {
+		*handle = (u32)devpack;
+		return 0;
+	}
+
+	devpack = kzalloc(sizeof(struct xlnk_device_pack),
+			  GFP_KERNEL);
+	if (!devpack)
+		return -ENOMEM;
+
+	strcpy(devpack->name, name);
+	devpack->pdev.name = devpack->name;
+
+	devpack->pdev.id = id;
+
+	devpack->dma_chan_cfg[0].include_dre = chan0_include_dre;
+	devpack->dma_chan_cfg[0].datawidth   = chan0_data_width;
+	devpack->dma_chan_cfg[0].irq = chan0_irq;
+	devpack->dma_chan_cfg[0].poll_mode   = chan0_poll_mode;
+	devpack->dma_chan_cfg[0].type = chan0_dir ?
+					"axi-dma-s2mm-channel" :
+					"axi-dma-mm2s-channel";
+
+	if (chan_num > 1) {
+		devpack->dma_chan_cfg[1].include_dre = chan1_include_dre;
+		devpack->dma_chan_cfg[1].datawidth   = chan1_data_width;
+		devpack->dma_chan_cfg[1].irq = chan1_irq;
+		devpack->dma_chan_cfg[1].poll_mode   = chan1_poll_mode;
+		devpack->dma_chan_cfg[1].type = chan1_dir ?
+						"axi-dma-s2mm-channel" :
+						"axi-dma-mm2s-channel";
+	}
+
+	devpack->dma_dev_cfg.type = "axi-dma";
+	devpack->dma_dev_cfg.include_sg = 1;
+	devpack->dma_dev_cfg.sg_include_stscntrl_strm = 1;
+	devpack->dma_dev_cfg.channel_count = chan_num;
+	devpack->dma_dev_cfg.channel_config = &devpack->dma_chan_cfg[0];
+
+	devpack->pdev.dev.platform_data = &devpack->dma_dev_cfg;
+
+	devpack->pdev.dev.dma_mask = &dma_mask;
+	devpack->pdev.dev.coherent_dma_mask = 0xFFFFFFFF;
+
+	devpack->res[0].start = base;
+	devpack->res[0].end = base + size - 1;
+	devpack->res[0].flags = IORESOURCE_MEM;
+
+	devpack->pdev.resource = devpack->res;
+	devpack->pdev.num_resources = 1;
+
+	status = platform_device_register(&devpack->pdev);
+	if (status) {
+		kfree(devpack);
+		*handle = 0;
+	} else {
+		xlnk_devpacks_add(devpack);
+		*handle = (u32)devpack;
+	}
+
+#endif
+	return status;
+}
+
+static int xlnk_mcdmaregister(char *name, unsigned int id,
+			      unsigned long base, unsigned int size,
+			      unsigned int mm2s_chan_num,
+			      unsigned int mm2s_chan_irq,
+			      unsigned int s2mm_chan_num,
+			      unsigned int s2mm_chan_irq,
+			      u32 *handle)
+{
+	int status = -1;
+
+#ifdef CONFIG_XILINX_MCDMA
+	struct xlnk_device_pack *devpack;
+
+	if (strcmp(name, "xdma"))
+		return -EINVAL;
+
+
+	devpack = xlnk_devpacks_find(base);
+	if (devpack) {
+		*handle = (u32)devpack;
+		return 0;
+	}
+
+	devpack = kzalloc(sizeof(struct xlnk_device_pack),
+			  GFP_KERNEL);
+	if (!devpack)
+		return -ENOMEM;
+
+	strcpy(devpack->name, name);
+	devpack->pdev.name = devpack->name;
+	devpack->pdev.id = id;
+
+	devpack->mcdma_dev_cfg.tx_chans	= mm2s_chan_num;
+	devpack->mcdma_dev_cfg.rx_chans	= s2mm_chan_num;
+	devpack->mcdma_dev_cfg.legacy_mode = XDMA_MCHAN_MODE;
+	devpack->mcdma_dev_cfg.device_id   = id;
+
+	devpack->pdev.dev.platform_data	 = &devpack->mcdma_dev_cfg;
+	devpack->pdev.dev.dma_mask = &dma_mask;
+	devpack->pdev.dev.coherent_dma_mask = 0xFFFFFFFF;
+	devpack->pdev.dev.release = xdma_if_device_release,
+
+	devpack->res[0].start = base;
+	devpack->res[0].end   = base + size - 1;
+	devpack->res[0].flags = IORESOURCE_MEM;
+
+	devpack->res[1].start = mm2s_chan_irq;
+	devpack->res[1].end   = s2mm_chan_irq;
+	devpack->res[1].flags = IORESOURCE_IRQ;
+
+	devpack->pdev.resource	  = devpack->res;
+	devpack->pdev.num_resources = 2;
+
+	status = platform_device_register(&devpack->pdev);
+	if (status) {
+		kfree(devpack);
+		*handle = 0;
+	} else {
+		xlnk_devpacks_add(devpack);
+		*handle = (u32)devpack;
+	}
+
+#endif
+
+	return status;
+}
+
+static int xlnk_allocbuf_ioctl(struct file *filp, unsigned int code,
+			unsigned long args)
+{
+
+	union xlnk_args temp_args;
+	int status;
+	int id;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	id = xlnk_allocbuf(temp_args.allocbuf.len,
+			   temp_args.allocbuf.cacheable);
+
+	if (id <= 0)
+		return -ENOMEM;
+
+	put_user(id, temp_args.allocbuf.idptr);
+	put_user((u32)(xlnk_phyaddr[id]), temp_args.allocbuf.phyaddrptr);
+
+	return 0;
+}
+
+static int xlnk_freebuf(int id)
+{
+
+	if (id <= 0 || id >= xlnk_bufpool_size)
+		return -ENOMEM;
+
+	if (!xlnk_bufpool[id])
+		return -ENOMEM;
+
+	dma_free_coherent(xlnk_dev, xlnk_buflen[id], xlnk_bufpool[id],
+			  xlnk_phyaddr[id]);
+
+	xlnk_bufpool[id] = NULL;
+	xlnk_phyaddr[id] = (dma_addr_t)NULL;
+	xlnk_buflen[id] = 0;
+
+	return 0;
+}
+
+static void xlnk_free_all_buf(void)
+{
+	int i;
+
+	for (i = 1; i < xlnk_bufpool_size; i++)
+		xlnk_freebuf(i);
+}
+
+static int xlnk_freebuf_ioctl(struct file *filp, unsigned int code,
+			unsigned long args)
+{
+
+	union xlnk_args temp_args;
+	int status;
+	int id;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	id = temp_args.freebuf.id;
+	return xlnk_freebuf(id);
+}
+
+static int xlnk_dmarequest_ioctl(struct file *filp, unsigned int code,
+				 unsigned long args)
+{
+
+#ifdef CONFIG_XILINX_DMA_APF
+
+	union xlnk_args temp_args;
+	int status;
+	struct xdma_chan *chan;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	if (!temp_args.dmarequest.name[0])
+		return 0;
+
+	chan = xdma_request_channel(temp_args.dmarequest.name);
+
+	if (!chan) {
+		return -ENOMEM;
+	}
+
+	temp_args.dmarequest.dmachan = (u32)chan;
+	temp_args.dmarequest.bd_space_phys_addr = chan->bd_phys_addr;
+	temp_args.dmarequest.bd_space_size = chan->bd_chain_size;
+
+	copy_to_user((void __user *)args, &temp_args, sizeof(union xlnk_args));
+
+	return 0;
+
+#else
+
+	return -1;
+
+#endif
+
+}
+
+static int xlnk_dmasubmit_ioctl(struct file *filp, unsigned int code,
+				unsigned long args)
+{
+
+#ifdef CONFIG_XILINX_DMA_APF
+	union xlnk_args temp_args;
+	struct xdma_head *dmahead;
+	int status = -1;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	if (!temp_args.dmasubmit.dmachan)
+		return -ENODEV;
+
+	status = xdma_submit((struct xdma_chan *)temp_args.dmasubmit.dmachan,
+						temp_args.dmasubmit.buf,
+						temp_args.dmasubmit.len,
+						temp_args.dmasubmit.nappwords_i,
+						temp_args.dmasubmit.appwords_i,
+						temp_args.dmasubmit.nappwords_o,
+						temp_args.dmasubmit.flag,
+						&dmahead);
+
+	if (!status) {
+		temp_args.dmasubmit.dmahandle = (u32)dmahead;
+		temp_args.dmasubmit.last_bd_index =
+					(u32)dmahead->last_bd_index;
+		copy_to_user((void __user *)args, &temp_args,
+				sizeof(union xlnk_args));
+		return 0;
+	}
+#endif
+	return -ENOMEM;
+}
+
+
+static int xlnk_dmawait_ioctl(struct file *filp, unsigned int code,
+				  unsigned long args)
+{
+	int status = -1;
+
+#ifdef CONFIG_XILINX_DMA_APF
+	union xlnk_args temp_args;
+	struct xdma_head *dmahead;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	dmahead = (struct xdma_head *)temp_args.dmawait.dmahandle;
+	status = xdma_wait(dmahead, dmahead->userflag);
+
+	if (temp_args.dmawait.nappwords) {
+		memcpy(temp_args.dmawait.appwords, dmahead->appwords_o,
+			   dmahead->nappwords_o * sizeof(u32));
+
+		copy_to_user((void __user *)args, &temp_args,
+				sizeof(union xlnk_args));
+	}
+	kfree(dmahead);
+
+#endif
+
+	return status;
+}
+
+static int xlnk_dmarelease_ioctl(struct file *filp, unsigned int code,
+				 unsigned long args)
+{
+	int status = -1;
+
+#ifdef CONFIG_XILINX_DMA_APF
+
+	union xlnk_args temp_args;
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	xdma_release_channel((struct xdma_chan *)temp_args.dmarelease.dmachan);
+#endif
+
+	return status;
+}
+
+
+static int xlnk_devregister_ioctl(struct file *filp, unsigned int code,
+				  unsigned long args)
+{
+	union xlnk_args temp_args;
+	int status;
+	u32 handle;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	status = xlnk_devregister(temp_args.devregister.name,
+				  temp_args.devregister.id,
+				  temp_args.devregister.base,
+				  temp_args.devregister.size,
+				  temp_args.devregister.irqs,
+				  &handle);
+
+	return status;
+}
+
+static int xlnk_dmaregister_ioctl(struct file *filp, unsigned int code,
+				  unsigned long args)
+{
+	union xlnk_args temp_args;
+	int status;
+	u32 handle;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	status = xlnk_dmaregister(temp_args.dmaregister.name,
+				  temp_args.dmaregister.id,
+				  temp_args.dmaregister.base,
+				  temp_args.dmaregister.size,
+				  temp_args.dmaregister.chan_num,
+				  temp_args.dmaregister.chan0_dir,
+				  temp_args.dmaregister.chan0_irq,
+				  temp_args.dmaregister.chan0_poll_mode,
+				  temp_args.dmaregister.chan0_include_dre,
+				  temp_args.dmaregister.chan0_data_width,
+				  temp_args.dmaregister.chan1_dir,
+				  temp_args.dmaregister.chan1_irq,
+				  temp_args.dmaregister.chan1_poll_mode,
+				  temp_args.dmaregister.chan1_include_dre,
+				  temp_args.dmaregister.chan1_data_width,
+				  &handle);
+
+	return status;
+}
+
+static int xlnk_mcdmaregister_ioctl(struct file *filp, unsigned int code,
+				  unsigned long args)
+{
+	union xlnk_args temp_args;
+	int status;
+	u32 handle;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	status = xlnk_mcdmaregister(temp_args.mcdmaregister.name,
+				  temp_args.mcdmaregister.id,
+				  temp_args.mcdmaregister.base,
+				  temp_args.mcdmaregister.size,
+				  temp_args.mcdmaregister.mm2s_chan_num,
+				  temp_args.mcdmaregister.mm2s_chan_irq,
+				  temp_args.mcdmaregister.s2mm_chan_num,
+				  temp_args.mcdmaregister.s2mm_chan_irq,
+				  &handle);
+
+	return status;
+}
+
+static int xlnk_devunregister_ioctl(struct file *filp, unsigned int code,
+					unsigned long args)
+{
+	union xlnk_args temp_args;
+	int status;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+				sizeof(union xlnk_args));
+
+	if (status)
+		return -ENOMEM;
+
+	xlnk_devpacks_free(temp_args.devunregister.base);
+
+	return 0;
+}
+
+static int xlnk_cachecontrol_ioctl(struct file *filp, unsigned int code,
+				   unsigned long args)
+{
+	union xlnk_args temp_args;
+	int status, size;
+	void *paddr, *kaddr;
+
+	status = copy_from_user(&temp_args, (void __user *)args,
+						sizeof(union xlnk_args));
+
+	if (status) {
+		pr_err("Error in copy_from_user. status = %d\n", status);
+		return -ENOMEM;
+	}
+
+	if (!(temp_args.cachecontrol.action == 0 ||
+		  temp_args.cachecontrol.action == 1)) {
+		pr_err("Illegal action specified to cachecontrol_ioctl: %d\n",
+		       temp_args.cachecontrol.action);
+		return -EINVAL;
+	}
+
+	size = temp_args.cachecontrol.size;
+	paddr = temp_args.cachecontrol.phys_addr;
+	kaddr = phys_to_virt((unsigned int)paddr);
+
+	if (temp_args.cachecontrol.action == 0) {
+		/* flush cache */
+		dmac_map_area(kaddr, size, DMA_TO_DEVICE);
+		outer_clean_range((unsigned int)paddr,
+				  (unsigned int)(paddr + size));
+	} else {
+		/* invalidate cache */
+		outer_inv_range((unsigned int)paddr,
+				(unsigned int)(paddr + size));
+		dmac_unmap_area(kaddr, size, DMA_FROM_DEVICE);
+	}
+
+	return 0;
+}
+
+/* This function provides IO interface to the bridge driver. */
+static long xlnk_ioctl(struct file *filp, unsigned int code,
+			 unsigned long args)
+{
+	int status = 0;
+
+	xlnk_record_event(XLNK_ET_KERNEL_ENTER_IOCTL);
+
+	if (_IOC_TYPE(code) != XLNK_IOC_MAGIC)
+		return -ENOTTY;
+	if (_IOC_NR(code) > XLNK_IOC_MAXNR)
+		return -ENOTTY;
+
+	/* some sanity check */
+	switch (code) {
+	case XLNK_IOCALLOCBUF:
+		status = xlnk_allocbuf_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCFREEBUF:
+		status = xlnk_freebuf_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDMAREQUEST:
+		status = xlnk_dmarequest_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDMASUBMIT:
+		status = xlnk_dmasubmit_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDMAWAIT:
+		status = xlnk_dmawait_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDMARELEASE:
+		status = xlnk_dmarelease_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDEVREGISTER:
+		status = xlnk_devregister_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDMAREGISTER:
+		status = xlnk_dmaregister_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCMCDMAREGISTER:
+		status = xlnk_mcdmaregister_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDEVUNREGISTER:
+		status = xlnk_devunregister_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCGETEVENTSIZE:
+		status = xlnk_get_event_size(args);
+		break;
+	case XLNK_IOCCACHECTRL:
+		status = xlnk_cachecontrol_ioctl(filp, code, args);
+		break;
+	case XLNK_IOCDUMPEVENTS:
+		status = xlnk_dump_events(args);
+		break;
+	case XLNK_IOCSHUTDOWN:
+		status = xlnk_shutdown(args);
+		break;
+	case XLNK_IOCRECRES: /* recover resource */
+		status = xlnk_recover_resource(args);
+		break;
+	}
+
+	xlnk_record_event(XLNK_ET_KERNEL_LEAVE_IOCTL);
+	return status;
+}
+
+static struct vm_operations_struct xlnk_vm_ops = {
+	.open = xlnk_vma_open,
+	.close = xlnk_vma_close,
+};
+
+/* This function maps kernel space memory to user space memory. */
+static int xlnk_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+
+	int bufid;
+	int status;
+
+	bufid = vma->vm_pgoff >> (24 - PAGE_SHIFT);
+
+	if (bufid == 0)
+		status = remap_pfn_range(vma, vma->vm_start,
+				virt_to_phys(xlnk_dev_buf) >> PAGE_SHIFT,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot);
+	else {
+		if (xlnk_bufcacheable[bufid] == 0)
+			vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+		status = remap_pfn_range(vma, vma->vm_start,
+					 xlnk_phyaddr[bufid] >> PAGE_SHIFT,
+					 vma->vm_end - vma->vm_start,
+					 vma->vm_page_prot);
+	}
+	if (status)
+		return -EAGAIN;
+
+	xlnk_vma_open(vma);
+	vma->vm_ops = &xlnk_vm_ops;
+	vma->vm_private_data = xlnk_bufpool[bufid];
+
+	return 0;
+}
+
+static void xlnk_vma_open(struct vm_area_struct *vma)
+{
+	xlnk_dev_vmas++;
+}
+
+static void xlnk_vma_close(struct vm_area_struct *vma)
+{
+	xlnk_dev_vmas--;
+}
+
+
+#ifdef CONFIG_ARCH_ZYNQ
+
+/*
+ * Xidane XLNK benchmark counter support
+ */
+static u32 __iomem *bc_virt;
+
+
+/* Zynq global counter */
+static const unsigned long bc_phyaddr = 0xF8F00200;
+static const unsigned long bc_to_cpu_shift = 1;
+static const unsigned long bc_csr_size = 16;
+static const unsigned long bc_ctr_offset = 2;
+static const unsigned long bc_ctr_start = 1;
+static const unsigned long bc_data_offset;
+
+
+static void xlnk_start_benchmark_counter(void)
+{
+	bc_virt = ioremap(bc_phyaddr, bc_csr_size);
+	if (bc_virt) {
+		iowrite32(bc_ctr_start, bc_virt + bc_ctr_offset);
+		pr_info("xlnk: benchmark counter started\n");
+		/* iounmap(bc_virt); */
+	}
+}
+
+#define XLNK_EVENT_TRACER_ENTRY_NUM 60000
+static struct event_tracer {
+	u32 event_id;
+	u32 event_time;
+} xlnk_et[XLNK_EVENT_TRACER_ENTRY_NUM];
+
+static unsigned long xlnk_et_index;
+static unsigned long xlnk_et_numbers_to_dump;
+
+void xlnk_record_event(u32 event_id)
+{
+	if (xlnk_et_index >= XLNK_EVENT_TRACER_ENTRY_NUM)
+		return;
+
+	xlnk_et[xlnk_et_index].event_id = event_id;
+	xlnk_et[xlnk_et_index].event_time = ioread32(bc_virt +
+						bc_data_offset) <<
+						bc_to_cpu_shift;
+	xlnk_et_index++;
+}
+EXPORT_SYMBOL(xlnk_record_event);
+
+static int xlnk_get_event_size(unsigned long args)
+{
+	unsigned long __user *datap = (unsigned long __user *)args;
+
+	/* take a snapshot of current index and only copy this
+	 * size to user space thru xlnk_dump_events(), as the snapshot
+	 * value determine the dynamically created user space event
+	 * trace buffer size  but the xlnk_et_index could keep going up
+	 * with any xlnk_record_event() calls after this function
+	 */
+	xlnk_et_numbers_to_dump = xlnk_et_index;
+	put_user(xlnk_et_numbers_to_dump, datap);
+	return 0;
+}
+
+static int xlnk_dump_events(unsigned long buf)
+{
+	/* only dump the number of event traces reported thru
+	 * xlnk_get_event_size() and ignore the rest to avoid
+	 * buffer overflow issue
+	 */
+	copy_to_user((void __user *)buf, xlnk_et,
+		xlnk_et_numbers_to_dump * sizeof(struct event_tracer));
+
+	/* clear up event pool so it's ready to use again */
+	xlnk_et_index = 0;
+	xlnk_et_numbers_to_dump = 0;
+
+	return 0;
+}
+#endif
+
+
+static int xlnk_shutdown(unsigned long buf)
+{
+	return 0;
+}
+
+static int xlnk_recover_resource(unsigned long buf)
+{
+	xlnk_free_all_buf();
+#ifdef CONFIG_XILINX_DMA_APF
+	xdma_release_all_channels();
+#endif
+	return 0;
+}
+
+static int __init xlnk_init(void)
+{
+	pr_info("%s driver initializing\n", DRIVER_NAME);
+
+	xlnk_dev_buf = NULL;
+	xlnk_dev_size = 0;
+	xlnk_dev_vmas = 0;
+	xlnk_bufpool = NULL;
+
+	platform_device_register(&xlnk_device);
+
+	return platform_driver_register(&xlnk_driver);
+}
+
+static void __exit xlnk_exit(void)
+{
+	platform_driver_unregister(&xlnk_driver);
+}
+
+/* APF driver initialization and de-initialization functions */
+module_init(xlnk_init);
+module_exit(xlnk_exit);
+
+MODULE_DESCRIPTION("Xilinx APF driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-eng.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-eng.c	2014-07-20 22:06:37.567285743 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx XLNK Engine Driver
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/uio_driver.h>
+
+
+#include "xlnk-eng.h"
+
+static DEFINE_MUTEX(xlnk_eng_list_mutex);
+static LIST_HEAD(xlnk_eng_list);
+
+int xlnk_eng_register_device(struct xlnk_eng_device *xlnk_dev)
+{
+	mutex_lock(&xlnk_eng_list_mutex);
+	/* todo: need to add more error checking */
+
+	list_add_tail(&xlnk_dev->global_node, &xlnk_eng_list);
+
+	mutex_unlock(&xlnk_eng_list_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(xlnk_eng_register_device);
+
+
+void xlnk_eng_unregister_device(struct xlnk_eng_device *xlnk_dev)
+{
+	mutex_lock(&xlnk_eng_list_mutex);
+	/* todo: need to add more error checking */
+
+	list_del(&xlnk_dev->global_node);
+
+	mutex_unlock(&xlnk_eng_list_mutex);
+}
+EXPORT_SYMBOL(xlnk_eng_unregister_device);
+
+struct xlnk_eng_device *xlnk_eng_request_by_name(char *name)
+{
+	struct xlnk_eng_device *device, *_d;
+	int found = 0;
+
+	mutex_lock(&xlnk_eng_list_mutex);
+
+	list_for_each_entry_safe(device, _d, &xlnk_eng_list, global_node) {
+		if (!strcmp(dev_name(device->dev), name)) {
+			found = 1;
+			break;
+		}
+	}
+	if (found)
+		device = device->alloc(device);
+	else
+		device = NULL;
+
+	mutex_unlock(&xlnk_eng_list_mutex);
+
+	return device;
+}
+EXPORT_SYMBOL(xlnk_eng_request_by_name);
+
+void xlnk_eng_release(struct xlnk_eng_device *xlnk_dev)
+{
+	if (!xlnk_dev)
+		return;
+
+	xlnk_dev->free(xlnk_dev);
+}
+EXPORT_SYMBOL(xlnk_eng_release);
+
+#define DRIVER_NAME "xilinx-xlnk-eng"
+
+struct xilinx_xlnk_eng_device {
+	struct xlnk_eng_device common;
+	void __iomem *base;
+	spinlock_t lock;
+	int cnt;
+};
+
+
+#define to_xilinx_xlnk(dev)	container_of(dev, \
+					struct xilinx_xlnk_eng_device, common)
+
+static struct xlnk_eng_device *xilinx_xlnk_alloc(
+					struct xlnk_eng_device *xlnkdev)
+{
+	struct xilinx_xlnk_eng_device *xdev;
+	struct xlnk_eng_device *retdev;
+
+	xdev = to_xilinx_xlnk(xlnkdev);
+
+	if (xdev->cnt == 0) {
+		xdev->cnt++;
+		retdev = xlnkdev;
+	} else
+		retdev = NULL;
+
+	return retdev;
+}
+
+static void xilinx_xlnk_free(struct xlnk_eng_device *xlnkdev)
+{
+	struct xilinx_xlnk_eng_device *xdev;
+
+	xdev = to_xilinx_xlnk(xlnkdev);
+
+	xdev->cnt = 0;
+}
+
+static int xlnk_eng_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct xilinx_xlnk_eng_device *xdev;
+	struct uio_info *info;
+	char *devname;
+
+	pr_info("xlnk_eng_probe ...\n");
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev) {
+		dev_err(&pdev->dev, "Not enough memory for device\n");
+		return -ENOMEM;
+	}
+
+	/* more error handling */
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&pdev->dev, "Not enough memory for device\n");
+		return -ENOMEM;
+	}
+
+	devname = devm_kzalloc(&pdev->dev, 64, GFP_KERNEL);
+	if (!devname) {
+		dev_err(&pdev->dev, "Not enough memory for device\n");
+		return -ENOMEM;
+	}
+	sprintf(devname, "%s.%d", DRIVER_NAME, pdev->id);
+	pr_info("uio name %s\n", devname);
+	/* iomap registers */
+
+	/* Get the data from the platform device */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->base = devm_ioremap_resource(&pdev->dev, res);
+
+	/* %pa types should be used here */
+	dev_info(&pdev->dev, "physical base : 0x%lx\n",
+		(unsigned long)res->start);
+	dev_info(&pdev->dev, "register range : 0x%lx\n",
+		(unsigned long)resource_size(res));
+	dev_info(&pdev->dev, "base remapped to: 0x%lx\n",
+		(unsigned long)xdev->base);
+	if (!xdev->base) {
+		dev_err(&pdev->dev, "unable to iomap registers\n");
+		return -ENOMEM;
+	}
+
+	info->mem[0].addr = res->start;
+	info->mem[0].size = resource_size(res);
+	info->mem[0].memtype = UIO_MEM_PHYS;
+	info->mem[0].internal_addr = xdev->base;
+
+	/* info->name = DRIVER_NAME; */
+	info->name = devname;
+	info->version = "0.0.1";
+
+	info->irq = -1;
+
+	xdev->common.dev = &pdev->dev;
+
+	xdev->common.alloc = xilinx_xlnk_alloc;
+	xdev->common.free = xilinx_xlnk_free;
+
+	dev_set_drvdata(&pdev->dev, xdev);
+
+	spin_lock_init(&xdev->lock);
+
+	xdev->cnt = 0;
+
+	xlnk_eng_register_device(&xdev->common);
+
+	if (uio_register_device(&pdev->dev, info)) {
+		dev_err(&pdev->dev, "uio_register_device failed\n");
+		return -ENODEV;
+	}
+	dev_info(&pdev->dev, "xilinx-xlnk-eng uio registered\n");
+
+	return 0;
+}
+
+static int xlnk_eng_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver xlnk_eng_driver = {
+	.probe = xlnk_eng_probe,
+	.remove = xlnk_eng_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DRIVER_NAME,
+	},
+};
+
+module_platform_driver(xlnk_eng_driver);
+
+MODULE_DESCRIPTION("Xilinx xlnk engine generic driver");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-eng.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-eng.h	2014-07-20 22:06:37.643284489 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx XLNK Engine Driver
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ *
+ */
+
+#ifndef XLNK_ENG_H
+#define XLNK_ENG_H
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+
+struct xlnk_eng_device {
+	struct list_head global_node;
+	struct xlnk_eng_device * (*alloc)(struct xlnk_eng_device *xdev);
+	void (*free)(struct xlnk_eng_device *xdev);
+	struct device *dev;
+};
+extern int xlnk_eng_register_device(struct xlnk_eng_device *xlnk_dev);
+extern void xlnk_eng_unregister_device(struct xlnk_eng_device *xlnk_dev);
+extern struct xlnk_eng_device *xlnk_eng_request_by_name(char *name);
+extern void xlnk_eng_release(struct xlnk_eng_device *xlnk_dev);
+
+#endif
+
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-event-tracer-type.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-event-tracer-type.h	2014-07-20 22:06:37.649284390 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#ifndef XLNK_EVENT_TRACER_TYPE_H
+#define XLNK_EVENT_TRACER_TYPE_H
+
+#define XLNK_ET_USERSPACE_BEFORE_ACC_TRANSFER_CALL	50
+#define XLNK_ET_USERSPACE_BEFORE_PORT_WAIT4COMPLETION	51
+
+#define XLNK_ET_USERSPACE_BEFORE_DMA_SUBMIT		100
+#define XLNK_ET_USERSPACE_AFTER_DMA_SUBMIT		101
+#define XLNK_ET_USERSPACE_BEFORE_DMA_WAIT4COMPLETION	102
+#define XLNK_ET_USERSPACE_AFTER_DMA_WAIT4COMPLETION	103
+
+#define XLNK_ET_KERNEL_ENTER_IOCTL			5000
+#define XLNK_ET_KERNEL_LEAVE_IOCTL			5001
+#define XLNK_ET_KERNEL_ENTER_DMA_SUBMIT			5002
+#define XLNK_ET_KERNEL_LEAVE_DMA_SUBMIT			5003
+#define XLNK_ET_KERNEL_BEFORE_PIN_USER_PAGE		5004
+#define XLNK_ET_KERNEL_BEFORE_GET_USER_PAGES		5005
+#define XLNK_ET_KERNEL_AFTER_GET_USER_PAGES		5006
+#define XLNK_ET_KERNEL_AFTER_PIN_USER_PAGE		5007
+#define XLNK_ET_KERNEL_BEFORE_DMA_MAP_SG		5008
+#define XLNK_ET_KERNEL_AFTER_DMA_MAP_SG			5009
+#define XLNK_ET_KERNEL_BEFORE_DMA_SETUP_BD		5010
+#define XLNK_ET_KERNEL_AFTER_DMA_KICKOFF		5011
+#define XLNK_ET_KERNEL_AFTER_DMA_SETUP_BD		5012
+#define XLNK_ET_KERNEL_ENTER_DMA_WAIT			5013
+#define XLNK_ET_KERNEL_BEFORE_DMA_UNMAP_SG		5014
+#define XLNK_ET_KERNEL_AFTER_DMA_UNMAP_SG		5015
+#define XLNK_ET_KERNEL_LEAVE_DMA_WAIT			5016
+
+
+#define XLNK_ET_KERNEL_DMA_MM2S_INTR			5100
+#define XLNK_ET_KERNEL_DMA_MM2S_HALF_BOTTOM_START	5101
+#define XLNK_ET_KERNEL_DMA_MM2S_HALF_BOTTOM_END		5102
+#define XLNK_ET_KERNEL_DMA_S2MM_INTR			5110
+#define XLNK_ET_KERNEL_DMA_S2MM_HALF_BOTTOM_START	5111
+#define XLNK_ET_KERNEL_DMA_S2MM_HALF_BOTTOM_END		5112
+
+#endif
+
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk.h	2014-07-20 22:06:37.656284275 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#ifndef _XLNK_OS_H
+#define _XLNK_OS_H
+
+#include <linux/stddef.h>
+
+#define XLNK_FLAG_COHERENT		0x00000001
+#define XLNK_FLAG_KERNEL_BUFFER		0x00000002
+#define XLNK_FLAG_DMAPOLLING		0x00000004
+#define XLNK_FLAG_PHYSICAL_ADDR		0x00000100
+#define XLNK_FLAG_VIRTUAL_ADDR		0x00000200
+
+#define CF_FLAG_CACHE_FLUSH_INVALIDATE	0x00000001
+#define CF_FLAG_PHYSICALLY_CONTIGUOUS	0x00000002
+#define CF_FLAG_DMAPOLLING		0x00000004
+
+extern void xlnk_record_event(u32 event_id);
+
+
+enum xlnk_dma_direction {
+	XLNK_DMA_BI = 0,
+	XLNK_DMA_TO_DEVICE = 1,
+	XLNK_DMA_FROM_DEVICE = 2,
+	XLNK_DMA_NONE = 3,
+};
+
+union xlnk_args {
+	struct {
+		unsigned int len;
+		unsigned int __user *idptr;
+		unsigned int __user *phyaddrptr;
+		unsigned int cacheable;
+	} allocbuf;
+	struct {
+		unsigned int id;
+		void *buf;
+	} freebuf;
+	struct {
+		char name[64]; /* max length of 64 */
+		u32 dmachan; /* return value */
+		unsigned int bd_space_phys_addr;/*for bd chain used by dmachan*/
+		unsigned int bd_space_size; /* bd chain size in bytes */
+	} dmarequest;
+#define XLNK_MAX_APPWORDS 5
+	struct {
+		u32 dmachan;
+		void *buf;      /* buffer base address */
+		void *buf2;	/* used to point src_buf in cdma case */
+		unsigned int buf_offset; /* used on kernel allocated buffers */
+		unsigned int len;
+		unsigned int bufflag; /* zero all the time so far */
+		u32 sglist; /* ignored */
+		unsigned int sgcnt; /* ignored */
+		enum xlnk_dma_direction dmadir;
+		unsigned int nappwords_i; /* n appwords passed to BD */
+		unsigned int appwords_i[XLNK_MAX_APPWORDS];
+		unsigned int nappwords_o; /* n appwords passed from BD */
+		/* appwords array we only accept 5 max */
+		unsigned int flag;
+		u32 dmahandle; /* return value */
+		unsigned int last_bd_index; /*index of last bd used by request*/
+	} dmasubmit;
+	struct {
+		u32 dmahandle;
+		unsigned int nappwords; /* n appwords read from BD */
+		unsigned int appwords[XLNK_MAX_APPWORDS];
+		/* appwords array we only accept 5 max */
+	} dmawait;
+	struct {
+		u32 dmachan;
+	} dmarelease;
+	struct {
+		unsigned long base;
+		unsigned int size;
+		unsigned int irqs[8];
+		char name[32];
+		unsigned int id;
+	} devregister;
+	struct {
+		unsigned int base;
+	} devunregister;
+	struct {
+		char name[32];
+		unsigned int id;
+		unsigned long base;
+		unsigned int size;
+		unsigned int chan_num;
+		unsigned int chan0_dir;
+		unsigned int chan0_irq;
+		unsigned int chan0_poll_mode;
+		unsigned int chan0_include_dre;
+		unsigned int chan0_data_width;
+		unsigned int chan1_dir;
+		unsigned int chan1_irq;
+		unsigned int chan1_poll_mode;
+		unsigned int chan1_include_dre;
+		unsigned int chan1_data_width;
+	} dmaregister;
+	struct {
+		char name[32];
+		unsigned int id;
+		unsigned long base;
+		unsigned int size;
+		unsigned int mm2s_chan_num;
+		unsigned int mm2s_chan_irq;
+		unsigned int s2mm_chan_num;
+		unsigned int s2mm_chan_irq;
+	} mcdmaregister;
+	struct {
+		void *phys_addr;
+		int size;
+		int action;
+	} cachecontrol;
+};
+
+
+#endif
Index: linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-ioctl.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/apf/xlnk-ioctl.h	2014-07-20 22:06:37.662284176 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#ifndef _XLNK_IOCTL_H
+#define _XLNK_IOCTL_H
+
+#include <linux/ioctl.h>
+
+#define XLNK_IOC_MAGIC 'X'
+
+#define XLNK_IOCRESET		_IO(XLNK_IOC_MAGIC, 0)
+
+#define XLNK_IOCALLOCBUF	_IOWR(XLNK_IOC_MAGIC, 2, unsigned long)
+#define XLNK_IOCFREEBUF		_IOWR(XLNK_IOC_MAGIC, 3, unsigned long)
+
+
+
+#define XLNK_IOCDMAREQUEST	_IOWR(XLNK_IOC_MAGIC, 7, unsigned long)
+#define XLNK_IOCDMASUBMIT	_IOWR(XLNK_IOC_MAGIC, 8, unsigned long)
+#define XLNK_IOCDMAWAIT		_IOWR(XLNK_IOC_MAGIC, 9, unsigned long)
+#define XLNK_IOCDMARELEASE	_IOWR(XLNK_IOC_MAGIC, 10, unsigned long)
+
+
+
+
+
+#define XLNK_IOCDEVREGISTER	_IOWR(XLNK_IOC_MAGIC, 16, unsigned long)
+#define XLNK_IOCDMAREGISTER	_IOWR(XLNK_IOC_MAGIC, 17, unsigned long)
+#define XLNK_IOCDEVUNREGISTER	_IOWR(XLNK_IOC_MAGIC, 18, unsigned long)
+#define XLNK_IOCCDMAREQUEST	_IOWR(XLNK_IOC_MAGIC, 19, unsigned long)
+#define XLNK_IOCCDMASUBMIT	_IOWR(XLNK_IOC_MAGIC, 20, unsigned long)
+#define XLNK_IOCGETEVENTSIZE	_IOWR(XLNK_IOC_MAGIC, 21, unsigned long)
+#define XLNK_IOCDUMPEVENTS	_IOWR(XLNK_IOC_MAGIC, 22, unsigned long)
+#define XLNK_IOCMCDMAREGISTER	_IOWR(XLNK_IOC_MAGIC, 23, unsigned long)
+#define XLNK_IOCCACHECTRL	_IOWR(XLNK_IOC_MAGIC, 24, unsigned long)
+
+#define XLNK_IOCSHUTDOWN	_IOWR(XLNK_IOC_MAGIC, 100, unsigned long)
+#define XLNK_IOCRECRES		_IOWR(XLNK_IOC_MAGIC, 101, unsigned long)
+
+#define XLNK_IOC_MAXNR		101
+
+#endif
Index: linux-3.12.24-rt38-xilinx/drivers/staging/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/staging/Kconfig	2014-07-20 22:05:50.165067793 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/staging/Kconfig	2014-07-20 22:06:37.669284060 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:151 @
 
 source "drivers/staging/dgap/Kconfig"
 
+source "drivers/staging/video/axivdma/Kconfig"
+
+source "drivers/staging/apf/Kconfig"
+
+source "drivers/staging/pmods/Kconfig"
+
 endif # STAGING
Index: linux-3.12.24-rt38-xilinx/drivers/staging/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/staging/Makefile	2014-07-20 22:05:50.164067809 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/staging/Makefile	2014-07-20 22:06:37.678283912 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:69 @
 obj-$(CONFIG_XILLYBUS)		+= xillybus/
 obj-$(CONFIG_DGNC)			+= dgnc/
 obj-$(CONFIG_DGAP)			+= dgap/
+obj-$(CONFIG_XILINX_VIDEO_IP)	+= video/axivdma/
+obj-$(CONFIG_XILINX_APF)	+= apf/
+obj-$(CONFIG_PMODS)		+= pmods/
Index: linux-3.12.24-rt38-xilinx/drivers/staging/pmods/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/pmods/Kconfig	2014-07-20 22:06:37.690283714 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+menuconfig PMODS
+	bool "Pmod Support"
+	depends on HAS_IOMEM && OF
+	help
+		Digilent PMOD Support
+
+if PMODS
+
+config PMODS_DEBUG
+	bool "Enable Debug Message"
+
+config PMODOLED
+	tristate "PmodOLED1"
+	select SPI_BITBANG
+	select SPI_GPIO
+	help
+		The Digilent PmodOLED1, as well as ZED on-board OLED. Uses SPI over GPIO.
+		Configuration SPI_BITBANG and SPI_GPIO will be selected automatically.
+
+endif # PMODS
Index: linux-3.12.24-rt38-xilinx/drivers/staging/pmods/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/pmods/Makefile	2014-07-20 22:06:37.696283615 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+
+ccflags-$(CONFIG_PMODS_DEBUG)  += -DDEBUG
+
+obj-$(CONFIG_PMODOLED) += pmodoled-gpio.o
Index: linux-3.12.24-rt38-xilinx/drivers/staging/pmods/pmodoled-gpio.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/pmods/pmodoled-gpio.c	2014-07-20 22:06:37.708283417 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * pmodolde-gpio.c - PmodOLED-GPIO driver
+ *
+ * Copyright (c) 2012 Digilent.  All right reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+
+#define DRIVER_NAME "pmodoled-gpio"
+#define SPI_DRIVER_NAME "pmodoled-gpio-spi"
+#define MAX_PMODOLED_GPIO_DEV_NUM 16
+#define DISPLAY_BUF_SZ	512 /* 32 x 128 bit monochrome  == 512 bytes        */
+#define MAX_LINE_LEN	16 /* 128 bits wide and current char width is 8 bit */
+#define MAX_ROW			4
+#define OLED_MAX_PG_CNT      4 /* number of display pages in OLED controller */
+#define OLED_CONTROLLER_PG_SZ	128
+#define OLED_CONTROLLER_CMD	0
+#define OLED_CONTROLLER_DATA	1
+
+/* commands for the OLED display controller	*/
+#define OLED_SET_PG_ADDR		0x22
+#define OLED_DISPLAY_OFF		0xAE
+#define OLED_DISPLAY_ON			0xAF
+#define OLED_CONTRAST_CTRL		0x81
+#define OLED_SET_PRECHARGE_PERIOD	0xD9
+#define OLED_SET_SEGMENT_REMAP		0xA1
+#define OLED_SET_COM_DIR			0xC8
+#define OLED_SET_COM_PINS		0xDA
+
+static dev_t gpio_pmodoled_dev_id;
+static unsigned int device_num;
+static unsigned int cur_minor;
+static unsigned int spi_drv_registered;
+/* struct mutex minor_mutex; */
+static struct class *gpio_pmodoled_class;
+
+struct gpio_pmodoled_device {
+	const char *name;
+	/* R/W Mutex Lock */
+	struct mutex mutex;
+	/* Display Buffers */
+	uint8_t disp_on;
+	uint8_t *disp_buf;
+	/* Pin Assignment */
+	unsigned long iVBAT;
+	unsigned long iVDD;
+	unsigned long iRES;
+	unsigned long iDC;
+	unsigned long iSCLK;
+	unsigned long iSDIN;
+	unsigned long iCS;
+	/* SPI Info */
+	uint32_t spi_id;
+	/* platform device structures */
+	struct platform_device *pdev;
+	/* Char Device */
+	struct cdev cdev;
+	struct spi_device *spi;
+	dev_t dev_id;
+};
+
+/**
+ * screen_buf_to_display -
+ * @screen_buf -
+ * @dev -
+ *
+ */
+static int screen_buf_to_display(uint8_t *screen_buf, struct gpio_pmodoled_device *dev)
+{
+	uint32_t pg;
+	int status;
+	uint8_t lower_start_column = 0x00;
+	uint8_t upper_start_column = 0x10;
+	uint8_t wr_buf[10];
+
+	for (pg = 0; pg < OLED_MAX_PG_CNT; pg++) {
+		wr_buf[0] = OLED_SET_PG_ADDR;
+		wr_buf[1] = pg;
+		wr_buf[2] = lower_start_column;
+		wr_buf[3] = upper_start_column;
+		gpio_set_value(dev->iDC, OLED_CONTROLLER_CMD);
+		status = spi_write(dev->spi, wr_buf, 4);
+		if (status) {
+			dev_err(&dev->spi->dev, "screen_buf_to_display: Error writing to SPI\n");
+			break;
+		}
+
+		gpio_set_value(dev->iDC, OLED_CONTROLLER_DATA);
+		status = spi_write(dev->spi, (uint8_t *) (screen_buf +
+						(pg*OLED_CONTROLLER_PG_SZ)), OLED_CONTROLLER_PG_SZ);
+		if (status) {
+			dev_err(&dev->spi->dev, "screen_buf_to_display: Error writing to SPI\n");
+			break;
+		}
+	}
+	return status;
+}
+
+/**
+ * A basic open function. It exists mainly to save the id of
+ * the OLED and some other basic information.
+ */
+static int 	gpio_pmodoled_open(struct inode *inode, struct file *fp)
+{
+	struct gpio_pmodoled_device *dev;
+
+	dev = container_of(inode->i_cdev, struct gpio_pmodoled_device, cdev);
+	fp->private_data = dev;
+
+	return 0;
+}
+
+static int 	gpio_pmodoled_close(struct inode *inode, struct file *fp)
+{
+	return 0;
+}
+
+/**
+ * Driver write function
+ *
+ * This function uses a generic SPI write to send values to the Pmod device
+ * It takes a raw data array from the app in the buffer, copied it into
+ * device dispay buffer, and finally sends the buffer to the OLED using SPI
+ */
+static ssize_t gpio_pmodoled_write(struct file *fp, const char __user *buffer, size_t length, loff_t *offset)
+{
+	ssize_t retval = 0;
+	struct gpio_pmodoled_device *dev;
+	unsigned int minor_id;
+	int cnt;
+	int status;
+
+	dev = fp->private_data;
+	minor_id = MINOR(dev->dev_id);
+
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		retval = -ERESTARTSYS;
+		goto write_lock_err;
+	}
+
+	if (buffer == NULL) {
+		dev_err(&dev->spi->dev, "oled_write: ERROR: invalid buffer address: 0x%08lx\n",
+					(__force unsigned long) buffer);
+		retval = -EINVAL;
+		goto quit_write;
+	}
+
+	if (length > DISPLAY_BUF_SZ)
+		cnt = DISPLAY_BUF_SZ;
+	else
+		cnt = length;
+
+	if (copy_from_user(dev->disp_buf, buffer, cnt)) {
+		dev_err(&dev->spi->dev, "oled_write: copy_from_user failed\n");
+		retval = -EFAULT;
+		goto quit_write;
+	} else
+		retval = cnt;
+
+	status = screen_buf_to_display(dev->disp_buf, dev);
+	if (status) {
+		dev_err(&dev->spi->dev, "oled_write: Error sending string to display\n");
+		retval = -EFAULT;
+		goto quit_write;
+	}
+
+quit_write:
+	mutex_unlock(&dev->mutex);
+write_lock_err:
+	return retval;
+}
+
+/**
+ * Driver Read Function
+ *
+ * This function does not actually read the Pmod as it is a write-only device. Instead
+ * It returns data in the buffer generated for the display that was used when the OLED
+ * was last programmed.
+ */
+static ssize_t	gpio_pmodoled_read(struct file *fp, char __user *buffer, size_t length, loff_t *offset)
+{
+	ssize_t retval = 0;
+	struct gpio_pmodoled_device *dev;
+	unsigned int minor_id;
+	int cnt;
+
+	dev = fp->private_data;
+	minor_id = MINOR(dev->dev_id);
+
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		retval = -ERESTARTSYS;
+		goto read_lock_err;
+	}
+
+	if (buffer == NULL) {
+		dev_err(&dev->spi->dev, "OLED_read: ERROR: invalid buffer "
+				"address: 0x%08lx\n", (__force unsigned long)buffer);
+		retval = -EINVAL;
+		goto quit_read;
+	}
+
+	if (length > DISPLAY_BUF_SZ)
+		cnt = DISPLAY_BUF_SZ;
+	else
+		cnt = length;
+	retval = copy_to_user((void __user *)buffer, dev->disp_buf, cnt);
+	if (!retval)
+		retval = cnt; /* copy success, return amount in buffer */
+
+quit_read:
+	mutex_unlock(&dev->mutex);
+read_lock_err:
+	return retval;
+}
+
+static struct file_operations gpio_pmodoled_cdev_fops = {
+	.owner = THIS_MODULE,
+	.write = gpio_pmodoled_write,
+	.read = gpio_pmodoled_read,
+	.open = gpio_pmodoled_open,
+	.release = gpio_pmodoled_close,
+};
+
+static int add_gpio_pmodoled_device_to_bus(struct gpio_pmodoled_device *dev)
+{
+	struct spi_master *spi_master;
+	struct spi_device *spi_device;
+	int status = 0;
+
+	spi_master = spi_busnum_to_master(dev->spi_id);
+	if (!spi_master) {
+		dev_err(&dev->pdev->dev, "spi_busnum_to_master(%d) returned NULL\n", dev->spi_id);
+		return -ENOSYS;
+	}
+
+	spi_device = spi_alloc_device(spi_master);
+	if (!spi_device) {
+		put_device(&spi_master->dev);
+		dev_err(&dev->pdev->dev, "spi_alloc_device() failed\n");
+		return -ENOMEM;
+	}
+
+	spi_device->chip_select = 0;
+	spi_device->max_speed_hz = 4000000;
+	spi_device->mode = SPI_MODE_0;
+	spi_device->bits_per_word = 8;
+	spi_device->controller_data = (void *) dev->iCS;
+	spi_device->dev.platform_data = dev;
+	strlcpy(spi_device->modalias, SPI_DRIVER_NAME, sizeof(SPI_DRIVER_NAME));
+
+	status = spi_add_device(spi_device);
+	if (status < 0) {
+		spi_dev_put(spi_device);
+		dev_err(&dev->pdev->dev, "spi_add_device() failed %d\n", status);
+		return status;
+	}
+	dev->spi = spi_device;
+
+	put_device(&spi_master->dev);
+
+	return status;
+}
+
+/**
+ * gpio_pmodoled_setup_cdev - Setup Char Device for ZED on-board OLED device.
+ * @dev: pointer to device tree node
+ * @dev_id: pointer to device major and minor number
+ * @spi: pointer to spi_device structure
+ *
+ * This function initializes char device for OLED device, and add it into
+ * kernel device structure. It returns 0, if the cdev is successfully
+ * initialized, or a negative value if there is an error.
+ */
+static int gpio_pmodoled_setup_cdev(struct gpio_pmodoled_device *dev, dev_t *dev_id, struct spi_device *spi)
+{
+	int status = 0;
+	struct device *device;
+
+	cdev_init(&dev->cdev, &gpio_pmodoled_cdev_fops);
+	dev->cdev.owner = THIS_MODULE;
+	dev->cdev.ops = &gpio_pmodoled_cdev_fops;
+	dev->spi = spi;
+
+	*dev_id = MKDEV(MAJOR(gpio_pmodoled_dev_id), cur_minor++);
+	status = cdev_add(&dev->cdev, *dev_id, 1);
+	if (status < 0)
+		return status;
+
+	/* Add Device node in system */
+	device = device_create(gpio_pmodoled_class, NULL,
+					*dev_id, NULL,
+					"%s", dev->name);
+	if (IS_ERR(device)) {
+		status = PTR_ERR(device);
+		dev_err(&spi->dev, "failed to create device node %s, err %d\n",
+				dev->name, status);
+		cdev_del(&dev->cdev);
+	}
+
+	return status;
+}
+
+/**
+ * gpio_pmodoled_init_gpio - Initialize GPIO for ZED Onboard OLED
+ * @dev - gpio_pmodoled_device
+ *
+ * Initializes OLED GPIO Control Pins.
+ * It returns 0, if the gpio pins are successfully
+ * initialized, or a negative value if there is an error.
+ */
+static int gpio_pmodoled_init_gpio(struct gpio_pmodoled_device *dev)
+{
+	struct gpio gpio_pmodoled_ctrl[] = {
+		{dev->iVBAT, GPIOF_OUT_INIT_HIGH, "OLED VBat"},
+		{dev->iVDD, GPIOF_OUT_INIT_HIGH, "OLED VDD"},
+		{dev->iRES, GPIOF_OUT_INIT_HIGH, "OLED_RESET"},
+		{dev->iDC, GPIOF_OUT_INIT_HIGH, "OLED_D/C"},
+	};
+	int status;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gpio_pmodoled_ctrl); i++) {
+		status = gpio_is_valid(gpio_pmodoled_ctrl[i].gpio);
+		if (!status) {
+			dev_err(&dev->spi->dev, "!! gpio_is_valid for GPIO %d, %s FAILED!, status: %d\n",
+					gpio_pmodoled_ctrl[i].gpio, gpio_pmodoled_ctrl[i].label, status);
+			goto gpio_invalid;
+		}
+	}
+
+	status = gpio_request_array(gpio_pmodoled_ctrl, ARRAY_SIZE(gpio_pmodoled_ctrl));
+	if (status) {
+		dev_err(&dev->spi->dev, "!!  gpio_request_array FAILED!\n");
+		dev_err(&dev->spi->dev, "          status is: %d\n", status);
+		gpio_free_array(gpio_pmodoled_ctrl, 4);
+		goto gpio_invalid;
+	}
+
+gpio_invalid:
+	return status;
+}
+
+/**
+ * gpio_pmodoled_disp_init -
+ * @dev:
+ *
+ */
+static void gpio_pmodoled_disp_init(struct gpio_pmodoled_device *dev)
+{
+	int status;
+	uint8_t wr_buf[20];
+
+	/* We are going to be sending commands
+	 * so clear the data/cmd bit */
+	gpio_set_value(dev->iDC, OLED_CONTROLLER_CMD);
+
+	/* Start by turning VDD on and wait for the power to come up */
+	gpio_set_value(dev->iVDD, 0);
+	msleep(1);
+
+	/* Display off Command */
+	wr_buf[0] = OLED_DISPLAY_OFF;
+	status = spi_write(dev->spi, wr_buf, 1);
+
+	/* Bring Reset Low and then High */
+	gpio_set_value(dev->iRES, 1);
+	msleep(1);
+	gpio_set_value(dev->iRES, 0);
+	msleep(1);
+	gpio_set_value(dev->iRES, 1);
+
+	/* Send the set charge pump and set precharge period commands */
+	wr_buf[0] = 0x8D;
+	wr_buf[1] = 0x14;
+	wr_buf[2] = OLED_SET_PRECHARGE_PERIOD;
+	wr_buf[3] = 0xF1;
+
+	status = spi_write(dev->spi, wr_buf, 4);
+
+	/* Turn on VCC and wait 100ms */
+	gpio_set_value(dev->iVBAT, 0);
+	msleep(100);
+
+	/* Set Display COntrast */
+	wr_buf[0] = OLED_CONTRAST_CTRL;
+	wr_buf[1] = 0x0F;
+
+	/* Invert the display */
+	wr_buf[2] = OLED_SET_SEGMENT_REMAP; /* Remap Columns */
+	wr_buf[3] = OLED_SET_COM_DIR;	/* Remap Rows */
+
+	/* Select sequential COM configuration */
+	wr_buf[4] = OLED_SET_COM_PINS;
+	wr_buf[5] = 0x00;
+	wr_buf[6] = 0xC0;
+	wr_buf[7] = 0x20;
+	wr_buf[8] = 0x00;
+
+	/* Turn on Display */
+	wr_buf[9] = OLED_DISPLAY_ON;
+
+	status = spi_write(dev->spi, wr_buf, 10);
+}
+
+
+/**
+ * SPI hardware probe. Sets correct SPI mode, attempts
+ * to obtain memory needed by the driver, and performs
+ * a simple initialization of the device.
+ */
+static int gpio_pmodoled_spi_probe(struct spi_device *spi)
+{
+	int status = 0;
+	struct gpio_pmodoled_device *gpio_pmodoled_dev;
+
+	/* We rely on full duplex transfers, mostly to reduce
+	 * per transfer overheads (by making few transfers).
+	 */
+	if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) {
+		status = -EINVAL;
+		dev_err(&spi->dev, "SPI settings incorrect: %d\n", status);
+		goto spi_err;
+	}
+
+	/* We must use SPI_MODE_0 */
+	spi->mode = SPI_MODE_0;
+	spi->bits_per_word = 8;
+
+	status = spi_setup(spi);
+	if (status < 0) {
+		dev_err(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
+				spi->mode, spi->max_speed_hz / 1000,
+				status);
+		goto spi_err;
+	}
+
+	/* Get gpio_pmodoled_device structure */
+	gpio_pmodoled_dev = (struct gpio_pmodoled_device *) spi->dev.platform_data;
+	if (gpio_pmodoled_dev == NULL) {
+		dev_err(&spi->dev, "Cannot get gpio_pmodoled_device.\n");
+		status = -EINVAL;
+		goto spi_platform_data_err;
+	}
+
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] SPI Probing\n", gpio_pmodoled_dev->name);
+
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_probe: setup char device\n", gpio_pmodoled_dev->name);
+#endif
+
+	/* Setup char driver */
+	status = gpio_pmodoled_setup_cdev(gpio_pmodoled_dev, &(gpio_pmodoled_dev->dev_id), spi);
+	if (status) {
+		dev_err(&spi->dev, "spi_probe: Error adding %s device: %d\n", SPI_DRIVER_NAME, status);
+		goto cdev_add_err;
+	}
+
+	/* Initialize Mutex */
+	mutex_init(&gpio_pmodoled_dev->mutex);
+
+	/**
+	 * It is important to the OLED's longevity that the lines that
+	 * control it's power are carefully controlled. This is a good
+	 * time to ensure that the device is ot turned on until it is
+	 * instructed to do so.
+	 */
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_probe: initialize device\n", gpio_pmodoled_dev->name);
+#endif
+
+	status = gpio_pmodoled_init_gpio(gpio_pmodoled_dev);
+	if (status) {
+		dev_err(&spi->dev, "spi_probe: Error initializing GPIO\n");
+		goto oled_init_error;
+	}
+
+	gpio_pmodoled_disp_init(gpio_pmodoled_dev);
+
+	memset(gpio_pmodoled_dev->disp_buf, 0x00, DISPLAY_BUF_SZ);
+
+	status = screen_buf_to_display(gpio_pmodoled_dev->disp_buf, gpio_pmodoled_dev);
+	if (status) {
+		dev_err(&spi->dev, "spi_probe: Error sending initial Display String\n");
+		goto oled_init_error;
+	}
+	return status;
+
+oled_init_error:
+	if (&gpio_pmodoled_dev->cdev)
+		cdev_del(&gpio_pmodoled_dev->cdev);
+cdev_add_err:
+spi_platform_data_err:
+spi_err:
+	return status;
+}
+
+static int gpio_pmodoled_spi_remove(struct spi_device *spi)
+{
+	int status;
+	struct gpio_pmodoled_device *dev;
+	uint8_t wr_buf[10];
+
+	dev = (struct gpio_pmodoled_device *) spi->dev.platform_data;
+
+	if (dev == NULL) {
+		dev_err(&spi->dev, "spi_remove: Error fetch gpio_pmodoled_device struct\n");
+		return -EINVAL;
+	}
+
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_remove: Clearing Display\n", dev->name);
+#endif
+
+	/* Clear Display */
+	memset(dev->disp_buf, 0, DISPLAY_BUF_SZ);
+	status = screen_buf_to_display(dev->disp_buf, dev);
+
+	/* Turn off display */
+	wr_buf[0] = OLED_DISPLAY_OFF;
+	status = spi_write(spi, wr_buf, 1);
+	if (status)
+		dev_err(&spi->dev, "oled_spi_remove: Error writing to SPI device\n");
+
+	/* Turn off VCC (VBAT) */
+	gpio_set_value(dev->iVBAT, 1);
+	msleep(100);
+	/* TUrn off VDD Power */
+	gpio_set_value(dev->iVDD, 1);
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_remove: Free GPIOs\n", dev->name);
+#endif
+
+{
+	struct gpio gpio_pmodoled_ctrl[] = {
+		{dev->iVBAT, GPIOF_OUT_INIT_HIGH, "OLED VBat"},
+		{dev->iVDD, GPIOF_OUT_INIT_HIGH, "OLED VDD"},
+		{dev->iRES, GPIOF_OUT_INIT_HIGH, "OLED_RESET"},
+		{dev->iDC, GPIOF_OUT_INIT_HIGH, "OLED_D/C"},
+	};
+
+	gpio_free_array(gpio_pmodoled_ctrl, 4);
+}
+
+	if (&dev->cdev) {
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_remove: Destroy Char Device\n", dev->name);
+#endif
+		device_destroy(gpio_pmodoled_class, dev->dev_id);
+		cdev_del(&dev->cdev);
+	}
+
+	cur_minor--;
+
+	printk(KERN_INFO SPI_DRIVER_NAME " [%s] spi_remove: Device Removed\n", dev->name);
+
+	return status;
+}
+
+static struct spi_driver gpio_pmodoled_spi_driver = {
+	.driver = {
+		.name = SPI_DRIVER_NAME,
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = gpio_pmodoled_spi_probe,
+	.remove = gpio_pmodoled_spi_remove,
+};
+
+static const struct of_device_id gpio_pmodoled_of_match[] = {
+	{ .compatible = "dglnt,pmodoled-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, gpio_pmodoled_of_match);
+
+/**
+ * gpio_pmodoled_of_probe - Probe method for PmodOLED device (over GPIO).
+ * @pdev: pointer to platform devices
+ *
+ * This function probes the OLED device in the device tree. It initializes the
+ * OLED driver data structure. It returns 0, if the driver is bound to the OLED
+ * device, or a negative value if there is an error.
+ */
+static int gpio_pmodoled_of_probe(struct platform_device *pdev)
+{
+	struct gpio_pmodoled_device *gpio_pmodoled_dev;
+	struct platform_device *gpio_pmodoled_pdev;
+	struct spi_gpio_platform_data *gpio_pmodoled_pdata;
+
+	struct device_node *np = pdev->dev.of_node;
+
+	const u32 *tree_info;
+	int status = 0;
+
+	/* Alloc Space for platform device structure */
+	gpio_pmodoled_dev = (struct gpio_pmodoled_device *) kzalloc(sizeof(*gpio_pmodoled_dev), GFP_KERNEL);
+	if (!gpio_pmodoled_dev) {
+		status = -ENOMEM;
+		goto dev_alloc_err;
+	}
+
+	/* Alloc Graphic Buffer for device */
+	gpio_pmodoled_dev->disp_buf = (uint8_t *) kmalloc(DISPLAY_BUF_SZ, GFP_KERNEL);
+	if (!gpio_pmodoled_dev->disp_buf) {
+		status = -ENOMEM;
+		dev_err(&pdev->dev, "Device Display data buffer allocation failed: %d\n", status);
+		goto disp_buf_alloc_err;
+	}
+
+	/* Get the GPIO Pins */
+	gpio_pmodoled_dev->iVBAT = of_get_named_gpio(np, "vbat-gpio", 0);
+	gpio_pmodoled_dev->iVDD = of_get_named_gpio(np, "vdd-gpio", 0);
+	gpio_pmodoled_dev->iRES = of_get_named_gpio(np, "res-gpio", 0);
+	gpio_pmodoled_dev->iDC = of_get_named_gpio(np, "dc-gpio", 0);
+	gpio_pmodoled_dev->iSCLK = of_get_named_gpio(np, "spi-sclk-gpio", 0);
+	gpio_pmodoled_dev->iSDIN = of_get_named_gpio(np, "spi-sdin-gpio", 0);
+	status = of_get_named_gpio(np, "spi-cs-gpio", 0);
+	gpio_pmodoled_dev->iCS = (status < 0) ? SPI_GPIO_NO_CHIPSELECT : status;
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO DRIVER_NAME " %s: iVBAT: 0x%lx\n", np->name, gpio_pmodoled_dev->iVBAT);
+	printk(KERN_INFO DRIVER_NAME " %s: iVDD : 0x%lx\n", np->name, gpio_pmodoled_dev->iVDD);
+	printk(KERN_INFO DRIVER_NAME " %s: iRES : 0x%lx\n", np->name, gpio_pmodoled_dev->iRES);
+	printk(KERN_INFO DRIVER_NAME " %s: iDC  : 0x%lx\n", np->name, gpio_pmodoled_dev->iDC);
+	printk(KERN_INFO DRIVER_NAME " %s: iSCLK: 0x%lx\n", np->name, gpio_pmodoled_dev->iSCLK);
+	printk(KERN_INFO DRIVER_NAME " %s: iSDIN: 0x%lx\n", np->name, gpio_pmodoled_dev->iSDIN);
+	printk(KERN_INFO DRIVER_NAME " %s: iCS  : 0x%lx\n", np->name, gpio_pmodoled_dev->iCS);
+#endif
+
+	/* Get SPI Related Params */
+	tree_info = of_get_property(np, "spi-bus-num", NULL);
+	if (tree_info) {
+		gpio_pmodoled_dev->spi_id = be32_to_cpup((tree_info));
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " %s: BUS_ID\t%x\n", np->name, gpio_pmodoled_dev->spi_id);
+#endif
+	}
+
+	/* Alloc Space for platform data structure */
+	gpio_pmodoled_pdata = (struct spi_gpio_platform_data *) kzalloc(sizeof(*gpio_pmodoled_pdata), GFP_KERNEL);
+	if (!gpio_pmodoled_pdata) {
+		status = -ENOMEM;
+		goto pdata_alloc_err;
+	}
+
+	/* Fill up Platform Data Structure */
+	gpio_pmodoled_pdata->sck = gpio_pmodoled_dev->iSCLK;
+	gpio_pmodoled_pdata->miso = SPI_GPIO_NO_MISO;
+	gpio_pmodoled_pdata->mosi = gpio_pmodoled_dev->iSDIN;
+	gpio_pmodoled_pdata->num_chipselect = 1;
+
+	/* Alloc Space for platform data structure */
+	gpio_pmodoled_pdev = (struct platform_device *) kzalloc(sizeof(*gpio_pmodoled_pdev), GFP_KERNEL);
+	if (!gpio_pmodoled_pdev) {
+		status = -ENOMEM;
+		goto pdev_alloc_err;
+	}
+
+	/* Fill up Platform Device Structure */
+	gpio_pmodoled_pdev->name = "spi_gpio";
+	gpio_pmodoled_pdev->id = gpio_pmodoled_dev->spi_id;
+	gpio_pmodoled_pdev->dev.platform_data = gpio_pmodoled_pdata;
+	gpio_pmodoled_dev->pdev = gpio_pmodoled_pdev;
+
+	/* Register spi_gpio master */
+	status = platform_device_register(gpio_pmodoled_dev->pdev);
+	if (status < 0) {
+		dev_err(&pdev->dev, "platform_device_register failed: %d\n", status);
+		goto pdev_reg_err;
+	}
+
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO DRIVER_NAME " %s: spi_gpio platform device registered.\n", np->name);
+#endif
+	gpio_pmodoled_dev->name = np->name;
+
+	/* Fill up Board Info for SPI device */
+	status = add_gpio_pmodoled_device_to_bus(gpio_pmodoled_dev);
+	if (status < 0) {
+		dev_err(&pdev->dev, "add_gpio_pmodoled_device_to_bus failed: %d\n", status);
+		goto spi_add_err;
+	}
+
+#ifdef CONFIG_PMODS_DEBUG
+	printk(KERN_INFO DRIVER_NAME " %s: spi device registered.\n", np->name);
+#endif
+
+	/* Point device node data to gpio_pmodoled_device structure */
+	if (np->data == NULL)
+		np->data = gpio_pmodoled_dev;
+
+	if (gpio_pmodoled_dev_id == 0) {
+		/* Alloc Major & Minor number for char device */
+		status = alloc_chrdev_region(&gpio_pmodoled_dev_id, 0, MAX_PMODOLED_GPIO_DEV_NUM, DRIVER_NAME);
+		if (status) {
+			dev_err(&pdev->dev, "Character device region not allocated correctly: %d\n", status);
+			goto err_alloc_chrdev_region;
+		}
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " : Char Device Region Registered, with Major: %d.\n",
+						MAJOR(gpio_pmodoled_dev_id));
+#endif
+	}
+
+	if (gpio_pmodoled_class == NULL) {
+		/* Create Pmodoled-gpio Device Class */
+		gpio_pmodoled_class = class_create(THIS_MODULE, DRIVER_NAME);
+		if (IS_ERR(gpio_pmodoled_class)) {
+			status = PTR_ERR(gpio_pmodoled_class);
+			goto err_create_class;
+		}
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " : pmodoled_gpio device class registered.\n");
+#endif
+	}
+
+	if (spi_drv_registered == 0) {
+		/* Register SPI Driver for Pmodoled Device */
+		status = spi_register_driver(&gpio_pmodoled_spi_driver);
+		if (status < 0) {
+			dev_err(&pdev->dev, "gpio_pmodoled_spi_driver register failed: %d\n", status);
+			goto err_spi_register;
+		}
+		spi_drv_registered = 1;
+	}
+
+	device_num++;
+
+	return status;
+
+err_spi_register:
+	class_destroy(gpio_pmodoled_class);
+	gpio_pmodoled_class = NULL;
+err_create_class:
+	unregister_chrdev_region(gpio_pmodoled_dev_id, MAX_PMODOLED_GPIO_DEV_NUM);
+	gpio_pmodoled_dev_id = 0;
+err_alloc_chrdev_region:
+	spi_unregister_device(gpio_pmodoled_dev->spi);
+spi_add_err:
+	platform_device_unregister(gpio_pmodoled_dev->pdev);
+pdev_reg_err:
+	kfree(gpio_pmodoled_pdev);
+pdev_alloc_err:
+	kfree(gpio_pmodoled_pdata);
+pdata_alloc_err:
+	kfree(gpio_pmodoled_dev->disp_buf);
+disp_buf_alloc_err:
+	kfree(gpio_pmodoled_dev);
+dev_alloc_err:
+	return status;
+}
+
+/**
+ * gpio_pmodoled_of_remove - Remove method for ZED on-board OLED device.
+ * @np: pointer to device tree node
+ *
+ * This function removes the OLED device in the device tree. It frees the
+ * OLED driver data structure. It returns 0, if the driver is successfully
+ * removed, or a negative value if there is an error.
+ */
+static int gpio_pmodoled_of_remove(struct platform_device *pdev)
+{
+	struct gpio_pmodoled_device *gpio_pmodoled_dev;
+	struct device_node *np = pdev->dev.of_node;
+
+	if (np->data == NULL) {
+		dev_err(&pdev->dev, "pmodoled %s: ERROR: No gpio_pmodoled_device structure found!\n", np->name);
+		return -ENOSYS;
+	}
+	gpio_pmodoled_dev = (struct gpio_pmodoled_device *) (np->data);
+
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " %s : Free display buffer.\n", np->name);
+#endif
+
+	if (gpio_pmodoled_dev->disp_buf != NULL)
+		kfree(gpio_pmodoled_dev->disp_buf);
+
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " %s : Unregister gpio_spi Platform Devices.\n", np->name);
+#endif
+
+	if (gpio_pmodoled_dev->pdev != NULL)
+		platform_device_unregister(gpio_pmodoled_dev->pdev);
+
+	np->data = NULL;
+	device_num--;
+
+	/* Unregister SPI Driver, Destroy pmodoled-gpio class, Release device id Region after
+	 * all pmodoled-gpio devices have been removed.
+	 */
+	if (device_num == 0) {
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " : Unregister SPI Driver.\n");
+#endif
+		spi_unregister_driver(&gpio_pmodoled_spi_driver);
+		spi_drv_registered = 0;
+
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " : Destroy pmodoled_gpio Class.\n");
+#endif
+
+		if (gpio_pmodoled_class)
+			class_destroy(gpio_pmodoled_class);
+
+		gpio_pmodoled_class = NULL;
+
+#ifdef CONFIG_PMODS_DEBUG
+		printk(KERN_INFO DRIVER_NAME " : Release Char Device Region.\n");
+#endif
+
+		unregister_chrdev_region(gpio_pmodoled_dev_id, MAX_PMODOLED_GPIO_DEV_NUM);
+		gpio_pmodoled_dev_id = 0;
+	}
+
+	return 0;
+}
+
+static struct platform_driver gpio_pmodoled_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = gpio_pmodoled_of_match,
+	},
+	.probe = gpio_pmodoled_of_probe,
+	.remove = gpio_pmodoled_of_remove,
+};
+
+module_platform_driver(gpio_pmodoled_driver);
+
+MODULE_AUTHOR("Digilent, Inc.");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRIVER_NAME": PmodOLED display driver");
+MODULE_ALIAS(DRIVER_NAME);
Index: linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/Kconfig	2014-07-20 22:06:37.720283219 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+menuconfig XILINX_VIDEO_IP
+	tristate "Xilinx Video IP components"
+	---help---
+	  This adds support to include Xilinx Video IP components.
+	  Xilinx video IP need few additional drivers which are not currently in Xilinx
+	  main-stream kernel are added in this section.
+	  Example includes : AXI VDMA client driver.
+
+config XILINX_VDMA_WRAPPER
+	tristate "Video DMA Wrapper"
+	depends on XILINX_VIDEO_IP && XILINX_DMA_ENGINES
+	---help---
+	  Enables Video DMA IP component.Uses Slave-DMA API of the DMA engine.
+	  Provides user space application an interface to configure/control
+	  Xilinx VDMA IP.
+	  VDMA wrapper can be extened to supports other features exported by VDMA engine.
Index: linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/Makefile	2014-07-20 22:06:37.726283120 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+obj-$(CONFIG_XILINX_VDMA_WRAPPER) += xvdma.o
Index: linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/xvdma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/xvdma.c	2014-07-20 22:06:37.734282988 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * xvdma.c
+ *
+ * Xilinx Video DMA Driver
+ *
+ * Author: Xilinx Inc.
+ *
+ * 2002-2006 (c)Xilinx Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/cdev.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/uaccess.h>
+#include "xvdma.h"
+
+
+struct xvdma_dev *xvdma_dev_info[MAX_DEVICES + 1];
+static u64 dma_mask = 0xFFFFFFFFUL;
+struct chan_buf chan_buf[MAX_FRAMES];
+u32 num_devices;
+struct completion cmp;
+
+void xvdma_get_dev_info(u32 device_id, struct xvdma_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < MAX_DEVICES; i++) {
+		if (xvdma_dev_info[i]->device_id == device_id)
+			break;
+	}
+	memcpy(dev, xvdma_dev_info[i], sizeof(struct xvdma_dev));
+}
+
+/*
+ * This function is called when an application opens handle to the
+ * bridge driver.
+ */
+static int xvdma_open(struct inode *ip, struct file *filp)
+{
+	return 0;
+}
+
+static int xvdma_release(struct inode *ip, struct file *filp)
+{
+	return 0;
+}
+
+
+static long xvdma_ioctl(struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct xvdma_dev xvdma_dev;
+	struct xvdma_chan_cfg chan_cfg;
+	struct xvdma_buf_info buf_info;
+	struct xvdma_transfer tx_info;
+	u32 devices, chan;
+
+	switch (cmd) {
+	case XVDMA_GET_NUM_DEVICES:
+	{
+		if (copy_from_user((void *)&devices,
+			(const void __user *)arg,
+			sizeof(u32)))
+			return -EFAULT;
+
+		devices = num_devices;
+		 if (copy_to_user((u32 *)arg,
+			&devices, sizeof(u32)))
+			return -EFAULT;
+		break;
+	}
+	case XVDMA_GET_DEV_INFO:
+	{
+		if (copy_from_user((void *)&xvdma_dev,
+			(const void __user *)arg,
+				sizeof(struct xvdma_dev)))
+			return -EFAULT;
+
+		xvdma_get_dev_info(xvdma_dev.device_id, &xvdma_dev);
+
+		if (copy_to_user((struct xvdma_dev *)arg,
+			&xvdma_dev, sizeof(struct xvdma_dev)))
+			return -EFAULT;
+		break;
+	}
+	case XVDMA_DEVICE_CONTROL:
+	{
+		if (copy_from_user((void *)&chan_cfg,
+				(const void __user *)arg,
+				sizeof(struct xvdma_chan_cfg)))
+			return -EFAULT;
+
+		xvdma_device_control(&chan_cfg);
+		break;
+	}
+	case XVDMA_PREP_BUF:
+	{
+		if (copy_from_user((void *)&buf_info,
+				(const void __user *)arg,
+				sizeof(struct xvdma_buf_info)))
+			return -EFAULT;
+		xvdma_prep_slave_sg(&buf_info);
+		break;
+	}
+	case XVDMA_START_TRANSFER:
+	{
+		if (copy_from_user((void *)&tx_info,
+				(const void __user *)arg,
+				sizeof(struct xvdma_transfer)))
+			return -EFAULT;
+
+		xvdma_start_transfer(&tx_info);
+		break;
+	}
+	case XVDMA_STOP_TRANSFER:
+	{
+		if (copy_from_user((void *)&chan,
+				(const void __user *)arg,
+				sizeof(u32)))
+			return -EFAULT;
+
+		xvdma_stop_transfer((struct dma_chan *)chan);
+		break;
+	}
+	default:
+		break;
+	}
+	return 0;
+}
+
+static bool xvdma_filter(struct dma_chan *chan, void *param)
+{
+	if (*((int *)chan->private) == *(int *)param)
+		return true;
+
+
+	return false;
+}
+
+void vdma_sync_callback(void *completion)
+{
+	complete(completion);
+}
+
+void xvdma_stop_transfer(struct dma_chan *chan)
+{
+	struct dma_device *chan_dev;
+
+	if (chan) {
+		chan_dev = chan->device;
+		chan_dev->device_control(chan, DMA_TERMINATE_ALL,
+					(unsigned long)NULL);
+	}
+}
+
+void xvdma_start_transfer(struct xvdma_transfer *tx_info)
+{
+	unsigned long tmo = msecs_to_jiffies(3000);
+
+	init_completion(&cmp);
+	if (tx_info->chan)
+		dma_async_issue_pending((struct dma_chan *)tx_info->chan);
+
+	if (tx_info->wait) {
+		tmo = wait_for_completion_timeout(&cmp, tmo);
+		if (0 == tmo)
+			pr_err("Timeout has occured...\n");
+	}
+}
+
+void xvdma_prep_slave_sg(struct xvdma_buf_info *buf_info)
+{
+	struct dma_chan *chan;
+	struct dma_device *chan_dev;
+	struct dma_async_tx_descriptor *chan_desc;
+	struct scatterlist chansg[MAX_FRAMES];
+	dma_addr_t dma_srcs[MAX_FRAMES];
+	u8 **buf = NULL;
+	int buf_size;
+	u32 flags = 0;
+	int i;
+	u32 device_id;
+	u32 frm_cnt = buf_info->frm_cnt;
+
+	buf_size = buf_info->buf_size;
+	chan = (struct dma_chan *) buf_info->chan;
+	device_id = buf_info->device_id;
+
+	if (chan) {
+		flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP
+			| DMA_PREP_INTERRUPT;
+
+		if (buf_info->fixed_buffer) {
+			chan_dev = chan->device;
+			sg_init_table(chansg, frm_cnt);
+			for (i = 0; i < frm_cnt; i++) {
+				if (!buf_info->shared_buffer) {
+					dma_srcs[i] =
+					buf_info->addr_base + i * buf_size;
+					chan_buf[device_id].dma_addr[i] =
+					dma_srcs[i];
+				}
+				sg_dma_address(&chansg[i]) =
+				chan_buf[device_id].dma_addr[i];
+				sg_dma_len(&chansg[i]) = buf_size;
+			}
+		} else {
+			if (!buf_info->shared_buffer) {
+				buf = kcalloc(frm_cnt + 1, sizeof(u8 *),
+						 GFP_KERNEL);
+				if (!buf)
+					pr_err("Buf failed\n");
+
+				for (i = 0; i < frm_cnt; i++) {
+					buf[i] = kmalloc(buf_size, GFP_KERNEL);
+					if (!buf[i])
+						pr_err("Buf[%d] failed\n", i);
+				}
+				buf[i] = NULL;
+			}
+
+			chan_dev = chan->device;
+			sg_init_table(chansg, frm_cnt);
+			for (i = 0; i < frm_cnt; i++) {
+				if (!buf_info->shared_buffer) {
+					dma_srcs[i] = dma_map_single(
+						chan_dev->dev, buf[i], buf_size,
+							buf_info->mem_type);
+					chan_buf[device_id].dma_addr[i] =
+								dma_srcs[i];
+			}
+			sg_dma_address(&chansg[i]) =
+			chan_buf[device_id].dma_addr[i];
+			sg_dma_len(&chansg[i]) = buf_size;
+			}
+		}
+		chan_desc = chan_dev->device_prep_slave_sg(chan, chansg,
+				frm_cnt, buf_info->direction, flags, NULL);
+		if (buf_info->callback) {
+			chan_desc->callback = vdma_sync_callback;
+			chan_desc->callback_param = &cmp;
+		}
+		chan_desc->tx_submit(chan_desc);
+	}
+}
+
+void xvdma_device_control(struct xvdma_chan_cfg *chan_cfg)
+{
+	struct dma_chan *chan;
+	struct dma_device *chan_dev;
+
+	chan = (struct dma_chan *) chan_cfg->chan;
+
+	if (chan) {
+		chan_dev = chan->device;
+		chan_dev->device_control(chan, DMA_SLAVE_CONFIG,
+					 (unsigned long)&chan_cfg->config);
+	}
+}
+
+void xvdma_add_dev_info(struct dma_chan *tx_chan,
+				struct dma_chan *rx_chan)
+{
+	static u32 i;
+
+	xvdma_dev_info[i] = (struct xvdma_dev *)
+		kzalloc(sizeof(struct xvdma_dev), GFP_KERNEL);
+
+	xvdma_dev_info[i]->tx_chan = (u32) tx_chan;
+	xvdma_dev_info[i]->rx_chan = (u32) rx_chan;
+	xvdma_dev_info[i]->device_id = i;
+	num_devices++;
+	i++;
+}
+
+void xvdma_scan_channels(void)
+{
+	dma_cap_mask_t mask;
+	u32 match_tx, match_rx;
+	struct dma_chan *tx_chan, *rx_chan;
+	u32 device_id = 0;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask);
+
+	for (;;) {
+		match_tx = (DMA_TO_DEVICE & 0xFF) | XILINX_DMA_IP_VDMA |
+			(device_id << XVDMA_DEVICE_ID_SHIFT);
+		tx_chan = dma_request_channel(mask, xvdma_filter,
+				(void *)&match_tx);
+		match_rx = (DMA_FROM_DEVICE & 0xFF) | XILINX_DMA_IP_VDMA |
+			(device_id << XVDMA_DEVICE_ID_SHIFT);
+		rx_chan = dma_request_channel(mask, xvdma_filter,
+				(void *)&match_rx);
+
+		if (!tx_chan && !rx_chan)
+			break;
+		else
+			xvdma_add_dev_info(tx_chan, rx_chan);
+
+		device_id++;
+	}
+}
+
+void xvdma_release_channels(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_DEVICES; i++) {
+		if (xvdma_dev_info[i]->tx_chan)
+			dma_release_channel((struct dma_chan *)
+				xvdma_dev_info[i]->tx_chan);
+		if (xvdma_dev_info[i]->rx_chan)
+			dma_release_channel((struct dma_chan *)
+				xvdma_dev_info[i]->rx_chan);
+	}
+}
+
+static const struct file_operations xvdma_fops = {
+	.owner = THIS_MODULE,
+	.open = xvdma_open,
+	.unlocked_ioctl = xvdma_ioctl,
+	.release = xvdma_release,
+};
+
+static int xvdma_probe(struct platform_device *pdev)
+{
+	dev_t devt;
+	struct xvdma_drvdata *drvdata = NULL;
+	struct device *dev = &pdev->dev;
+	int retval;
+
+	devt = MKDEV(XVDMA_MAJOR, XVDMA_MINOR);
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(struct xvdma_drvdata),
+				GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+	dev_set_drvdata(dev, (void *)drvdata);
+
+	drvdata->dev = dev;
+	drvdata->devt = devt;
+
+	cdev_init(&drvdata->cdev, &xvdma_fops);
+	drvdata->cdev.owner = THIS_MODULE;
+	retval = cdev_add(&drvdata->cdev, devt, 1);
+	if (retval) {
+		dev_err(dev, "cdev_add() failed\n");
+		return retval;
+	}
+
+	xvdma_scan_channels();
+	dev_info(dev, "Xilinx VDMA probe successful\n");
+	dev_info(dev, "Devices Scanned %d\n", num_devices);
+	return 0;
+}
+
+static int xvdma_remove(struct platform_device *op)
+{
+	struct xvdma_drvdata *drvdata;
+	struct device *dev = &op->dev;
+
+	drvdata = (struct xvdma_drvdata *)dev_get_drvdata(dev);
+	if (!drvdata)
+		return 0;
+
+	xvdma_release_channels();
+	cdev_del(&drvdata->cdev);
+	return 0;
+}
+
+static struct platform_driver xvdma_driver = {
+	.driver = {
+		   .name = DRIVER_NAME,
+		   },
+	.probe = xvdma_probe,
+	.remove = xvdma_remove,
+	.suspend = XVDMA_SUSPEND,
+	.resume = XVDMA_RESUME,
+};
+
+static struct platform_device xvdma_device = {
+	.name = "xvdma",
+	.id = 0,
+	.dev = {
+		.platform_data = NULL,
+		.dma_mask = &dma_mask,
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+	.resource = NULL,
+	.num_resources = 0,
+};
+
+static int __init xvdma_init(void)
+{
+	platform_device_register(&xvdma_device);
+
+	return platform_driver_register(&xvdma_driver);
+}
+
+static void __exit xvdma_exit(void)
+{
+	platform_driver_unregister(&xvdma_driver);
+}
+
+late_initcall(xvdma_init);
+module_exit(xvdma_exit);
+
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_DESCRIPTION("Xilinx AXI VDMA client driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/xvdma.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/staging/video/axivdma/xvdma.h	2014-07-20 22:06:37.741282873 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+xvdma.h
+Wrapper client driver for xilinx VDMA Engine.
+
+*/
+#ifndef __XVDMA_H
+#define __XVDMA_H
+
+#include <linux/amba/xilinx_dma.h>
+
+#define DRIVER_NAME     "xvdma"
+#define XVDMA_SUSPEND   NULL
+#define XVDMA_RESUME    NULL
+
+#define XVDMA_MAJOR     10
+#define XVDMA_MINOR     224
+
+#define MAX_DEVICES     4
+#define MAX_FRAMES      5
+#define DMA_CHAN_RESET 10
+
+#define XVDMA_IOCTL_BASE        'W'
+#define XVDMA_GET_NUM_DEVICES   _IO(XVDMA_IOCTL_BASE, 0)
+#define XVDMA_GET_DEV_INFO      _IO(XVDMA_IOCTL_BASE, 1)
+#define XVDMA_DEVICE_CONTROL    _IO(XVDMA_IOCTL_BASE, 2)
+#define XVDMA_PREP_BUF          _IO(XVDMA_IOCTL_BASE, 3)
+#define XVDMA_START_TRANSFER    _IO(XVDMA_IOCTL_BASE, 4)
+#define XVDMA_STOP_TRANSFER     _IO(XVDMA_IOCTL_BASE, 5)
+
+#define XVDMA_DEVICE_ID_SHIFT   28
+
+struct xvdma_drvdata {
+	struct device *dev;
+	struct cdev cdev;       /* Char device structure */
+	dev_t devt;
+};
+
+struct xvdma_dev {
+
+	u32 tx_chan;
+	u32 rx_chan;
+	u32 device_id;
+};
+
+struct xvdma_chan_cfg {
+	struct xilinx_vdma_config config;
+	u32 chan;
+};
+
+struct xvdma_buf_info {
+	u32 chan;
+	u32 device_id;
+	u32 direction;
+	u32 shared_buffer;
+	u32 mem_type;
+	u32 fixed_buffer;
+	u32 buf_size;
+	u32 addr_base;
+	u32 frm_cnt;
+	u32 callback;
+};
+
+struct xvdma_transfer {
+	u32 chan;
+	u32 wait;
+};
+
+struct chan_buf {
+	u32 device_id;
+	dma_addr_t dma_addr[MAX_FRAMES];
+};
+
+void xvdma_device_control(struct xvdma_chan_cfg *);
+void xvdma_prep_slave_sg(struct xvdma_buf_info *);
+void xvdma_start_transfer(struct xvdma_transfer *);
+void xvdma_stop_transfer(struct dma_chan *);
+
+#endif
Index: linux-3.12.24-rt38-xilinx/drivers/tty/serial/8250/8250_core.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/tty/serial/8250/8250_core.c	2014-07-20 22:05:50.214066984 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/tty/serial/8250/8250_core.c	2014-07-20 22:06:37.769282411 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3194 @
 		if (uart_match_port(&serial8250_ports[i].port, port))
 			return &serial8250_ports[i];
 
+	/* Look at setup port->line port first. If is available, use it */
+	if (port->line >= 0 && port->line < nr_uarts)
+		if (serial8250_ports[port->line].port.type == PORT_UNKNOWN &&
+		    serial8250_ports[port->line].port.iobase == 0) {
+			return &serial8250_ports[port->line];
+		}
+
 	/*
 	 * We didn't find a matching entry, so look for the first
 	 * free entry.  We look for one which hasn't been previously
Index: linux-3.12.24-rt38-xilinx/drivers/tty/serial/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/tty/serial/Kconfig	2014-07-20 22:05:50.211067034 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/tty/serial/Kconfig	2014-07-20 22:06:37.845281157 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1391 @
 
 config SERIAL_XILINX_PS_UART
 	tristate "Xilinx PS UART support"
-	depends on OF
+	depends on ARCH_ZYNQ
 	select SERIAL_CORE
 	help
 	  This driver supports the Xilinx PS UART port.
Index: linux-3.12.24-rt38-xilinx/drivers/tty/serial/of_serial.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/tty/serial/of_serial.c	2014-07-20 22:05:50.209067067 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/tty/serial/of_serial.c	2014-07-20 22:06:37.856280976 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:154 @
 	struct uart_port port;
 	int port_type;
 	int ret;
+	int ids;
 
 	match = of_match_device(of_platform_serial_table, &ofdev->dev);
 	if (!match)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:172 @
 	if (ret)
 		goto out;
 
+	ids = of_alias_get_id(ofdev->dev.of_node, "serial");
+	if (ids < 0) {
+		dev_warn(&ofdev->dev, "FAILED to find out alias id\n");
+	} else {
+		if (ids < CONFIG_SERIAL_8250_RUNTIME_UARTS)
+			port.line = ids;
+		else {
+			dev_warn(&ofdev->dev,
+				"FAILED to register serial driver with id %d\n",
+									ids);
+			goto out;
+		}
+	}
+
 	switch (port_type) {
 #ifdef CONFIG_SERIAL_8250
 	case PORT_8250 ... PORT_MAX_8250:
Index: linux-3.12.24-rt38-xilinx/drivers/tty/serial/uartlite.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/tty/serial/uartlite.c	2014-07-20 22:05:50.212067017 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/tty/serial/uartlite.c	2014-07-20 22:06:37.868280778 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:425 @
 	u8 val;
 
 	/* Spin waiting for TX fifo to have space available */
-	for (i = 0; i < 100000; i++) {
+	for (i = 0; i < 10000000; i++) {
 		val = uart_in32(ULITE_STATUS, port);
 		if ((val & ULITE_STATUS_TXFULL) == 0)
 			break;
Index: linux-3.12.24-rt38-xilinx/drivers/tty/serial/xilinx_uartps.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/tty/serial/xilinx_uartps.c	2014-07-20 22:05:50.213067000 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/tty/serial/xilinx_uartps.c	2014-07-20 22:06:37.890280415 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
 /*
  * Xilinx PS UART driver
  *
- * 2011 (c) Xilinx Inc.
+ * 2011 - 2013 (C) Xilinx Inc.
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General Public
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:14 @
  *
  */
 
+#if defined(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE)
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+#endif
+
 #include <linux/platform_device.h>
 #include <linux/serial.h>
+#include <linux/console.h>
 #include <linux/serial_core.h>
-#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <linux/console.h>
-#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/moduleparam.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
 
 #define XUARTPS_TTY_NAME	"ttyPS"
 #define XUARTPS_NAME		"xuartps"
 #define XUARTPS_MAJOR		0	/* use dynamic node allocation */
 #define XUARTPS_MINOR		0	/* works best with devtmpfs */
-#define XUARTPS_NR_PORTS	2
-#define XUARTPS_FIFO_SIZE	16	/* FIFO size */
+
+#define XUARTPS_NR_PORTS	10
+#define XUARTPS_FIFO_SIZE	64	/* FIFO size */
+
 #define XUARTPS_REGISTER_SPACE	0xFFF
 
 #define xuartps_readl(offset)		ioread32(port->membase + offset)
 #define xuartps_writel(val, offset)	iowrite32(val, port->membase + offset)
 
+/* Rx Trigger level */
+static int rx_trigger_level = 56;
+module_param (rx_trigger_level, uint, S_IRUGO);
+MODULE_PARM_DESC (rx_trigger_level, "Rx trigger level, 1-63 bytes");
+
+/* Rx Timeout */
+static int rx_timeout = 10;
+module_param (rx_timeout, uint, S_IRUGO);
+MODULE_PARM_DESC (rx_timeout, "Rx timeout, 1-255");
+
+
 /********************************Register Map********************************/
 /** UART
  *
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:152 @
 #define XUARTPS_IXR_RXEMPTY	0x00000002 /* RX FIFO empty interrupt. */
 #define XUARTPS_IXR_MASK	0x00001FFF /* Valid bit mask */
 
+/* Goes in read_status_mask for break detection as the HW doesn't do it*/
+#define XUARTPS_IXR_BRK		0x80000000
+
 /** Channel Status Register
  *
  * The channel status register (CSR) is provided to enable the control logic
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:166 @
 #define XUARTPS_SR_TXFULL	0x00000010 /* TX FIFO full */
 #define XUARTPS_SR_RXTRIG	0x00000001 /* Rx Trigger */
 
-/**
- * struct xuartps - device data
- * @refclk	Reference clock
- * @aperclk	APB clock
- */
 struct xuartps {
-	struct clk		*refclk;
+	struct uart_port	*port;
+	unsigned int		baud;
+	struct clk		*devclk;
 	struct clk		*aperclk;
+	struct notifier_block	clk_rate_change_nb;
 };
+#define to_xuartps(_nb) container_of(_nb, struct xuartps, clk_rate_change_nb);
+
 
 /**
  * xuartps_isr - Interrupt handler
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:198 @
 	 */
 	isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET);
 
+	/* There is no hardware break detection, so we interpret framing
+	 * error with all-zeros data as a break sequence. Most of the time,
+	 * there's another non-zero byte at the end of the sequence.
+	 *
+	 */
+
+	if (isrstatus & XUARTPS_IXR_FRAMING) {
+		while(!(xuartps_readl(XUARTPS_SR_OFFSET) & \
+			XUARTPS_SR_RXEMPTY)) {
+			if(!xuartps_readl(XUARTPS_FIFO_OFFSET)) {
+				port->read_status_mask |= XUARTPS_IXR_BRK;
+				isrstatus &=~ XUARTPS_IXR_FRAMING;
+			}
+		}
+		xuartps_writel(XUARTPS_IXR_FRAMING,
+				XUARTPS_ISR_OFFSET);
+	}
+
 	/* drop byte with parity error if IGNPAR specified */
 	if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY)
-		isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT);
+		isrstatus &= ~XUARTPS_IXR_TOUT;
 
 	isrstatus &= port->read_status_mask;
 	isrstatus &= ~port->ignore_status_mask;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:229 @
 		while ((xuartps_readl(XUARTPS_SR_OFFSET) &
 			XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) {
 			data = xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+			/*Non-NULL byte after BREAK is garbage (99%)*/
+			if(data && (port->read_status_mask &
+				XUARTPS_IXR_BRK)) {
+				port->read_status_mask&=~XUARTPS_IXR_BRK;
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					continue;
+			}
+
+
+			/*uart_handle_sysrq_char() doesn't work if
+			 *spinlocked, for some reason
+			 */
+			 if (port->sysrq) {
+				spin_unlock(&port->lock);
+				if(uart_handle_sysrq_char(port, \
+					(unsigned char)data)) {
+					spin_lock(&port->lock);
+					continue;
+				}
+				spin_lock(&port->lock);
+			}
+
 			port->icount.rx++;
 
 			if (isrstatus & XUARTPS_IXR_PARITY) {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:316 @
 }
 
 /**
- * xuartps_set_baud_rate - Calculate and set the baud rate
- * @port: Handle to the uart port structure
- * @baud: Baud rate to set
- *
+ * xuartps_calc_baud_divs - Calculate baud rate divisors
+ * @clk: UART module input clock
+ * @baud: Desired baud rate
+ * @rbdiv: BDIV value (return value)
+ * @rcd: CD value (return value)
+ * @div8: Value for clk_sel bit in mod (return value)
  * Returns baud rate, requested baud when possible, or actual baud when there
- *	was too much error
- **/
-static unsigned int xuartps_set_baud_rate(struct uart_port *port,
-						unsigned int baud)
+ *	was too much error, zero if no valid divisors are found.
+ *
+ * Formula to obtain baud rate is
+ *	baud_tx/rx rate = clk/CD * (BDIV + 1)
+ *	input_clk = (Uart User Defined Clock or Apb Clock)
+ *		depends on UCLKEN in MR Reg
+ *	clk = input_clk or input_clk/8;
+ *		depends on CLKS in MR reg
+ *	CD and BDIV depends on values in
+ *			baud rate generate register
+ *			baud rate clock divisor register
+ */
+static unsigned int xuartps_calc_baud_divs(unsigned int clk, unsigned int baud,
+		u32 *rbdiv, u32 *rcd, int *div8)
 {
-	unsigned int sel_clk;
-	unsigned int calc_baud = 0;
-	unsigned int brgr_val, brdiv_val;
+	u32 cd, bdiv;
+	unsigned int calc_baud;
+	unsigned int bestbaud = 0;
 	unsigned int bauderror;
+	unsigned int besterror = ~0;
 
-	/* Formula to obtain baud rate is
-	 *	baud_tx/rx rate = sel_clk/CD * (BDIV + 1)
-	 *	input_clk = (Uart User Defined Clock or Apb Clock)
-	 *		depends on UCLKEN in MR Reg
-	 *	sel_clk = input_clk or input_clk/8;
-	 *		depends on CLKS in MR reg
-	 *	CD and BDIV depends on values in
-	 *			baud rate generate register
-	 *			baud rate clock divisor register
-	 */
-	sel_clk = port->uartclk;
-	if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL)
-		sel_clk = sel_clk / 8;
-
-	/* Find the best values for baud generation */
-	for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) {
+	if (baud < clk / (256 * 65535)) {
+		*div8 = 1;
+		clk /= 8;
+	} else {
+		*div8 = 0;
+	}
 
-		brgr_val = sel_clk / (baud * (brdiv_val + 1));
-		if (brgr_val < 2 || brgr_val > 65535)
+	for (bdiv = 4; bdiv <= 255; bdiv++) {
+		cd = DIV_ROUND_CLOSEST(clk, baud * (bdiv + 1));
+		if (cd < 1 || cd > 65535)
 			continue;
 
-		calc_baud = sel_clk / (brgr_val * (brdiv_val + 1));
+		calc_baud = clk / (cd * (bdiv + 1));
 
 		if (baud > calc_baud)
 			bauderror = baud - calc_baud;
 		else
 			bauderror = calc_baud - baud;
 
-		/* use the values when percent error is acceptable */
-		if (((bauderror * 100) / baud) < 3) {
-			calc_baud = baud;
-			break;
+		if (besterror > bauderror) {
+			*rbdiv = bdiv;
+			*rcd = cd;
+			bestbaud = calc_baud;
+			besterror = bauderror;
 		}
 	}
+	/* use the values when percent error is acceptable */
+	if (((besterror * 100) / baud) < 3)
+		bestbaud = baud;
 
-	/* Set the values for the new baud rate */
-	xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET);
-	xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET);
+	return bestbaud;
+}
+
+/**
+ * xuartps_set_baud_rate - Calculate and set the baud rate
+ * @port: Handle to the uart port structure
+ * @baud: Baud rate to set
+ * Returns baud rate, requested baud when possible, or actual baud when there
+ *	was too much error, zero if no valid divisors are found.
+ */
+static unsigned int xuartps_set_baud_rate(struct uart_port *port,
+						unsigned int baud)
+{
+	unsigned int calc_baud;
+	u32 cd, bdiv;
+	u32 mreg;
+	int div8;
+	struct xuartps *xuartps = port->private_data;
+
+	calc_baud = xuartps_calc_baud_divs(port->uartclk, baud, &bdiv, &cd,
+			&div8);
+
+	/* Write new divisors to hardware */
+	mreg = xuartps_readl(XUARTPS_MR_OFFSET);
+	if (div8)
+		mreg |= XUARTPS_MR_CLKSEL;
+	else
+		mreg &= ~XUARTPS_MR_CLKSEL;
+	xuartps_writel(mreg, XUARTPS_MR_OFFSET);
+	xuartps_writel(cd, XUARTPS_BAUDGEN_OFFSET);
+	xuartps_writel(bdiv, XUARTPS_BAUDDIV_OFFSET);
+	xuartps->baud = baud;
 
 	return calc_baud;
 }
 
+/*
+ * no clue yet how to implement this. i think we need access to the port
+ * structure in this function to do the required changes. but i don't know how
+ * to get it in here.
+ *
+ * Think I got it. port must have a notifier_block* member from where we then
+ * can get to the outer port structure with a container_of() call.
+ *
+ * Not sure when to stop UART. probably it's enough to stop, reconfigure, start
+ * in POST_RATE_CHANGE
+ */
+static int xuartps_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+	u32 ctrl_reg;
+	struct uart_port *port;
+	int locked = 0;
+	struct clk_notifier_data *ndata = data;
+	unsigned long flags = 0;
+	struct xuartps *xuartps = to_xuartps(nb);
+
+	port = xuartps->port;
+	if (port->suspended)
+		return NOTIFY_OK;
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+	{
+		u32 bdiv;
+		u32 cd;
+		int div8;
+
+		/* Find out if current baud-rate can be achieved with new clock
+		 * frequency. */
+		if (!xuartps_calc_baud_divs(ndata->new_rate, xuartps->baud,
+					&bdiv, &cd, &div8))
+			return NOTIFY_BAD;
+
+		spin_lock_irqsave(&xuartps->port->lock, flags);
+
+		/* Disable the TX and RX to set baud rate */
+		xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+				(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS),
+				XUARTPS_CR_OFFSET);
+
+		spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+		return NOTIFY_OK;
+	}
+	case POST_RATE_CHANGE:
+		/* Set clk dividers to generate correct baud with new clock
+		 * frequency. */
+
+		spin_lock_irqsave(&xuartps->port->lock, flags);
+
+		locked = 1;
+		port->uartclk = ndata->new_rate;
+
+		xuartps->baud = xuartps_set_baud_rate(xuartps->port,
+				xuartps->baud);
+		/* fall through */
+	case ABORT_RATE_CHANGE:
+		if (!locked)
+			spin_lock_irqsave(&xuartps->port->lock, flags);
+
+		/* Set TX/RX Reset */
+		xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+				(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+				XUARTPS_CR_OFFSET);
+
+		while (xuartps_readl(XUARTPS_CR_OFFSET) &
+				(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+			cpu_relax();
+
+		/*
+		 * Clear the RX disable and TX disable bits and then set the TX
+		 * enable bit and RX enable bit to enable the transmitter and
+		 * receiver.
+		 */
+		xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+		ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+		xuartps_writel(
+			(ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+			(XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+			XUARTPS_CR_OFFSET);
+
+		spin_unlock_irqrestore(&xuartps->port->lock, flags);
+
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
 /*----------------------Uart Operations---------------------------*/
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:546 @
 		port->state->xmit.tail = (port->state->xmit.tail + 1) &
 					(UART_XMIT_SIZE - 1);
 	}
-
+	xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_ISR_OFFSET);
 	/* Enable the TX Empty interrupt */
 	xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET);
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:594 @
 {
 	unsigned int status;
 
-	status = xuartps_readl(XUARTPS_ISR_OFFSET) & XUARTPS_IXR_TXEMPTY;
+	status = xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_IXR_TXEMPTY;
 	return status ? TIOCSER_TEMT : 0;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:640 @
 	unsigned int baud;
 	unsigned long flags;
 	unsigned int ctrl_reg, mode_reg;
+	unsigned int minbaud, maxbaud;
 
 	spin_lock_irqsave(&port->lock, flags);
 
 	/* Empty the receive FIFO 1st before making changes */
 	while ((xuartps_readl(XUARTPS_SR_OFFSET) &
-		 XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) {
+		 XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY)
 		xuartps_readl(XUARTPS_FIFO_OFFSET);
-	}
 
 	/* Disable the TX and RX to set baud rate */
 	xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:655 @
 			XUARTPS_CR_OFFSET);
 
 	/* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */
-	baud = uart_get_baud_rate(port, termios, old, 0, 10000000);
+	/* min and max baud should be calculated here based on port->uartclk.
+	 * this way we get a valid baud and can safely call set_baud() */
+	minbaud = port->uartclk / (256 * 65535 * 8);
+	maxbaud = port->uartclk / 5; /* not sure about bdiv < 4 */
+	baud = uart_get_baud_rate(port, termios, old, minbaud, maxbaud);
 	baud = xuartps_set_baud_rate(port, baud);
 	if (tty_termios_baud_rate(termios))
 		tty_termios_encode_baud_rate(termios, baud, baud);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:684 @
 			| (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
 			XUARTPS_CR_OFFSET);
 
-	xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+	xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
 	port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG |
 			XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:735 @
 				cval |= XUARTPS_MR_PARITY_MARK;
 			else
 				cval |= XUARTPS_MR_PARITY_SPACE;
-		} else if (termios->c_cflag & PARODD)
+		} else {
+			if (termios->c_cflag & PARODD)
 				cval |= XUARTPS_MR_PARITY_ODD;
 			else
 				cval |= XUARTPS_MR_PARITY_EVEN;
-	} else
+		}
+	} else {
 		cval |= XUARTPS_MR_PARITY_NONE;
-	xuartps_writel(cval , XUARTPS_MR_OFFSET);
+	}
+	cval |= mode_reg & 1;
+	xuartps_writel(cval, XUARTPS_MR_OFFSET);
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:759 @
 static int xuartps_startup(struct uart_port *port)
 {
 	unsigned int retval = 0, status = 0;
+	unsigned long flags;
 
 	retval = request_irq(port->irq, xuartps_isr, 0, XUARTPS_NAME,
 								(void *)port);
 	if (retval)
 		return retval;
 
+	spin_lock_irqsave(&port->lock, flags);
+
 	/* Disable the TX and RX */
 	xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS,
 						XUARTPS_CR_OFFSET);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:794 @
 		| XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT,
 		 XUARTPS_MR_OFFSET);
 
-	/* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */
-	xuartps_writel(14, XUARTPS_RXWM_OFFSET);
+	/* Set the RX FIFO Trigger level to use most of the FIFO, but it
+	 * can be tuned with a module parameter
+	 */
+	xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
 
-	/* Receive Timeout register is enabled with value of 10 */
-	xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
+ 	/* Receive Timeout register is enabled but it
+	 * can be tuned with a module parameter
+	 */
+	xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
 
 	/* Clear out any pending interrupts before enabling them */
 	xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:812 @
 		XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN |
 		XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET);
 
+	spin_unlock_irqrestore(&port->lock, flags);
+
 	return retval;
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:825 @
 static void xuartps_shutdown(struct uart_port *port)
 {
 	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
 
 	/* Disable interrupts */
 	status = xuartps_readl(XUARTPS_IMR_OFFSET);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:836 @
 	/* Disable the TX and RX */
 	xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS,
 				 XUARTPS_CR_OFFSET);
+
+	spin_unlock_irqrestore(&port->lock, flags);
 	free_irq(port->irq, port);
 }
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:949 @
 	/* N/A */
 }
 
+#if defined(CONFIG_CONSOLE_POLL)
+static int xuartps_poll_get_char(struct uart_port *port)
+{
+	u32 imr;
+	int c;
+
+	/*Disable all interrupts*/
+	imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+	xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+	/*Check if  FIFO is empty*/
+	if
+	(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY)
+		c = NO_POLL_CHAR;
+		else
+	/*Read a character*/
+		c = (unsigned char) xuartps_readl(XUARTPS_FIFO_OFFSET);
+
+	/*Enable interrupts*/
+	xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+	return c;
+}
+
+static void xuartps_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	u32 imr;
+
+	/*Disable all interrupts*/
+	imr = xuartps_readl(XUARTPS_IMR_OFFSET);
+	xuartps_writel(imr, XUARTPS_IDR_OFFSET);
+
+	/*Wait until FIFO is empty*/
+	while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+		cpu_relax();
+
+	/*Write a character*/
+	xuartps_writel(c, XUARTPS_FIFO_OFFSET);
+
+	/*Wait until FIFO is empty*/
+	while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY))
+		cpu_relax();
+
+	/*Enable interrupts*/
+	xuartps_writel(imr, XUARTPS_IER_OFFSET);
+
+	return;
+}
+#endif
+
 /** The UART operations structure
  */
 static struct uart_ops xuartps_ops = {
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1031 @
 	.config_port	= xuartps_config_port,	/* Configure when driver
 						 * adds a xuartps port
 						 */
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_get_char	= xuartps_poll_get_char,
+	.poll_put_char	= xuartps_poll_put_char,
+#endif
 };
 
 static struct uart_port xuartps_port[2];
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1045 @
  *
  * Returns a pointer to a uart_port or NULL for failure
  **/
-static struct uart_port *xuartps_get_port(void)
+static struct uart_port *xuartps_get_port(int id)
 {
 	struct uart_port *port;
-	int id;
 
-	/* Find the next unused port */
-	for (id = 0; id < XUARTPS_NR_PORTS; id++)
-		if (xuartps_port[id].mapbase == 0)
-			break;
+	/* try the given port id if failed use default method */
+	if (xuartps_port[id].mapbase != 0) {
+		/* Find the next unused port */
+		for (id = 0; id < XUARTPS_NR_PORTS; id++)
+			if (xuartps_port[id].mapbase == 0)
+				break;
+	}
 
 	if (id >= XUARTPS_NR_PORTS)
 		return NULL;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1115 @
 {
 	struct uart_port *port = &xuartps_port[co->index];
 	unsigned long flags;
-	unsigned int imr;
+	unsigned int imr, ctrl;
 	int locked = 1;
 
 	if (oops_in_progress)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1127 @
 	imr = xuartps_readl(XUARTPS_IMR_OFFSET);
 	xuartps_writel(imr, XUARTPS_IDR_OFFSET);
 
+	/*
+	 * Make sure that the tx part is enabled. Set the TX enable bit and
+	 * clear the TX disable bit to enable the transmitter.
+	 */
+	ctrl = xuartps_readl(XUARTPS_CR_OFFSET);
+	xuartps_writel((ctrl & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN,
+		XUARTPS_CR_OFFSET);
+
 	uart_console_write(port, s, count, xuartps_console_putchar);
 	xuartps_console_wait_tx(port);
 
+	xuartps_writel(ctrl, XUARTPS_CR_OFFSET);
+
 	/* restore interrupt state, it seems like there may be a h/w bug
 	 * in that the interrupt enable register should not need to be
 	 * written based on the data sheet
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1232 @
  **/
 static int xuartps_probe(struct platform_device *pdev)
 {
-	int rc;
 	struct uart_port *port;
 	struct resource *res, *res2;
-	struct xuartps *xuartps_data;
+	unsigned int clk = 0;
+	int ret;
+	int id = 0;
 
-	xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL);
-	if (!xuartps_data)
-		return -ENOMEM;
+	struct xuartps *xuartps;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
 
-	xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk");
-	if (IS_ERR(xuartps_data->aperclk)) {
+	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res2)
+		return -ENODEV;
+
+	/* Look for a serialN alias */
+	id = of_alias_get_id(pdev->dev.of_node, "serial");
+	if (id < 0) {
+		dev_warn(&pdev->dev, "failed to get alias id, errno %d\n", id);
+		id = 0;
+	}
+
+	port = xuartps_get_port(id);
+	xuartps = devm_kzalloc(&pdev->dev, sizeof(*xuartps), GFP_KERNEL);
+
+	xuartps->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
+	if (IS_ERR(xuartps->aperclk)) {
 		dev_err(&pdev->dev, "aper_clk clock not found.\n");
-		rc = PTR_ERR(xuartps_data->aperclk);
-		goto err_out_free;
+		return PTR_ERR(xuartps->aperclk);
 	}
-	xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk");
-	if (IS_ERR(xuartps_data->refclk)) {
+	xuartps->devclk = devm_clk_get(&pdev->dev, "ref_clk");
+	if (IS_ERR(xuartps->devclk)) {
 		dev_err(&pdev->dev, "ref_clk clock not found.\n");
-		rc = PTR_ERR(xuartps_data->refclk);
-		goto err_out_clk_put_aper;
+		return PTR_ERR(xuartps->devclk);
 	}
 
-	rc = clk_prepare_enable(xuartps_data->aperclk);
-	if (rc) {
+	ret = clk_prepare_enable(xuartps->aperclk);
+	if (ret) {
 		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
-		goto err_out_clk_put;
+		return ret;
 	}
-	rc = clk_prepare_enable(xuartps_data->refclk);
-	if (rc) {
+	ret = clk_prepare_enable(xuartps->devclk);
+	if (ret) {
 		dev_err(&pdev->dev, "Unable to enable device clock.\n");
 		goto err_out_clk_dis_aper;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		rc = -ENODEV;
-		goto err_out_clk_disable;
-	}
-
-	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res2) {
-		rc = -ENODEV;
-		goto err_out_clk_disable;
-	}
+	clk = (unsigned int)clk_get_rate(xuartps->devclk);
+	xuartps->clk_rate_change_nb.notifier_call = xuartps_clk_notifier_cb;
+	xuartps->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(xuartps->devclk,
+				&xuartps->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
 
 	/* Initialize the port structure */
-	port = xuartps_get_port();
-
 	if (!port) {
 		dev_err(&pdev->dev, "Cannot get uart_port structure\n");
-		rc = -ENODEV;
-		goto err_out_clk_disable;
+		ret = -ENODEV;
+		goto err_out_clk_dis;
 	} else {
 		/* Register the port.
 		 * This function also registers this device with the tty layer
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1300 @
 		port->mapbase = res->start;
 		port->irq = res2->start;
 		port->dev = &pdev->dev;
-		port->uartclk = clk_get_rate(xuartps_data->refclk);
-		port->private_data = xuartps_data;
+		port->uartclk = clk;
+		port->private_data = xuartps;
+		xuartps->port = port;
 		platform_set_drvdata(pdev, port);
-		rc = uart_add_one_port(&xuartps_uart_driver, port);
-		if (rc) {
+		ret = uart_add_one_port(&xuartps_uart_driver, port);
+		if (ret) {
 			dev_err(&pdev->dev,
-				"uart_add_one_port() failed; err=%i\n", rc);
-			goto err_out_clk_disable;
+				"uart_add_one_port() failed; err=%i\n", ret);
+			port->private_data = NULL;
+			xuartps->port = NULL;
+			goto err_out_clk_dis;
 		}
 		return 0;
 	}
-
-err_out_clk_disable:
-	clk_disable_unprepare(xuartps_data->refclk);
+err_out_clk_dis:
+	clk_notifier_unregister(xuartps->devclk, &xuartps->clk_rate_change_nb);
+	clk_disable_unprepare(xuartps->devclk);
 err_out_clk_dis_aper:
-	clk_disable_unprepare(xuartps_data->aperclk);
-err_out_clk_put:
-	clk_put(xuartps_data->refclk);
-err_out_clk_put_aper:
-	clk_put(xuartps_data->aperclk);
-err_out_free:
-	kfree(xuartps_data);
+	clk_disable_unprepare(xuartps->aperclk);
 
-	return rc;
+	return ret;
 }
 
 /**
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1332 @
 static int xuartps_remove(struct platform_device *pdev)
 {
 	struct uart_port *port = platform_get_drvdata(pdev);
-	struct xuartps *xuartps_data = port->private_data;
-	int rc;
+	int rc = 0;
+	struct xuartps *xuartps;
 
 	/* Remove the xuartps port from the serial core */
-	rc = uart_remove_one_port(&xuartps_uart_driver, port);
-	port->mapbase = 0;
-	clk_disable_unprepare(xuartps_data->refclk);
-	clk_disable_unprepare(xuartps_data->aperclk);
-	clk_put(xuartps_data->refclk);
-	clk_put(xuartps_data->aperclk);
-	kfree(xuartps_data);
+	if (port) {
+		xuartps = port->private_data;
+		clk_notifier_unregister(xuartps->devclk,
+				&xuartps->clk_rate_change_nb);
+		xuartps->port = NULL;
+		port->private_data = NULL;
+		rc = uart_remove_one_port(&xuartps_uart_driver, port);
+		port->mapbase = 0;
+		clk_disable_unprepare(xuartps->devclk);
+		clk_disable_unprepare(xuartps->aperclk);
+	}
 	return rc;
 }
 
+#ifdef CONFIG_PM_SLEEP
+/**
+ * xuartps_suspend - suspend event
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_suspend(struct device *device)
+{
+	struct uart_port *port = dev_get_drvdata(device);
+	struct tty_struct *tty;
+	struct device *tty_dev;
+	int may_wake = 0;
+
+	/* Get the tty which could be NULL so don't assume it's valid */
+	tty = tty_port_tty_get(&port->state->port);
+	if (tty) {
+		tty_dev = tty->dev;
+		may_wake = device_may_wakeup(tty_dev);
+		tty_kref_put(tty);
+	}
+
+	/*
+	 * Call the API provided in serial_core.c file which handles
+	 * the suspend.
+	 */
+	uart_suspend_port(&xuartps_uart_driver, port);
+	if (console_suspend_enabled && !may_wake) {
+		struct xuartps *xuartps = port->private_data;
+
+		clk_disable(xuartps->devclk);
+		clk_disable(xuartps->aperclk);
+	} else {
+		unsigned long flags = 0;
+
+		spin_lock_irqsave(&port->lock, flags);
+		/* Empty the receive FIFO 1st before making changes */
+		while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY))
+			xuartps_readl(XUARTPS_FIFO_OFFSET);
+		dmb();
+		/* set RX trigger level to 1 */
+		xuartps_writel(1, XUARTPS_RXWM_OFFSET);
+		/* disable RX timeout interrups */
+		xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IDR_OFFSET);
+		spin_unlock_irqrestore(&port->lock, flags);
+	}
+
+	return 0;
+}
+
+/**
+ * xuartps_resume - Resume after a previous suspend
+ * @device: Pointer to the device structure
+ *
+ * Returns 0
+ */
+static int xuartps_resume(struct device *device)
+{
+	struct uart_port *port = dev_get_drvdata(device);
+	unsigned long flags = 0;
+	u32 ctrl_reg;
+	struct tty_struct *tty;
+	struct device *tty_dev;
+	int may_wake = 0;
+
+	/* Get the tty which could be NULL so don't assume it's valid */
+	tty = tty_port_tty_get(&port->state->port);
+	if (tty) {
+		tty_dev = tty->dev;
+		may_wake = device_may_wakeup(tty_dev);
+		tty_kref_put(tty);
+	}
+
+	if (console_suspend_enabled && !may_wake) {
+		struct xuartps *xuartps = port->private_data;
+
+		clk_enable(xuartps->aperclk);
+		clk_enable(xuartps->devclk);
+
+		spin_lock_irqsave(&port->lock, flags);
+
+		/* Set TX/RX Reset */
+		xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) |
+				(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST),
+				XUARTPS_CR_OFFSET);
+		while (xuartps_readl(XUARTPS_CR_OFFSET) &
+				(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST))
+			cpu_relax();
+
+		/* restore rx timeout value */
+		xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET);
+		/* Enable Tx/Rx */
+		ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET);
+		xuartps_writel(
+			(ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) |
+			(XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN),
+			XUARTPS_CR_OFFSET);
+
+		spin_unlock_irqrestore(&port->lock, flags);
+	} else {
+		spin_lock_irqsave(&port->lock, flags);
+		/* restore original rx trigger level */
+		xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET);
+		/* enable RX timeout interrupt */
+		xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET);
+		spin_unlock_irqrestore(&port->lock, flags);
+	}
+
+	return uart_resume_port(&xuartps_uart_driver, port);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(xuartps_dev_pm_ops, xuartps_suspend, xuartps_resume);
+
 /* Match table for of_platform binding */
 static struct of_device_id xuartps_of_match[] = {
+	{ .compatible = "xlnx,ps7-uart-1.00.a", },
 	{ .compatible = "xlnx,xuartps", },
 	{}
 };
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1479 @
 		.owner = THIS_MODULE,
 		.name = XUARTPS_NAME,		/* Driver name */
 		.of_match_table = xuartps_of_match,
+		.pm = &xuartps_dev_pm_ops,
 		},
 };
 
Index: linux-3.12.24-rt38-xilinx/drivers/uio/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/uio/Kconfig	2014-07-20 22:05:50.194067314 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/uio/Kconfig	2014-07-20 22:06:37.904280184 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:138 @
 
 	  If you compile this as a module, it will be called uio_mf624.
 
+config UIO_XILINX_APM
+	tristate "Xilinx AXI Performance Monitor driver"
+	depends on MICROBLAZE || ARCH_ZYNQ
+	help
+	  This driver is developed for AXI Performance Monitor IP, designed to
+	  monitor AXI4 traffic for performance analysis of AXI bus in the
+	  system. Driver maps HW registers and parameters to userspace.
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called uio_xilinx_apm.
+
 endif
Index: linux-3.12.24-rt38-xilinx/drivers/uio/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/uio/Makefile	2014-07-20 22:05:50.192067347 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/uio/Makefile	2014-07-20 22:06:37.913280036 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:11 @
 obj-$(CONFIG_UIO_NETX)	+= uio_netx.o
 obj-$(CONFIG_UIO_PRUSS)         += uio_pruss.o
 obj-$(CONFIG_UIO_MF624)         += uio_mf624.o
+obj-$(CONFIG_UIO_XILINX_APM)	+= uio_xilinx_apm.o
Index: linux-3.12.24-rt38-xilinx/drivers/uio/uio_pdrv_genirq.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/uio/uio_pdrv_genirq.c	2014-07-20 22:05:50.191067363 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/uio/uio_pdrv_genirq.c	2014-07-20 22:06:37.923279871 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:270 @
 
 #ifdef CONFIG_OF
 static struct of_device_id uio_of_genirq_match[] = {
+	{ .compatible = "generic-uio", },
 	{ /* This is filled with module_parm */ },
 	{ /* Sentinel */ },
 };
Index: linux-3.12.24-rt38-xilinx/drivers/uio/uio_xilinx_apm.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/uio/uio_xilinx_apm.c	2014-07-20 22:06:37.933279706 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI Performance Monitor
+ *
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * Description:
+ * This driver is developed for AXI Performance Monitor IP,
+ * designed to monitor AXI4 traffic for performance analysis
+ * of AXI bus in the system. Driver maps HW registers and parameters
+ * to userspace. Userspace need not clear the interrupt of IP since
+ * driver clears the interrupt.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/uio_driver.h>
+
+#define XAPM_IS_OFFSET		0x0038  /* Interrupt Status Register */
+#define DRV_NAME		"xilinxapm_uio"
+#define DRV_VERSION		"1.0"
+#define UIO_DUMMY_MEMSIZE	4096
+#define XAPM_MODE_ADVANCED	1
+#define XAPM_MODE_PROFILE	2
+#define XAPM_MODE_TRACE		3
+
+/**
+ * struct xapm_param - HW parameters structure
+ * @mode: Mode in which APM is working
+ * @maxslots: Maximum number of Slots in APM
+ * @eventcnt: Event counting enabled in APM
+ * @eventlog: Event logging enabled in APM
+ * @sampledcnt: Sampled metric counters enabled in APM
+ * @numcounters: Number of counters in APM
+ * @metricwidth: Metric Counter width (32/64)
+ * @sampledwidth: Sampled metric counter width
+ * @globalcntwidth: Global Clock counter width
+ * @scalefactor: Scaling factor
+ * @isr: Interrupts info shared to userspace
+ */
+struct xapm_param {
+	u32 mode;
+	u32 maxslots;
+	u32 eventcnt;
+	u32 eventlog;
+	u32 sampledcnt;
+	u32 numcounters;
+	u32 metricwidth;
+	u32 sampledwidth;
+	u32 globalcntwidth;
+	u32 scalefactor;
+	u32 isr;
+};
+
+/**
+ * struct xapm_dev - Global driver structure
+ * @info: uio_info structure
+ * @param: xapm_param structure
+ * @regs: IOmapped base address
+ */
+struct xapm_dev {
+	struct uio_info info;
+	struct xapm_param param;
+	void __iomem *regs;
+};
+
+/**
+ * xapm_handler - Interrupt handler for APM
+ * @irq: IRQ number
+ * @info: Pointer to uio_info structure
+ */
+static irqreturn_t xapm_handler(int irq, struct uio_info *info)
+{
+	struct xapm_dev *xapm = (struct xapm_dev *)info->priv;
+	void *ptr;
+
+	ptr = (unsigned long *)xapm->info.mem[1].addr;
+	/* Clear the interrupt and copy the ISR value to userspace */
+	xapm->param.isr = readl(xapm->regs + XAPM_IS_OFFSET);
+	writel(xapm->param.isr, xapm->regs + XAPM_IS_OFFSET);
+	memcpy(ptr, &xapm->param, sizeof(struct xapm_param));
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xapm_getprop - Retrieves dts properties to param structure
+ * @pdev: Pointer to platform device
+ * @param: Pointer to param structure
+ */
+static int xapm_getprop(struct platform_device *pdev, struct xapm_param *param)
+{
+	u32 mode = 0;
+	int ret;
+	struct device_node *node;
+
+	node = pdev->dev.of_node;
+
+	/* Retrieve required dts properties and fill param structure */
+	ret = of_property_read_u32(node, "xlnx,enable-profile", &mode);
+	if (ret < 0)
+		dev_info(&pdev->dev, "no property xlnx,enable-profile\n");
+	else if (mode)
+		param->mode = XAPM_MODE_PROFILE;
+
+	ret = of_property_read_u32(node, "xlnx,enable-trace", &mode);
+	if (ret < 0)
+		dev_info(&pdev->dev, "no property xlnx,enable-trace\n");
+	else if (mode)
+		param->mode = XAPM_MODE_TRACE;
+
+	ret = of_property_read_u32(node, "xlnx,num-monitor-slots",
+				   &param->maxslots);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,num-monitor-slots");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,enable-event-count",
+				   &param->eventcnt);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,enable-event-count");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,enable-event-log",
+				   &param->eventlog);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,enable-event-log");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,have-sampled-metric-cnt",
+				   &param->sampledcnt);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,have-sampled-metric-cnt");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,num-of-counters",
+				   &param->numcounters);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,num-of-counters");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,metric-count-width",
+				   &param->metricwidth);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,metric-count-width");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,metrics-sample-count-width",
+				   &param->sampledwidth);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property metrics-sample-count-width");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,global-count-width",
+				   &param->globalcntwidth);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,global-count-width");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "xlnx,metric-count-scale",
+				   &param->scalefactor);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no property xlnx,metric-count-scale");
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * xapm_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Returns '0' on success and failure value on error
+ */
+
+static int xapm_probe(struct platform_device *pdev)
+{
+	struct xapm_dev *xapm;
+	struct resource *res;
+	int irq;
+	int ret;
+	void *ptr;
+
+	xapm = devm_kzalloc(&pdev->dev, (sizeof(struct xapm_dev)), GFP_KERNEL);
+	if (!xapm)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xapm->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (!xapm->regs) {
+		dev_err(&pdev->dev, "unable to iomap registers\n");
+		return -ENOMEM;
+	}
+
+	/* Initialize mode as Advanced so that if no mode in dts, default
+	 * is Advanced
+	 */
+	xapm->param.mode = XAPM_MODE_ADVANCED;
+	ret = xapm_getprop(pdev, &xapm->param);
+	if (ret < 0)
+		return ret;
+
+	xapm->info.mem[0].name = "xilinx_apm";
+	xapm->info.mem[0].addr = res->start;
+	xapm->info.mem[0].size = resource_size(res);
+	xapm->info.mem[0].memtype = UIO_MEM_PHYS;
+
+	xapm->info.mem[1].addr = (unsigned long)kzalloc(UIO_DUMMY_MEMSIZE,
+							GFP_KERNEL);
+	ptr = (unsigned long *)xapm->info.mem[1].addr;
+	xapm->info.mem[1].size = UIO_DUMMY_MEMSIZE;
+	xapm->info.mem[1].memtype = UIO_MEM_LOGICAL;
+
+	xapm->info.name = "axi-pmon";
+	xapm->info.version = DRV_VERSION;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "unable to get irq\n");
+		return irq;
+	}
+
+	xapm->info.irq = irq;
+	xapm->info.handler = xapm_handler;
+	xapm->info.priv = xapm;
+
+	memcpy(ptr, &xapm->param, sizeof(struct xapm_param));
+
+	ret = uio_register_device(&pdev->dev, &xapm->info);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to register to UIO\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, xapm);
+
+	dev_info(&pdev->dev, "Probed Xilinx APM\n");
+
+	return 0;
+}
+
+/**
+ * xapm_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Always returns '0'
+ */
+static int xapm_remove(struct platform_device *pdev)
+{
+	struct xapm_dev *xapm = platform_get_drvdata(pdev);
+
+	uio_unregister_device(&xapm->info);
+
+	return 0;
+}
+
+static struct of_device_id xapm_of_match[] = {
+	{ .compatible = "xlnx,axi-perf-monitor", },
+	{ /* end of table*/ }
+};
+
+MODULE_DEVICE_TABLE(of, xapm_of_match);
+
+static struct platform_driver xapm_driver = {
+	.driver = {
+		.name = "xilinx-axipmon",
+		.owner = THIS_MODULE,
+		.of_match_table = xapm_of_match,
+	},
+	.probe = xapm_probe,
+	.remove = xapm_remove,
+};
+
+module_platform_driver(xapm_driver);
+
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_DESCRIPTION("Xilinx AXI Performance Monitor driver");
+MODULE_LICENSE("GPL v2");
Index: linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-drv.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/c67x00/c67x00-drv.c	2014-07-20 22:05:50.227066770 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-drv.c	2014-07-20 22:06:37.947279475 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:44 @
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/c67x00.h>
+#include <linux/of_platform.h>
 
 #include "c67x00.h"
 #include "c67x00-hcd.h"
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:124 @
 {
 	struct c67x00_device *c67x00;
 	struct c67x00_platform_data *pdata;
-	struct resource *res, *res2;
-	int ret, i;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENODEV;
-
-	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res2)
-		return -ENODEV;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata)
-		return -ENODEV;
+	struct resource *res;
+	int ret, i, irq;
 
-	c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL);
+	c67x00 = devm_kzalloc(&pdev->dev, sizeof(*c67x00), GFP_KERNEL);
 	if (!c67x00)
 		return -ENOMEM;
 
-	if (!request_mem_region(res->start, resource_size(res),
-				pdev->name)) {
-		dev_err(&pdev->dev, "Memory region busy\n");
-		ret = -EBUSY;
-		goto request_mem_failed;
-	}
-	c67x00->hpi.base = ioremap(res->start, resource_size(res));
-	if (!c67x00->hpi.base) {
-		dev_err(&pdev->dev, "Unable to map HPI registers\n");
-		ret = -EIO;
-		goto map_failed;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	c67x00->hpi.base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(c67x00->hpi.base))
+		return PTR_ERR(c67x00->hpi.base);
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (!pdata) {
+		if (!pdev->dev.of_node)
+			return -ENODEV;
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		ret = of_property_read_u32(pdev->dev.of_node, "hpi-regstep",
+					   &pdata->hpi_regstep);
+		if (!ret)
+			return ret;
+
+		ret = of_property_read_u32(pdev->dev.of_node, "sie-config",
+					   &pdata->sie_config);
+		if (!ret)
+			return ret;
 	}
 
 	spin_lock_init(&c67x00->hpi.lock);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:163 @
 	c67x00_ll_init(c67x00);
 	c67x00_ll_hpi_reg_init(c67x00);
 
-	ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "irq resource not found\n");
+		return irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev, irq, c67x00_irq, 0, pdev->name,
+			       c67x00);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot claim IRQ\n");
-		goto request_irq_failed;
+		return ret;
 	}
 
 	ret = c67x00_ll_reset(c67x00);
 	if (ret) {
 		dev_err(&pdev->dev, "Device reset failed\n");
-		goto reset_failed;
+		return ret;
 	}
 
 	for (i = 0; i < C67X00_SIES; i++)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:188 @
 	platform_set_drvdata(pdev, c67x00);
 
 	return 0;
-
- reset_failed:
-	free_irq(res2->start, c67x00);
- request_irq_failed:
-	iounmap(c67x00->hpi.base);
- map_failed:
-	release_mem_region(res->start, resource_size(res));
- request_mem_failed:
-	kfree(c67x00);
-
-	return ret;
 }
 
 static int c67x00_drv_remove(struct platform_device *pdev)
 {
 	struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
-	struct resource *res;
 	int i;
 
 	for (i = 0; i < C67X00_SIES; i++)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:200 @
 
 	c67x00_ll_release(c67x00);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res)
-		free_irq(res->start, c67x00);
-
-	iounmap(c67x00->hpi.base);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res)
-		release_mem_region(res->start, resource_size(res));
-
-	kfree(c67x00);
-
 	return 0;
 }
 
+#ifdef CONFIG_OF
+/* Match table for OF platform binding - from xilinx_emaclite */
+static struct of_device_id c67x00_of_match[] = {
+	{ .compatible = "cypress,c67x00", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, c67x00_of_match);
+#endif
+
 static struct platform_driver c67x00_driver = {
 	.probe	= c67x00_drv_probe,
 	.remove	= c67x00_drv_remove,
 	.driver	= {
 		.owner = THIS_MODULE,
 		.name = "c67x00",
+		.of_match_table = of_match_ptr(c67x00_of_match),
 	},
 };
 
Index: linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-hcd.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/c67x00/c67x00-hcd.h	2014-07-20 22:05:50.226066786 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-hcd.h	2014-07-20 22:06:37.957279310 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:55 @
  */
 
 #define TOTAL_FRAME_BW		12000
-#define DEFAULT_EOT		2250
+#define DEFAULT_EOT		9600 /* This value fits MicroBlaze system.
+					it may requires a bigger value for
+					some USB device. */
 
 #define MAX_FRAME_BW_STD	(TOTAL_FRAME_BW - DEFAULT_EOT)
 #define MAX_FRAME_BW_ISO	2400
Index: linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-sched.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/c67x00/c67x00-sched.c	2014-07-20 22:05:50.228066753 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/c67x00/c67x00-sched.c	2014-07-20 22:06:38.040277941 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1036 @
 		    !td_acked(td))
 			goto cont;
 
+		/*
+		 * at this point, there are no errors, but it's still possible
+		 * that the td wasn't executed by the c67x00. Confirm it was
+		 * executed or force a retry
+		 */
+		if ((td->retry_cnt & TD_RETRYCNTMASK_ACT_FLG) &&
+		    td->status == 0)
+			goto cont;
+
 		/* Sequence ok and acked, don't need to fix toggle */
 		ack_ok = 1;
 
Index: linux-3.12.24-rt38-xilinx/drivers/usb/core/hub.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/core/hub.c	2014-07-20 22:05:50.225066802 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/core/hub.c	2014-07-20 22:06:38.083277232 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:860 @
 				"%s failed (err = %d)\n", __func__, ret);
 	} else {
 		*status = le16_to_cpu(hub->status->hub.wHubStatus);
-		*change = le16_to_cpu(hub->status->hub.wHubChange); 
+		*change = le16_to_cpu(hub->status->hub.wHubChange);
 		ret = 0;
 	}
 	mutex_unlock(&hub->status_mutex);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1696 @
 	 * where the controller driver doesn't have bus_suspend and
 	 * bus_resume methods.
 	 */
+#ifdef CONFIG_USB_ZYNQ_PHY
+	usb_disable_autosuspend(hdev);
+#else
 	if (hdev->parent) {		/* normal device */
 		usb_enable_autosuspend(hdev);
 	} else {			/* root hub */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1707 @
 		if (drv->bus_suspend && drv->bus_resume)
 			usb_enable_autosuspend(hdev);
 	}
+#endif
 
 	if (hdev->level == MAX_TOPO_LEVEL) {
 		dev_err(&intf->dev,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:3856 @
  * Between connect detection and reset signaling there must be a delay
  * of 100ms at least for debounce and power-settling.  The corresponding
  * timer shall restart whenever the downstream port detects a disconnect.
- * 
+ *
  * Apparently there are some bluetooth and irda-dongles and a number of
  * low-speed devices for which this debounce period may last over a second.
  * Not covered by the spec - but easy to deal with.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4082 @
 		udev->tt = &hub->tt;
 		udev->ttport = port1;
 	}
- 
+
 	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
 	 * Because device hardware and firmware is sometimes buggy in
 	 * this area, and this is how Linux has done it for ages.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4246 @
 		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
 		usb_ep0_reinit(udev);
 	}
-  
+
 	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
 	if (retval < (signed)sizeof(udev->descriptor)) {
 		if (retval != -ENODEV)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4532 @
 				goto loop_disable;
 			}
 		}
- 
+
 		/* check for devices running slower than they could */
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
 				&& udev->speed == USB_SPEED_FULL
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4592 @
 			dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
 					port1);
 	}
- 
+
 done:
 	hub_port_disable(hub, port1, 1);
 	if (hcd->driver->relinquish_port && !hub->hdev->parent)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4757 @
 				 * EM interference sometimes causes badly
 				 * shielded USB devices to be shutdown by
 				 * the hub, this hack enables them again.
-				 * Works at least with mouse driver. 
+				 * Works at least with mouse driver.
 				 */
 				if (!(portstatus & USB_PORT_STAT_ENABLE)
 				    && !connect_change
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:5155 @
 
 	if (ret < 0)
 		goto re_enumerate;
- 
+
 	/* Device might have changed firmware (DFU or similar) */
 	if (descriptors_changed(udev, &descriptor, bos)) {
 		dev_info(&udev->dev, "device firmware changed\n");
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:5234 @
 	usb_release_bos_descriptor(udev);
 	udev->bos = bos;
 	return 0;
- 
+
 re_enumerate:
 	/* LPM state doesn't matter when we're about to destroy the device. */
 	hub_port_logical_disconnect(parent_hub, port1);
Index: linux-3.12.24-rt38-xilinx/drivers/usb/gadget/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/gadget/Kconfig	2014-07-20 22:05:50.237066604 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/gadget/Kconfig	2014-07-20 22:06:38.106276852 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:188 @
 	   dynamically linked module called "fsl_usb2_udc" and force
 	   all gadget drivers to also be dynamically linked.
 
+config USB_GADGET_XUSBPS
+	tristate "Xilinx PS Highspeed USB DR Peripheral Controller"
+	depends on ARCH_ZYNQ
+	select USB_GADGET_DUALSPEED
+	select USB_XUSBPS_DR_OF if OF
+	help
+	   Xilinx PS USB controller core supports device mode.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "xilinx_usbps_udc" and
+	   force all gadget drivers to also be dynamically linked.
+
+config XUSBPS_ERRATA_DT654401
+	bool "USB Errata: Adding a dTD to a Primed Endpoint May Not Get Recognized"
+	depends on USB_GADGET_XUSBPS
+	---help---
+	  There is an issue with the add dTD tripwire semaphore (ATDTW bit
+	  in USBCMD register) that can cause the controller to ignore a dTD
+	  that is added to a primed endpoint. When this happens, the software
+	  can read the tripwire bit and the status bit at '1' even though
+	  the endpoint is unprimed.
+
+	  This issue is only applicable for the Zynq silicon revisions < 3.0.
+	  For silicon versions 3.0 and higher, disable this option.
+
+config USB_XUSBPS
+	tristate
+	depends on USB_GADGET_XUSBPS
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
 config USB_FUSB300
 	tristate "Faraday FUSB300 USB Peripheral Controller"
 	depends on !PHYS_ADDR_T_64BIT && HAS_DMA
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:288 @
 	   dynamically linked module called "r8a66597_udc" and force all
 	   gadget drivers to also be dynamically linked.
 
+config USB_GADGET_XILINX
+	boolean "Xilinx USB Driver"
+	depends on (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
+	select USB_GADGET_DUALSPEED
+	help
+	   Sample USB gadget driver
+
 config USB_RENESAS_USBHS_UDC
 	tristate 'Renesas USBHS controller'
 	depends on USB_RENESAS_USBHS
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:780 @
 	help
 	  This driver implements Ethernet style communication, in one of
 	  several ways:
-	  
+
 	   - The "Communication Device Class" (CDC) Ethernet Control Model.
 	     That protocol is often avoided with pure Ethernet adapters, in
 	     favor of simpler vendor-specific hardware, but is widely
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:822 @
 	   If you say "y" here, the Ethernet gadget driver will try to provide
 	   a second device configuration, supporting RNDIS to talk to such
 	   Microsoft USB hosts.
-	   
+
 	   To make MS-Windows work with this, use Documentation/usb/linux.inf
 	   as the "driver info file".  For versions of MS-Windows older than
 	   XP, you'll need to download drivers from Microsoft's website; a URL
Index: linux-3.12.24-rt38-xilinx/drivers/usb/gadget/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/gadget/Makefile	2014-07-20 22:05:50.236066621 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/gadget/Makefile	2014-07-20 22:06:38.117276671 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:30 @
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
 obj-$(CONFIG_USB_S3C_HSUDC)	+= s3c-hsudc.o
+obj-$(CONFIG_USB_GADGET_XILINX)	+= xilinx_udc.o
 obj-$(CONFIG_USB_LPC32XX)	+= lpc32xx_udc.o
 obj-$(CONFIG_USB_EG20T)		+= pch_udc.o
 obj-$(CONFIG_USB_MV_UDC)	+= mv_udc.o
 mv_udc-y			:= mv_udc_core.o
+obj-$(CONFIG_USB_XUSBPS)	+= xilinx_usbps_udc.o
 obj-$(CONFIG_USB_FUSB300)	+= fusb300_udc.o
 obj-$(CONFIG_USB_FOTG210_UDC)	+= fotg210-udc.o
 obj-$(CONFIG_USB_MV_U3D)	+= mv_u3d_core.o
Index: linux-3.12.24-rt38-xilinx/drivers/usb/gadget/xilinx_udc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/gadget/xilinx_udc.c	2014-07-20 22:06:38.146276193 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx USB peripheral controller driver
+ *
+ * Copyright (C) 2010 - 2013 Xilinx, Inc.
+ *
+ * Copyright (C) 2004 by Thomas Rathbone
+ * Copyright (C) 2005 by HP Labs
+ * Copyright (C) 2005 by David Brownell
+ *
+ * Some parts of this driver code is based on the driver for at91-series
+ * USB peripheral controller (at91_udc.c).
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * 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/interrupt.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/prefetch.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/io.h>
+#include <linux/seq_file.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/dma-mapping.h>
+#include "gadget_chips.h"
+
+/* Register offsets for the USB device.*/
+#define XUSB_EP0_CONFIG_OFFSET		0x0000  /* EP0 Config Reg Offset */
+#define XUSB_SETUP_PKT_ADDR_OFFSET	0x0080  /* Setup Packet Address */
+#define XUSB_ADDRESS_OFFSET		0x0100  /* Address Register */
+#define XUSB_CONTROL_OFFSET		0x0104  /* Control Register */
+#define XUSB_STATUS_OFFSET		0x0108  /* Status Register */
+#define XUSB_FRAMENUM_OFFSET		0x010C	/* Frame Number Register */
+#define XUSB_IER_OFFSET			0x0110	/* Interrupt Enable Register */
+#define XUSB_BUFFREADY_OFFSET		0x0114	/* Buffer Ready Register */
+#define XUSB_TESTMODE_OFFSET		0x0118	/* Test Mode Register */
+#define XUSB_DMA_RESET_OFFSET		0x0200  /* DMA Soft Reset Register */
+#define XUSB_DMA_CONTROL_OFFSET		0x0204	/* DMA Control Register */
+#define XUSB_DMA_DSAR_ADDR_OFFSET	0x0208	/* DMA source Address Reg */
+#define XUSB_DMA_DDAR_ADDR_OFFSET	0x020C	/* DMA destination Addr Reg */
+#define XUSB_DMA_LENGTH_OFFSET		0x0210	/* DMA Length Register */
+#define XUSB_DMA_STATUS_OFFSET		0x0214	/* DMA Status Register */
+
+/* Endpoint Configuration Space offsets */
+#define XUSB_EP_CFGSTATUS_OFFSET	0x00	/* Endpoint Config Status  */
+#define XUSB_EP_BUF0COUNT_OFFSET	0x08	/* Buffer 0 Count */
+#define XUSB_EP_BUF1COUNT_OFFSET	0x0C	/* Buffer 1 Count */
+
+#define XUSB_CONTROL_USB_READY_MASK	0x80000000 /* USB ready Mask */
+
+/* Interrupt register related masks.*/
+#define XUSB_STATUS_GLOBAL_INTR_MASK	0x80000000 /* Global Intr Enable */
+#define XUSB_STATUS_RESET_MASK		0x00800000 /* USB Reset Mask */
+#define XUSB_STATUS_SUSPEND_MASK	0x00400000 /* USB Suspend Mask */
+#define XUSB_STATUS_DISCONNECT_MASK	0x00200000 /* USB Disconnect Mask */
+#define XUSB_STATUS_FIFO_BUFF_RDY_MASK	0x00100000 /* FIFO Buff Ready Mask */
+#define XUSB_STATUS_FIFO_BUFF_FREE_MASK	0x00080000 /* FIFO Buff Free Mask */
+#define XUSB_STATUS_SETUP_PACKET_MASK	0x00040000 /* Setup packet received */
+#define XUSB_STATUS_EP1_BUFF2_COMP_MASK	0x00000200 /* EP 1 Buff 2 Processed */
+#define XUSB_STATUS_EP1_BUFF1_COMP_MASK	0x00000002 /* EP 1 Buff 1 Processed */
+#define XUSB_STATUS_EP0_BUFF2_COMP_MASK	0x00000100 /* EP 0 Buff 2 Processed */
+#define XUSB_STATUS_EP0_BUFF1_COMP_MASK	0x00000001 /* EP 0 Buff 1 Processed */
+#define XUSB_STATUS_HIGH_SPEED_MASK	0x00010000 /* USB Speed Mask */
+/* Suspend,Reset and Disconnect Mask */
+#define XUSB_STATUS_INTR_EVENT_MASK	0x00E00000
+/* Buffers  completion Mask */
+#define XUSB_STATUS_INTR_BUFF_COMP_ALL_MASK	0x0000FEFF
+/* Mask for buffer 0 and buffer 1 completion for all Endpoints */
+#define XUSB_STATUS_INTR_BUFF_COMP_SHIFT_MASK	0x00000101
+#define XUSB_STATUS_EP_BUFF2_SHIFT	8	   /* EP buffer offset */
+
+/* Endpoint Configuration Status Register */
+#define XUSB_EP_CFG_VALID_MASK		0x80000000 /* Endpoint Valid bit */
+#define XUSB_EP_CFG_STALL_MASK		0x40000000 /* Endpoint Stall bit */
+#define XUSB_EP_CFG_DATA_TOGGLE_MASK	0x08000000 /* Endpoint Data toggle */
+
+/* USB device specific global configuration constants.*/
+#define XUSB_MAX_ENDPOINTS		8	/* Maximum End Points */
+#define XUSB_EP_NUMBER_ZERO		0	/* End point Zero */
+
+/* Test Modes (Set Feature).*/
+#define TEST_J				1	/* Chirp J Test */
+#define TEST_K				2	/* Chirp K Test */
+#define TEST_SE0_NAK			3	/* Chirp SE0 Test */
+#define TEST_PKT			4	/* Packet Test */
+
+#define CONFIGURATION_ONE		0x01	/* USB device configuration*/
+#define STANDARD_OUT_DEVICE		0x00	/* Out device */
+#define STANDARD_OUT_ENDPOINT		0x02	/* Standard Out end point */
+
+#define XUSB_DMA_READ_FROM_DPRAM	0x80000000/**< DPRAM is the source
+							address for DMA transfer
+							*/
+#define XUSB_DMA_DMASR_BUSY		0x80000000 /**< DMA busy*/
+#define XUSB_DMA_DMASR_ERROR		0x40000000 /**< DMA Error */
+
+/*
+ * When this bit is set, the DMA buffer ready bit is set by hardware upon
+ * DMA transfer completion.
+ */
+#define XUSB_DMA_BRR_CTRL		0x40000000 /**< DMA bufready ctrl bit */
+
+/* Phase States */
+#define SETUP_PHASE			0x0000	/* Setup Phase */
+#define DATA_PHASE			0x0001  /* Data Phase */
+#define STATUS_PHASE			0x0002  /* Status Phase */
+
+#define EP_TRANSMIT		0	/* EP is IN endpoint */
+#define DRIVER_VERSION  "10 October 2010" /* Driver version date */
+
+#define EP0_MAX_PACKET		64 /* Endpoint 0 maximum packet length */
+
+/**
+ * struct xusb_request - Xilinx USB device request structure
+ * @usb_req: Linux usb request structure
+ * @queue: usb device request queue
+ */
+struct xusb_request {
+	struct usb_request usb_req;
+	struct list_head queue;
+};
+
+/**
+ * struct xusb_ep - USB end point structure.
+ * @ep_usb: usb endpoint instance
+ * @queue: endpoint message queue
+ * @udc: xilinx usb peripheral driver instance pointer
+ * @epnumber: endpoint number
+ * @is_in: endpoint direction (IN or OUT)
+ * @stopped: endpoint active status
+ * @is_iso: endpoint type(isochronous or non isochronous)
+ * @maxpacket: maximum packet size the endpoint can store
+ * @rambase: the endpoint buffer address
+ * @buffer0count: the size of the packet recieved in the first buffer
+ * @buffer0ready: the busy state of first buffer
+ * @buffer1count: the size of the packet received in the second buffer
+ * @buffer1ready: the busy state of second buffer
+ * @eptype: endpoint transfer type (BULK, INTERRUPT)
+ * @curbufnum: current buffer of endpoint that will be processed next
+ * @endpointoffset: the endpoint register offset value
+ * @desc: pointer to the usb endpoint descriptor
+ * @data: pointer to the xusb_request structure
+ */
+struct xusb_ep {
+	struct usb_ep ep_usb;
+	struct list_head queue;
+	struct xusb_udc *udc;
+	u16 epnumber;
+	u8 is_in;
+	u8 stopped;
+	u8 is_iso;
+	u16 maxpacket;
+	u32 rambase;
+	u16 buffer0count;
+	u8 buffer0ready;
+	u16 buffer1count;
+	u8 buffer1ready;
+	u8 eptype;
+	u8 curbufnum;
+	u32 endpointoffset;
+	const struct usb_endpoint_descriptor *desc;
+	struct xusb_request *data;
+};
+
+/**
+ * struct xusb_udc -  USB peripheral driver structure
+ * @gadget: USB gadget driver instance
+ * @lock: instance of spinlock
+ * @ep: an array of endpoint structures
+ * @base_address: the usb device base address
+ * @driver pointer: to the usb gadget driver instance
+ * @dma_enabled: flag indicating whether the dma is included in the system
+ * @status: status flag indicating the device cofiguration
+ * @read_fn: function pointer to read device registers
+ * @write_fn: function pointer to write to device registers
+ */
+struct xusb_udc {
+	struct usb_gadget gadget;
+	spinlock_t lock;
+	struct xusb_ep ep[8];
+	void __iomem *base_address;
+	struct usb_gadget_driver *driver;
+	bool dma_enabled;
+	u8 status;
+	unsigned int (*read_fn) (void __iomem *);
+	void (*write_fn) (u32, void __iomem *);
+};
+
+/* Global xusb_udc variable*/
+static struct xusb_udc controller;
+
+/**
+ * struct cmdbuf - Standard USB Command Buffer Structure defined
+ * @setup: usb_ctrlrequest structure for control requests
+ * @contreadptr: pointer to endpoint0 read data
+ * @contwriteptr: pointer to endpoint0 write data
+ * @contreadcount: read data bytes count
+ * @contwritecount: write data bytes count
+ * @setupseqtx: tx status
+ * @setupseqrx: rx status
+ * @contreaddatabuffer: read data buffer for endpoint0
+ */
+struct cmdbuf {
+	struct usb_ctrlrequest setup;
+	u8 *contreadptr;
+	u8 *contwriteptr;
+	u32 contreadcount;
+	u32 contwritecount;
+	u32 setupseqtx;
+	u32 setupseqrx;
+	u8 contreaddatabuffer[64];
+};
+
+static struct cmdbuf ch9_cmdbuf;
+
+/*
+ * Initial Fixed locations provided for endpoint memory address
+ * in the USB core. The user needs to modify this as per his application.
+ */
+static u32 rambase[8] = { 0x22, 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500,
+			0x1600 };
+
+static const char driver_name[] = "xilinx_udc";
+static const char ep0name[] = "ep0";
+
+/* Control endpoint configuration.*/
+static struct usb_endpoint_descriptor config_bulk_out_desc = {
+	.bLength = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+	.bEndpointAddress = USB_DIR_OUT,
+	.bmAttributes = USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize = __constant_cpu_to_le16(0x40),
+};
+
+/**
+ * to_udc - Returns the udc instance pointer
+ * @g: pointer to the usb gadget driver instance
+ *
+ * Returns: xusb_udc pointer
+ */
+static inline struct xusb_udc *to_udc(struct usb_gadget *g)
+{
+
+	return container_of(g, struct xusb_udc, gadget);
+}
+
+/**
+ * xusb_write32 - little endian write to device registers
+ * @val: data to be written
+ * @addr: addr of device register
+ */
+static void xusb_write32(u32 val, void __iomem *addr)
+{
+	iowrite32(val, addr);
+}
+
+/**
+ * xusb_read32 - little endian read from device registers
+ * @addr: addr of device register
+ */
+static unsigned int xusb_read32(void __iomem *addr)
+{
+	return ioread32(addr);
+}
+
+/**
+ * xusb_write32_be - big endian write to device registers
+ * @val: data to be written
+ * @addr: addr of device register
+ */
+static void xusb_write32_be(u32 val, void __iomem *addr)
+{
+	iowrite32be(val, addr);
+}
+
+/**
+ * xusb_read32_be - big endian read from device registers
+ * @addr: addr of device register
+ */
+static unsigned int xusb_read32_be(void __iomem *addr)
+{
+	return ioread32be(addr);
+}
+
+/**
+ * setup_ctrl_wr_status_stage - Sets up the usb device status stages.
+ * @udc: pointer to the usb device controller structure.
+ */
+static void setup_ctrl_wr_status_stage(struct xusb_udc *udc)
+{
+	u32 epcfgreg;
+
+	epcfgreg = (udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset)|
+				XUSB_EP_CFG_DATA_TOGGLE_MASK);
+	udc->write_fn(epcfgreg, (udc->base_address +
+			udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+	udc->write_fn(0, (udc->base_address +
+			udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset +
+			  XUSB_EP_BUF0COUNT_OFFSET));
+	udc->write_fn(1, (udc->base_address + XUSB_BUFFREADY_OFFSET));
+}
+
+/**
+ * ep_configure - Configures the given endpoint.
+ * @ep: pointer to the usb device endpoint structure.
+ * @udc: pointer to the usb peripheral controller structure.
+ *
+ * This function configures a specific endpoint with the given configuration
+ * data.
+ */
+static void ep_configure(struct xusb_ep *ep, struct xusb_udc *udc)
+{
+	u32 epcfgreg = 0;
+
+	/*
+	 * Configure the end point direction, type, Max Packet Size and the
+	 * EP buffer location.
+	 */
+	epcfgreg = ((ep->is_in << 29) | (ep->eptype << 28) |
+			(ep->ep_usb.maxpacket << 15) | (ep->rambase));
+	udc->write_fn(epcfgreg, (udc->base_address + ep->endpointoffset));
+
+	/* Set the Buffer count and the Buffer ready bits.*/
+	udc->write_fn(ep->buffer0count,
+			(udc->base_address + ep->endpointoffset +
+			XUSB_EP_BUF0COUNT_OFFSET));
+	udc->write_fn(ep->buffer1count,
+			(udc->base_address + ep->endpointoffset +
+			XUSB_EP_BUF1COUNT_OFFSET));
+	if (ep->buffer0ready == 1)
+		udc->write_fn(1 << ep->epnumber,
+			(udc->base_address + XUSB_BUFFREADY_OFFSET));
+	if (ep->buffer1ready == 1)
+		udc->write_fn(1 << (ep->epnumber + XUSB_STATUS_EP_BUFF2_SHIFT),
+			(udc->base_address + XUSB_BUFFREADY_OFFSET));
+}
+
+/**
+ * ep_sendrecv - Transmits or receives data to or from an endpoint.
+ * @ep: pointer to the usb endpoint configuration structure.
+ * @bufferptr: pointer to buffer containing the data to be sent.
+ * @bufferlen: The number of data bytes to be sent.
+ * @direction: The direction of data transfer (transmit or receive).
+ *
+ * Returns: 0 on success and 1 on failure
+ *
+ * This function copies the transmit/receive data to/from the end point buffer
+ * and enables the buffer for transmission/reception.
+ */
+static int ep_sendrecv(struct xusb_ep *ep, u8 *bufferptr, u32 bufferlen,
+			u8 direction)
+{
+	u32 *eprambase;
+	u32 bytestosend;
+	u8 *temprambase;
+	unsigned long timeout;
+	u32 srcaddr = 0;
+	u32 dstaddr = 0;
+	int rc = 0;
+	struct xusb_udc *udc = &controller;
+
+	bytestosend = bufferlen;
+
+	/* Put the transmit buffer into the correct ping-pong buffer.*/
+	if ((!(ep->curbufnum)) && (!(ep->buffer0ready))) {
+		/* Get the Buffer address and copy the transmit data.*/
+		eprambase = (u32 __force *)(ep->udc->base_address +
+				ep->rambase);
+
+		if (ep->udc->dma_enabled) {
+			if (direction == EP_TRANSMIT) {
+				srcaddr = dma_map_single(
+					ep->udc->gadget.dev.parent,
+					bufferptr, bufferlen, DMA_TO_DEVICE);
+				dstaddr = virt_to_phys(eprambase);
+				udc->write_fn(bufferlen,
+						(ep->udc->base_address +
+						ep->endpointoffset +
+						XUSB_EP_BUF0COUNT_OFFSET));
+				udc->write_fn(XUSB_DMA_BRR_CTRL |
+						(1 << (ep->epnumber)),
+						(ep->udc->base_address +
+						XUSB_DMA_CONTROL_OFFSET));
+			} else {
+				srcaddr = virt_to_phys(eprambase);
+				dstaddr = dma_map_single(
+					ep->udc->gadget.dev.parent,
+					bufferptr, bufferlen, DMA_FROM_DEVICE);
+				udc->write_fn(XUSB_DMA_BRR_CTRL |
+					XUSB_DMA_READ_FROM_DPRAM |
+					(1 << (ep->epnumber)),
+					(ep->udc->base_address +
+					XUSB_DMA_CONTROL_OFFSET));
+			}
+			/*
+			 * Set the addresses in the DMA source and destination
+			 * registers and then set the length into the DMA length
+			 * register.
+			 */
+			udc->write_fn(srcaddr, (ep->udc->base_address +
+				XUSB_DMA_DSAR_ADDR_OFFSET));
+			udc->write_fn(dstaddr, (ep->udc->base_address +
+				XUSB_DMA_DDAR_ADDR_OFFSET));
+			udc->write_fn(bufferlen, (ep->udc->base_address +
+					XUSB_DMA_LENGTH_OFFSET));
+		} else {
+
+			while (bytestosend > 3) {
+				if (direction == EP_TRANSMIT)
+					*eprambase++ = *(u32 *) bufferptr;
+				else
+					*(u32 *) bufferptr = *eprambase++;
+				bufferptr += 4;
+				bytestosend -= 4;
+			}
+			temprambase = (u8 *) eprambase;
+			while (bytestosend--) {
+				if (direction == EP_TRANSMIT)
+					*temprambase++ = *bufferptr++;
+				else
+					*bufferptr++ = *temprambase++;
+			}
+			/*
+			 * Set the Buffer count register with transmit length
+			 * and enable the buffer for transmission.
+			 */
+			if (direction == EP_TRANSMIT)
+				udc->write_fn(bufferlen,
+					(ep->udc->base_address +
+					ep->endpointoffset +
+					XUSB_EP_BUF0COUNT_OFFSET));
+			udc->write_fn(1 << ep->epnumber,
+					(ep->udc->base_address +
+					XUSB_BUFFREADY_OFFSET));
+		}
+		ep->buffer0ready = 1;
+		ep->curbufnum = 1;
+
+	} else
+		if ((ep->curbufnum == 1) && (!(ep->buffer1ready))) {
+
+			/* Get the Buffer address and copy the transmit data.*/
+			eprambase = (u32 __force *)(ep->udc->base_address +
+					ep->rambase + ep->ep_usb.maxpacket);
+			if (ep->udc->dma_enabled) {
+				if (direction == EP_TRANSMIT) {
+					srcaddr = dma_map_single(
+						ep->udc->gadget.dev.parent,
+						bufferptr, bufferlen,
+						DMA_TO_DEVICE);
+					dstaddr = virt_to_phys(eprambase);
+					udc->write_fn(bufferlen,
+						(ep->udc->base_address +
+						ep->endpointoffset +
+						XUSB_EP_BUF1COUNT_OFFSET));
+					udc->write_fn(XUSB_DMA_BRR_CTRL |
+						(1 << (ep->epnumber +
+						XUSB_STATUS_EP_BUFF2_SHIFT)),
+						(ep->udc->base_address +
+						XUSB_DMA_CONTROL_OFFSET));
+				} else {
+					srcaddr = virt_to_phys(eprambase);
+					dstaddr = dma_map_single(
+						ep->udc->gadget.dev.parent,
+						bufferptr, bufferlen,
+						DMA_FROM_DEVICE);
+				udc->write_fn(XUSB_DMA_BRR_CTRL |
+						XUSB_DMA_READ_FROM_DPRAM |
+						(1 << (ep->epnumber +
+						XUSB_STATUS_EP_BUFF2_SHIFT)),
+						(ep->udc->base_address +
+						XUSB_DMA_CONTROL_OFFSET));
+				}
+				/*
+				 * Set the addresses in the DMA source and
+				 * destination registers and then set the length
+				 * into the DMA length register.
+				 */
+				udc->write_fn(srcaddr,
+					(ep->udc->base_address +
+					XUSB_DMA_DSAR_ADDR_OFFSET));
+				udc->write_fn(dstaddr,
+					(ep->udc->base_address +
+					XUSB_DMA_DDAR_ADDR_OFFSET));
+				udc->write_fn(bufferlen,
+					(ep->udc->base_address +
+					XUSB_DMA_LENGTH_OFFSET));
+			} else {
+				while (bytestosend > 3) {
+					if (direction == EP_TRANSMIT)
+						*eprambase++ =
+							*(u32 *) bufferptr;
+					else
+						*(u32 *) bufferptr =
+							*eprambase++;
+					bufferptr += 4;
+					bytestosend -= 4;
+				}
+				temprambase = (u8 *) eprambase;
+				while (bytestosend--) {
+					if (direction == EP_TRANSMIT)
+						*temprambase++ = *bufferptr++;
+					else
+						*bufferptr++ = *temprambase++;
+				}
+				/*
+				 * Set the Buffer count register with transmit
+				 * length and enable the buffer for
+				 * transmission.
+				 */
+				if (direction == EP_TRANSMIT)
+					udc->write_fn(bufferlen,
+						(ep->udc->base_address +
+						ep->endpointoffset +
+						XUSB_EP_BUF1COUNT_OFFSET));
+				udc->write_fn(1 << (ep->epnumber +
+						XUSB_STATUS_EP_BUFF2_SHIFT),
+						(ep->udc->base_address +
+						XUSB_BUFFREADY_OFFSET));
+			}
+			ep->buffer1ready = 1;
+			ep->curbufnum = 0;
+		} else
+			/*
+			 * None of the ping-pong buffer is free. Return a
+			 * failure.
+			 */
+			return 1;
+
+	if (ep->udc->dma_enabled) {
+		/*
+		 * Wait till DMA transaction is complete and
+		 * check whether the DMA transaction was
+		 * successful.
+		 */
+		while ((udc->read_fn(ep->udc->base_address +
+			XUSB_DMA_STATUS_OFFSET) & XUSB_DMA_DMASR_BUSY) ==
+			XUSB_DMA_DMASR_BUSY) {
+			timeout = jiffies + 10000;
+
+			if (time_after(jiffies, timeout)) {
+				rc = -ETIMEDOUT;
+				goto clean;
+			}
+
+		}
+		if ((udc->read_fn(ep->udc->base_address +
+			XUSB_DMA_STATUS_OFFSET) & XUSB_DMA_DMASR_ERROR) ==
+			XUSB_DMA_DMASR_ERROR)
+			dev_dbg(&ep->udc->gadget.dev, "DMA Error\n");
+clean:
+		if (direction == EP_TRANSMIT) {
+
+			dma_unmap_single(ep->udc->gadget.dev.parent,
+				srcaddr, bufferlen, DMA_TO_DEVICE);
+		} else {
+
+			dma_unmap_single(ep->udc->gadget.dev.parent,
+				dstaddr, bufferlen, DMA_FROM_DEVICE);
+		}
+
+	}
+	return rc;
+}
+
+/**
+ * done - Exeutes the endpoint data transfer completion tasks.
+ * @ep: pointer to the usb device endpoint structure.
+ * @req: pointer to the usb request structure.
+ * @status: Status of the data transfer.
+ *
+ * Deletes the message from the queue and updates data transfer completion
+ * status.
+ */
+static void done(struct xusb_ep *ep, struct xusb_request *req, int status)
+{
+	u8 stopped = ep->stopped;
+
+	list_del_init(&req->queue);
+
+	if (req->usb_req.status == -EINPROGRESS)
+		req->usb_req.status = status;
+	else
+		status = req->usb_req.status;
+
+	if (status && status != -ESHUTDOWN)
+		dev_dbg(&ep->udc->gadget.dev, "%s done %p, status %d\n",
+				ep->ep_usb.name, req, status);
+	ep->stopped = 1;
+
+	spin_unlock(&ep->udc->lock);
+	if (req->usb_req.complete)
+		req->usb_req.complete(&ep->ep_usb, &req->usb_req);
+	spin_lock(&ep->udc->lock);
+
+	ep->stopped = stopped;
+}
+
+/**
+ * read_fifo - Reads the data from the given endpoint buffer.
+ * @ep: pointer to the usb device endpoint structure.
+ * @req: pointer to the usb request structure.
+ *
+ * Returns: 0 for success and error value on failure
+ *
+ * Pulls OUT packet data from the endpoint buffer.
+ */
+static int read_fifo(struct xusb_ep *ep, struct xusb_request *req)
+{
+	u8 *buf;
+	u32 is_short, count, bufferspace;
+	u8 bufoffset;
+	u8 two_pkts = 0;
+	struct xusb_udc *udc = &controller;
+
+	if ((ep->buffer0ready == 1) && (ep->buffer1ready == 1)) {
+		dev_dbg(&ep->udc->gadget.dev, "%s: Packet NOT ready!\n",
+				__func__);
+		return -EINVAL;
+	}
+top:
+	if (ep->curbufnum)
+		bufoffset = 0xC;
+	else
+		bufoffset = 0x08;
+		count = udc->read_fn(ep->udc->base_address +
+				ep->endpointoffset + bufoffset);
+	if (!ep->buffer0ready && !ep->buffer1ready)
+		two_pkts = 1;
+
+	dev_dbg(&ep->udc->gadget.dev,
+		"curbufnum is %d  and buf0rdy is %d, buf1rdy is %d\n",
+		ep->curbufnum, ep->buffer0ready, ep->buffer1ready);
+
+	buf = req->usb_req.buf + req->usb_req.actual;
+	prefetchw(buf);
+	bufferspace = req->usb_req.length - req->usb_req.actual;
+
+	req->usb_req.actual += min(count, bufferspace);
+	is_short = (count < ep->ep_usb.maxpacket);
+
+	if (count) {
+		if (unlikely(!bufferspace)) {
+			/* This happens when the driver's buffer
+			 * is smaller than what the host sent.
+			 * discard the extra data.
+			 */
+			if (req->usb_req.status != -EOVERFLOW)
+				dev_dbg(&ep->udc->gadget.dev,
+					"%s overflow %d\n",
+					ep->ep_usb.name, count);
+			req->usb_req.status = -EOVERFLOW;
+		} else {
+			if (!ep_sendrecv(ep, buf, count, 1)) {
+				dev_dbg(&ep->udc->gadget.dev,
+					"read %s, %d bytes%s req %p %d/%d\n",
+					ep->ep_usb.name, count,
+					is_short ? "/S" : "", req,
+					req->usb_req.actual,
+					req->usb_req.length);
+				bufferspace -= count;
+				/* Completion */
+				if ((req->usb_req.actual ==
+					 req->usb_req.length) || is_short) {
+					done(ep, req, 0);
+					return 1;
+				}
+
+				if (two_pkts) {
+					two_pkts = 0;
+					goto top;
+				}
+
+			} else {
+				dev_dbg(&ep->udc->gadget.dev,
+				"rcv fail..curbufnum is %d and buf0rdy is"
+				"%d, buf1rdy is %d\n", ep->curbufnum,
+				ep->buffer0ready, ep->buffer1ready);
+				req->usb_req.actual -= min(count, bufferspace);
+				return -EINVAL;
+			}
+		}
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * write_fifo - Writes data into the given endpoint buffer.
+ * @ep: pointer to the usb device endpoint structure.
+ * @req: pointer to the usb request structure.
+ *
+ * Returns: 0 for success and error value on failure
+ *
+ * Loads endpoint buffer for an IN packet.
+ */
+static int write_fifo(struct xusb_ep *ep, struct xusb_request *req)
+{
+	u8 *buf;
+	u32 max;
+	u32 length;
+	int is_last, is_short = 0;
+
+	max = le16_to_cpu(ep->desc->wMaxPacketSize);
+
+	if (req) {
+		buf = req->usb_req.buf + req->usb_req.actual;
+		prefetch(buf);
+		length = req->usb_req.length - req->usb_req.actual;
+	} else {
+		buf = NULL;
+		length = 0;
+	}
+
+	length = min(length, max);
+	if (ep_sendrecv(ep, buf, length, EP_TRANSMIT) == 1) {
+		buf = req->usb_req.buf - req->usb_req.actual;
+		dev_dbg(&ep->udc->gadget.dev, "Send failure\n");
+		return 0;
+	} else {
+		req->usb_req.actual += length;
+
+		if (unlikely(length != max))
+			is_last = is_short = 1;
+		else {
+			if (likely(req->usb_req.length !=
+				req->usb_req.actual) || req->usb_req.zero)
+				is_last = 0;
+			else
+				is_last = 1;
+		}
+		dev_dbg(&ep->udc->gadget.dev,
+			"%s: wrote %s %d bytes%s%s %d left %p\n", __func__,
+			ep->ep_usb.name, length,
+			is_last ? "/L" : "", is_short ? "/S" : "",
+			req->usb_req.length - req->usb_req.actual, req);
+
+		if (is_last) {
+			done(ep, req, 0);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/**
+ * nuke - Cleans up the data transfer message list.
+ * @ep: pointer to the usb device endpoint structure.
+ * @status: Status of the data transfer.
+ */
+static void nuke(struct xusb_ep *ep, int status)
+{
+	struct xusb_request *req;
+
+	while (!list_empty(&ep->queue)) {
+		req = list_entry(ep->queue.next, struct xusb_request, queue);
+
+		done(ep, req, status);
+	}
+}
+
+/***************************** Endpoint related functions*********************/
+/**
+ * xusb_ep_set_halt - Stalls/unstalls the given endpoint.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @value: value to indicate stall/unstall.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct xusb_ep *ep = container_of(_ep, struct xusb_ep, ep_usb);
+	unsigned long flags;
+	u32 epcfgreg;
+	struct xusb_udc *udc = &controller;
+
+	if (!_ep || (!ep->desc && ep->epnumber))
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	if (ep->is_in && (!list_empty(&ep->queue)) && value) {
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EAGAIN;
+	}
+	if ((ep->buffer0ready == 1) || (ep->buffer1ready == 1)) {
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EAGAIN;
+	}
+
+	if (value) {
+		/* Stall the device.*/
+		epcfgreg = udc->read_fn(ep->udc->base_address +
+				   ep->endpointoffset);
+		epcfgreg |= XUSB_EP_CFG_STALL_MASK;
+
+		udc->write_fn(epcfgreg,
+			(ep->udc->base_address + ep->endpointoffset));
+		ep->stopped = 1;
+	} else {
+
+		ep->stopped = 0;
+		/* Unstall the device.*/
+		epcfgreg = udc->read_fn(ep->udc->base_address +
+					    ep->endpointoffset);
+		epcfgreg &= ~XUSB_EP_CFG_STALL_MASK;
+		udc->write_fn(epcfgreg,
+		(ep->udc->base_address + ep->endpointoffset));
+		if (ep->epnumber) {
+			/* Reset the toggle bit.*/
+			epcfgreg = udc->read_fn(ep->udc->base_address +
+						    ep->endpointoffset);
+			epcfgreg &= ~XUSB_EP_CFG_DATA_TOGGLE_MASK;
+			udc->write_fn(epcfgreg, (ep->udc->base_address +
+					   ep->endpointoffset));
+		}
+	}
+
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return 0;
+}
+
+/**
+ * xusb_ep_enable - Enables the given endpoint.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @desc: pointer to usb endpoint descriptor.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ep_enable(struct usb_ep *_ep,
+			  const struct usb_endpoint_descriptor *desc)
+{
+	struct xusb_ep *ep = container_of(_ep, struct xusb_ep, ep_usb);
+	struct xusb_udc *dev = ep->udc;
+	u32 tmp;
+	u8 eptype = 0;
+	unsigned long flags;
+	u32 epcfg;
+	struct xusb_udc *udc = &controller;
+
+	/*
+	 * The check for _ep->name == ep0name is not done as this enable i used
+	 * for enabling ep0 also. In other gadget drivers, this ep name is not
+	 * used.
+	 */
+	if (!_ep || !desc || ep->desc ||
+	    desc->bDescriptorType != USB_DT_ENDPOINT) {
+		dev_dbg(&ep->udc->gadget.dev, "first check fails\n");
+		return -EINVAL;
+	}
+
+	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+		dev_dbg(&ep->udc->gadget.dev, "bogus device state\n");
+		return -ESHUTDOWN;
+	}
+
+
+	ep->is_in = ((desc->bEndpointAddress & USB_DIR_IN) != 0);
+	/*
+	 * The address of the endpoint is encoded as follows:
+	 * Bit 3...0: The endpoint number
+	 * Bit 6...4: Reserved, reset to zero
+	 * Bit 7: Direction, ignored for
+	 * control endpoints
+	 * 0 = OUT endpoint
+	 * 1 = IN endpoint
+	 */
+	ep->epnumber = (desc->bEndpointAddress & 0x0f);
+	ep->stopped = 0;
+	ep->desc = desc;
+	ep->ep_usb.desc = desc;
+	tmp = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	ep->ep_usb.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+
+	switch (tmp) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		dev_dbg(&ep->udc->gadget.dev, "only one control endpoint\n");
+		/* NON- ISO */
+		eptype = 0;
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EINVAL;
+	case USB_ENDPOINT_XFER_INT:
+		/* NON- ISO */
+		eptype = 0;
+		if (ep->ep_usb.maxpacket > 64)
+			goto bogus_max;
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		/* NON- ISO */
+		eptype = 0;
+		switch (ep->ep_usb.maxpacket) {
+		case 8:
+		case 16:
+		case 32:
+		case 64:
+		case 512:
+		goto ok;
+		}
+bogus_max:
+		dev_dbg(&ep->udc->gadget.dev, "bogus maxpacket %d\n",
+			ep->ep_usb.maxpacket);
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EINVAL;
+	case USB_ENDPOINT_XFER_ISOC:
+		/* ISO */
+		eptype = 1;
+		ep->is_iso = 1;
+		break;
+	}
+
+ok:	ep->eptype = eptype;
+	ep->buffer0ready = 0;
+	ep->buffer1ready = 0;
+	ep->curbufnum = 0;
+	ep->rambase = rambase[ep->epnumber];
+	ep_configure(ep, ep->udc);
+
+	dev_dbg(&ep->udc->gadget.dev, "Enable Endpoint %d max pkt is %d\n",
+		ep->epnumber, ep->ep_usb.maxpacket);
+
+	/* Enable the End point.*/
+	epcfg = udc->read_fn(ep->udc->base_address + ep->endpointoffset);
+	epcfg |= XUSB_EP_CFG_VALID_MASK;
+	udc->write_fn(epcfg,
+		(ep->udc->base_address + ep->endpointoffset));
+	if (ep->epnumber)
+		ep->rambase <<= 2;
+
+	if (ep->epnumber)
+		udc->write_fn((udc->read_fn(ep->udc->base_address +
+				XUSB_IER_OFFSET) |
+				(XUSB_STATUS_INTR_BUFF_COMP_SHIFT_MASK <<
+				ep->epnumber)),
+				(ep->udc->base_address + XUSB_IER_OFFSET));
+	if ((ep->epnumber) && (!ep->is_in)) {
+
+		/* Set the buffer ready bits.*/
+		udc->write_fn(1 << ep->epnumber, (ep->udc->base_address +
+				  XUSB_BUFFREADY_OFFSET));
+		ep->buffer0ready = 1;
+		udc->write_fn((1 << (ep->epnumber +
+				XUSB_STATUS_EP_BUFF2_SHIFT)),
+				(ep->udc->base_address +
+				XUSB_BUFFREADY_OFFSET));
+		ep->buffer1ready = 1;
+	}
+
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return 0;
+}
+
+/**
+ * xusb_ep_disable - Disables the given endpoint.
+ * @_ep: pointer to the usb device endpoint structure.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ep_disable(struct usb_ep *_ep)
+{
+	struct xusb_ep *ep = container_of(_ep, struct xusb_ep, ep_usb);
+	unsigned long flags;
+	u32 epcfg;
+	struct xusb_udc *udc = &controller;
+
+	if (ep == &ep->udc->ep[XUSB_EP_NUMBER_ZERO]) {
+		dev_dbg(&ep->udc->gadget.dev, "Ep0 disable called\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	nuke(ep, -ESHUTDOWN);
+
+	/* Restore the endpoint's pristine config */
+	ep->desc = NULL;
+	ep->ep_usb.desc = NULL;
+
+	ep->stopped = 1;
+
+	/*
+	 * The address of the endpoint is encoded as follows:
+	 * Bit 3...0: The endpoint number
+	 * Bit 6...4: Reserved, reset to zero
+	 * Bit 7: Direction, ignored for
+	 * control endpoints
+	 * 0 = OUT endpoint
+	 * 1 = IN endpoint
+	 */
+	dev_dbg(&ep->udc->gadget.dev, "USB Ep %d disable\n ", ep->epnumber);
+
+	/* Disable the endpoint.*/
+	epcfg = udc->read_fn(ep->udc->base_address + ep->endpointoffset);
+	epcfg &= ~XUSB_EP_CFG_VALID_MASK;
+	udc->write_fn(epcfg, (ep->udc->base_address + ep->endpointoffset));
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return 0;
+}
+
+/**
+ * xusb_ep_alloc_request - Initializes the request queue.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @gfp_flags: Flags related to the request call.
+ *
+ * Returns: pointer to request structure on success and a NULL on failure.
+ */
+static struct usb_request *xusb_ep_alloc_request(struct usb_ep *_ep,
+						 gfp_t gfp_flags)
+{
+	struct xusb_request *req;
+
+	req = kmalloc(sizeof(*req), gfp_flags);
+	if (!req)
+		return NULL;
+
+	memset(req, 0, sizeof(*req));
+	INIT_LIST_HEAD(&req->queue);
+	return &req->usb_req;
+}
+
+/**
+ * xusb_ep_free_request - Releases the request from queue.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @_req: pointer to the usb request structure.
+ */
+static void xusb_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct xusb_ep *ep = container_of(_ep, struct xusb_ep, ep_usb);
+	struct xusb_request *req;
+
+	req = container_of(_req, struct xusb_request, usb_req);
+
+	if (!list_empty(&req->queue))
+		dev_warn(&ep->udc->gadget.dev, "Error: No memory to free");
+
+	kfree(req);
+}
+
+/**
+ * xusb_ep_queue - Adds the request to the queue.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @_req: pointer to the usb request structure.
+ * @gfp_flags: Flags related to the request call.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+			 gfp_t gfp_flags)
+{
+	struct xusb_request *req;
+	struct xusb_ep *ep;
+	struct xusb_udc *dev;
+	unsigned long flags;
+	u32 length, count;
+	u8 *corebuf;
+	struct xusb_udc *udc = &controller;
+
+	req = container_of(_req, struct xusb_request, usb_req);
+	ep = container_of(_ep, struct xusb_ep, ep_usb);
+
+	if (!_req || !_req->complete || !_req->buf ||
+	    !list_empty(&req->queue)) {
+		dev_dbg(&ep->udc->gadget.dev, "invalid request\n");
+		return -EINVAL;
+	}
+
+	if (!_ep || (!ep->desc && ep->ep_usb.name != ep0name)) {
+		dev_dbg(&ep->udc->gadget.dev, "invalid ep\n");
+		return -EINVAL;
+	}
+
+	dev = ep->udc;
+	if (!dev || !dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+		dev_dbg(&ep->udc->gadget.dev, "%s, bogus device state %p\n",
+			__func__, dev->driver);
+		return -ESHUTDOWN;
+	}
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+
+	/* Try to kickstart any empty and idle queue */
+	if (list_empty(&ep->queue)) {
+		if (!ep->epnumber) {
+			ep->data = req;
+			if (ch9_cmdbuf.setup.bRequestType & USB_DIR_IN) {
+				ch9_cmdbuf.contwriteptr = req->usb_req.buf +
+							req->usb_req.actual;
+				prefetch(ch9_cmdbuf.contwriteptr);
+				length = req->usb_req.length -
+					req->usb_req.actual;
+				corebuf = (void __force *) ((ep->rambase << 2) +
+					    ep->udc->base_address);
+				ch9_cmdbuf.contwritecount = length;
+				length = count = min_t(u32, length,
+							EP0_MAX_PACKET);
+				while (length--)
+					*corebuf++ = *ch9_cmdbuf.contwriteptr++;
+				udc->write_fn(count, (ep->udc->base_address +
+					   XUSB_EP_BUF0COUNT_OFFSET));
+				udc->write_fn(1, (ep->udc->base_address +
+					   XUSB_BUFFREADY_OFFSET));
+				ch9_cmdbuf.contwritecount -= count;
+			} else {
+				if (ch9_cmdbuf.setup.wLength) {
+					ch9_cmdbuf.contreadptr =
+						req->usb_req.buf +
+							req->usb_req.actual;
+					udc->write_fn(req->usb_req.length ,
+						(ep->udc->base_address +
+						XUSB_EP_BUF0COUNT_OFFSET));
+					udc->write_fn(1, (ep->udc->base_address
+						+ XUSB_BUFFREADY_OFFSET));
+				} else {
+					setup_ctrl_wr_status_stage(udc);
+					req = NULL;
+				}
+			}
+		} else {
+
+			if (ep->is_in) {
+				dev_dbg(&ep->udc->gadget.dev,
+					"write_fifo called from queue\n");
+				if (write_fifo(ep, req) == 1)
+					req = NULL;
+			} else {
+				dev_dbg(&ep->udc->gadget.dev,
+					"read_fifo called from queue\n");
+				if (read_fifo(ep, req) == 1)
+					req = NULL;
+			}
+		}
+	}
+
+	if (req != NULL)
+		list_add_tail(&req->queue, &ep->queue);
+	spin_unlock_irqrestore(&dev->lock, flags);
+	return 0;
+}
+
+/**
+ * xusb_ep_dequeue - Removes the request from the queue.
+ * @_ep: pointer to the usb device endpoint structure.
+ * @_req: pointer to the usb request structure.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct xusb_ep *ep;
+	struct xusb_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct xusb_ep, ep_usb);
+
+	if (!_ep || ep->ep_usb.name == ep0name)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	/* Make sure it's actually queued on this endpoint */
+	list_for_each_entry(req, &ep->queue, queue) {
+		if (&req->usb_req == _req)
+			break;
+	}
+	if (&req->usb_req != _req) {
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EINVAL;
+	}
+
+	done(ep, req, -ECONNRESET);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return 0;
+}
+
+static struct usb_ep_ops xusb_ep_ops = {
+	.enable = xusb_ep_enable,
+	.disable = xusb_ep_disable,
+
+	.alloc_request = xusb_ep_alloc_request,
+	.free_request = xusb_ep_free_request,
+
+	.queue = xusb_ep_queue,
+	.dequeue = xusb_ep_dequeue,
+	.set_halt = xusb_ep_set_halt,
+};
+
+/**
+ * xusb_get_frame - Reads the current usb frame number.
+ * @gadget: pointer to the usb gadget structure.
+ *
+ * Returns: current frame number for success and error value on failure.
+ */
+static int xusb_get_frame(struct usb_gadget *gadget)
+{
+
+	struct xusb_udc *udc = to_udc(gadget);
+	unsigned long flags;
+	int retval;
+
+	if (!gadget)
+		return -ENODEV;
+
+	local_irq_save(flags);
+	retval = udc->read_fn(udc->base_address + XUSB_FRAMENUM_OFFSET);
+	local_irq_restore(flags);
+	return retval;
+}
+
+/**
+ * set_testmode - Sets the usb device into the given test mode.
+ * @udc: pointer to the usb controller structure.
+ * @testmode: Test mode to which the device is to be set.
+ * @bufptr: pointer to the buffer containing the test packet.
+ *
+ * Returns: This function never returns if the command is successful
+ *		and -ENOTSUPP on failure.
+ *
+ * This function is needed for USB certification tests.
+ */
+static int set_testmode(struct xusb_udc *udc, u8 testmode, u8 *bufptr)
+{
+	u32 *src, *dst;
+	u32 count;
+	u32 crtlreg;
+
+	/* Stop the SIE.*/
+	crtlreg = udc->read_fn(udc->base_address + XUSB_CONTROL_OFFSET);
+	crtlreg &= ~XUSB_CONTROL_USB_READY_MASK;
+	udc->write_fn(crtlreg, (udc->base_address + XUSB_CONTROL_OFFSET));
+	if (testmode == TEST_PKT) {
+
+		if (bufptr == NULL)
+			/* Null pointer is passed.*/
+			return -EINVAL;
+
+
+		src = (u32 *) bufptr;
+		dst = (u32 __force *) (udc->base_address);
+		count = 14;
+
+		/* Copy Leurker PKT to DPRAM at 0.*/
+		while (count--)
+			*dst++ = *src++;
+	}
+
+	/* Set the test mode.*/
+	udc->write_fn(testmode, (udc->base_address + XUSB_TESTMODE_OFFSET));
+	/* Re-start the SIE.*/
+	udc->write_fn(XUSB_CONTROL_USB_READY_MASK,
+		(udc->base_address + XUSB_CONTROL_OFFSET));
+
+	while (1)
+		;		/* Only way out is through hardware reset! */
+
+	return 0;
+}
+
+/**
+ * xusb_ioctl - The i/o control function to call the testmode function.
+ * @gadget: pointer to the usb gadget structure.
+ * @code: Test mode to which the device is to be set.
+ * @param: Parameter to be sent for the test.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xusb_ioctl(struct usb_gadget *gadget, unsigned code,
+		      unsigned long param)
+{
+	struct xusb_udc *udc = to_udc(gadget);
+	u8 *BufPtr;
+
+	BufPtr = (u8 *) param;
+
+	if ((code == TEST_J) || (code == TEST_K) ||
+	    (code == TEST_SE0_NAK) || (code == TEST_PKT))
+
+		return set_testmode(udc, code, BufPtr);
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int xudc_start(struct usb_gadget *gadget,
+			struct usb_gadget_driver *driver);
+static int xudc_stop(struct usb_gadget *gadget,
+			struct usb_gadget_driver *driver);
+static void xusb_release(struct device *dev);
+
+static const struct usb_gadget_ops xusb_udc_ops = {
+	.get_frame = xusb_get_frame,
+	.ioctl = xusb_ioctl,
+	.udc_start = xudc_start,
+	.udc_stop  = xudc_stop,
+};
+
+/*-------------------------------------------------------------------------*/
+static struct xusb_udc controller = {
+	.gadget = {
+		.ops = &xusb_udc_ops,
+		.ep0 = &controller.ep[XUSB_EP_NUMBER_ZERO].ep_usb,
+		.speed = USB_SPEED_HIGH,
+		.max_speed = USB_SPEED_HIGH,
+		.is_otg = 0,
+		.is_a_peripheral = 0,
+		.b_hnp_enable = 0,
+		.a_hnp_support = 0,
+		.a_alt_hnp_support = 0,
+		.name = driver_name,
+		.dev = {
+			.init_name = "xilinx_udc",
+			.release = xusb_release,
+			},
+		},
+	.ep[0] = {
+		.ep_usb = {
+			.name = ep0name,
+			.ops = &xusb_ep_ops,
+			.maxpacket = 0x40,
+		},
+			.udc = &controller,
+		.epnumber = 0,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[1] = {
+		.ep_usb = {
+			.name = "ep1",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 1,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[2] = {
+		.ep_usb = {
+			.name = "ep2",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 2,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[3] = {
+		.ep_usb = {
+			.name = "ep3",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 3,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[4] = {
+		.ep_usb = {
+			.name = "ep4",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 4,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[5] = {
+		.ep_usb = {
+			.name = "ep5",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 5,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.ep[6] = {
+		.ep_usb = {
+			.name = "ep6",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 6,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.eptype = 0,
+		.curbufnum = 0,
+		.endpointoffset = 0,
+		},
+	.ep[7] = {
+		.ep_usb = {
+			.name = "ep7",
+			.ops = &xusb_ep_ops,
+		},
+		.udc = &controller,
+		.epnumber = 7,
+		.buffer0count = 0,
+		.buffer0ready = 0,
+		.buffer1count = 0,
+		.buffer1ready = 0,
+		.curbufnum = 0,
+		.eptype = 0,
+		.endpointoffset = 0,
+		},
+	.status = 0,
+	.write_fn = xusb_write32_be,
+	.read_fn = xusb_read32_be,
+};
+
+/**
+ * xudc_reinit - Restores inital software state.
+ * @udc: pointer to the usb device controller structure.
+ */
+static void xudc_reinit(struct xusb_udc *udc)
+{
+	u32 ep_number;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+	INIT_LIST_HEAD(&udc->gadget.ep0->ep_list);
+
+	for (ep_number = 0; ep_number < XUSB_MAX_ENDPOINTS; ep_number++) {
+		struct xusb_ep *ep = &udc->ep[ep_number];
+
+		if (ep_number) {
+			list_add_tail(&ep->ep_usb.ep_list,
+					&udc->gadget.ep_list);
+			ep->ep_usb.maxpacket = (unsigned short)~0;
+		}
+		ep->desc = NULL;
+		ep->stopped = 0;
+		/*
+		 * The configuration register address offset between
+		 * each endpoint is 0x10.
+		 */
+		ep->endpointoffset = XUSB_EP0_CONFIG_OFFSET +
+					(ep_number * 0x10);
+		ep->is_in = 0;
+		ep->is_iso = 0;
+		ep->maxpacket = 0;
+		ep_configure(ep, udc);
+		udc->status = 0;
+
+		/* Initialize one queue per endpoint */
+		INIT_LIST_HEAD(&ep->queue);
+	}
+}
+
+/**
+ * stop_activity - Stops any further activity on the device.
+ * @udc: pointer to the usb device controller structure.
+ */
+static void stop_activity(struct xusb_udc *udc)
+{
+	struct usb_gadget_driver *driver = udc->driver;
+	int i;
+
+	if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+		driver = NULL;
+	udc->gadget.speed = USB_SPEED_HIGH;
+
+	for (i = 0; i < XUSB_MAX_ENDPOINTS; i++) {
+		struct xusb_ep *ep = &udc->ep[i];
+
+		ep->stopped = 1;
+		nuke(ep, -ESHUTDOWN);
+	}
+	if (driver) {
+		spin_unlock(&udc->lock);
+		driver->disconnect(&udc->gadget);
+		spin_lock(&udc->lock);
+	}
+
+	xudc_reinit(udc);
+}
+
+/**
+ * startup_intrhandler - The usb device controller interrupt handler.
+ * @callbackref: pointer to the reference value being passed.
+ * @intrstatus: The mask value containing the interrupt sources.
+ *
+ * This handler handles the RESET, SUSPEND and DISCONNECT interrupts.
+ */
+static void startup_intrhandler(void *callbackref, u32 intrstatus)
+{
+	struct xusb_udc *udc;
+	u32 intrreg;
+
+	udc = (struct xusb_udc *) callbackref;
+
+	if (intrstatus & XUSB_STATUS_RESET_MASK) {
+		dev_dbg(&udc->gadget.dev, "Reset\n");
+		if (intrstatus & XUSB_STATUS_HIGH_SPEED_MASK)
+			udc->gadget.speed = USB_SPEED_HIGH;
+		else
+			udc->gadget.speed = USB_SPEED_FULL;
+
+		if (udc->status == 1) {
+			udc->status = 0;
+			/* Set device address to 0.*/
+			udc->write_fn(0, (udc->base_address +
+						XUSB_ADDRESS_OFFSET));
+		}
+		/* Disable the Reset interrupt.*/
+		intrreg = udc->read_fn(udc->base_address +
+					XUSB_IER_OFFSET);
+
+		intrreg &= ~XUSB_STATUS_RESET_MASK;
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+		/* Enable thesuspend and disconnect.*/
+		intrreg =
+			udc->read_fn(udc->base_address + XUSB_IER_OFFSET);
+		intrreg |=
+			(XUSB_STATUS_SUSPEND_MASK |
+			 XUSB_STATUS_DISCONNECT_MASK);
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+	}
+
+	if (intrstatus & XUSB_STATUS_DISCONNECT_MASK) {
+
+		/* Disable the Disconnect interrupt.*/
+		intrreg =
+			udc->read_fn(udc->base_address + XUSB_IER_OFFSET);
+		intrreg &= ~XUSB_STATUS_DISCONNECT_MASK;
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+		dev_dbg(&udc->gadget.dev, "Disconnect\n");
+		if (udc->status == 1) {
+			udc->status = 0;
+			/* Set device address to 0.*/
+			udc->write_fn(0, (udc->base_address +
+					XUSB_ADDRESS_OFFSET));
+			/* Enable the USB device.*/
+			udc->write_fn(XUSB_CONTROL_USB_READY_MASK,
+				(udc->base_address + XUSB_CONTROL_OFFSET));
+		}
+
+		/* Enable the suspend and reset interrupts.*/
+		intrreg = (udc->read_fn(udc->base_address + XUSB_IER_OFFSET) |
+				(XUSB_STATUS_SUSPEND_MASK |
+				XUSB_STATUS_RESET_MASK));
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+		stop_activity(udc);
+	}
+
+	if (intrstatus & XUSB_STATUS_SUSPEND_MASK) {
+		dev_dbg(&udc->gadget.dev, "Suspend\n");
+		/* Disable the Suspend interrupt.*/
+		intrreg = (udc->read_fn(udc->base_address + XUSB_IER_OFFSET) &
+					~XUSB_STATUS_SUSPEND_MASK);
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+		/* Enable the Disconnect and reset interrupts. */
+		intrreg = (udc->read_fn(udc->base_address + XUSB_IER_OFFSET)|
+				(XUSB_STATUS_DISCONNECT_MASK |
+				XUSB_STATUS_RESET_MASK));
+		udc->write_fn(intrreg, (udc->base_address + XUSB_IER_OFFSET));
+	}
+}
+
+/**
+ * setclearfeature - Executes the set feature and clear feature commands.
+ * @udc: pointer to the usb device controller structure.
+ * @flag: Value deciding the set or clear action.
+ *
+ * Processes the SET_FEATURE and CLEAR_FEATURE commands.
+ */
+static void set_clear_feature(struct xusb_udc *udc, int flag)
+{
+	u8 endpoint;
+	u8 outinbit;
+	u32 epcfgreg;
+
+	switch (ch9_cmdbuf.setup.bRequestType) {
+	case STANDARD_OUT_DEVICE:
+		switch (ch9_cmdbuf.setup.wValue) {
+		case USB_DEVICE_REMOTE_WAKEUP:
+			/* User needs to add code here.*/
+			break;
+
+		case USB_DEVICE_TEST_MODE:
+			/*
+			 * The Test Mode will be executed
+			 * after the status phase.
+			 */
+			break;
+
+		default:
+			epcfgreg = udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset);
+			epcfgreg |= XUSB_EP_CFG_STALL_MASK;
+			udc->write_fn(epcfgreg, (udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+			break;
+		}
+		break;
+
+	case STANDARD_OUT_ENDPOINT:
+		if (!ch9_cmdbuf.setup.wValue) {
+			endpoint = ch9_cmdbuf.setup.wIndex & 0xf;
+			outinbit = ch9_cmdbuf.setup.wIndex & 0x80;
+			outinbit = outinbit >> 7;
+
+			/* Make sure direction matches.*/
+			if (outinbit != udc->ep[endpoint].is_in) {
+				epcfgreg = udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset);
+				epcfgreg |= XUSB_EP_CFG_STALL_MASK;
+
+				udc->write_fn(epcfgreg, (udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+				return;
+			}
+
+			if (!endpoint) {
+				/* Clear the stall.*/
+				epcfgreg = udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset);
+
+				epcfgreg &= ~XUSB_EP_CFG_STALL_MASK;
+
+				udc->write_fn(epcfgreg, (udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+				break;
+			} else {
+				if (flag == 1) {
+					epcfgreg =
+						udc->read_fn(udc->base_address +
+					udc->ep[XUSB_EP_NUMBER_ZERO].
+					endpointoffset);
+					epcfgreg |= XUSB_EP_CFG_STALL_MASK;
+
+					udc->write_fn(epcfgreg,
+						(udc->base_address +
+						udc->ep[XUSB_EP_NUMBER_ZERO].
+						endpointoffset));
+				} else {
+					/* Unstall the endpoint.*/
+					epcfgreg =
+						udc->read_fn(udc->base_address +
+					udc->ep[endpoint].endpointoffset);
+					epcfgreg &=
+						~(XUSB_EP_CFG_STALL_MASK |
+						  XUSB_EP_CFG_DATA_TOGGLE_MASK);
+					udc->write_fn(epcfgreg,
+						(udc->base_address +
+						udc->ep[endpoint].
+						endpointoffset));
+				}
+			}
+		}
+		break;
+
+	default:
+		epcfgreg = udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset);
+		epcfgreg |= XUSB_EP_CFG_STALL_MASK;
+		udc->write_fn(epcfgreg, (udc->base_address +
+			udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+		return;
+	}
+
+	/* Cause and valid status phase to be issued.*/
+	setup_ctrl_wr_status_stage(udc);
+
+	return;
+}
+
+/**
+ * execute_command - Processes the USB specification chapter 9 commands.
+ * @udc: pointer to the usb device controller structure.
+ *
+ * Returns: 0 for success and the same reuqest command if it is not handled.
+ */
+static int execute_command(struct xusb_udc *udc)
+{
+
+	if ((ch9_cmdbuf.setup.bRequestType & USB_TYPE_MASK) ==
+	    USB_TYPE_STANDARD) {
+		/* Process the chapter 9 command.*/
+		switch (ch9_cmdbuf.setup.bRequest) {
+
+		case USB_REQ_CLEAR_FEATURE:
+			set_clear_feature(udc, 0);
+			break;
+
+		case USB_REQ_SET_FEATURE:
+			set_clear_feature(udc, 1);
+			break;
+
+		case USB_REQ_SET_ADDRESS:
+			setup_ctrl_wr_status_stage(udc);
+			break;
+
+		case USB_REQ_SET_CONFIGURATION:
+			udc->status = 1;
+			return ch9_cmdbuf.setup.bRequest;
+
+		default:
+			/*
+			 * Return the same request to application for
+			 * handling.
+			 */
+			return ch9_cmdbuf.setup.bRequest;
+		}
+
+	} else
+		if ((ch9_cmdbuf.setup.bRequestType & USB_TYPE_MASK) ==
+					USB_TYPE_CLASS)
+			return ch9_cmdbuf.setup.bRequest;
+	return 0;
+}
+
+/**
+ * process_setup_pkt - Processes the setup packet.
+ * @udc: pointer to the usb device controller structure.
+ * @ctrl: pointer to the usb control endpoint structure.
+ *
+ * Returns: 0 for success and request to be handled by application if
+ *		is not handled by the driver.
+ */
+static int process_setup_pkt(struct xusb_udc *udc, struct usb_ctrlrequest *ctrl)
+{
+	u32 *ep0rambase;
+
+	/* Load up the chapter 9 command buffer.*/
+	ep0rambase = (u32 __force *) (udc->base_address +
+				  XUSB_SETUP_PKT_ADDR_OFFSET);
+	memcpy((void *)&ch9_cmdbuf.setup, (void *)ep0rambase, 8);
+
+	ctrl->bRequestType = ch9_cmdbuf.setup.bRequestType;
+	ctrl->bRequest     = ch9_cmdbuf.setup.bRequest;
+	ctrl->wValue       = ch9_cmdbuf.setup.wValue;
+	ctrl->wIndex       = ch9_cmdbuf.setup.wIndex;
+	ctrl->wLength      = ch9_cmdbuf.setup.wLength;
+
+	ch9_cmdbuf.setup.wValue = cpu_to_le16(ch9_cmdbuf.setup.wValue);
+	ch9_cmdbuf.setup.wIndex = cpu_to_le16(ch9_cmdbuf.setup.wIndex);
+	ch9_cmdbuf.setup.wLength = cpu_to_le16(ch9_cmdbuf.setup.wLength);
+
+	/* Restore ReadPtr to data buffer.*/
+	ch9_cmdbuf.contreadptr = &ch9_cmdbuf.contreaddatabuffer[0];
+	ch9_cmdbuf.contreadcount = 0;
+
+	if (ch9_cmdbuf.setup.bRequestType & USB_DIR_IN) {
+		/* Execute the get command.*/
+		ch9_cmdbuf.setupseqrx = STATUS_PHASE;
+		ch9_cmdbuf.setupseqtx = DATA_PHASE;
+		return execute_command(udc);
+	} else {
+		/* Execute the put command.*/
+		ch9_cmdbuf.setupseqrx = DATA_PHASE;
+		ch9_cmdbuf.setupseqtx = STATUS_PHASE;
+		return execute_command(udc);
+	}
+	/* Control should never come here.*/
+	return 0;
+}
+
+/**
+ * ep0_out_token - Processes the endpoint 0 OUT token.
+ * @udc: pointer to the usb device controller structure.
+ */
+static void ep0_out_token(struct xusb_udc *udc)
+{
+	struct xusb_ep *ep;
+	u8 count;
+	u8 *ep0rambase;
+	u16 index;
+
+	ep = &udc->ep[0];
+	switch (ch9_cmdbuf.setupseqrx) {
+	case STATUS_PHASE:
+		/*
+		 * This resets both state machines for the next
+		 * Setup packet.
+		 */
+		ch9_cmdbuf.setupseqrx = SETUP_PHASE;
+		ch9_cmdbuf.setupseqtx = SETUP_PHASE;
+		ep->data->usb_req.actual = ep->data->usb_req.length;
+		done(ep, ep->data, 0);
+		break;
+
+	case DATA_PHASE:
+		count = udc->read_fn(udc->base_address +
+				XUSB_EP_BUF0COUNT_OFFSET);
+		/* Copy the data to be received from the DPRAM. */
+		ep0rambase =
+			(u8 __force *) (udc->base_address +
+				(udc->ep[XUSB_EP_NUMBER_ZERO].rambase << 2));
+
+		for (index = 0; index < count; index++)
+			*ch9_cmdbuf.contreadptr++ = *ep0rambase++;
+
+		ch9_cmdbuf.contreadcount += count;
+		if (ch9_cmdbuf.setup.wLength == ch9_cmdbuf.contreadcount) {
+				setup_ctrl_wr_status_stage(udc);
+		} else {
+			/* Set the Tx packet size and the Tx enable bit.*/
+			udc->write_fn(0, (udc->base_address +
+				XUSB_EP_BUF0COUNT_OFFSET));
+			udc->write_fn(1, (udc->base_address +
+				XUSB_BUFFREADY_OFFSET));
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * ep0_in_token - Processes the endpoint 0 IN token.
+ * @udc: pointer to the usb device controller structure.
+ */
+static void ep0_in_token(struct xusb_udc *udc)
+{
+	struct xusb_ep *ep;
+	u32 epcfgreg;
+	u16 count;
+	u16 length;
+	u8 *ep0rambase;
+
+	ep = &udc->ep[0];
+	switch (ch9_cmdbuf.setupseqtx) {
+	case STATUS_PHASE:
+		if (ch9_cmdbuf.setup.bRequest == USB_REQ_SET_ADDRESS) {
+			/* Set the address of the device.*/
+			udc->write_fn(ch9_cmdbuf.setup.wValue,
+					(udc->base_address +
+					XUSB_ADDRESS_OFFSET));
+			break;
+		} else
+			if (ch9_cmdbuf.setup.bRequest == USB_REQ_SET_FEATURE) {
+				if (ch9_cmdbuf.setup.bRequestType ==
+					STANDARD_OUT_DEVICE) {
+					if (ch9_cmdbuf.setup.wValue ==
+						USB_DEVICE_TEST_MODE)
+						udc->write_fn(TEST_J,
+							(udc->base_address +
+							XUSB_TESTMODE_OFFSET));
+			}
+		}
+		ep->data->usb_req.actual = ch9_cmdbuf.setup.wLength;
+		done(ep, ep->data, 0);
+		break;
+
+	case DATA_PHASE:
+		if (!ch9_cmdbuf.contwritecount) {
+			/*
+			 * We're done with data transfer, next
+			 * will be zero length OUT with data toggle of
+			 * 1. Setup data_toggle.
+			 */
+			epcfgreg = udc->read_fn(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset);
+			epcfgreg |= XUSB_EP_CFG_DATA_TOGGLE_MASK;
+			udc->write_fn(epcfgreg,
+				(udc->base_address +
+				udc->ep[XUSB_EP_NUMBER_ZERO].endpointoffset));
+			count = 0;
+
+			ch9_cmdbuf.setupseqtx = STATUS_PHASE;
+
+		} else {
+			length = count = min_t(u32, ch9_cmdbuf.contwritecount,
+						EP0_MAX_PACKET);
+			/* Copy the data to be transmitted into the DPRAM. */
+			ep0rambase = (u8 __force *) (udc->base_address +
+				(udc->ep[XUSB_EP_NUMBER_ZERO].rambase << 2));
+			while (length--)
+				*ep0rambase++ = *ch9_cmdbuf.contwriteptr++;
+
+			ch9_cmdbuf.contwritecount -= count;
+		}
+		udc->write_fn(count, (udc->base_address +
+						XUSB_EP_BUF0COUNT_OFFSET));
+		udc->write_fn(1, (udc->base_address + XUSB_BUFFREADY_OFFSET));
+		break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * control_ep_intrhandler - Endpoint 0 interrupt handler.
+ * @callbackref: pointer to the call back reference passed by the
+ *			main interrupt handler.
+ * @intrstatus:	It's the mask value for the interrupt sources on endpoint 0.
+ *
+ * Processes the commands received during enumeration phase.
+ */
+static void control_ep_intrhandler(void *callbackref, u32 intrstatus)
+{
+	struct xusb_udc *udc;
+	struct usb_ctrlrequest ctrl;
+	int status;
+	int epnum;
+	u32 intrreg;
+
+	udc = (struct xusb_udc *) callbackref;
+
+	/* Process the end point zero buffer interrupt.*/
+	if (intrstatus & XUSB_STATUS_EP0_BUFF1_COMP_MASK) {
+		if (intrstatus & XUSB_STATUS_SETUP_PACKET_MASK) {
+			/*
+			 * Enable the Disconnect, suspend and reset
+			 * interrupts.
+			 */
+			intrreg = udc->read_fn(udc->base_address +
+					XUSB_IER_OFFSET);
+			intrreg |= (XUSB_STATUS_DISCONNECT_MASK |
+					 XUSB_STATUS_SUSPEND_MASK |
+					 XUSB_STATUS_RESET_MASK);
+			udc->write_fn(intrreg,
+				(udc->base_address + XUSB_IER_OFFSET));
+			status = process_setup_pkt(udc, &ctrl);
+			if (status || ((ch9_cmdbuf.setup.bRequestType &
+			USB_TYPE_MASK) == USB_TYPE_CLASS)) {
+				/*
+				 * Request is to be handled by the gadget
+				 * driver.
+				 */
+				spin_unlock(&udc->lock);
+				udc->driver->setup(&udc->gadget, &ctrl);
+				spin_lock(&udc->lock);
+			} else {
+				if (ctrl.bRequest == USB_REQ_CLEAR_FEATURE) {
+					epnum = ctrl.wIndex & 0xf;
+					udc->ep[epnum].stopped = 0;
+				}
+				if (ctrl.bRequest == USB_REQ_SET_FEATURE) {
+					epnum = ctrl.wIndex & 0xf;
+					udc->ep[epnum].stopped = 1;
+				}
+			}
+		} else
+			if (intrstatus & XUSB_STATUS_FIFO_BUFF_RDY_MASK)
+				ep0_out_token(udc);
+			else if (intrstatus &
+				XUSB_STATUS_FIFO_BUFF_FREE_MASK)
+				ep0_in_token(udc);
+	}
+}
+
+/**
+ * noncontrol_ep_intrhandler - Non control endpoint interrupt handler.
+ * @callbackref: pointer to the call back reference passed by the
+ *			main interrupt handler.
+ * @epnum: End point number for which the interrupt is to be processed
+ * @intrstatus:	It's the mask value for the interrupt sources on endpoint 0.
+ */
+static void noncontrol_ep_intrhandler(void *callbackref, u8 epnum,
+					u32 intrstatus)
+{
+
+	struct xusb_request *req;
+	struct xusb_udc *udc;
+	struct xusb_ep *ep;
+
+	udc = (struct xusb_udc *) callbackref;
+	ep = &udc->ep[epnum];
+
+	/* Process the End point interrupts.*/
+	if (intrstatus & (XUSB_STATUS_EP0_BUFF1_COMP_MASK << epnum))
+		ep->buffer0ready = 0;
+	if (intrstatus & (XUSB_STATUS_EP0_BUFF2_COMP_MASK << epnum))
+		ep->buffer1ready = 0;
+
+	if (list_empty(&ep->queue))
+		req = NULL;
+	else
+		req = list_entry(ep->queue.next, struct xusb_request, queue);
+	if (!req)
+		return;
+	if (ep->is_in)
+		(void)write_fifo(ep, req);
+	else
+		(void)read_fifo(ep, req);
+}
+
+/**
+ * xusb_udc_irq - The main interrupt handler.
+ * @irq: The interrupt number.
+ * @_udc: pointer to the usb device controller structure.
+ *
+ * Returns: IRQ_HANDLED after the interrupt is handled.
+ */
+static irqreturn_t xusb_udc_irq(int irq, void *_udc)
+{
+	struct xusb_udc *udc = _udc;
+	u32 intrstatus;
+	u8 index;
+	u32 bufintr;
+
+	spin_lock(&(udc->lock));
+
+	/* Read the Interrupt Status Register.*/
+	intrstatus = udc->read_fn(udc->base_address + XUSB_STATUS_OFFSET);
+	/* Call the handler for the event interrupt.*/
+	if (intrstatus & XUSB_STATUS_INTR_EVENT_MASK) {
+		/*
+		 * Check if there is any action to be done for :
+		 * - USB Reset received {XUSB_STATUS_RESET_MASK}
+		 * - USB Suspend received {XUSB_STATUS_SUSPEND_MASK}
+		 * - USB Disconnect received {XUSB_STATUS_DISCONNECT_MASK}
+		 */
+		startup_intrhandler(udc, intrstatus);
+	}
+
+	/* Check the buffer completion interrupts */
+	if (intrstatus & XUSB_STATUS_INTR_BUFF_COMP_ALL_MASK) {
+		if (intrstatus & XUSB_STATUS_EP0_BUFF1_COMP_MASK)
+			control_ep_intrhandler(udc, intrstatus);
+
+		for (index = 1; index < 8; index++) {
+			bufintr = ((intrstatus &
+					(XUSB_STATUS_EP1_BUFF1_COMP_MASK <<
+							(index - 1))) ||
+				   (intrstatus &
+					(XUSB_STATUS_EP1_BUFF2_COMP_MASK <<
+							(index - 1))));
+
+			if (bufintr)
+				noncontrol_ep_intrhandler(udc, index,
+						intrstatus);
+		}
+	}
+	spin_unlock(&(udc->lock));
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xudc_start - Starts the device.
+ * @gadget: pointer to the usb gadget structure
+ * @driver: pointer to gadget driver structure
+ *
+ * Returns: zero always
+ */
+static int xudc_start(struct usb_gadget *gadget,
+			struct usb_gadget_driver *driver)
+{
+	struct xusb_udc *udc = &controller;
+	const struct usb_endpoint_descriptor *d = &config_bulk_out_desc;
+
+	driver->driver.bus = NULL;
+	/* hook up the driver */
+	udc->driver = driver;
+	udc->gadget.dev.driver = &driver->driver;
+	udc->gadget.speed = driver->max_speed;
+
+	/* Enable the USB device.*/
+	xusb_ep_enable(&udc->ep[XUSB_EP_NUMBER_ZERO].ep_usb, d);
+	udc->write_fn(0, (udc->base_address + XUSB_ADDRESS_OFFSET));
+	udc->write_fn(XUSB_CONTROL_USB_READY_MASK,
+		(udc->base_address + XUSB_CONTROL_OFFSET));
+
+	return 0;
+}
+
+/**
+ * xudc_stop - stops the device.
+ * @gadget: pointer to the usb gadget structure
+ * @driver: pointer to usb gadget driver structure
+ *
+ * Returns: zero always
+ */
+static int xudc_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
+{
+	struct xusb_udc *udc = &controller;
+	unsigned long flags;
+	u32 crtlreg;
+
+	/* Disable USB device.*/
+	crtlreg = udc->read_fn(udc->base_address + XUSB_CONTROL_OFFSET);
+	crtlreg &= ~XUSB_CONTROL_USB_READY_MASK;
+	udc->write_fn(crtlreg, (udc->base_address + XUSB_CONTROL_OFFSET));
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	stop_activity(udc);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	udc->gadget.dev.driver = NULL;
+	udc->driver = NULL;
+
+	return 0;
+}
+
+/**
+ * xusb_release - Releases device structure
+ * @dev: pointer to device structure
+ */
+static void xusb_release(struct device *dev)
+{
+}
+
+/**
+ * xudc_probe - The device probe function for driver initialization.
+ * @pdev: pointer to the platform device structure.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xudc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	struct xusb_udc *udc = &controller;
+	int err;
+	int irq;
+	int ret;
+
+	dev_dbg(&pdev->dev, "%s(%p)\n", __func__, pdev);
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	udc->base_address = devm_ioremap_nocache(&pdev->dev, res->start,
+						 resource_size(res));
+	if (!udc->base_address)
+		return -ENOMEM;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "unable to get irq\n");
+		return irq;
+	}
+	err = devm_request_irq(&pdev->dev, irq, xusb_udc_irq,
+			       0, dev_name(&pdev->dev), udc);
+	if (err < 0) {
+		dev_err(&pdev->dev, "unable to request irq %d", irq);
+		return err;
+	}
+
+	udc->dma_enabled = of_property_read_bool(np, "xlnx,include-dma");
+
+	udc->gadget.dev.parent = &pdev->dev;
+
+	spin_lock_init(&udc->lock);
+
+	/* Check for IP endianness */
+	udc->write_fn(TEST_J, (udc->base_address + XUSB_TESTMODE_OFFSET));
+	if ((udc->read_fn(udc->base_address + XUSB_TESTMODE_OFFSET))
+			!= TEST_J) {
+		controller.write_fn = xusb_write32;
+		controller.read_fn = xusb_read32;
+	}
+	udc->write_fn(0, (udc->base_address + XUSB_TESTMODE_OFFSET));
+
+	xudc_reinit(udc);
+
+	/* Set device address to 0.*/
+	udc->write_fn(0, (udc->base_address + XUSB_ADDRESS_OFFSET));
+
+	ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
+	if (ret)
+		dev_dbg(&pdev->dev, "usb_add_gadget_udc returned %d\n", ret);
+
+	/* Enable the interrupts.*/
+	udc->write_fn((XUSB_STATUS_GLOBAL_INTR_MASK |
+		       XUSB_STATUS_RESET_MASK |
+		       XUSB_STATUS_DISCONNECT_MASK |
+		       XUSB_STATUS_SUSPEND_MASK |
+		       XUSB_STATUS_FIFO_BUFF_RDY_MASK |
+		       XUSB_STATUS_FIFO_BUFF_FREE_MASK |
+		       XUSB_STATUS_EP0_BUFF1_COMP_MASK),
+		      (udc->base_address + XUSB_IER_OFFSET));
+
+	platform_set_drvdata(pdev, udc);
+
+	dev_info(&pdev->dev, "%s version %s\n", driver_name, DRIVER_VERSION);
+	dev_info(&pdev->dev, "%s #%d at 0x%08X mapped to 0x%08X\n",
+		 driver_name, 0, (u32)res->start,
+		 (u32 __force)udc->base_address);
+
+	return 0;
+}
+
+/**
+ * xudc_remove - Releases the resources allocated during the initialization.
+ * @pdev: pointer to the platform device structure.
+ *
+ * Returns: 0 for success and error value on failure
+ */
+static int xudc_remove(struct platform_device *pdev)
+{
+	struct xusb_udc *udc = platform_get_drvdata(pdev);
+
+	dev_dbg(&pdev->dev, "remove\n");
+	usb_del_gadget_udc(&udc->gadget);
+	if (udc->driver)
+		return -EBUSY;
+
+	device_unregister(&udc->gadget.dev);
+
+	return 0;
+}
+
+/* Match table for of_platform binding */
+static const struct of_device_id usb_of_match[] = {
+	{ .compatible = "xlnx,xps-usb2-device-4.00.a", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, usb_of_match);
+
+static struct platform_driver xudc_driver = {
+	.driver = {
+		.name = driver_name,
+		.owner = THIS_MODULE,
+		.of_match_table = usb_of_match,
+	},
+	.probe = xudc_probe,
+	.remove = xudc_remove,
+};
+
+module_platform_driver(xudc_driver);
+
+MODULE_DESCRIPTION("Xilinx udc driver");
+MODULE_AUTHOR("Xilinx, Inc");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/usb/gadget/xilinx_usbps_udc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/gadget/xilinx_usbps_udc.c	2014-07-20 22:06:38.181275615 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB Device Controller Driver.
+ *
+ * Copyright (C) 2011 Xilinx, Inc.
+ *
+ * This file is based on fsl_udc_core.c file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * 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 bydrive
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#undef VERBOSE
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/xilinx_devices.h>
+#include <linux/dmapool.h>
+#include <linux/delay.h>
+
+#include <linux/io.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+#include <asm/dma.h>
+
+#include <linux/usb/xilinx_usbps_otg.h>
+
+#define	DRIVER_DESC	"Xilinx PS USB Device Controller driver"
+#define	DRIVER_AUTHOR	"Xilinx, Inc."
+#define	DRIVER_VERSION	"Apr 01, 2011"
+
+
+/* USB registers */
+#define USB_MAX_CTRL_PAYLOAD		64
+
+ /* USB DR device mode registers (Little Endian) */
+struct usb_dr_device {
+	/* Capability register */
+	u8 res1[256];
+	u16 caplength;		/* Capability Register Length */
+	u16 hciversion;		/* Host Controller Interface Version */
+	u32 hcsparams;		/* Host Controller Structual Parameters */
+	u32 hccparams;		/* Host Controller Capability Parameters */
+	u8 res2[20];
+	u32 dciversion;		/* Device Controller Interface Version */
+	u32 dccparams;		/* Device Controller Capability Parameters */
+	u8 res3[24];
+	/* Operation register */
+	u32 usbcmd;		/* USB Command Register */
+	u32 usbsts;		/* USB Status Register */
+	u32 usbintr;		/* USB Interrupt Enable Register */
+	u32 frindex;		/* Frame Index Register */
+	u8 res4[4];
+	u32 deviceaddr;		/* Device Address */
+	u32 endpointlistaddr;	/* Endpoint List Address Register */
+	u8 res5[4];
+	u32 burstsize;		/* Master Interface Data Burst Size Register */
+	u32 txttfilltuning;	/* Transmit FIFO Tuning Controls Register */
+	u8 res6[24];
+	u32 configflag;		/* Configure Flag Register */
+	u32 portsc1;		/* Port 1 Status and Control Register */
+	u8 res7[28];
+	u32 otgsc;		/* On-The-Go Status and Control */
+	u32 usbmode;		/* USB Mode Register */
+	u32 endptsetupstat;	/* Endpoint Setup Status Register */
+	u32 endpointprime;	/* Endpoint Initialization Register */
+	u32 endptflush;		/* Endpoint Flush Register */
+	u32 endptstatus;	/* Endpoint Status Register */
+	u32 endptcomplete;	/* Endpoint Complete Register */
+	u32 endptctrl[6];	/* Endpoint Control Registers */
+};
+
+/* ep0 transfer state */
+#define WAIT_FOR_SETUP          0
+#define DATA_STATE_XMIT         1
+#define WAIT_FOR_OUT_STATUS     3
+#define DATA_STATE_RECV         4
+
+/* Device Controller Capability Parameter register */
+#define DCCPARAMS_DC				0x00000080
+#define DCCPARAMS_DEN_MASK			0x0000001f
+
+/* Frame Index Register Bit Masks */
+#define	USB_FRINDEX_MASKS			0x3fff
+/* USB CMD  Register Bit Masks */
+#define  USB_CMD_RUN_STOP                     0x00000001
+#define  USB_CMD_CTRL_RESET                   0x00000002
+#define  USB_CMD_ASYNC_SCHEDULE_EN            0x00000020
+#define  USB_CMD_SUTW                         0x00002000
+#define  USB_CMD_ATDTW                        0x00004000
+
+/* USB STS Register Bit Masks */
+#define  USB_STS_INT                          0x00000001
+#define  USB_STS_ERR                          0x00000002
+#define  USB_STS_PORT_CHANGE                  0x00000004
+#define  USB_STS_SYS_ERR                      0x00000010
+#define  USB_STS_RESET                        0x00000040
+#define  USB_STS_SOF                          0x00000080
+#define  USB_STS_SUSPEND                      0x00000100
+
+/* USB INTR Register Bit Masks */
+#define  USB_INTR_INT_EN                      0x00000001
+#define  USB_INTR_ERR_INT_EN                  0x00000002
+#define  USB_INTR_PTC_DETECT_EN               0x00000004
+#define  USB_INTR_SYS_ERR_EN                  0x00000010
+#define  USB_INTR_RESET_EN                    0x00000040
+#define  USB_INTR_SOF_EN                      0x00000080
+#define  USB_INTR_DEVICE_SUSPEND              0x00000100
+
+/* Device Address bit masks */
+#define  USB_DEVICE_ADDRESS_MASK              0xFE000000
+#define  USB_DEVICE_ADDRESS_BIT_POS           25
+
+/* endpoint list address bit masks */
+#define USB_EP_LIST_ADDRESS_MASK              0xfffff800
+
+/* PORTSCX  Register Bit Masks */
+#define  PORTSCX_CURRENT_CONNECT_STATUS       0x00000001
+#define  PORTSCX_PORT_ENABLE                  0x00000004
+#define  PORTSCX_PORT_EN_DIS_CHANGE           0x00000008
+#define  PORTSCX_OVER_CURRENT_CHG             0x00000020
+#define  PORTSCX_PORT_FORCE_RESUME            0x00000040
+#define  PORTSCX_PORT_SUSPEND                 0x00000080
+#define  PORTSCX_PORT_RESET                   0x00000100
+#define  PORTSCX_PHY_LOW_POWER_SPD            0x00800000
+#define  PORTSCX_PORT_SPEED_MASK              0x0C000000
+#define  PORTSCX_PORT_WIDTH                   0x10000000
+#define  PORTSCX_PHY_TYPE_SEL                 0xC0000000
+
+/* bit 27-26 are port speed */
+#define  PORTSCX_PORT_SPEED_FULL              0x00000000
+#define  PORTSCX_PORT_SPEED_LOW               0x04000000
+#define  PORTSCX_PORT_SPEED_HIGH              0x08000000
+#define  PORTSCX_PORT_SPEED_UNDEF             0x0C000000
+
+/* bit 28 is parallel transceiver width for UTMI interface */
+#define  PORTSCX_PTW_16BIT                    0x10000000
+
+/* bit 31-30 are port transceiver select */
+#define  PORTSCX_PTS_UTMI                     0x00000000
+#define  PORTSCX_PTS_ULPI                     0x80000000
+#define  PORTSCX_PTS_FSLS                     0xC0000000
+
+/* otgsc Register Bit Masks */
+#define  OTGSC_CTRL_OTG_TERM                  0x00000008
+
+/* USB MODE Register Bit Masks */
+#define  USB_MODE_CTRL_MODE_IDLE              0x00000000
+#define  USB_MODE_CTRL_MODE_DEVICE            0x00000002
+#define  USB_MODE_CTRL_MODE_HOST              0x00000003
+#define  USB_MODE_SETUP_LOCK_OFF              0x00000008
+
+/* Endpoint Setup Status bit masks */
+#define  EP_SETUP_STATUS_MASK                 0x0000003F
+#define  EP_SETUP_STATUS_EP0		      0x00000001
+
+/* ENDPOINTCTRLx  Register Bit Masks */
+#define  EPCTRL_TX_ENABLE                     0x00800000
+#define  EPCTRL_TX_DATA_TOGGLE_RST            0x00400000	/* Not EP0 */
+#define  EPCTRL_TX_EP_STALL                   0x00010000
+#define  EPCTRL_RX_ENABLE                     0x00000080
+#define  EPCTRL_RX_DATA_TOGGLE_RST            0x00000040	/* Not EP0 */
+#define  EPCTRL_RX_EP_STALL                   0x00000001
+
+/* bit 19-18 and 3-2 are endpoint type */
+#define  EPCTRL_TX_EP_TYPE_SHIFT              18
+#define  EPCTRL_RX_EP_TYPE_SHIFT              2
+
+
+/* Endpoint Queue Head data struct
+ * Rem: all the variables of qh are LittleEndian Mode
+ * and NEXT_POINTER_MASK should operate on a LittleEndian, Phy Addr
+ */
+struct ep_queue_head {
+	u32 max_pkt_length;	/* Mult(31-30) , Zlt(29) , Max Pkt len
+				   and IOS(15) */
+	u32 curr_dtd_ptr;	/* Current dTD Pointer(31-5) */
+	u32 next_dtd_ptr;	/* Next dTD Pointer(31-5), T(0) */
+	u32 size_ioc_int_sts;	/* Total bytes (30-16), IOC (15),
+				   MultO(11-10), STS (7-0)  */
+	u32 buff_ptr0;		/* Buffer pointer Page 0 (31-12) */
+	u32 buff_ptr1;		/* Buffer pointer Page 1 (31-12) */
+	u32 buff_ptr2;		/* Buffer pointer Page 2 (31-12) */
+	u32 buff_ptr3;		/* Buffer pointer Page 3 (31-12) */
+	u32 buff_ptr4;		/* Buffer pointer Page 4 (31-12) */
+	u32 res1;
+	u8 setup_buffer[8];	/* Setup data 8 bytes */
+	u32 res2[4];
+};
+
+/* Endpoint Queue Head Bit Masks */
+#define  EP_QUEUE_HEAD_MULT_POS               30
+#define  EP_QUEUE_HEAD_ZLT_SEL                0x20000000
+#define  EP_QUEUE_HEAD_MAX_PKT_LEN_POS        16
+#define  EP_QUEUE_HEAD_IOS                    0x00008000
+#define  EP_QUEUE_HEAD_STATUS_HALT	      0x00000040
+#define  EP_QUEUE_HEAD_STATUS_ACTIVE          0x00000080
+#define  EP_QUEUE_HEAD_NEXT_POINTER_MASK      0xFFFFFFE0
+#define  EP_MAX_LENGTH_TRANSFER               0x4000
+
+/* Endpoint Transfer Descriptor data struct */
+/* Rem: all the variables of td are LittleEndian Mode */
+struct ep_td_struct {
+	u32 next_td_ptr;	/* Next TD pointer(31-5), T(0) set
+				   indicate invalid */
+	u32 size_ioc_sts;	/* Total bytes (30-16), IOC (15),
+				   MultO(11-10), STS (7-0)  */
+	u32 buff_ptr0;		/* Buffer pointer Page 0 */
+	u32 buff_ptr1;		/* Buffer pointer Page 1 */
+	u32 buff_ptr2;		/* Buffer pointer Page 2 */
+	u32 buff_ptr3;		/* Buffer pointer Page 3 */
+	u32 buff_ptr4;		/* Buffer pointer Page 4 */
+	u32 res;
+	/* 32 bytes */
+	dma_addr_t td_dma;	/* dma address for this td */
+	/* virtual address of next td specified in next_td_ptr */
+	struct ep_td_struct *next_td_virt;
+};
+
+/* Endpoint Transfer Descriptor bit Masks */
+#define  DTD_NEXT_TERMINATE                   0x00000001
+#define  DTD_IOC                              0x00008000
+#define  DTD_STATUS_ACTIVE                    0x00000080
+#define  DTD_STATUS_HALTED                    0x00000040
+#define  DTD_STATUS_DATA_BUFF_ERR             0x00000020
+#define  DTD_STATUS_TRANSACTION_ERR           0x00000008
+#define  DTD_RESERVED_FIELDS                  0x80007300
+#define  DTD_ADDR_MASK                        0xFFFFFFE0
+#define  DTD_PACKET_SIZE                      0x7FFF0000
+#define  DTD_LENGTH_BIT_POS                   16
+#define  DTD_ERROR_MASK                       (DTD_STATUS_HALTED | \
+					DTD_STATUS_DATA_BUFF_ERR | \
+					DTD_STATUS_TRANSACTION_ERR)
+/* Alignment requirements; must be a power of two */
+#define DTD_ALIGNMENT				0x20
+#define QH_ALIGNMENT				2048
+
+/* Controller dma boundary */
+#define UDC_DMA_BOUNDARY			0x1000
+
+/*-------------------------------------------------------------------------*/
+
+/* ### driver private data
+ */
+struct xusbps_req {
+	struct usb_request req;
+	struct list_head queue;
+	/* ep_queue() func will add
+	   a request->queue into a udc_ep->queue 'd tail */
+	struct xusbps_ep *ep;
+	unsigned mapped:1;
+
+	struct ep_td_struct *head, *tail;	/* For dTD List
+						   cpu endian Virtual addr */
+	unsigned int dtd_count;
+};
+
+#define REQ_UNCOMPLETE			1
+
+struct xusbps_ep {
+	struct usb_ep ep;
+	struct list_head queue;
+	struct xusbps_udc *udc;
+	struct ep_queue_head *qh;
+	struct usb_gadget *gadget;
+
+	char name[14];
+	unsigned stopped:1;
+	unsigned int wedge;
+};
+
+#define EP_DIR_IN	1
+#define EP_DIR_OUT	0
+
+struct xusbps_udc {
+	struct usb_gadget gadget;
+	struct usb_gadget_driver *driver;
+	struct completion *done;	/* to make sure release() is done */
+	struct xusbps_ep *eps;
+	unsigned int max_ep;
+	unsigned int irq;
+
+	/* xusbps otg transceiver */
+	struct xusbps_otg	*xotg;
+
+	struct usb_ctrlrequest local_setup_buff;
+	spinlock_t lock;
+	struct usb_phy *transceiver;
+	unsigned softconnect:1;
+	unsigned vbus_active:1;
+	unsigned stopped:1;
+	unsigned remote_wakeup:1;
+
+	struct ep_queue_head *ep_qh;	/* Endpoints Queue-Head */
+	struct xusbps_req *status_req;	/* ep0 status request */
+	struct dma_pool *td_pool;	/* dma pool for DTD */
+	enum xusbps_usb2_phy_modes phy_mode;
+
+	size_t ep_qh_size;		/* size after alignment adjustment*/
+	dma_addr_t ep_qh_dma;		/* dma address of QH */
+
+	u32 max_pipes;          /* Device max pipes */
+	u32 resume_state;	/* USB state to resume */
+	u32 usb_state;		/* USB current state */
+	u32 ep0_state;		/* Endpoint zero state */
+	u32 ep0_dir;		/* Endpoint zero direction: can be
+				   USB_DIR_IN or USB_DIR_OUT */
+	u8 device_address;	/* Device USB address */
+};
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+#define DBG(fmt, args...)	pr_debug("[%s]  " fmt "\n", \
+				__func__, ## args)
+#else
+#define DBG(fmt, args...)	do {} while (0)
+#endif
+
+
+#ifdef VERBOSE
+#define VDBG		DBG
+#else
+#define VDBG(stuff...)	do {} while (0)
+#endif
+
+#define ERR(stuff...)		pr_err("udc: " stuff)
+#define WARNING(stuff...)		pr_warn("udc: " stuff)
+#define INFO(stuff...)		pr_info("udc: " stuff)
+
+/*-------------------------------------------------------------------------*/
+
+/* ### Add board specific defines here */
+
+/* pipe direction macro from device view */
+#define USB_RECV	0	/* OUT EP */
+#define USB_SEND	1	/* IN EP */
+
+/* internal used help routines. */
+#define ep_index(EP)		((EP)->ep.desc->bEndpointAddress&0xF)
+#define ep_maxpacket(EP)	((EP)->ep.maxpacket)
+#define ep_is_in(EP)	((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \
+			USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \
+			& USB_DIR_IN) == USB_DIR_IN)
+#define get_ep_by_pipe(udc, pipe)	((pipe == 1) ? &udc->eps[0] : \
+					&udc->eps[pipe])
+#define get_pipe_by_windex(windex)	((windex & USB_ENDPOINT_NUMBER_MASK) \
+					* 2 + ((windex & USB_DIR_IN) ? 1 : 0))
+
+
+static int xusbps_udc_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers.
+		 */
+		/* fall through */
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static int xusbps_udc_clk_init(struct platform_device *pdev)
+{
+	struct xusbps_usb2_platform_data *pdata = pdev->dev.platform_data;
+	int rc;
+
+	rc = clk_prepare_enable(pdata->clk);
+	if (rc) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto err_out_clk_put;
+	}
+
+	pdata->clk_rate_change_nb.notifier_call = xusbps_udc_clk_notifier_cb;
+	pdata->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(pdata->clk, &pdata->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+	return 0;
+
+err_out_clk_put:
+	clk_put(pdata->clk);
+
+	return rc;
+}
+
+static void xusbps_udc_clk_release(struct platform_device *pdev)
+{
+	struct xusbps_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+	clk_disable_unprepare(pdata->clk);
+}
+
+
+#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
+
+static const char driver_name[] = "xusbps-udc";
+static const char driver_desc[] = DRIVER_DESC;
+
+static struct usb_dr_device __iomem *dr_regs;
+
+/* it is initialized in probe()  */
+static struct xusbps_udc *udc_controller;
+
+static const struct usb_endpoint_descriptor
+xusbps_ep0_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	0,
+	.bmAttributes =		USB_ENDPOINT_XFER_CONTROL,
+	.wMaxPacketSize =	USB_MAX_CTRL_PAYLOAD,
+};
+
+static void xusbps_ep_fifo_flush(struct usb_ep *_ep);
+
+static inline u32 xusbps_readl(const unsigned __iomem *addr)
+{
+	return readl(addr);
+}
+
+static inline void xusbps_writel(u32 val32, unsigned __iomem *addr)
+{
+	writel(val32, addr);
+}
+
+/********************************************************************
+ *	Internal Used Function
+********************************************************************/
+/*-----------------------------------------------------------------
+ * done() - retire a request; caller blocked irqs
+ * @status : request status to be set, only works when
+ *	request is still in progress.
+ *--------------------------------------------------------------*/
+static void done(struct xusbps_ep *ep, struct xusbps_req *req, int status)
+{
+	struct xusbps_udc *udc = NULL;
+	unsigned char stopped = ep->stopped;
+	struct ep_td_struct *curr_td, *next_td;
+	int j;
+
+	udc = (struct xusbps_udc *)ep->udc;
+	/* Removed the req from xusbps_ep->queue */
+	list_del_init(&req->queue);
+
+	/* req.status should be set as -EINPROGRESS in ep_queue() */
+	if (req->req.status == -EINPROGRESS)
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	/* Free dtd for the request */
+	next_td = req->head;
+	for (j = 0; j < req->dtd_count; j++) {
+		curr_td = next_td;
+		if (j != req->dtd_count - 1)
+			next_td = curr_td->next_td_virt;
+		dma_pool_free(udc->td_pool, curr_td, curr_td->td_dma);
+	}
+
+	if (req->mapped) {
+		dma_unmap_single(ep->udc->gadget.dev.parent,
+			req->req.dma, req->req.length,
+			ep_is_in(ep)
+				? DMA_TO_DEVICE
+				: DMA_FROM_DEVICE);
+		req->req.dma = DMA_ADDR_INVALID;
+		req->mapped = 0;
+	} else
+		dma_sync_single_for_cpu(ep->udc->gadget.dev.parent,
+			req->req.dma, req->req.length,
+			ep_is_in(ep)
+				? DMA_TO_DEVICE
+				: DMA_FROM_DEVICE);
+
+	if (status && (status != -ESHUTDOWN))
+		VDBG("complete %s req %p stat %d len %u/%u",
+			ep->ep.name, &req->req, status,
+			req->req.actual, req->req.length);
+
+	ep->stopped = 1;
+
+	spin_unlock(&ep->udc->lock);
+	/* complete() is from gadget layer,
+	 * eg fsg->bulk_in_complete() */
+	if (req->req.complete)
+		req->req.complete(&ep->ep, &req->req);
+
+	spin_lock(&ep->udc->lock);
+	ep->stopped = stopped;
+}
+
+/*-----------------------------------------------------------------
+ * nuke(): delete all requests related to this ep
+ * called with spinlock held
+ *--------------------------------------------------------------*/
+static void nuke(struct xusbps_ep *ep, int status)
+{
+	ep->stopped = 1;
+
+	/* Flush fifo */
+	xusbps_ep_fifo_flush(&ep->ep);
+
+	/* Whether this eq has request linked */
+	while (!list_empty(&ep->queue)) {
+		struct xusbps_req *req = NULL;
+
+		req = list_entry(ep->queue.next, struct xusbps_req, queue);
+		done(ep, req, status);
+	}
+}
+
+/*------------------------------------------------------------------
+	Internal Hardware related function
+ ------------------------------------------------------------------*/
+
+static int dr_controller_setup(struct xusbps_udc *udc)
+{
+	unsigned int tmp, portctrl;
+	unsigned long timeout;
+#define XUSBPS_UDC_RESET_TIMEOUT 1000
+
+	/* Config PHY interface */
+	portctrl = xusbps_readl(&dr_regs->portsc1);
+	portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
+	switch (udc->phy_mode) {
+	case XUSBPS_USB2_PHY_ULPI:
+		portctrl |= PORTSCX_PTS_ULPI;
+		break;
+	case XUSBPS_USB2_PHY_UTMI_WIDE:
+		portctrl |= PORTSCX_PTW_16BIT;
+		/* fall through */
+	case XUSBPS_USB2_PHY_UTMI:
+		portctrl |= PORTSCX_PTS_UTMI;
+		break;
+	case XUSBPS_USB2_PHY_SERIAL:
+		portctrl |= PORTSCX_PTS_FSLS;
+		break;
+	default:
+		return -EINVAL;
+	}
+	xusbps_writel(portctrl, &dr_regs->portsc1);
+
+	/* Stop and reset the usb controller */
+	tmp = xusbps_readl(&dr_regs->usbcmd);
+	tmp &= ~USB_CMD_RUN_STOP;
+	xusbps_writel(tmp, &dr_regs->usbcmd);
+
+	tmp = xusbps_readl(&dr_regs->usbcmd);
+	tmp |= USB_CMD_CTRL_RESET;
+	xusbps_writel(tmp, &dr_regs->usbcmd);
+
+	/* Wait for reset to complete */
+	timeout = jiffies + XUSBPS_UDC_RESET_TIMEOUT;
+	while (xusbps_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
+		if (time_after(jiffies, timeout)) {
+			ERR("udc reset timeout!\n");
+			return -ETIMEDOUT;
+		}
+		cpu_relax();
+	}
+
+	/* Set the controller as device mode */
+	tmp = xusbps_readl(&dr_regs->usbmode);
+	tmp |= USB_MODE_CTRL_MODE_DEVICE;
+	/* Disable Setup Lockout */
+	tmp |= USB_MODE_SETUP_LOCK_OFF;
+	xusbps_writel(tmp, &dr_regs->usbmode);
+
+	/* Set OTG Terminate bit */
+	tmp = xusbps_readl(&dr_regs->otgsc);
+	tmp |= OTGSC_CTRL_OTG_TERM;
+	xusbps_writel(tmp, &dr_regs->otgsc);
+
+	/* Clear the setup status */
+	xusbps_writel(0, &dr_regs->usbsts);
+
+	tmp = udc->ep_qh_dma;
+	tmp &= USB_EP_LIST_ADDRESS_MASK;
+	xusbps_writel(tmp, &dr_regs->endpointlistaddr);
+
+	VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x",
+		udc->ep_qh, (int)tmp,
+		xusbps_readl(&dr_regs->endpointlistaddr));
+
+	return 0;
+}
+
+/* Enable DR irq and set controller to run state */
+static void dr_controller_run(struct xusbps_udc *udc)
+{
+	u32 temp;
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (gadget_is_otg(&udc->gadget)) {
+		/* Enable DR irq reg except suspend interrupt */
+		temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN
+			| USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN
+			| USB_INTR_SYS_ERR_EN;
+	} else {
+		/* Enable DR irq reg */
+		temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN
+			| USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN
+			| USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN;
+	}
+#else
+	/* Enable DR irq reg */
+	temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN
+		| USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN
+		| USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN;
+#endif
+
+	xusbps_writel(temp, &dr_regs->usbintr);
+
+	/*
+	 * Enable disconnect notification using B session end interrupt.
+	 * This is a SW workaround for USB disconnect detection as mentioned
+	 * in AR# 47538
+	 */
+	if (!gadget_is_otg(&udc->gadget)) {
+		temp = xusbps_readl(&dr_regs->otgsc);
+		temp |= OTGSC_BSEIE;
+		xusbps_writel(temp, &dr_regs->otgsc);
+	}
+
+	/* Clear stopped bit */
+	udc->stopped = 0;
+
+	/* Set the controller as device mode */
+	temp = xusbps_readl(&dr_regs->usbmode);
+	temp |= USB_MODE_CTRL_MODE_DEVICE;
+	temp |= USB_MODE_SETUP_LOCK_OFF;
+	xusbps_writel(temp, &dr_regs->usbmode);
+
+	/* Set OTG Terminate bit */
+	temp = xusbps_readl(&dr_regs->otgsc);
+	temp |= OTGSC_CTRL_OTG_TERM;
+	xusbps_writel(temp, &dr_regs->otgsc);
+
+	/* Set controller to Run */
+	temp = xusbps_readl(&dr_regs->usbcmd);
+	temp |= USB_CMD_RUN_STOP;
+	xusbps_writel(temp, &dr_regs->usbcmd);
+}
+
+static void dr_controller_stop(struct xusbps_udc *udc)
+{
+	unsigned int tmp;
+
+	/* disable all INTR */
+	xusbps_writel(0, &dr_regs->usbintr);
+
+	/* Set stopped bit for isr */
+	udc->stopped = 1;
+
+	/* disable IO output */
+/*	usb_sys_regs->control = 0; */
+
+	/* set controller to Stop */
+	tmp = xusbps_readl(&dr_regs->usbcmd);
+	tmp &= ~USB_CMD_RUN_STOP;
+	xusbps_writel(tmp, &dr_regs->usbcmd);
+}
+
+static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
+			unsigned char ep_type)
+{
+	unsigned int tmp_epctrl = 0;
+
+	tmp_epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+	if (dir) {
+		if (ep_num)
+			tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST;
+		tmp_epctrl |= EPCTRL_TX_ENABLE;
+		tmp_epctrl |= ((unsigned int)(ep_type)
+				<< EPCTRL_TX_EP_TYPE_SHIFT);
+	} else {
+		if (ep_num)
+			tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST;
+		tmp_epctrl |= EPCTRL_RX_ENABLE;
+		tmp_epctrl |= ((unsigned int)(ep_type)
+				<< EPCTRL_RX_EP_TYPE_SHIFT);
+	}
+
+	xusbps_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]);
+}
+
+static void
+dr_ep_change_stall(unsigned char ep_num, unsigned char dir, int value)
+{
+	u32 tmp_epctrl = 0;
+
+	tmp_epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+
+	if (value) {
+		/* set the stall bit */
+		if (dir)
+			tmp_epctrl |= EPCTRL_TX_EP_STALL;
+		else
+			tmp_epctrl |= EPCTRL_RX_EP_STALL;
+	} else {
+		/* clear the stall bit and reset data toggle */
+		if (dir) {
+			tmp_epctrl &= ~EPCTRL_TX_EP_STALL;
+			tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST;
+		} else {
+			tmp_epctrl &= ~EPCTRL_RX_EP_STALL;
+			tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST;
+		}
+	}
+	xusbps_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]);
+}
+
+/* Get stall status of a specific ep
+   Return: 0: not stalled; 1:stalled */
+static int dr_ep_get_stall(unsigned char ep_num, unsigned char dir)
+{
+	u32 epctrl;
+
+	epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+	if (dir)
+		return (epctrl & EPCTRL_TX_EP_STALL) ? 1 : 0;
+	else
+		return (epctrl & EPCTRL_RX_EP_STALL) ? 1 : 0;
+}
+
+/********************************************************************
+	Internal Structure Build up functions
+********************************************************************/
+
+/*------------------------------------------------------------------
+* struct_ep_qh_setup(): set the Endpoint Capabilites field of QH
+ * @zlt: Zero Length Termination Select (1: disable; 0: enable)
+ * @mult: Mult field
+ ------------------------------------------------------------------*/
+static void struct_ep_qh_setup(struct xusbps_udc *udc, unsigned char ep_num,
+		unsigned char dir, unsigned char ep_type,
+		unsigned int max_pkt_len,
+		unsigned int zlt, unsigned char mult)
+{
+	struct ep_queue_head *p_QH = &udc->ep_qh[2 * ep_num + dir];
+	unsigned int tmp = 0;
+
+	/* set the Endpoint Capabilites in QH */
+	switch (ep_type) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		/* Interrupt On Setup (IOS). for control ep  */
+		tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS)
+			| EP_QUEUE_HEAD_IOS;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS)
+			| (mult << EP_QUEUE_HEAD_MULT_POS);
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+	case USB_ENDPOINT_XFER_INT:
+		tmp = max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS;
+		break;
+	default:
+		VDBG("error ep type is %d", ep_type);
+		return;
+	}
+	if (zlt)
+		tmp |= EP_QUEUE_HEAD_ZLT_SEL;
+
+	p_QH->max_pkt_length = cpu_to_le32(tmp);
+	p_QH->next_dtd_ptr = 1;
+	p_QH->size_ioc_int_sts = 0;
+}
+
+/* Setup qh structure and ep register for ep0. */
+static void ep0_setup(struct xusbps_udc *udc)
+{
+	/* the intialization of an ep includes: fields in QH, Regs,
+	 * xusbps_ep struct */
+	struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL,
+			USB_MAX_CTRL_PAYLOAD, 1, 0);
+	struct_ep_qh_setup(udc, 0, USB_SEND, USB_ENDPOINT_XFER_CONTROL,
+			USB_MAX_CTRL_PAYLOAD, 1, 0);
+	dr_ep_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL);
+	dr_ep_setup(0, USB_SEND, USB_ENDPOINT_XFER_CONTROL);
+
+	return;
+
+}
+
+/***********************************************************************
+		Endpoint Management Functions
+***********************************************************************/
+
+/*-------------------------------------------------------------------------
+ * when configurations are set, or when interface settings change
+ * for example the do_set_interface() in gadget layer,
+ * the driver will enable or disable the relevant endpoints
+ * ep0 doesn't use this routine. It is always enabled.
+-------------------------------------------------------------------------*/
+static int xusbps_ep_enable(struct usb_ep *_ep,
+		const struct usb_endpoint_descriptor *desc)
+{
+	struct xusbps_udc *udc = NULL;
+	struct xusbps_ep *ep = NULL;
+	unsigned short max = 0;
+	unsigned char mult = 0, zlt;
+	int retval = -EINVAL;
+	unsigned long flags = 0;
+
+	ep = container_of(_ep, struct xusbps_ep, ep);
+
+	/* catch various bogus parameters */
+	if (!_ep || !desc
+			|| (desc->bDescriptorType != USB_DT_ENDPOINT))
+		return -EINVAL;
+
+	udc = ep->udc;
+
+	if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN))
+		return -ESHUTDOWN;
+
+	max = usb_endpoint_maxp(desc);
+
+	/* Disable automatic zlp generation.  Driver is reponsible to indicate
+	 * explicitly through req->req.zero.  This is needed to enable multi-td
+	 * request. */
+	zlt = 1;
+
+	/* Assume the max packet size from gadget is always correct */
+	switch (desc->bmAttributes & 0x03) {
+	case USB_ENDPOINT_XFER_CONTROL:
+	case USB_ENDPOINT_XFER_BULK:
+	case USB_ENDPOINT_XFER_INT:
+		/* mult = 0.  Execute N Transactions as demonstrated by
+		 * the USB variable length packet protocol where N is
+		 * computed using the Maximum Packet Length (dQH) and
+		 * the Total Bytes field (dTD) */
+		mult = 0;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		/* Calculate transactions needed for high bandwidth iso */
+		mult = (unsigned char)(1 + ((max >> 11) & 0x03));
+		max = max & 0x7ff;	/* bit 0~10 */
+		/* 3 transactions at most */
+		if (mult > 3)
+			goto en_done;
+		break;
+	default:
+		goto en_done;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	ep->ep.maxpacket = max;
+	ep->ep.desc = desc;
+	ep->stopped = 0;
+	ep->wedge = 0;
+
+	/* Controller related setup */
+	/* Init EPx Queue Head (Ep Capabilites field in QH
+	 * according to max, zlt, mult) */
+	struct_ep_qh_setup(udc, (unsigned char) ep_index(ep),
+			(unsigned char) ((desc->bEndpointAddress & USB_DIR_IN)
+					?  USB_SEND : USB_RECV),
+			(unsigned char) (desc->bmAttributes
+					& USB_ENDPOINT_XFERTYPE_MASK),
+			max, zlt, mult);
+
+	/* Init endpoint ctrl register */
+	dr_ep_setup((unsigned char) ep_index(ep),
+			(unsigned char) ((desc->bEndpointAddress & USB_DIR_IN)
+					? USB_SEND : USB_RECV),
+			(unsigned char) (desc->bmAttributes
+					& USB_ENDPOINT_XFERTYPE_MASK));
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+	retval = 0;
+
+	VDBG("enabled %s (ep%d%s) maxpacket %d", ep->ep.name,
+			ep->ep.desc->bEndpointAddress & 0x0f,
+			(desc->bEndpointAddress & USB_DIR_IN)
+				? "in" : "out", max);
+en_done:
+	return retval;
+}
+
+/*---------------------------------------------------------------------
+ * @ep : the ep being unconfigured. May not be ep0
+ * Any pending and uncomplete req will complete with status (-ESHUTDOWN)
+*---------------------------------------------------------------------*/
+static int xusbps_ep_disable(struct usb_ep *_ep)
+{
+	struct xusbps_udc *udc = NULL;
+	struct xusbps_ep *ep = NULL;
+	unsigned long flags = 0;
+	u32 epctrl;
+	int ep_num;
+
+	ep = container_of(_ep, struct xusbps_ep, ep);
+	if (!_ep || !ep->ep.desc) {
+		VDBG("%s not enabled", _ep ? ep->ep.name : NULL);
+		return -EINVAL;
+	}
+
+	/* disable ep on controller */
+	ep_num = ep_index(ep);
+	epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+	if (ep_is_in(ep))
+		epctrl &= ~EPCTRL_TX_ENABLE;
+	else
+		epctrl &= ~EPCTRL_RX_ENABLE;
+	xusbps_writel(epctrl, &dr_regs->endptctrl[ep_num]);
+
+	udc = (struct xusbps_udc *)ep->udc;
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* nuke all pending requests (does flush) */
+	nuke(ep, -ESHUTDOWN);
+
+	ep->ep.desc = NULL;
+	ep->stopped = 1;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	VDBG("disabled %s OK", _ep->name);
+	return 0;
+}
+
+/*---------------------------------------------------------------------
+ * allocate a request object used by this endpoint
+ * the main operation is to insert the req->queue to the eq->queue
+ * Returns the request, or null if one could not be allocated
+*---------------------------------------------------------------------*/
+static struct usb_request *
+xusbps_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+{
+	struct xusbps_req *req = NULL;
+
+	req = kzalloc(sizeof *req, gfp_flags);
+	if (!req)
+		return NULL;
+
+	req->req.dma = DMA_ADDR_INVALID;
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void xusbps_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct xusbps_req *req = NULL;
+
+	req = container_of(_req, struct xusbps_req, req);
+
+	if (_req)
+		kfree(req);
+}
+
+/*-------------------------------------------------------------------------*/
+static void xusbps_queue_td(struct xusbps_ep *ep, struct xusbps_req *req)
+{
+	int i = ep_index(ep) * 2 + ep_is_in(ep);
+	u32 temp, bitmask, tmp_stat;
+	struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
+
+	/* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
+	VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
+
+	bitmask = ep_is_in(ep)
+		? (1 << (ep_index(ep) + 16))
+		: (1 << (ep_index(ep)));
+
+	/* check if the pipe is empty */
+	if (!(list_empty(&ep->queue))) {
+		/* Add td to the end */
+		struct xusbps_req *lastreq;
+		lastreq = list_entry(ep->queue.prev, struct xusbps_req, queue);
+		lastreq->tail->next_td_ptr =
+			cpu_to_le32(req->head->td_dma & DTD_ADDR_MASK);
+		wmb();
+		/* Read prime bit, if 1 goto done */
+		if (xusbps_readl(&dr_regs->endpointprime) & bitmask)
+			goto out;
+
+		do {
+			/* Set ATDTW bit in USBCMD */
+			temp = xusbps_readl(&dr_regs->usbcmd);
+			xusbps_writel(temp | USB_CMD_ATDTW, &dr_regs->usbcmd);
+
+			/* Read correct status bit */
+			tmp_stat = xusbps_readl(&dr_regs->endptstatus) &
+				bitmask;
+
+#ifdef CONFIG_XUSBPS_ERRATA_DT654401
+			/* Workaround for USB errata DT# 654401 */
+			temp = xusbps_readl(&dr_regs->usbcmd);
+			if (temp & USB_CMD_ATDTW) {
+				udelay(5);
+				if (xusbps_readl(&dr_regs->usbcmd) & USB_CMD_ATDTW)
+					break;
+			}
+		} while (1);
+#else
+		} while (!(xusbps_readl(&dr_regs->usbcmd) & USB_CMD_ATDTW));
+#endif
+
+		/* Write ATDTW bit to 0 */
+		temp = xusbps_readl(&dr_regs->usbcmd);
+		xusbps_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
+
+		if (tmp_stat)
+			goto out;
+	}
+
+	/* Write dQH next pointer and terminate bit to 0 */
+	temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
+	dQH->next_dtd_ptr = cpu_to_le32(temp);
+
+	/* Clear active and halt bit */
+	temp = cpu_to_le32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
+			| EP_QUEUE_HEAD_STATUS_HALT));
+	dQH->size_ioc_int_sts &= temp;
+
+	/* Ensure that updates to the QH will occure before priming. */
+	wmb();
+
+	/* Prime endpoint by writing 1 to ENDPTPRIME */
+	temp = ep_is_in(ep)
+		? (1 << (ep_index(ep) + 16))
+		: (1 << (ep_index(ep)));
+	xusbps_writel(temp, &dr_regs->endpointprime);
+out:
+	return;
+}
+
+/* Fill in the dTD structure
+ * @req: request that the transfer belongs to
+ * @length: return actually data length of the dTD
+ * @dma: return dma address of the dTD
+ * @is_last: return flag if it is the last dTD of the request
+ * return: pointer to the built dTD */
+static struct ep_td_struct *xusbps_build_dtd(struct xusbps_req *req, unsigned
+		*length, dma_addr_t *dma, int *is_last)
+{
+	u32 swap_temp;
+	struct ep_td_struct *dtd;
+
+	/* how big will this transfer be? */
+	*length = min(req->req.length - req->req.actual,
+			(unsigned)EP_MAX_LENGTH_TRANSFER);
+
+	dtd = dma_pool_alloc(udc_controller->td_pool, GFP_ATOMIC, dma);
+	if (dtd == NULL)
+		return dtd;
+
+	dtd->td_dma = *dma;
+	/* Clear reserved field */
+	swap_temp = cpu_to_le32(dtd->size_ioc_sts);
+	swap_temp &= ~DTD_RESERVED_FIELDS;
+	dtd->size_ioc_sts = cpu_to_le32(swap_temp);
+
+	/* Init all of buffer page pointers */
+	swap_temp = (u32) (req->req.dma + req->req.actual);
+	dtd->buff_ptr0 = cpu_to_le32(swap_temp);
+	dtd->buff_ptr1 = cpu_to_le32(swap_temp + 0x1000);
+	dtd->buff_ptr2 = cpu_to_le32(swap_temp + 0x2000);
+	dtd->buff_ptr3 = cpu_to_le32(swap_temp + 0x3000);
+	dtd->buff_ptr4 = cpu_to_le32(swap_temp + 0x4000);
+
+	req->req.actual += *length;
+
+	/* zlp is needed if req->req.zero is set */
+	if (req->req.zero) {
+		if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0)
+			*is_last = 1;
+		else
+			*is_last = 0;
+	} else if (req->req.length == req->req.actual)
+		*is_last = 1;
+	else
+		*is_last = 0;
+
+	if ((*is_last) == 0)
+		VDBG("multi-dtd request!");
+	/* Fill in the transfer size; set active bit */
+	swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE);
+
+	/* Enable interrupt for the last dtd of a request */
+	if (*is_last && !req->req.no_interrupt)
+		swap_temp |= DTD_IOC;
+
+	dtd->size_ioc_sts = cpu_to_le32(swap_temp);
+
+	mb();
+
+	VDBG("length = %d address= 0x%x", *length, (int)*dma);
+
+	return dtd;
+}
+
+/* Generate dtd chain for a request */
+static int xusbps_req_to_dtd(struct xusbps_req *req)
+{
+	unsigned	count;
+	int		is_last;
+	int		is_first = 1;
+	struct ep_td_struct	*last_dtd = NULL, *dtd;
+	dma_addr_t dma;
+
+	do {
+		dtd = xusbps_build_dtd(req, &count, &dma, &is_last);
+		if (dtd == NULL)
+			return -ENOMEM;
+
+		if (is_first) {
+			is_first = 0;
+			req->head = dtd;
+		} else {
+			last_dtd->next_td_ptr = cpu_to_le32(dma);
+			last_dtd->next_td_virt = dtd;
+		}
+		last_dtd = dtd;
+
+		req->dtd_count++;
+	} while (!is_last);
+
+	dtd->next_td_ptr = cpu_to_le32(DTD_NEXT_TERMINATE);
+
+	mb();
+	req->tail = dtd;
+
+	return 0;
+}
+
+/* queues (submits) an I/O request to an endpoint */
+static int
+xusbps_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+{
+	struct xusbps_ep *ep = container_of(_ep, struct xusbps_ep, ep);
+	struct xusbps_req *req = container_of(_req, struct xusbps_req, req);
+	struct xusbps_udc *udc;
+	unsigned long flags;
+
+	/* catch various bogus parameters */
+	if (!_req || !req->req.complete || !req->req.buf
+			|| !list_empty(&req->queue)) {
+		VDBG("%s, bad params", __func__);
+		return -EINVAL;
+	}
+	if (unlikely(!_ep || !ep->ep.desc)) {
+		VDBG("%s, bad ep", __func__);
+		return -EINVAL;
+	}
+	if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
+		if (req->req.length > ep->ep.maxpacket)
+			return -EMSGSIZE;
+	}
+
+	udc = ep->udc;
+	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	req->ep = ep;
+
+	/* map virtual address to hardware */
+	if (req->req.dma == DMA_ADDR_INVALID) {
+		req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+					req->req.buf,
+					req->req.length, ep_is_in(ep)
+						? DMA_TO_DEVICE
+						: DMA_FROM_DEVICE);
+		req->mapped = 1;
+	} else {
+		dma_sync_single_for_device(ep->udc->gadget.dev.parent,
+					req->req.dma, req->req.length,
+					ep_is_in(ep)
+						? DMA_TO_DEVICE
+						: DMA_FROM_DEVICE);
+		req->mapped = 0;
+	}
+
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->dtd_count = 0;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* build dtds and push them to device queue */
+	if (!xusbps_req_to_dtd(req)) {
+		xusbps_queue_td(ep, req);
+	} else {
+		spin_unlock_irqrestore(&udc->lock, flags);
+		return -ENOMEM;
+	}
+
+	/* Update ep0 state */
+	if ((ep_index(ep) == 0))
+		udc->ep0_state = DATA_STATE_XMIT;
+
+	/* irq handler advances the queue */
+	if (req != NULL)
+		list_add_tail(&req->queue, &ep->queue);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/* dequeues (cancels, unlinks) an I/O request from an endpoint */
+static int xusbps_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct xusbps_ep *ep = container_of(_ep, struct xusbps_ep, ep);
+	struct xusbps_req *req;
+	unsigned long flags;
+	int ep_num, stopped, ret = 0;
+	u32 epctrl;
+
+	if (!_ep || !_req)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	stopped = ep->stopped;
+
+	/* Stop the ep before we deal with the queue */
+	ep->stopped = 1;
+	ep_num = ep_index(ep);
+	epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+	if (ep_is_in(ep))
+		epctrl &= ~EPCTRL_TX_ENABLE;
+	else
+		epctrl &= ~EPCTRL_RX_ENABLE;
+	xusbps_writel(epctrl, &dr_regs->endptctrl[ep_num]);
+
+	/* make sure it's actually queued on this endpoint */
+	list_for_each_entry(req, &ep->queue, queue) {
+		if (&req->req == _req)
+			break;
+	}
+	if (&req->req != _req) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* The request is in progress, or completed but not dequeued */
+	if (ep->queue.next == &req->queue) {
+		_req->status = -ECONNRESET;
+		xusbps_ep_fifo_flush(_ep);	/* flush current transfer */
+
+		/* The request isn't the last request in this ep queue */
+		if (req->queue.next != &ep->queue) {
+			struct ep_queue_head *qh;
+			struct xusbps_req *next_req;
+
+			qh = ep->qh;
+			next_req = list_entry(req->queue.next, struct
+					xusbps_req, queue);
+
+			/* Point the QH to the first TD of next request */
+			xusbps_writel((u32) next_req->head,
+				(void __force __iomem *)&qh->curr_dtd_ptr);
+		}
+
+		/* The request hasn't been processed, patch up the TD chain */
+	} else {
+		struct xusbps_req *prev_req;
+
+		prev_req = list_entry(req->queue.prev, struct xusbps_req,
+				queue);
+		xusbps_writel(
+		xusbps_readl((void __force __iomem *)&req->tail->next_td_ptr),
+			(void __force __iomem *)&prev_req->tail->next_td_ptr);
+
+	}
+
+	done(ep, req, -ECONNRESET);
+
+	/* Enable EP */
+out:	epctrl = xusbps_readl(&dr_regs->endptctrl[ep_num]);
+	if (ep_is_in(ep))
+		epctrl |= EPCTRL_TX_ENABLE;
+	else
+		epctrl |= EPCTRL_RX_ENABLE;
+	xusbps_writel(epctrl, &dr_regs->endptctrl[ep_num]);
+	ep->stopped = stopped;
+
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------
+ * modify the endpoint halt feature
+ * @ep: the non-isochronous endpoint being stalled
+ * @value: 1--set halt  0--clear halt
+ * Returns zero, or a negative error code.
+*----------------------------------------------------------------*/
+static int xusbps_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct xusbps_ep *ep = NULL;
+	unsigned long flags = 0;
+	int status = -EOPNOTSUPP;	/* operation not supported */
+	unsigned char ep_dir = 0, ep_num = 0;
+	struct xusbps_udc *udc = NULL;
+
+	ep = container_of(_ep, struct xusbps_ep, ep);
+	udc = ep->udc;
+	if (!_ep || !ep->ep.desc) {
+		status = -EINVAL;
+		goto out;
+	}
+
+	if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
+		status = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Attempt to halt IN ep will fail if any transfer requests
+	 * are still queue */
+	if (value && ep_is_in(ep) && !list_empty(&ep->queue)) {
+		status = -EAGAIN;
+		goto out;
+	}
+
+	status = 0;
+	ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV;
+	ep_num = (unsigned char)(ep_index(ep));
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	if (!value)
+		ep->wedge = 0;
+	dr_ep_change_stall(ep_num, ep_dir, value);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	if (ep_index(ep) == 0) {
+		udc->ep0_state = WAIT_FOR_SETUP;
+		udc->ep0_dir = 0;
+	}
+out:
+	VDBG(" %s %s halt stat %d", ep->ep.name,
+			value ?  "set" : "clear", status);
+
+	return status;
+}
+
+static int xusbps_ep_set_wedge(struct usb_ep *_ep)
+{
+	struct xusbps_ep *ep = NULL;
+	unsigned long flags = 0;
+
+	ep = container_of(_ep, struct xusbps_ep, ep);
+
+	if (!ep || !ep->ep.desc)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	ep->wedge = 1;
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return usb_ep_set_halt(_ep);
+}
+
+static void xusbps_ep_fifo_flush(struct usb_ep *_ep)
+{
+	struct xusbps_ep *ep;
+	int ep_num, ep_dir;
+	u32 bits;
+	unsigned long timeout;
+#define XUSBPS_UDC_FLUSH_TIMEOUT 1000
+
+	if (!_ep) {
+		return;
+	} else {
+		ep = container_of(_ep, struct xusbps_ep, ep);
+		if (!ep->ep.desc)
+			return;
+	}
+	ep_num = ep_index(ep);
+	ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV;
+
+	if (ep_num == 0)
+		bits = (1 << 16) | 1;
+	else if (ep_dir == USB_SEND)
+		bits = 1 << (16 + ep_num);
+	else
+		bits = 1 << ep_num;
+
+	timeout = jiffies + XUSBPS_UDC_FLUSH_TIMEOUT;
+	do {
+		xusbps_writel(bits, &dr_regs->endptflush);
+
+		/* Wait until flush complete */
+		while (xusbps_readl(&dr_regs->endptflush)) {
+			if (time_after(jiffies, timeout)) {
+				ERR("ep flush timeout\n");
+				return;
+			}
+			cpu_relax();
+		}
+		/* See if we need to flush again */
+	} while (xusbps_readl(&dr_regs->endptstatus) & bits);
+}
+
+static struct usb_ep_ops xusbps_ep_ops = {
+	.enable = xusbps_ep_enable,
+	.disable = xusbps_ep_disable,
+
+	.alloc_request = xusbps_alloc_request,
+	.free_request = xusbps_free_request,
+
+	.queue = xusbps_ep_queue,
+	.dequeue = xusbps_ep_dequeue,
+
+	.set_halt = xusbps_ep_set_halt,
+	.set_wedge = xusbps_ep_set_wedge,
+	.fifo_flush = xusbps_ep_fifo_flush,	/* flush fifo */
+};
+
+/*-------------------------------------------------------------------------
+		Gadget Driver Layer Operations
+-------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------
+ * Get the current frame number (from DR frame_index Reg )
+ *----------------------------------------------------------------------*/
+static int xusbps_get_frame(struct usb_gadget *gadget)
+{
+	return (int)(xusbps_readl(&dr_regs->frindex) & USB_FRINDEX_MASKS);
+}
+
+/*-----------------------------------------------------------------------
+ * Tries to wake up the host connected to this gadget
+ -----------------------------------------------------------------------*/
+static int xusbps_wakeup(struct usb_gadget *gadget)
+{
+	struct xusbps_udc *udc = container_of(gadget, struct xusbps_udc,
+			gadget);
+	u32 portsc;
+
+	/* Remote wakeup feature not enabled by host */
+	if (!udc->remote_wakeup)
+		return -ENOTSUPP;
+
+	portsc = xusbps_readl(&dr_regs->portsc1);
+	/* not suspended? */
+	if (!(portsc & PORTSCX_PORT_SUSPEND))
+		return 0;
+	/* trigger force resume */
+	portsc |= PORTSCX_PORT_FORCE_RESUME;
+	xusbps_writel(portsc, &dr_regs->portsc1);
+	return 0;
+}
+
+static int can_pullup(struct xusbps_udc *udc)
+{
+	return udc->driver && udc->softconnect && udc->vbus_active;
+}
+
+/* Notify controller that VBUS is powered, Called by whatever
+   detects VBUS sessions */
+static int xusbps_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+	struct xusbps_udc	*udc;
+	unsigned long	flags;
+
+	udc = container_of(gadget, struct xusbps_udc, gadget);
+	spin_lock_irqsave(&udc->lock, flags);
+	VDBG("VBUS %s", is_active ? "on" : "off");
+	udc->vbus_active = (is_active != 0);
+	if (can_pullup(udc))
+		xusbps_writel((xusbps_readl(&dr_regs->usbcmd) |
+					USB_CMD_RUN_STOP), &dr_regs->usbcmd);
+	else
+		xusbps_writel((xusbps_readl(&dr_regs->usbcmd) &
+					~USB_CMD_RUN_STOP), &dr_regs->usbcmd);
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return 0;
+}
+
+/* constrain controller's VBUS power usage
+ * This call is used by gadget drivers during SET_CONFIGURATION calls,
+ * reporting how much power the device may consume.  For example, this
+ * could affect how quickly batteries are recharged.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static int xusbps_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+{
+	struct xusbps_udc *udc;
+
+	udc = container_of(gadget, struct xusbps_udc, gadget);
+	if (udc->transceiver)
+		return usb_phy_set_power(udc->transceiver, mA);
+	return -ENOTSUPP;
+}
+
+/* Change Data+ pullup status
+ * this func is used by usb_gadget_connect/disconnet
+ */
+static int xusbps_pullup(struct usb_gadget *gadget, int is_on)
+{
+	struct xusbps_udc *udc;
+
+	udc = container_of(gadget, struct xusbps_udc, gadget);
+	udc->softconnect = (is_on != 0);
+	if (can_pullup(udc))
+		xusbps_writel((xusbps_readl(&dr_regs->usbcmd) |
+					USB_CMD_RUN_STOP), &dr_regs->usbcmd);
+	else
+		xusbps_writel((xusbps_readl(&dr_regs->usbcmd) &
+					~USB_CMD_RUN_STOP), &dr_regs->usbcmd);
+
+	return 0;
+}
+
+static void udc_reset_ep_queue(struct xusbps_udc *udc, u8 pipe)
+{
+	struct xusbps_ep *ep = get_ep_by_pipe(udc, pipe);
+
+	if (ep->name)
+		nuke(ep, -ESHUTDOWN);
+}
+
+/* Clear up all ep queues */
+static int reset_queues(struct xusbps_udc *udc)
+{
+	u8 pipe;
+
+	for (pipe = 0; pipe < udc->max_pipes; pipe++)
+		udc_reset_ep_queue(udc, pipe);
+
+	/* report disconnect; the driver is already quiesced */
+	spin_unlock(&udc->lock);
+	udc->driver->disconnect(&udc->gadget);
+	spin_lock(&udc->lock);
+
+	return 0;
+}
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+/*----------------------------------------------------------------
+ * OTG Related changes
+ *--------------------------------------------------------------*/
+static int xusbps_udc_start_peripheral(struct usb_phy  *otg)
+{
+	struct usb_gadget	*gadget = otg->otg->gadget;
+	struct xusbps_udc *udc = container_of(gadget, struct xusbps_udc,
+						gadget);
+	unsigned long flags = 0;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	if (!otg->otg->default_a) {
+		dr_controller_setup(udc);
+		reset_queues(udc);
+	} else {
+		/* A-device HABA resets the controller */
+		tmp = udc->ep_qh_dma;
+		tmp &= USB_EP_LIST_ADDRESS_MASK;
+		xusbps_writel(tmp, &dr_regs->endpointlistaddr);
+	}
+	ep0_setup(udc);
+	dr_controller_run(udc);
+
+	udc->usb_state = USB_STATE_ATTACHED;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = 0;
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int xusbps_udc_stop_peripheral(struct usb_phy *otg)
+{
+	struct usb_gadget	*gadget = otg->otg->gadget;
+	struct xusbps_udc *udc = container_of(gadget, struct xusbps_udc,
+						gadget);
+
+	dr_controller_stop(udc);
+
+	/* refer to USB OTG 6.6.2.3 b_hnp_en is cleared */
+	if (!udc->xotg->otg.otg->default_a)
+		udc->xotg->hsm.b_hnp_enable = 0;
+
+	return 0;
+}
+#endif
+
+/*----------------------------------------------------------------*
+ * Hook to gadget drivers
+ * Called by initialization code of gadget drivers
+*----------------------------------------------------------------*/
+static int xusbps_udc_start(struct usb_gadget *g,
+				struct usb_gadget_driver *driver)
+{
+	int retval = 0;
+	unsigned long flags = 0;
+
+	/* lock is needed but whether should use this lock or another */
+	spin_lock_irqsave(&udc_controller->lock, flags);
+
+	driver->driver.bus = NULL;
+	/* hook up the driver */
+	udc_controller->driver = driver;
+	udc_controller->gadget.dev.driver = &driver->driver;
+	spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (gadget_is_otg(&udc_controller->gadget)) {
+		retval = otg_set_peripheral(udc_controller->transceiver->otg,
+				&udc_controller->gadget);
+		if (retval < 0) {
+			VDBG("can't bind to otg transceiver\n");
+			driver->unbind(&udc_controller->gadget);
+			udc_controller->gadget.dev.driver = NULL;
+			udc_controller->driver = NULL;
+			return retval;
+		}
+		/* Exporting start and stop routines */
+		udc_controller->xotg->start_peripheral =
+					xusbps_udc_start_peripheral;
+		udc_controller->xotg->stop_peripheral =
+					xusbps_udc_stop_peripheral;
+
+		if (!udc_controller->transceiver->otg->default_a &&
+					udc_controller->stopped &&
+				udc_controller->xotg->hsm.b_sess_vld) {
+			dr_controller_setup(udc_controller);
+			ep0_setup(udc_controller);
+			/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
+			dr_controller_run(udc_controller);
+			udc_controller->usb_state = USB_STATE_ATTACHED;
+			udc_controller->ep0_state = WAIT_FOR_SETUP;
+			udc_controller->ep0_dir = 0;
+			xusbps_update_transceiver();
+		}
+	} else {
+		/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
+		dr_controller_run(udc_controller);
+		udc_controller->usb_state = USB_STATE_ATTACHED;
+		udc_controller->ep0_state = WAIT_FOR_SETUP;
+		udc_controller->ep0_dir = 0;
+	}
+#else
+	/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
+	dr_controller_run(udc_controller);
+	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = 0;
+#endif
+
+	pr_info("%s: bind to driver %s\n",
+			udc_controller->gadget.name, driver->driver.name);
+	if (retval)
+		pr_warn("gadget driver register failed %d\n", retval);
+
+	return retval;
+}
+
+/* Disconnect from gadget driver */
+static int xusbps_udc_stop(struct usb_gadget *g,
+		struct usb_gadget_driver *driver)
+{
+	struct xusbps_ep *loop_ep;
+	unsigned long flags;
+
+	if (udc_controller->transceiver)
+		otg_set_peripheral(udc_controller->transceiver->otg, NULL);
+
+	/* stop DR, disable intr */
+	dr_controller_stop(udc_controller);
+
+	/* in fact, no needed */
+	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = 0;
+
+	/* stand operation */
+	spin_lock_irqsave(&udc_controller->lock, flags);
+	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+	nuke(&udc_controller->eps[0], -ESHUTDOWN);
+	list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
+			ep.ep_list)
+		nuke(loop_ep, -ESHUTDOWN);
+	spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (gadget_is_otg(&udc_controller->gadget)) {
+		udc_controller->xotg->start_peripheral = NULL;
+		udc_controller->xotg->stop_peripheral = NULL;
+	}
+#endif
+	udc_controller->gadget.dev.driver = NULL;
+	udc_controller->driver = NULL;
+
+	return 0;
+}
+
+/* defined in gadget.h */
+static struct usb_gadget_ops xusbps_gadget_ops = {
+	.get_frame = xusbps_get_frame,
+	.wakeup = xusbps_wakeup,
+/*	.set_selfpowered = xusbps_set_selfpowered, */ /* Always selfpowered */
+	.vbus_session = xusbps_vbus_session,
+	.vbus_draw = xusbps_vbus_draw,
+	.pullup = xusbps_pullup,
+	.udc_start = xusbps_udc_start,
+	.udc_stop = xusbps_udc_stop,
+};
+
+/* Set protocol stall on ep0, protocol stall will automatically be cleared
+   on new transaction */
+static void ep0stall(struct xusbps_udc *udc)
+{
+	u32 tmp;
+
+	/* must set tx and rx to stall at the same time */
+	tmp = xusbps_readl(&dr_regs->endptctrl[0]);
+	tmp |= EPCTRL_TX_EP_STALL | EPCTRL_RX_EP_STALL;
+	xusbps_writel(tmp, &dr_regs->endptctrl[0]);
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = 0;
+}
+
+/* Prime a status phase for ep0 */
+static int ep0_prime_status(struct xusbps_udc *udc, int direction)
+{
+	struct xusbps_req *req = udc->status_req;
+	struct xusbps_ep *ep;
+
+	if (direction == EP_DIR_IN)
+		udc->ep0_dir = USB_DIR_IN;
+	else
+		udc->ep0_dir = USB_DIR_OUT;
+
+	ep = &udc->eps[0];
+	udc->ep0_state = WAIT_FOR_OUT_STATUS;
+
+	req->ep = ep;
+	req->req.length = 0;
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->req.complete = NULL;
+	req->dtd_count = 0;
+	req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+				req->req.buf, req->req.length,
+				ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	req->mapped = 1;
+
+	if (xusbps_req_to_dtd(req) == 0)
+		xusbps_queue_td(ep, req);
+	else
+		return -ENOMEM;
+
+	list_add_tail(&req->queue, &ep->queue);
+
+	return 0;
+}
+
+/*
+ * ch9 Set address
+ */
+static void ch9setaddress(struct xusbps_udc *udc, u16 value, u16 index, u16
+		length)
+{
+	/* Save the new address to device struct */
+	udc->device_address = (u8) value;
+	/* Update usb state */
+	udc->usb_state = USB_STATE_ADDRESS;
+	/* Status phase */
+	if (ep0_prime_status(udc, EP_DIR_IN))
+		ep0stall(udc);
+}
+
+/*
+ * ch9 Get status
+ */
+static void ch9getstatus(struct xusbps_udc *udc, u8 request_type, u16 value,
+		u16 index, u16 length)
+{
+	u16 tmp = 0;		/* Status, cpu endian */
+	struct xusbps_req *req;
+	struct xusbps_ep *ep;
+
+	ep = &udc->eps[0];
+
+	if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
+		/* Get device status */
+		tmp = 1 << USB_DEVICE_SELF_POWERED;
+		tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
+		/* Get interface status */
+		/* We don't have interface information in udc driver */
+		tmp = 0;
+	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
+		/* Get endpoint status */
+		struct xusbps_ep *target_ep;
+
+		target_ep = get_ep_by_pipe(udc, get_pipe_by_windex(index));
+
+		/* stall if endpoint doesn't exist */
+		if (!target_ep->ep.desc)
+			goto stall;
+		tmp = dr_ep_get_stall(ep_index(target_ep), ep_is_in(target_ep))
+				<< USB_ENDPOINT_HALT;
+	}
+
+	udc->ep0_dir = USB_DIR_IN;
+	/* Borrow the per device status_req */
+	req = udc->status_req;
+	/* Fill in the reqest structure */
+	*((u16 *) req->req.buf) = cpu_to_le16(tmp);
+	req->ep = ep;
+	req->req.length = 2;
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->req.complete = NULL;
+	req->dtd_count = 0;
+	req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+				req->req.buf, req->req.length,
+				ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	req->mapped = 1;
+
+	/* prime the data phase */
+	if ((xusbps_req_to_dtd(req) == 0))
+		xusbps_queue_td(ep, req);
+	else			/* no mem */
+		goto stall;
+
+	list_add_tail(&req->queue, &ep->queue);
+	udc->ep0_state = DATA_STATE_XMIT;
+	return;
+stall:
+	ep0stall(udc);
+}
+
+static void setup_received_irq(struct xusbps_udc *udc,
+		struct usb_ctrlrequest *setup)
+{
+	u16 wValue = le16_to_cpu(setup->wValue);
+	u16 wIndex = le16_to_cpu(setup->wIndex);
+	u16 wLength = le16_to_cpu(setup->wLength);
+	u16 testsel = 0;
+
+	udc_reset_ep_queue(udc, 0);
+
+	/* We process some stardard setup requests here */
+	switch (setup->bRequest) {
+	case USB_REQ_GET_STATUS:
+		/* Data+Status phase from udc */
+		if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
+					!= (USB_DIR_IN | USB_TYPE_STANDARD))
+			break;
+		ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength);
+		return;
+
+	case USB_REQ_SET_ADDRESS:
+		/* Status phase from udc */
+		if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
+						| USB_RECIP_DEVICE))
+			break;
+		ch9setaddress(udc, wValue, wIndex, wLength);
+		return;
+
+	case USB_REQ_CLEAR_FEATURE:
+	case USB_REQ_SET_FEATURE:
+		/* Status phase from udc */
+	{
+		int rc = -EOPNOTSUPP;
+
+		if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
+				== (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
+			int pipe = get_pipe_by_windex(wIndex);
+			struct xusbps_ep *ep;
+
+			if (wValue != 0 || wLength != 0 || pipe > udc->max_ep)
+				break;
+			ep = get_ep_by_pipe(udc, pipe);
+
+			spin_unlock(&udc->lock);
+			if (setup->bRequest == USB_REQ_SET_FEATURE) {
+				 rc = xusbps_ep_set_halt(&ep->ep, 1);
+			} else {
+				if (!ep->wedge)
+					rc = xusbps_ep_set_halt(&ep->ep, 0);
+				else
+					rc = 0;
+			}
+			spin_lock(&udc->lock);
+
+		} else if ((setup->bRequestType & (USB_RECIP_MASK
+				| USB_TYPE_MASK)) == (USB_RECIP_DEVICE
+				| USB_TYPE_STANDARD)) {
+			/* TEST MODE feature */
+			if (wValue == USB_DEVICE_TEST_MODE) {
+				testsel = (wIndex >> 8) & 0xff;
+				rc = 0;
+				goto status_phase;
+			}
+
+			/* Note: The driver has not include OTG support yet.
+			 * This will be set when OTG support is added */
+			if (!gadget_is_otg(&udc->gadget))
+				break;
+			else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
+				udc->gadget.b_hnp_enable = 1;
+#ifdef CONFIG_USB_ZYNQ_PHY
+				if (!udc->xotg->otg.otg->default_a)
+					udc->xotg->hsm.b_hnp_enable = 1;
+#endif
+			} else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
+				udc->gadget.a_hnp_support = 1;
+			else if (setup->bRequest ==
+					USB_DEVICE_A_ALT_HNP_SUPPORT)
+				udc->gadget.a_alt_hnp_support = 1;
+			else
+				break;
+			rc = 0;
+		} else
+			break;
+
+status_phase:
+		if (rc == 0) {
+			if (ep0_prime_status(udc, EP_DIR_IN)) {
+				ep0stall(udc);
+			} else {
+				if (testsel) {
+					u32 tmp;
+					/* Wait for status phase to complete */
+					mdelay(1);
+					tmp = xusbps_readl(&dr_regs->portsc1);
+					tmp |= (testsel << 16);
+					xusbps_writel(tmp, &dr_regs->portsc1);
+				}
+			}
+		}
+		return;
+	}
+
+	default:
+		break;
+	}
+
+	/* Requests handled by gadget */
+	if (wLength) {
+		/* Data phase from gadget, status phase from udc */
+		udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
+				?  USB_DIR_IN : USB_DIR_OUT;
+		spin_unlock(&udc->lock);
+		if (udc->driver->setup(&udc->gadget,
+				&udc->local_setup_buff) < 0)
+			ep0stall(udc);
+		spin_lock(&udc->lock);
+		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
+				?  DATA_STATE_XMIT : DATA_STATE_RECV;
+	} else {
+		/* No data phase, IN status from gadget */
+		udc->ep0_dir = USB_DIR_IN;
+		spin_unlock(&udc->lock);
+		if (udc->driver->setup(&udc->gadget,
+				&udc->local_setup_buff) < 0)
+			ep0stall(udc);
+		spin_lock(&udc->lock);
+		udc->ep0_state = WAIT_FOR_OUT_STATUS;
+	}
+}
+
+/* Process request for Data or Status phase of ep0
+ * prime status phase if needed */
+static void ep0_req_complete(struct xusbps_udc *udc, struct xusbps_ep *ep0,
+		struct xusbps_req *req)
+{
+	if (udc->usb_state == USB_STATE_ADDRESS) {
+		/* Set the new address */
+		u32 new_address = (u32) udc->device_address;
+		xusbps_writel(new_address << USB_DEVICE_ADDRESS_BIT_POS,
+				&dr_regs->deviceaddr);
+	}
+
+	done(ep0, req, 0);
+
+	switch (udc->ep0_state) {
+	case DATA_STATE_XMIT:
+		/* receive status phase */
+		if (ep0_prime_status(udc, EP_DIR_OUT))
+			ep0stall(udc);
+		break;
+	case DATA_STATE_RECV:
+		/* send status phase */
+		if (ep0_prime_status(udc, EP_DIR_IN))
+			ep0stall(udc);
+		break;
+	case WAIT_FOR_OUT_STATUS:
+		udc->ep0_state = WAIT_FOR_SETUP;
+		break;
+	case WAIT_FOR_SETUP:
+		ERR("Unexpect ep0 packets\n");
+		break;
+	default:
+		ep0stall(udc);
+		break;
+	}
+}
+
+/* Tripwire mechanism to ensure a setup packet payload is extracted without
+ * being corrupted by another incoming setup packet */
+static void tripwire_handler(struct xusbps_udc *udc, u8 ep_num, u8 *buffer_ptr)
+{
+	u32 temp;
+	struct ep_queue_head *qh;
+
+	qh = &udc->ep_qh[ep_num * 2 + EP_DIR_OUT];
+
+	/* Clear bit in ENDPTSETUPSTAT */
+	temp = xusbps_readl(&dr_regs->endptsetupstat);
+	xusbps_writel(temp | (1 << ep_num), &dr_regs->endptsetupstat);
+
+	/* while a hazard exists when setup package arrives */
+	do {
+		/* Set Setup Tripwire */
+		temp = xusbps_readl(&dr_regs->usbcmd);
+		xusbps_writel(temp | USB_CMD_SUTW, &dr_regs->usbcmd);
+
+		/* Copy the setup packet to local buffer */
+		memcpy(buffer_ptr, (u8 *) qh->setup_buffer, 8);
+	} while (!(xusbps_readl(&dr_regs->usbcmd) & USB_CMD_SUTW));
+
+	/* Clear Setup Tripwire */
+	temp = xusbps_readl(&dr_regs->usbcmd);
+	xusbps_writel(temp & ~USB_CMD_SUTW, &dr_regs->usbcmd);
+}
+
+/* process-ep_req(): free the completed Tds for this req */
+static int process_ep_req(struct xusbps_udc *udc, int pipe,
+		struct xusbps_req *curr_req)
+{
+	struct ep_td_struct *curr_td;
+	int	td_complete, actual, remaining_length, j, tmp;
+	int	status = 0;
+	int	errors = 0;
+	struct  ep_queue_head *curr_qh = &udc->ep_qh[pipe];
+	int direction = pipe % 2;
+
+	curr_td = curr_req->head;
+	td_complete = 0;
+	actual = curr_req->req.length;
+
+	for (j = 0; j < curr_req->dtd_count; j++) {
+		remaining_length = (le32_to_cpu(curr_td->size_ioc_sts)
+					& DTD_PACKET_SIZE)
+				>> DTD_LENGTH_BIT_POS;
+		actual -= remaining_length;
+		errors = le32_to_cpu(curr_td->size_ioc_sts) &
+						DTD_ERROR_MASK;
+		if (errors) {
+			if (errors & DTD_STATUS_HALTED) {
+				ERR("dTD error %08x QH=%d\n", errors, pipe);
+				/* Clear the errors and Halt condition */
+				tmp = le32_to_cpu(curr_qh->size_ioc_int_sts);
+				tmp &= ~errors;
+				curr_qh->size_ioc_int_sts = cpu_to_le32(tmp);
+				status = -EPIPE;
+				/* FIXME: continue with next queued TD? */
+
+				break;
+			}
+			if (errors & DTD_STATUS_DATA_BUFF_ERR) {
+				VDBG("Transfer overflow");
+				status = -EPROTO;
+				break;
+			} else if (errors & DTD_STATUS_TRANSACTION_ERR) {
+				VDBG("ISO error");
+				status = -EILSEQ;
+				break;
+			} else
+				ERR("Unknown error has occured (0x%x)!\n",
+					errors);
+
+		} else if (le32_to_cpu(curr_td->size_ioc_sts)
+				& DTD_STATUS_ACTIVE) {
+			VDBG("Request not complete");
+			status = REQ_UNCOMPLETE;
+			return status;
+		} else if (remaining_length) {
+			if (direction) {
+				VDBG("Transmit dTD remaining length not zero");
+				status = -EPROTO;
+				break;
+			} else {
+				td_complete++;
+				break;
+			}
+		} else {
+			td_complete++;
+			VDBG("dTD transmitted successful");
+		}
+
+		if (j != curr_req->dtd_count - 1)
+			curr_td = (struct ep_td_struct *)curr_td->next_td_virt;
+	}
+
+	if (status)
+		return status;
+
+	curr_req->req.actual = actual;
+
+	return 0;
+}
+
+/* Process a DTD completion interrupt */
+static void dtd_complete_irq(struct xusbps_udc *udc)
+{
+	u32 bit_pos;
+	int i, ep_num, direction, bit_mask, status;
+	struct xusbps_ep *curr_ep;
+	struct xusbps_req *curr_req, *temp_req;
+
+	/* Clear the bits in the register */
+	bit_pos = xusbps_readl(&dr_regs->endptcomplete);
+	xusbps_writel(bit_pos, &dr_regs->endptcomplete);
+
+	if (!bit_pos)
+		return;
+
+	for (i = 0; i < udc->max_ep; i++) {
+		ep_num = i >> 1;
+		direction = i % 2;
+
+		bit_mask = 1 << (ep_num + 16 * direction);
+
+		if (!(bit_pos & bit_mask))
+			continue;
+
+		curr_ep = get_ep_by_pipe(udc, i);
+
+		/* If the ep is configured */
+		if (curr_ep->name == NULL) {
+			WARNING("Invalid EP?");
+			continue;
+		}
+
+		/* process the req queue until an uncomplete request */
+		list_for_each_entry_safe(curr_req, temp_req, &curr_ep->queue,
+				queue) {
+			status = process_ep_req(udc, i, curr_req);
+
+			VDBG("status of process_ep_req= %d, ep = %d",
+					status, ep_num);
+			if (status == REQ_UNCOMPLETE)
+				break;
+			/* Clear the endpoint complete events */
+			xusbps_writel(bit_pos, &dr_regs->endptcomplete);
+			/* write back status to req */
+			curr_req->req.status = status;
+
+			if (ep_num == 0) {
+				ep0_req_complete(udc, curr_ep, curr_req);
+				break;
+			} else
+				done(curr_ep, curr_req, status);
+		}
+	}
+}
+
+/* Process a port change interrupt */
+static void port_change_irq(struct xusbps_udc *udc)
+{
+	u32 speed;
+
+	/* Bus resetting is finished */
+	if (!(xusbps_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
+		/* Get the speed */
+		speed = (xusbps_readl(&dr_regs->portsc1)
+				& PORTSCX_PORT_SPEED_MASK);
+		switch (speed) {
+		case PORTSCX_PORT_SPEED_HIGH:
+			udc->gadget.speed = USB_SPEED_HIGH;
+			break;
+		case PORTSCX_PORT_SPEED_FULL:
+			udc->gadget.speed = USB_SPEED_FULL;
+			break;
+		case PORTSCX_PORT_SPEED_LOW:
+			udc->gadget.speed = USB_SPEED_LOW;
+			break;
+		default:
+			udc->gadget.speed = USB_SPEED_UNKNOWN;
+			break;
+		}
+	}
+
+	/* Update USB state */
+	if (!udc->resume_state)
+		udc->usb_state = USB_STATE_DEFAULT;
+}
+
+/* Process suspend interrupt */
+static void suspend_irq(struct xusbps_udc *udc)
+{
+	udc->resume_state = udc->usb_state;
+	udc->usb_state = USB_STATE_SUSPENDED;
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (gadget_is_otg(&udc->gadget)) {
+		if (udc->xotg->otg.otg->default_a) {
+			udc->xotg->hsm.b_bus_suspend = 1;
+			/* notify transceiver the state changes */
+			if (spin_trylock(&udc->xotg->wq_lock)) {
+				xusbps_update_transceiver();
+				spin_unlock(&udc->xotg->wq_lock);
+			}
+		} else {
+			if (!udc->xotg->hsm.a_bus_suspend) {
+				udc->xotg->hsm.a_bus_suspend = 1;
+				udc->xotg->hsm.b_bus_req = 1;
+				/* notify transceiver the state changes */
+				if (spin_trylock(&udc->xotg->wq_lock)) {
+					xusbps_update_transceiver();
+					spin_unlock(&udc->xotg->wq_lock);
+				}
+			}
+		}
+	}
+#endif
+	/* report suspend to the driver, serial.c does not support this */
+	if (udc->driver->suspend)
+		udc->driver->suspend(&udc->gadget);
+}
+
+static void bus_resume(struct xusbps_udc *udc)
+{
+	udc->usb_state = udc->resume_state;
+	udc->resume_state = 0;
+
+	/* report resume to the driver, serial.c does not support this */
+	if (udc->driver->resume)
+		udc->driver->resume(&udc->gadget);
+}
+
+/* Process reset interrupt */
+static void reset_irq(struct xusbps_udc *udc)
+{
+	u32 temp;
+	unsigned long timeout;
+
+	/* Clear the device address */
+	temp = xusbps_readl(&dr_regs->deviceaddr);
+	xusbps_writel(temp & ~USB_DEVICE_ADDRESS_MASK, &dr_regs->deviceaddr);
+
+	udc->device_address = 0;
+
+	/* Clear usb state */
+	udc->resume_state = 0;
+	udc->ep0_dir = 0;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->remote_wakeup = 0;	/* default to 0 on reset */
+	udc->gadget.b_hnp_enable = 0;
+	udc->gadget.a_hnp_support = 0;
+	udc->gadget.a_alt_hnp_support = 0;
+
+	/* Clear all the setup token semaphores */
+	temp = xusbps_readl(&dr_regs->endptsetupstat);
+	xusbps_writel(temp, &dr_regs->endptsetupstat);
+
+	/* Clear all the endpoint complete status bits */
+	temp = xusbps_readl(&dr_regs->endptcomplete);
+	xusbps_writel(temp, &dr_regs->endptcomplete);
+
+	timeout = jiffies + 100;
+	while (xusbps_readl(&dr_regs->endpointprime)) {
+		/* Wait until all endptprime bits cleared */
+		if (time_after(jiffies, timeout)) {
+			ERR("Timeout for reset\n");
+			break;
+		}
+		cpu_relax();
+	}
+
+	/* Write 1s to the flush register */
+	xusbps_writel(0xffffffff, &dr_regs->endptflush);
+
+	VDBG("Bus reset");
+	/* Reset all the queues, include XD, dTD, EP queue
+	 * head and TR Queue */
+	reset_queues(udc);
+	udc->usb_state = USB_STATE_DEFAULT;
+}
+
+/*
+ * USB device controller interrupt handler
+ */
+static irqreturn_t xusbps_udc_irq(int irq, void *_udc)
+{
+	struct xusbps_udc *udc = _udc;
+	u32 irq_src, otg_sts;
+	irqreturn_t status = IRQ_NONE;
+	unsigned long flags;
+#ifdef CONFIG_USB_ZYNQ_PHY
+	unsigned long temp;
+#endif
+
+	/* Disable ISR for OTG host mode */
+	if (udc->stopped)
+		return IRQ_NONE;
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (gadget_is_otg(&udc->gadget)) {
+		/* A-device */
+		if (udc->transceiver->otg->default_a &&
+			(udc->transceiver->state != OTG_STATE_A_PERIPHERAL))
+			return IRQ_NONE;
+		/* B-device */
+		if ((udc->transceiver->state == OTG_STATE_B_WAIT_ACON) ||
+			(udc->transceiver->state == OTG_STATE_B_HOST))
+			return IRQ_NONE;
+	}
+#endif
+	spin_lock_irqsave(&udc->lock, flags);
+	irq_src = xusbps_readl(&dr_regs->usbsts) &
+		xusbps_readl(&dr_regs->usbintr);
+
+	/* Clear notification bits */
+	xusbps_writel(irq_src, &dr_regs->usbsts);
+
+	/*
+	 * Check disconnect event from B session end interrupt.
+	 * This is a SW workaround for USB disconnect detection as mentioned
+	 * in AR# 47538
+	 */
+	if (!gadget_is_otg(&udc->gadget)) {
+		otg_sts = xusbps_readl(&dr_regs->otgsc);
+		if (otg_sts & OTGSC_BSEIS) {
+			xusbps_writel(otg_sts, &dr_regs->otgsc);
+			reset_queues(udc);
+			status = IRQ_HANDLED;
+		}
+	}
+
+	/* VDBG("irq_src [0x%8x]", irq_src); */
+
+	/* Need to resume? */
+	if (udc->usb_state == USB_STATE_SUSPENDED)
+		if ((xusbps_readl(&dr_regs->portsc1) &
+					PORTSCX_PORT_SUSPEND) == 0)
+			bus_resume(udc);
+
+	/* USB Interrupt */
+	if (irq_src & USB_STS_INT) {
+		VDBG("Packet int");
+		/* Setup package, we only support ep0 as control ep */
+		if (xusbps_readl(&dr_regs->endptsetupstat) &
+						EP_SETUP_STATUS_EP0) {
+			tripwire_handler(udc, 0,
+					(u8 *) (&udc->local_setup_buff));
+			setup_received_irq(udc, &udc->local_setup_buff);
+			status = IRQ_HANDLED;
+		}
+
+		/* completion of dtd */
+		if (xusbps_readl(&dr_regs->endptcomplete)) {
+			dtd_complete_irq(udc);
+			status = IRQ_HANDLED;
+		}
+	}
+
+	/* SOF (for ISO transfer) */
+	if (irq_src & USB_STS_SOF)
+		status = IRQ_HANDLED;
+
+	/* Port Change */
+	if (irq_src & USB_STS_PORT_CHANGE) {
+		port_change_irq(udc);
+		status = IRQ_HANDLED;
+	}
+
+	/* Reset Received */
+	if (irq_src & USB_STS_RESET) {
+		reset_irq(udc);
+#ifdef CONFIG_USB_ZYNQ_PHY
+		if (gadget_is_otg(&udc->gadget)) {
+			/* Clear any previous suspend status bit */
+			temp = xusbps_readl(&dr_regs->usbsts);
+			if (temp & USB_INTR_DEVICE_SUSPEND) {
+				udc->usb_state = USB_STATE_SUSPENDED;
+				temp |= USB_INTR_DEVICE_SUSPEND;
+				xusbps_writel(temp, &dr_regs->usbsts);
+			}
+			/* Enable suspend interrupt */
+			temp = xusbps_readl(&dr_regs->usbintr);
+			temp |= USB_INTR_DEVICE_SUSPEND;
+			xusbps_writel(temp, &dr_regs->usbintr);
+		}
+#endif
+		status = IRQ_HANDLED;
+	}
+
+	/* Sleep Enable (Suspend) */
+	if (irq_src & USB_STS_SUSPEND) {
+		suspend_irq(udc);
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR))
+		VDBG("Error IRQ %x", irq_src);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return status;
+}
+
+/*-------------------------------------------------------------------------
+		PROC File System Support
+-------------------------------------------------------------------------*/
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+
+#include <linux/seq_file.h>
+
+static const char proc_filename[] = "driver/xusbps_udc";
+
+static int xusbps_proc_read(struct seq_file *m, void *v)
+{
+	unsigned long flags;
+	int i;
+	u32 tmp_reg;
+	struct xusbps_ep *ep = NULL;
+	struct xusbps_req *req;
+	struct xusbps_udc *udc = udc_controller;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* ------basic driver information ---- */
+	seq_printf(m, DRIVER_DESC "\n"
+			"%s version: %s\n"
+			"Gadget driver: %s\n\n",
+			driver_name, DRIVER_VERSION,
+			udc->driver ? udc->driver->driver.name : "(none)");
+
+	/* ------ DR Registers ----- */
+	tmp_reg = xusbps_readl(&dr_regs->usbcmd);
+	seq_printf(m, "USBCMD reg:\n"
+			"SetupTW: %d\n"
+			"Run/Stop: %s\n\n",
+			(tmp_reg & USB_CMD_SUTW) ? 1 : 0,
+			(tmp_reg & USB_CMD_RUN_STOP) ? "Run" : "Stop");
+
+	tmp_reg = xusbps_readl(&dr_regs->usbsts);
+	seq_printf(m, "USB Status Reg:\n"
+			"Dr Suspend: %d Reset Received: %d System Error: %s "
+			"USB Error Interrupt: %s\n\n",
+			(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
+			(tmp_reg & USB_STS_RESET) ? 1 : 0,
+			(tmp_reg & USB_STS_SYS_ERR) ? "Err" : "Normal",
+			(tmp_reg & USB_STS_ERR) ? "Err detected" : "No err");
+
+	tmp_reg = xusbps_readl(&dr_regs->usbintr);
+	seq_printf(m, "USB Intrrupt Enable Reg:\n"
+			"Sleep Enable: %d SOF Received Enable: %d "
+			"Reset Enable: %d\n"
+			"System Error Enable: %d "
+			"Port Change Dectected Enable: %d\n"
+			"USB Error Intr Enable: %d USB Intr Enable: %d\n\n",
+			(tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0,
+			(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
+			(tmp_reg & USB_INTR_RESET_EN) ? 1 : 0,
+			(tmp_reg & USB_INTR_SYS_ERR_EN) ? 1 : 0,
+			(tmp_reg & USB_INTR_PTC_DETECT_EN) ? 1 : 0,
+			(tmp_reg & USB_INTR_ERR_INT_EN) ? 1 : 0,
+			(tmp_reg & USB_INTR_INT_EN) ? 1 : 0);
+
+	tmp_reg = xusbps_readl(&dr_regs->frindex);
+	seq_printf(m, "USB Frame Index Reg: Frame Number is 0x%x\n\n",
+			(tmp_reg & USB_FRINDEX_MASKS));
+
+	tmp_reg = xusbps_readl(&dr_regs->deviceaddr);
+	seq_printf(m, "USB Device Address Reg: Device Addr is 0x%x\n\n",
+			(tmp_reg & USB_DEVICE_ADDRESS_MASK));
+
+	tmp_reg = xusbps_readl(&dr_regs->endpointlistaddr);
+	seq_printf(m, "USB Endpoint List Address Reg: "
+			"Device Addr is 0x%x\n\n",
+			(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
+
+	tmp_reg = xusbps_readl(&dr_regs->portsc1);
+	seq_printf(m, "USB Port Status&Control Reg:\n"
+		"Port Transceiver Type : %s Port Speed: %s\n"
+		"PHY Low Power Suspend: %s Port Reset: %s "
+		"Port Suspend Mode: %s\n"
+		"Over-current Change: %s "
+		"Port Enable/Disable Change: %s\n"
+		"Port Enabled/Disabled: %s "
+		"Current Connect Status: %s\n\n", ({
+			char *s;
+			switch (tmp_reg & PORTSCX_PTS_FSLS) {
+			case PORTSCX_PTS_UTMI:
+				s = "UTMI"; break;
+			case PORTSCX_PTS_ULPI:
+				s = "ULPI "; break;
+			case PORTSCX_PTS_FSLS:
+				s = "FS/LS Serial"; break;
+			default:
+				s = "None"; break;
+			}
+			s; }), ({
+			char *s;
+			switch (tmp_reg & PORTSCX_PORT_SPEED_UNDEF) {
+			case PORTSCX_PORT_SPEED_FULL:
+				s = "Full Speed"; break;
+			case PORTSCX_PORT_SPEED_LOW:
+				s = "Low Speed"; break;
+			case PORTSCX_PORT_SPEED_HIGH:
+				s = "High Speed"; break;
+			default:
+				s = "Undefined"; break;
+			}
+			s;
+		}),
+		(tmp_reg & PORTSCX_PHY_LOW_POWER_SPD) ?
+		"Normal PHY mode" : "Low power mode",
+		(tmp_reg & PORTSCX_PORT_RESET) ? "In Reset" :
+		"Not in Reset",
+		(tmp_reg & PORTSCX_PORT_SUSPEND) ? "In " : "Not in",
+		(tmp_reg & PORTSCX_OVER_CURRENT_CHG) ? "Dected" : "No",
+		(tmp_reg & PORTSCX_PORT_EN_DIS_CHANGE) ? "Disable" :
+		"Not change",
+		(tmp_reg & PORTSCX_PORT_ENABLE) ? "Enable" : "Not correct",
+		(tmp_reg & PORTSCX_CURRENT_CONNECT_STATUS) ?
+		"Attached" : "Not-Att");
+
+	tmp_reg = xusbps_readl(&dr_regs->usbmode);
+	seq_printf(m, "USB Mode Reg: Controller Mode is: %s\n\n", ({
+				char *s;
+				switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
+				case USB_MODE_CTRL_MODE_IDLE:
+					s = "Idle"; break;
+				case USB_MODE_CTRL_MODE_DEVICE:
+					s = "Device Controller"; break;
+				case USB_MODE_CTRL_MODE_HOST:
+					s = "Host Controller"; break;
+				default:
+					s = "None"; break;
+				}
+				s;
+			}));
+
+	tmp_reg = xusbps_readl(&dr_regs->endptsetupstat);
+	seq_printf(m, "Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n",
+			(tmp_reg & EP_SETUP_STATUS_MASK));
+
+	for (i = 0; i < udc->max_ep / 2; i++) {
+		tmp_reg = xusbps_readl(&dr_regs->endptctrl[i]);
+		seq_printf(m, "EP Ctrl Reg [0x%x]: = [0x%x]\n",
+				i, tmp_reg);
+	}
+	tmp_reg = xusbps_readl(&dr_regs->endpointprime);
+	seq_printf(m, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
+
+	/* ------xusbps_udc, xusbps_ep, xusbps_request structure information
+	 * ----- */
+	ep = &udc->eps[0];
+	seq_printf(m, "For %s Maxpkt is 0x%x index is 0x%x\n",
+			ep->ep.name, ep_maxpacket(ep), ep_index(ep));
+
+	if (list_empty(&ep->queue)) {
+		seq_puts(m, "its req queue is empty\n\n");
+	} else {
+		list_for_each_entry(req, &ep->queue, queue) {
+			seq_printf(m,
+				"req %p actual 0x%x length 0x%x buf %p\n",
+				&req->req, req->req.actual,
+				req->req.length, req->req.buf);
+		}
+	}
+	/* other gadget->eplist ep */
+	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+		if (ep->ep.desc) {
+			seq_printf(m, "\nFor %s Maxpkt is 0x%x "
+					"index is 0x%x\n",
+					ep->ep.name, ep_maxpacket(ep),
+					ep_index(ep));
+
+			if (list_empty(&ep->queue)) {
+				seq_puts(m, "its req queue is empty\n\n");
+			} else {
+				list_for_each_entry(req, &ep->queue, queue) {
+					seq_printf(m,
+						"req %p actual 0x%x length "
+						"0x%x  buf %p\n",
+						&req->req, req->req.actual,
+						req->req.length, req->req.buf);
+					} /* end for each_entry of ep req */
+				}	/* end for else */
+			}	/* end for if(ep->queue) */
+		}		/* end (ep->desc) */
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/*
+ * seq_file wrappers for procfile show routines.
+ */
+static int xusbps_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xusbps_proc_read, NULL);
+}
+
+static const struct file_operations proc_xusbps_fops = {
+	.open		= xusbps_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+#define create_proc_file()	proc_create(proc_filename, \
+					0, NULL, &proc_xusbps_fops)
+
+#define remove_proc_file()	remove_proc_entry(proc_filename, NULL)
+
+#else				/* !CONFIG_USB_GADGET_DEBUG_FILES */
+
+#define create_proc_file()	do {} while (0)
+#define remove_proc_file()	do {} while (0)
+
+#endif				/* CONFIG_USB_GADGET_DEBUG_FILES */
+
+/*-------------------------------------------------------------------------*/
+
+/* Release udc structures */
+static void xusbps_udc_release(struct device *dev)
+{
+	complete(udc_controller->done);
+	dma_free_coherent(dev->parent, udc_controller->ep_qh_size,
+			udc_controller->ep_qh, udc_controller->ep_qh_dma);
+	kfree(udc_controller);
+}
+
+/******************************************************************
+	Internal structure setup functions
+*******************************************************************/
+/*------------------------------------------------------------------
+ * init resource for globle controller
+ * Return the udc handle on success or NULL on failure
+ ------------------------------------------------------------------*/
+static int struct_udc_setup(struct xusbps_udc *udc,
+		struct platform_device *pdev)
+{
+	struct xusbps_usb2_platform_data *pdata;
+	size_t size;
+
+	pdata = pdev->dev.platform_data;
+	udc->phy_mode = pdata->phy_mode;
+
+	udc->eps = kzalloc(sizeof(*udc->eps) * udc->max_ep, GFP_KERNEL);
+	if (!udc->eps) {
+		dev_err(&pdev->dev, "malloc xusbps_ep failed\n");
+		return -1;
+	}
+
+	/* initialized QHs, take care of alignment */
+	size = udc->max_ep * sizeof(struct ep_queue_head);
+	if (size < QH_ALIGNMENT)
+		size = QH_ALIGNMENT;
+	else if ((size % QH_ALIGNMENT) != 0) {
+		size += QH_ALIGNMENT + 1;
+		size &= ~(QH_ALIGNMENT - 1);
+	}
+	udc->ep_qh = dma_alloc_coherent(&pdev->dev, size,
+					&udc->ep_qh_dma, GFP_KERNEL);
+	if (!udc->ep_qh) {
+		dev_err(&pdev->dev, "malloc QHs for udc failed\n");
+		kfree(udc->eps);
+		return -1;
+	}
+
+	udc->ep_qh_size = size;
+
+	/* Initialize ep0 status request structure */
+	/* FIXME: xusbps_alloc_request() ignores ep argument */
+	udc->status_req = container_of(xusbps_alloc_request(NULL, GFP_KERNEL),
+			struct xusbps_req, req);
+	/* allocate a small amount of memory to get valid address */
+	udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
+
+	udc->resume_state = USB_STATE_NOTATTACHED;
+	udc->usb_state = USB_STATE_POWERED;
+	udc->ep0_dir = 0;
+	udc->remote_wakeup = 0;	/* default to 0 on reset */
+
+	return 0;
+}
+
+/*----------------------------------------------------------------
+ * Setup the xusbps_ep struct for eps
+ * Link xusbps_ep->ep to gadget->ep_list
+ * ep0out is not used so do nothing here
+ * ep0in should be taken care
+ *--------------------------------------------------------------*/
+static int struct_ep_setup(struct xusbps_udc *udc,
+				unsigned char index, char *name, int link)
+{
+	struct xusbps_ep *ep = &udc->eps[index];
+
+	ep->udc = udc;
+	strcpy(ep->name, name);
+	ep->ep.name = ep->name;
+
+	ep->ep.ops = &xusbps_ep_ops;
+	ep->stopped = 0;
+
+	/* for ep0: maxP defined in desc
+	 * for other eps, maxP is set by epautoconfig() called by gadget layer
+	 */
+	ep->ep.maxpacket = (unsigned short) ~0;
+
+	/* the queue lists any req for this ep */
+	INIT_LIST_HEAD(&ep->queue);
+
+	/* gagdet.ep_list used for ep_autoconfig so no ep0 */
+	if (link)
+		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+	ep->gadget = &udc->gadget;
+	ep->qh = &udc->ep_qh[index];
+
+	return 0;
+}
+
+/* Driver probe function
+ * all intialization operations implemented here except enabling usb_intr reg
+ * board setup should have been done in the platform code
+ */
+static int xusbps_udc_probe(struct platform_device *pdev)
+{
+	int ret = -ENODEV;
+	unsigned int i;
+	u32 dccparams;
+	struct xusbps_usb2_platform_data *pdata;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		VDBG("Wrong device");
+		return -ENODEV;
+	}
+
+	if (strcmp(pdev->name, driver_name)) {
+		VDBG("Wrong device");
+		return -ENODEV;
+	}
+
+	udc_controller = kzalloc(sizeof(*udc_controller), GFP_KERNEL);
+	if (udc_controller == NULL) {
+		dev_err(&pdev->dev, "malloc udc failed\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&udc_controller->lock);
+	udc_controller->stopped = 1;
+
+	dr_regs = (struct usb_dr_device __iomem *)pdata->regs;
+	if (!dr_regs) {
+		ret = -ENOMEM;
+		goto err_kfree;
+	}
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (pdata->otg) {
+		udc_controller->transceiver = pdata->otg;
+		udc_controller->xotg =
+			xceiv_to_xotg(udc_controller->transceiver);
+	}
+#endif
+	/* Initialize USB clocks */
+	ret = xusbps_udc_clk_init(pdev);
+	if (ret < 0)
+		goto err_kfree;
+
+	/* Read Device Controller Capability Parameters register */
+	dccparams = xusbps_readl(&dr_regs->dccparams);
+	if (!(dccparams & DCCPARAMS_DC)) {
+		dev_err(&pdev->dev, "This SOC doesn't support device role\n");
+		ret = -ENODEV;
+		goto err_iounmap;
+	}
+	/* Get max device endpoints */
+	/* DEN is bidirectional ep number, max_ep doubles the number */
+	udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2;
+
+	udc_controller->irq = pdata->irq;
+	if (!udc_controller->irq) {
+		ret = -ENODEV;
+		goto err_iounmap;
+	}
+
+	ret = devm_request_irq(&pdev->dev, udc_controller->irq, xusbps_udc_irq,
+				IRQF_SHARED, driver_name, udc_controller);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "cannot request irq %d err %d\n",
+				udc_controller->irq, ret);
+		goto err_iounmap;
+	}
+
+	/* Initialize the udc structure including QH member and other member */
+	if (struct_udc_setup(udc_controller, pdev)) {
+		dev_err(&pdev->dev, "Can't initialize udc data structure\n");
+		ret = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	/* initialize usb hw reg except for regs for EP,
+	 * leave usbintr reg untouched */
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (!pdata->otg)
+		dr_controller_setup(udc_controller);
+#else
+	dr_controller_setup(udc_controller);
+#endif
+
+	/* Setup gadget structure */
+	udc_controller->gadget.ops = &xusbps_gadget_ops;
+	udc_controller->gadget.max_speed = USB_SPEED_HIGH;
+	udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
+	INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
+	udc_controller->gadget.name = driver_name;
+#ifdef CONFIG_USB_ZYNQ_PHY
+	udc_controller->gadget.is_otg = (pdata->otg != NULL);
+#endif
+
+	/* Setup gadget.dev and register with kernel */
+	dev_set_name(&udc_controller->gadget.dev, "gadget");
+	udc_controller->gadget.dev.release = xusbps_udc_release;
+	udc_controller->gadget.dev.parent = &pdev->dev;
+
+	/* setup QH and epctrl for ep0 */
+	ep0_setup(udc_controller);
+
+	/* setup udc->eps[] for ep0 */
+	struct_ep_setup(udc_controller, 0, "ep0", 0);
+	/* for ep0: the desc defined here;
+	 * for other eps, gadget layer called ep_enable with defined desc
+	 */
+	udc_controller->eps[0].ep.desc = &xusbps_ep0_desc;
+	udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD;
+
+	/* setup the udc->eps[] for non-control endpoints and link
+	 * to gadget.ep_list */
+	for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) {
+		char name[14];
+
+		sprintf(name, "ep%dout", i);
+		struct_ep_setup(udc_controller, i * 2, name, 1);
+		sprintf(name, "ep%din", i);
+		struct_ep_setup(udc_controller, i * 2 + 1, name, 1);
+	}
+
+	/* use dma_pool for TD management */
+	udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev,
+			sizeof(struct ep_td_struct),
+			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
+	if (udc_controller->td_pool == NULL) {
+		ret = -ENOMEM;
+		goto err_unregister;
+	}
+
+	/* TODO: Check if VBUS can be dynamically detected by VBUS session
+	 * interrupts using OTGSC register */
+	udc_controller->vbus_active = 1;
+
+	ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
+	if (ret)
+		goto err_del_udc;
+
+	create_proc_file();
+	return 0;
+
+err_del_udc:
+	dma_pool_destroy(udc_controller->td_pool);
+err_unregister:
+	device_unregister(&udc_controller->gadget.dev);
+err_iounmap:
+	xusbps_udc_clk_release(pdev);
+err_kfree:
+	kfree(udc_controller);
+	udc_controller = NULL;
+	return ret;
+}
+
+/* Driver removal function
+ * Free resources and finish pending transactions
+ */
+static int __exit xusbps_udc_remove(struct platform_device *pdev)
+{
+	DECLARE_COMPLETION(done);
+
+	if (!udc_controller)
+		return -ENODEV;
+
+	usb_del_gadget_udc(&udc_controller->gadget);
+	udc_controller->done = &done;
+
+	xusbps_udc_clk_release(pdev);
+
+	/* DR has been stopped in usb_gadget_unregister_driver() */
+	remove_proc_file();
+
+	/* Free allocated memory */
+	kfree(udc_controller->status_req->req.buf);
+	kfree(udc_controller->status_req);
+	kfree(udc_controller->eps);
+
+	dma_pool_destroy(udc_controller->td_pool);
+	free_irq(udc_controller->irq, udc_controller);
+	device_unregister(&udc_controller->gadget.dev);
+	/* free udc --wait for the release() finished */
+	wait_for_completion(&done);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+/*-----------------------------------------------------------------
+ * Modify Power management attributes
+ * Used by OTG statemachine to disable gadget temporarily
+ -----------------------------------------------------------------*/
+static int xusbps_udc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xusbps_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+	dr_controller_stop(udc_controller);
+
+	clk_disable(pdata->clk);
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------
+ * Invoked on USB resume. May be called in_interrupt.
+ * Here we start the DR controller and enable the irq
+ *-----------------------------------------------------------------*/
+static int xusbps_udc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xusbps_usb2_platform_data *pdata = pdev->dev.platform_data;
+	int ret;
+
+	ret = clk_enable(pdata->clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable APER clock.\n");
+		return ret;
+	}
+
+	/* Enable DR irq reg and set controller Run */
+	if (udc_controller->stopped) {
+		dr_controller_setup(udc_controller);
+		dr_controller_run(udc_controller);
+	}
+	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = 0;
+	return 0;
+}
+
+static const struct dev_pm_ops xusbps_udc_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xusbps_udc_suspend, xusbps_udc_resume)
+};
+#define XUSBPS_UDC_PM	(&xusbps_udc_dev_pm_ops)
+
+#else /* ! CONFIG_PM_SLEEP */
+#define XUSBPS_UDC_PM	NULL
+#endif /* ! CONFIG_PM_SLEEP */
+
+/*-------------------------------------------------------------------------
+	Register entry point for the peripheral controller driver
+--------------------------------------------------------------------------*/
+
+static struct platform_driver udc_driver = {
+	.probe   = xusbps_udc_probe,
+	.remove  = xusbps_udc_remove,
+	/* these suspend and resume are not usb suspend and resume */
+	.driver  = {
+		.name = (char *)driver_name,
+		.owner = THIS_MODULE,
+		.pm = XUSBPS_UDC_PM,
+	},
+};
+
+module_platform_driver(udc_driver);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:xusbps-udc");
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/host/ehci.h	2014-07-20 22:05:50.231066703 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci.h	2014-07-20 22:06:38.210275137 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:182 @
 	unsigned long		resuming_ports;		/* which ports have
 			started to resume */
 
+#ifdef CONFIG_USB_ZYNQ_PHY
+	/*
+	 * OTG controllers and transceivers need software interaction;
+	 * other external transceivers should be software-transparent
+	 */
+	void (*start_hnp)(struct ehci_hcd *ehci);
+#endif
+
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
 	struct dma_pool		*qtd_pool;	/* one or more per qh */
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-hcd.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/host/ehci-hcd.c	2014-07-20 22:05:50.234066654 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-hcd.c	2014-07-20 22:06:38.225274889 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:341 @
  */
 static void ehci_silence_controller(struct ehci_hcd *ehci)
 {
+#ifdef CONFIG_USB_ZYNQ_PHY
+	struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
+
 	ehci_halt(ehci);
 
 	spin_lock_irq(&ehci->lock);
 	ehci->rh_state = EHCI_RH_HALTED;
+#ifdef CONFIG_USB_ZYNQ_PHY
+	/* turn off for non-otg port */
+	if(!hcd->phy)
+		ehci_turn_off_all_ports(ehci);
+#else
 	ehci_turn_off_all_ports(ehci);
+#endif
 
 	/* make BIOS/etc use companion controller during reboot */
 	ehci_writel(ehci, 0, &ehci->regs->configured_flag);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:438 @
 
 	ehci_quiesce(ehci);
 	ehci_silence_controller(ehci);
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if(!hcd->phy)
+		ehci_reset (ehci);
+#else
 	ehci_reset (ehci);
+#endif
 
 	hrtimer_cancel(&ehci->hrtimer);
 	remove_sysfs_files(ehci);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:583 @
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	u32			temp;
 	u32			hcc_params;
+#if defined(CONFIG_ARCH_ZYNQ)
+	void __iomem *non_ehci = hcd->regs;
+#endif
 
 	hcd->uses_new_polling = 1;
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:655 @
 
 	ehci_writel(ehci, INTR_MASK,
 		    &ehci->regs->intr_enable); /* Turn On Interrupts */
-
+#if defined(CONFIG_ARCH_ZYNQ)
+	/* Modifying FIFO Burst Threshold value from 2 to 8 */
+	temp = readl(non_ehci + 0x164);
+	ehci_writel(ehci, 0x00080000, non_ehci + 0x164);
+#endif
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
 	 * since the class device isn't created that early.
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:708 @
 	u32			status, masked_status, pcd_status = 0, cmd;
 	int			bh;
 	unsigned long		flags;
+	u32			intr_en;
 
 	/*
 	 * For threadirqs option we use spin_lock_irqsave() variant to prevent
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:719 @
 	spin_lock_irqsave(&ehci->lock, flags);
 
 	status = ehci_readl(ehci, &ehci->regs->status);
+	intr_en = ehci_readl(ehci, &ehci->regs->intr_enable);
 
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if(hcd->phy) {
+		/* A device */
+		if (hcd->phy->otg->default_a &&
+			(hcd->phy->state == OTG_STATE_A_PERIPHERAL)) {
+			spin_unlock(&ehci->lock);
+			return IRQ_NONE;
+		}
+		/* B device */
+		if (!hcd->phy->otg->default_a &&
+			((hcd->phy->state != OTG_STATE_B_WAIT_ACON) &&
+			(hcd->phy->state != OTG_STATE_B_HOST))) {
+			spin_unlock(&ehci->lock);
+			return IRQ_NONE;
+		}
+		/* If HABA is set and B-disconnect occurs, don't process that interrupt */
+		if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) {
+			spin_unlock(&ehci->lock);
+			return IRQ_NONE;
+		}
+	}
+#endif
 	/* e.g. cardbus physical eject */
 	if (status == ~(u32) 0) {
 		ehci_dbg (ehci, "device removed\n");
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1294 @
 #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_XUSBPS
+#include "ehci-xilinx-usbps.c"
+#define PLATFORM_DRIVER		ehci_xusbps_driver
+#endif
+
 #ifdef CONFIG_USB_W90X900_EHCI
 #include "ehci-w90x900.c"
 #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-hub.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/host/ehci-hub.c	2014-07-20 22:05:50.235066638 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-hub.c	2014-07-20 22:06:38.241274626 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1183 @
 			 * Set appropriate bit thus could put phy into low power
 			 * mode if we have tdi_phy_lpm feature
 			 */
+#ifdef CONFIG_USB_ZYNQ_PHY
+			if (hcd->phy && (hcd->self.otg_port == (wIndex + 1))
+				&& (hcd->self.b_hnp_enable || hcd->self.is_b_host))
+				ehci->start_hnp(ehci);
+			else {
+				temp &= ~PORT_WKCONN_E;
+				temp |= PORT_WKDISC_E | PORT_WKOC_E;
+				ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+			}
+#else
 			temp &= ~PORT_WKCONN_E;
 			temp |= PORT_WKDISC_E | PORT_WKOC_E;
 			ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+#endif
 			if (ehci->has_tdi_phy_lpm) {
 				spin_unlock_irqrestore(&ehci->lock, flags);
 				msleep(5);/* 5ms for HCD enter low pwr mode */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1212 @
 			set_bit(wIndex, &ehci->suspended_ports);
 			break;
 		case USB_PORT_FEAT_POWER:
+#ifdef CONFIG_USB_ZYNQ_PHY
+			/* Check if otg is enabled */
+			if(!hcd->phy) {
+				if (HCS_PPC (ehci->hcs_params))
+					ehci_writel(ehci, temp | PORT_POWER,
+							status_reg);
+			}
+#else
 			if (HCS_PPC (ehci->hcs_params))
 				ehci_writel(ehci, temp | PORT_POWER,
 						status_reg);
+#endif
 			break;
 		case USB_PORT_FEAT_RESET:
 			if (temp & (PORT_SUSPEND|PORT_RESUME))
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-xilinx-usbps.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-xilinx-usbps.c	2014-07-20 22:06:38.253274428 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB Host Controller Driver.
+ *
+ * Copyright (C) 2011 Xilinx, Inc.
+ *
+ * This file is based on ehci-fsl.c file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/xilinx_devices.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/xilinx_usbps_otg.h>
+
+#include "ehci-xilinx-usbps.h"
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+/********************************************************************
+ * OTG related functions
+ ********************************************************************/
+static int ehci_xusbps_reinit(struct ehci_hcd *ehci);
+
+/* This connection event is useful when a OTG test device is connected.
+   In that case, the device connect notify event will not be generated
+   since the device will be suspended before complete enumeration.
+*/
+static int ehci_xusbps_update_device(struct usb_hcd *hcd, struct usb_device
+		*udev)
+{
+	struct xusbps_otg *xotg = xceiv_to_xotg(hcd->phy);
+
+	if (udev->portnum == hcd->self.otg_port) {
+		/* HNP test device */
+		if ((le16_to_cpu(udev->descriptor.idVendor) == 0x1a0a &&
+			le16_to_cpu(udev->descriptor.idProduct) == 0xbadd)) {
+			if (xotg->otg.otg->default_a == 1)
+				xotg->hsm.b_conn = 1;
+			else
+				xotg->hsm.a_conn = 1;
+			xusbps_update_transceiver();
+		}
+	}
+	return 0;
+}
+
+static void ehci_xusbps_start_hnp(struct ehci_hcd *ehci)
+{
+	const unsigned	port = ehci_to_hcd(ehci)->self.otg_port - 1;
+	struct usb_hcd *hcd = ehci_to_hcd(ehci);
+	unsigned long	flags;
+	u32 portsc;
+
+	local_irq_save(flags);
+	portsc = ehci_readl(ehci, &ehci->regs->port_status[port]);
+	portsc |= PORT_SUSPEND;
+	ehci_writel(ehci, portsc, &ehci->regs->port_status[port]);
+	local_irq_restore(flags);
+
+	otg_start_hnp(hcd->phy->otg);
+}
+
+static int ehci_xusbps_otg_start_host(struct usb_phy *otg)
+{
+	struct usb_hcd		*hcd = bus_to_hcd(otg->otg->host);
+	struct xusbps_otg *xotg =
+			xceiv_to_xotg(hcd->phy);
+
+	usb_add_hcd(hcd, xotg->irq, IRQF_SHARED);
+	return 0;
+}
+
+static int ehci_xusbps_otg_stop_host(struct usb_phy *otg)
+{
+	struct usb_hcd		*hcd = bus_to_hcd(otg->otg->host);
+
+	usb_remove_hcd(hcd);
+	return 0;
+}
+#endif
+
+static int xusbps_ehci_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers.
+		 */
+		/* fall through */
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+/**
+ * usb_hcd_xusbps_probe - initialize XUSBPS-based HCDs
+ * @driver: Driver to be used for this HCD
+ * @pdev: USB Host Controller being probed
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller.
+ *
+ */
+static int usb_hcd_xusbps_probe(const struct hc_driver *driver,
+			     struct platform_device *pdev)
+{
+	struct xusbps_usb2_platform_data *pdata;
+	struct usb_hcd *hcd;
+	int irq;
+	int retval;
+
+	pr_debug("initializing XUSBPS-SOC USB Controller\n");
+
+	/* Need platform data for setup */
+	pdata = (struct xusbps_usb2_platform_data *)pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev,
+			"No platform data for %s.\n", dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+
+	/*
+	 * This is a host mode driver, verify that we're supposed to be
+	 * in host mode.
+	 */
+	if (!((pdata->operating_mode == XUSBPS_USB2_DR_HOST) ||
+	      (pdata->operating_mode == XUSBPS_USB2_MPH_HOST) ||
+	      (pdata->operating_mode == XUSBPS_USB2_DR_OTG))) {
+		dev_err(&pdev->dev, "Non Host Mode configured for %s. Wrong \
+				driver linked.\n", dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	irq = pdata->irq;
+	hcd->regs = pdata->regs;
+
+	if (hcd->regs == NULL) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		retval = -EFAULT;
+		goto err2;
+	}
+
+	retval = clk_prepare_enable(pdata->clk);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto err2;
+	}
+
+	pdata->clk_rate_change_nb.notifier_call = xusbps_ehci_clk_notifier_cb;
+	pdata->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(pdata->clk, &pdata->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+
+	/*
+	 * do platform specific init: check the clock, grab/config pins, etc.
+	 */
+	if (pdata->init && pdata->init(pdev)) {
+		retval = -ENODEV;
+		goto err_out_clk_unreg_notif;
+	}
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+	if (pdata->otg) {
+		struct xusbps_otg *xotg;
+		struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+		hcd->self.otg_port = 1;
+		hcd->phy = pdata->otg;
+		retval = otg_set_host(hcd->phy->otg,
+				&ehci_to_hcd(ehci)->self);
+		if (retval)
+			goto err_out_clk_unreg_notif;
+		xotg = xceiv_to_xotg(hcd->phy);
+		ehci->start_hnp = ehci_xusbps_start_hnp;
+		xotg->start_host = ehci_xusbps_otg_start_host;
+		xotg->stop_host = ehci_xusbps_otg_stop_host;
+		/* inform otg driver about host driver */
+		xusbps_update_transceiver();
+	} else {
+		retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+		if (retval)
+			goto err_out_clk_unreg_notif;
+
+		/*
+		 * Enable vbus on ULPI - zedboard requirement
+		 * to get host mode to work
+		 */
+		if (pdata->ulpi)
+			otg_set_vbus(pdata->ulpi->otg, 1);
+	}
+#else
+	/* Don't need to set host mode here. It will be done by tdi_reset() */
+	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (retval)
+		goto err_out_clk_unreg_notif;
+#endif
+	return retval;
+
+err_out_clk_unreg_notif:
+	clk_notifier_unregister(pdata->clk, &pdata->clk_rate_change_nb);
+	clk_disable_unprepare(pdata->clk);
+err2:
+	usb_put_hcd(hcd);
+err1:
+	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
+	if (pdata->exit)
+		pdata->exit(pdev);
+
+	return retval;
+}
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_xusbps_remove - shutdown processing for XUSBPS-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_xusbps_probe().
+ *
+ */
+static void usb_hcd_xusbps_remove(struct usb_hcd *hcd,
+			       struct platform_device *pdev)
+{
+	struct xusbps_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+	usb_remove_hcd(hcd);
+
+	/*
+	 * do platform specific un-initialization:
+	 * release iomux pins, disable clock, etc.
+	 */
+	if (pdata->exit)
+		pdata->exit(pdev);
+	usb_put_hcd(hcd);
+	clk_notifier_unregister(pdata->clk, &pdata->clk_rate_change_nb);
+	clk_disable_unprepare(pdata->clk);
+}
+
+static void ehci_xusbps_setup_phy(struct ehci_hcd *ehci,
+			       enum xusbps_usb2_phy_modes phy_mode,
+			       unsigned int port_offset)
+{
+	u32 portsc;
+
+	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
+	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
+
+	switch (phy_mode) {
+	case XUSBPS_USB2_PHY_ULPI:
+		portsc |= PORT_PTS_ULPI;
+		break;
+	case XUSBPS_USB2_PHY_SERIAL:
+		portsc |= PORT_PTS_SERIAL;
+		break;
+	case XUSBPS_USB2_PHY_UTMI_WIDE:
+		portsc |= PORT_PTS_PTW;
+		/* fall through */
+	case XUSBPS_USB2_PHY_UTMI:
+		portsc |= PORT_PTS_UTMI;
+		break;
+	case XUSBPS_USB2_PHY_NONE:
+		break;
+	}
+	ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
+}
+
+static void ehci_xusbps_usb_setup(struct ehci_hcd *ehci)
+{
+	struct usb_hcd *hcd = ehci_to_hcd(ehci);
+	struct xusbps_usb2_platform_data *pdata;
+
+	pdata = hcd->self.controller->platform_data;
+
+	if ((pdata->operating_mode == XUSBPS_USB2_DR_HOST) ||
+			(pdata->operating_mode == XUSBPS_USB2_DR_OTG))
+		ehci_xusbps_setup_phy(ehci, pdata->phy_mode, 0);
+
+	if (pdata->operating_mode == XUSBPS_USB2_MPH_HOST) {
+		if (pdata->port_enables & XUSBPS_USB2_PORT0_ENABLED)
+			ehci_xusbps_setup_phy(ehci, pdata->phy_mode, 0);
+		if (pdata->port_enables & XUSBPS_USB2_PORT1_ENABLED)
+			ehci_xusbps_setup_phy(ehci, pdata->phy_mode, 1);
+	}
+}
+
+/*
+ * FIXME USB: EHCI: remove ehci_port_power() routine
+ *(sha1: c73cee717e7d5da0698acb720ad1219646fe4f46)
+ */
+static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
+{
+	unsigned port;
+
+	if (!HCS_PPC (ehci->hcs_params))
+		return;
+
+	ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
+	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
+		(void) ehci_hub_control(ehci_to_hcd(ehci),
+				is_on ? SetPortFeature : ClearPortFeature,
+				USB_PORT_FEAT_POWER,
+				port--, NULL, 0);
+	/* Flush those writes */
+	ehci_readl(ehci, &ehci->regs->command);
+	msleep(20);
+}
+
+/* called after powerup, by probe or system-pm "wakeup" */
+static int ehci_xusbps_reinit(struct ehci_hcd *ehci)
+{
+#ifdef CONFIG_USB_ZYNQ_PHY
+	struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
+
+	ehci_xusbps_usb_setup(ehci);
+#ifdef CONFIG_USB_ZYNQ_PHY
+	/* Don't turn off port power in OTG mode */
+	if (!hcd->phy)
+#endif
+		ehci_port_power(ehci, 0);
+
+	return 0;
+}
+
+struct ehci_xusbps {
+	struct ehci_hcd	ehci;
+
+#ifdef CONFIG_PM
+	/* Saved USB PHY settings, need to restore after deep sleep. */
+	u32 usb_ctrl;
+#endif
+};
+
+/* called during probe() after chip reset completes */
+static int ehci_xusbps_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+
+	/* EHCI registers start at offset 0x100 */
+	ehci->caps = hcd->regs + 0x100;
+	ehci->regs = hcd->regs + 0x100 +
+	    HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
+	dbg_hcs_params(ehci, "reset");
+	dbg_hcc_params(ehci, "reset");
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	hcd->has_tt = 1;
+
+	/* data structure init */
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	ehci->sbrn = 0x20;
+
+	ehci_reset(ehci);
+
+	retval = ehci_xusbps_reinit(ehci);
+	return retval;
+}
+
+static void ehci_xusbps_shutdown(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+	if (ehci->regs)
+		ehci_shutdown(hcd);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ehci_xusbps_drv_suspend(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct xusbps_usb2_platform_data *pdata = dev->platform_data;
+
+	ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd),
+			device_may_wakeup(dev));
+
+	clk_disable(pdata->clk);
+
+	return 0;
+}
+
+static int ehci_xusbps_drv_resume(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	struct xusbps_usb2_platform_data *pdata = dev->platform_data;
+	int ret;
+
+	ret = clk_enable(pdata->clk);
+	if (ret) {
+		dev_err(dev, "cannot enable clock. resume failed\n");
+		return ret;
+	}
+
+	ehci_prepare_ports_for_controller_resume(ehci);
+
+	usb_root_hub_lost_power(hcd->self.root_hub);
+
+	ehci_reset(ehci);
+	ehci_xusbps_reinit(ehci);
+
+	return 0;
+}
+
+static const struct dev_pm_ops ehci_xusbps_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ehci_xusbps_drv_suspend, ehci_xusbps_drv_resume)
+};
+#define EHCI_XUSBPS_PM_OPS	(&ehci_xusbps_pm_ops)
+
+#else /* ! CONFIG_PM_SLEEP */
+#define EHCI_XUSBPS_PM_OPS	NULL
+#endif /* ! CONFIG_PM_SLEEP */
+
+
+static const struct hc_driver ehci_xusbps_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "Xilinx PS USB EHCI Host Controller",
+	.hcd_priv_size = sizeof(struct ehci_xusbps),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq = ehci_irq,
+	.flags = HCD_USB2 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset = ehci_xusbps_setup,
+	.start = ehci_run,
+	.stop = ehci_stop,
+	.shutdown = ehci_xusbps_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue = ehci_urb_enqueue,
+	.urb_dequeue = ehci_urb_dequeue,
+	.endpoint_disable = ehci_endpoint_disable,
+	.endpoint_reset = ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number = ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data = ehci_hub_status_data,
+	.hub_control = ehci_hub_control,
+	.bus_suspend = ehci_bus_suspend,
+	.bus_resume = ehci_bus_resume,
+	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+#ifdef CONFIG_USB_ZYNQ_PHY
+	.update_device = ehci_xusbps_update_device,
+#endif
+};
+
+static int ehci_xusbps_drv_probe(struct platform_device *pdev)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	/* FIXME we only want one one probe() not two */
+	return usb_hcd_xusbps_probe(&ehci_xusbps_hc_driver, pdev);
+}
+
+static int ehci_xusbps_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	/* FIXME we only want one one remove() not two */
+	usb_hcd_xusbps_remove(hcd, pdev);
+	return 0;
+}
+
+MODULE_ALIAS("platform:xusbps-ehci");
+
+static struct platform_driver ehci_xusbps_driver = {
+	.probe = ehci_xusbps_drv_probe,
+	.remove = ehci_xusbps_drv_remove,
+	.shutdown = usb_hcd_platform_shutdown,
+	.driver = {
+		.name = "xusbps-ehci",
+		.pm = EHCI_XUSBPS_PM_OPS,
+	},
+};
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-xilinx-usbps.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/ehci-xilinx-usbps.h	2014-07-20 22:06:38.260274312 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB Host Controller Driver Header file.
+ *
+ * Copyright (C) 2011 Xilinx, Inc.
+ *
+ * This file is based on ehci-fsl.h file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef _EHCI_XILINX_XUSBPS_H
+#define _EHCI_XILINX_XUSBPS_H
+
+#include <linux/usb/xilinx_usbps_otg.h>
+
+/* offsets for the non-ehci registers in the XUSBPS SOC USB controller */
+#define XUSBPS_SOC_USB_ULPIVP	0x170
+#define XUSBPS_SOC_USB_PORTSC1	0x184
+#define PORT_PTS_MSK		(3<<30)
+#define PORT_PTS_UTMI		(0<<30)
+#define PORT_PTS_ULPI		(2<<30)
+#define	PORT_PTS_SERIAL		(3<<30)
+#define PORT_PTS_PTW		(1<<28)
+#define XUSBPS_SOC_USB_PORTSC2	0x188
+
+#endif				/* _EHCI_XILINX_XUSBPS_H */
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/host/Kconfig	2014-07-20 22:05:50.233066671 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/Kconfig	2014-07-20 22:06:38.270274147 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:118 @
 		support both high speed and full speed devices, or high speed
 		devices only.
 
+config USB_XUSBPS_DR_OF
+	tristate
+	select USB_PHY
+	select USB_ULPI
+	select USB_ULPI_VIEWPORT
+
+config USB_EHCI_XUSBPS
+	bool "Support for Xilinx PS EHCI USB controller"
+	depends on USB_EHCI_HCD && ARCH_ZYNQ
+	select USB_EHCI_ROOT_HUB_TT
+	select USB_XUSBPS_DR_OF
+	---help---
+		Xilinx PS USB host controller core is EHCI compilant and has
+		transaction translator built-in.
+
 config USB_EHCI_FSL
 	bool "Support for Freescale PPC on-chip EHCI USB controller"
 	depends on FSL_SOC
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/host/Makefile	2014-07-20 22:05:50.232066687 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/Makefile	2014-07-20 22:06:38.280273982 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:61 @
 obj-$(CONFIG_USB_HWA_HCD)	+= hwa-hc.o
 obj-$(CONFIG_USB_IMX21_HCD)	+= imx21-hcd.o
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
+obj-$(CONFIG_USB_XUSBPS_DR_OF)	+= xusbps-dr-of.o
 obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
Index: linux-3.12.24-rt38-xilinx/drivers/usb/host/xusbps-dr-of.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/host/xusbps-dr-of.c	2014-07-20 22:06:38.290273817 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB Driver for device tree support.
+ *
+ * Copyright (C) 2011 Xilinx, Inc.
+ *
+ * This file is based on fsl-mph-dr-of.c file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * Setup platform devices needed by the dual-role USB controller modules
+ * based on the description in flat device tree.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/xilinx_devices.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/usb/ulpi.h>
+
+#include "ehci-xilinx-usbps.h"
+
+static u64 dma_mask = 0xFFFFFFF0;
+
+struct xusbps_dev_data {
+	char *dr_mode;		/* controller mode */
+	char *drivers[3];	/* drivers to instantiate for this mode */
+	enum xusbps_usb2_operating_modes op_mode;	/* operating mode */
+};
+
+struct xusbps_host_data {
+	struct clk *clk;
+};
+
+static struct xusbps_dev_data dr_mode_data[] = {
+	{
+		.dr_mode = "host",
+		.drivers = { "xusbps-ehci", NULL, NULL, },
+		.op_mode = XUSBPS_USB2_DR_HOST,
+	},
+	{
+		.dr_mode = "otg",
+		.drivers = { "xusbps-otg", "xusbps-ehci", "xusbps-udc", },
+		.op_mode = XUSBPS_USB2_DR_OTG,
+	},
+	{
+		.dr_mode = "peripheral",
+		.drivers = { "xusbps-udc", NULL, NULL, },
+		.op_mode = XUSBPS_USB2_DR_DEVICE,
+	},
+};
+
+static struct xusbps_dev_data * get_dr_mode_data(
+		struct device_node *np)
+{
+	const unsigned char *prop;
+	int i;
+
+	prop = of_get_property(np, "dr_mode", NULL);
+	if (prop) {
+		for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) {
+			if (!strcmp(prop, dr_mode_data[i].dr_mode))
+				return &dr_mode_data[i];
+		}
+	}
+	pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n",
+		np->full_name);
+	return &dr_mode_data[0]; /* mode not specified, use host */
+}
+
+static enum xusbps_usb2_phy_modes determine_usb_phy(const char *phy_type)
+{
+	if (!phy_type)
+		return XUSBPS_USB2_PHY_NONE;
+	if (!strcasecmp(phy_type, "ulpi"))
+		return XUSBPS_USB2_PHY_ULPI;
+	if (!strcasecmp(phy_type, "utmi"))
+		return XUSBPS_USB2_PHY_UTMI;
+	if (!strcasecmp(phy_type, "utmi_wide"))
+		return XUSBPS_USB2_PHY_UTMI_WIDE;
+	if (!strcasecmp(phy_type, "serial"))
+		return XUSBPS_USB2_PHY_SERIAL;
+
+	return XUSBPS_USB2_PHY_NONE;
+}
+
+static struct platform_device * xusbps_device_register(
+					struct platform_device *ofdev,
+					struct xusbps_usb2_platform_data *pdata,
+					const char *name, int id)
+{
+	struct platform_device *pdev;
+	const struct resource *res = ofdev->resource;
+	unsigned int num = ofdev->num_resources;
+	struct xusbps_usb2_platform_data *pdata1;
+	int retval;
+
+	pdev = platform_device_alloc(name, id);
+	if (!pdev) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	pdev->dev.parent = &ofdev->dev;
+
+	pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
+	pdev->dev.dma_mask = &dma_mask;
+
+	retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+	if (retval)
+		goto error;
+
+	if (num) {
+		retval = platform_device_add_resources(pdev, res, num);
+		if (retval)
+			goto error;
+	}
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto error;
+
+	pdata1 = pdev->dev.platform_data;
+	/* Copy the otg transceiver pointer into host/device platform data */
+	if (pdata1->otg)
+		pdata->otg = pdata1->otg;
+
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return ERR_PTR(retval);
+}
+
+static int xusbps_dr_of_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct platform_device *usb_dev;
+	struct xusbps_usb2_platform_data data, *pdata;
+	struct xusbps_dev_data *dev_data;
+	struct xusbps_host_data *hdata;
+	const unsigned char *prop;
+	static unsigned int idx;
+	struct resource *res;
+	int i, phy_init;
+	int ret;
+
+	pdata = &data;
+	memset(pdata, 0, sizeof(data));
+
+	res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0);
+	if (IS_ERR(res)) {
+		dev_err(&ofdev->dev,
+			"IRQ not found\n");
+		return PTR_ERR(res);
+	}
+	pdata->irq = res->start;
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	pdata->regs = devm_ioremap_resource(&ofdev->dev, res);
+	if (IS_ERR(pdata->regs)) {
+		dev_err(&ofdev->dev, "unable to iomap registers\n");
+		return PTR_ERR(pdata->regs);
+	}
+
+	dev_data = get_dr_mode_data(np);
+	pdata->operating_mode = dev_data->op_mode;
+
+	prop = of_get_property(np, "phy_type", NULL);
+	pdata->phy_mode = determine_usb_phy(prop);
+
+	hdata = devm_kzalloc(&ofdev->dev, sizeof(*hdata), GFP_KERNEL);
+	if (!hdata)
+		return -ENOMEM;
+	platform_set_drvdata(ofdev, hdata);
+
+	hdata->clk = devm_clk_get(&ofdev->dev, NULL);
+	if (IS_ERR(hdata->clk)) {
+		dev_err(&ofdev->dev, "input clock not found.\n");
+		return PTR_ERR(hdata->clk);
+	}
+
+	ret = clk_prepare_enable(hdata->clk);
+	if (ret) {
+		dev_err(&ofdev->dev, "Unable to enable APER clock.\n");
+		return ret;
+	}
+
+	pdata->clk = hdata->clk;
+
+	/* If ULPI phy type, set it up */
+	if (pdata->phy_mode == XUSBPS_USB2_PHY_ULPI) {
+		pdata->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops,
+			ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+		if (pdata->ulpi) {
+			pdata->ulpi->io_priv = pdata->regs +
+							XUSBPS_SOC_USB_ULPIVP;
+
+			phy_init = usb_phy_init(pdata->ulpi);
+			if (phy_init) {
+				dev_err(&ofdev->dev,
+					"Unable to init USB phy, missing?\n");
+				ret = -ENODEV;
+				goto err_out_clk_disable;
+			}
+		} else {
+			dev_err(&ofdev->dev,
+				"Unable to create ULPI transceiver\n");
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
+		if (!dev_data->drivers[i])
+			continue;
+		usb_dev = xusbps_device_register(ofdev, pdata,
+					dev_data->drivers[i], idx);
+		if (IS_ERR(usb_dev)) {
+			dev_err(&ofdev->dev, "Can't register usb device\n");
+			ret = PTR_ERR(usb_dev);
+			goto err_out_clk_disable;
+		}
+	}
+	idx++;
+	return 0;
+
+err_out_clk_disable:
+	clk_disable_unprepare(hdata->clk);
+
+	return ret;
+}
+
+static int __unregister_subdev(struct device *dev, void *d)
+{
+	platform_device_unregister(to_platform_device(dev));
+	return 0;
+}
+
+static int xusbps_dr_of_remove(struct platform_device *ofdev)
+{
+	struct xusbps_host_data *hdata = platform_get_drvdata(ofdev);
+
+	device_for_each_child(&ofdev->dev, NULL, __unregister_subdev);
+	clk_disable_unprepare(hdata->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int xusbps_dr_of_suspend(struct device *dev)
+{
+	struct xusbps_host_data *hdata = dev_get_drvdata(dev);
+
+	clk_disable(hdata->clk);
+
+	return 0;
+}
+
+static int xusbps_dr_of_resume(struct device *dev)
+{
+	struct xusbps_host_data *hdata = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_enable(hdata->clk);
+	if (ret) {
+		dev_err(dev, "cannot enable clock. resume failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(xusbps_pm_ops, xusbps_dr_of_suspend,
+		xusbps_dr_of_resume);
+
+static const struct of_device_id xusbps_dr_of_match[] = {
+	{ .compatible = "xlnx,ps7-usb-1.00.a" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, xusbps_dr_of_match);
+
+static struct platform_driver xusbps_dr_driver = {
+	.driver = {
+		.name = "xusbps-dr",
+		.owner = THIS_MODULE,
+		.of_match_table = xusbps_dr_of_match,
+		.pm = &xusbps_pm_ops,
+	},
+	.probe	= xusbps_dr_of_probe,
+	.remove	= xusbps_dr_of_remove,
+};
+
+#ifdef CONFIG_USB_ZYNQ_PHY
+extern struct platform_driver xusbps_otg_driver;
+
+static int __init xusbps_dr_init(void)
+{
+	int retval;
+
+	/* Register otg driver first */
+	retval = platform_driver_register(&xusbps_otg_driver);
+	if (retval != 0)
+		return retval;
+
+	return platform_driver_register(&xusbps_dr_driver);
+}
+module_init(xusbps_dr_init);
+
+static void __exit xusbps_dr_exit(void)
+{
+	platform_driver_unregister(&xusbps_dr_driver);
+}
+module_exit(xusbps_dr_exit);
+#else
+module_platform_driver(xusbps_dr_driver);
+#endif
+
+MODULE_DESCRIPTION("XUSBPS DR OF devices driver");
+MODULE_AUTHOR("Xilinx");
+MODULE_LICENSE("GPL");
Index: linux-3.12.24-rt38-xilinx/drivers/usb/phy/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/phy/Kconfig	2014-07-20 22:05:50.230066720 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/phy/Kconfig	2014-07-20 22:06:38.303273603 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:231 @
 	  Provides read/write operations to the ULPI phy register set for
 	  controllers with a viewport register (e.g. Chipidea/ARC controllers).
 
+config USB_ZYNQ_PHY
+	tristate "Xilinx Zynq USB OTG dual-role support"
+	depends on USB && ARCH_ZYNQ && USB_EHCI_XUSBPS && USB_GADGET_XUSBPS && USB_OTG
+	select USB_OTG_UTILS
+	help
+	  Say Y here if you want to build Xilinx USB PS OTG
+	  driver in kernel. This driver implements role
+	  switch between EHCI host driver and USB gadget driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called xilinx_usbps_otg.
+
 endmenu
Index: linux-3.12.24-rt38-xilinx/drivers/usb/phy/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/usb/phy/Makefile	2014-07-20 22:05:50.229066737 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/usb/phy/Makefile	2014-07-20 22:06:38.312273454 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:34 @
 obj-$(CONFIG_USB_RCAR_PHY)		+= phy-rcar-usb.o
 obj-$(CONFIG_USB_ULPI)			+= phy-ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)		+= phy-ulpi-viewport.o
+obj-$(CONFIG_USB_ZYNQ_PHY)		+= phy-zynq-usb.o
Index: linux-3.12.24-rt38-xilinx/drivers/usb/phy/phy-zynq-usb.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/usb/phy/phy-zynq-usb.c	2014-07-20 22:06:38.341272976 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB otg driver.
+ *
+ * Copyright 2011 Xilinx, Inc.
+ *
+ * This file is based on langwell_otg.c file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* This driver helps to switch Xilinx OTG controller function between host
+ * and peripheral. It works with EHCI driver and Xilinx client controller
+ * driver together.
+ */
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/moduleparam.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/hcd.h>
+#include <linux/notifier.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/io.h>
+
+#include "../core/usb.h"
+
+#include <linux/xilinx_devices.h>
+#include <linux/usb/xilinx_usbps_otg.h>
+
+#define	DRIVER_NAME	"xusbps-otg"
+
+static const char driver_name[] = DRIVER_NAME;
+
+/* HSM timers */
+static inline struct xusbps_otg_timer *otg_timer_initializer
+(void (*function)(unsigned long), unsigned long expires, unsigned long data)
+{
+	struct xusbps_otg_timer *timer;
+	timer = kmalloc(sizeof(struct xusbps_otg_timer), GFP_KERNEL);
+	if (timer == NULL)
+		return timer;
+
+	timer->function = function;
+	timer->expires = expires;
+	timer->data = data;
+	return timer;
+}
+
+static struct xusbps_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr,
+	*b_se0_srp_tmr, *b_srp_init_tmr;
+
+static struct list_head active_timers;
+
+static struct xusbps_otg *the_transceiver;
+
+/* host/client notify transceiver when event affects HNP state */
+void xusbps_update_transceiver(void)
+{
+	struct xusbps_otg *xotg = the_transceiver;
+
+	dev_dbg(xotg->dev, "transceiver is updated\n");
+
+	if (!xotg->qwork)
+		return ;
+
+	queue_work(xotg->qwork, &xotg->work);
+}
+EXPORT_SYMBOL(xusbps_update_transceiver);
+
+static int xusbps_otg_set_host(struct usb_otg *otg,
+					struct usb_bus *host)
+{
+	otg->host = host;
+
+	if (host) {
+		if (otg->default_a)
+			host->is_b_host = 0;
+		else
+			host->is_b_host = 1;
+	}
+
+	return 0;
+}
+
+static int xusbps_otg_set_peripheral(struct usb_otg *otg,
+					struct usb_gadget *gadget)
+{
+	otg->gadget = gadget;
+
+	if (gadget) {
+		if (otg->default_a)
+			gadget->is_a_peripheral = 1;
+		else
+			gadget->is_a_peripheral = 0;
+	}
+
+	return 0;
+}
+
+static int xusbps_otg_set_power(struct usb_phy *otg,
+				unsigned mA)
+{
+	return 0;
+}
+
+/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
+static int xusbps_otg_set_vbus(struct usb_otg *otg, bool enabled)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32 val;
+
+	dev_dbg(xotg->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off");
+
+	/* Enable ulpi VBUS if required */
+	if (xotg->ulpi)
+		otg_set_vbus(xotg->ulpi->otg, enabled);
+
+	val = readl(xotg->base + CI_PORTSC1);
+
+	if (enabled)
+		writel((val | PORTSC_PP), xotg->base + CI_PORTSC1);
+	else
+		writel((val & ~PORTSC_PP), xotg->base + CI_PORTSC1);
+
+	dev_dbg(xotg->dev, "%s --->\n", __func__);
+
+	return 0;
+}
+
+/* Charge vbus for VBUS pulsing in SRP */
+static void xusbps_otg_chrg_vbus(int on)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	u32	val;
+
+	val = readl(xotg->base + CI_OTGSC) & ~OTGSC_INTSTS_MASK;
+
+	if (on)
+		/* stop discharging, start charging */
+		val = (val & ~OTGSC_VD) | OTGSC_VC;
+	else
+		/* stop charging */
+		val &= ~OTGSC_VC;
+
+	writel(val, xotg->base + CI_OTGSC);
+}
+
+#if 0
+
+/* Discharge vbus through a resistor to ground */
+static void xusbps_otg_dischrg_vbus(int on)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	u32	val;
+
+	val = readl(xotg->base + CI_OTGSC) & ~OTGSC_INTSTS_MASK;
+
+	if (on)
+		/* stop charging, start discharging */
+		val = (val & ~OTGSC_VC) | OTGSC_VD;
+	else
+		val &= ~OTGSC_VD;
+
+	writel(val, xotg->base + CI_OTGSC);
+}
+
+#endif
+
+/* Start SRP */
+static int xusbps_otg_start_srp(struct usb_otg *otg)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32				val;
+
+	dev_warn(xotg->dev, "Starting SRP...\n");
+	dev_dbg(xotg->dev, "%s --->\n", __func__);
+
+	val = readl(xotg->base + CI_OTGSC);
+
+	writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
+				xotg->base + CI_OTGSC);
+
+	/* Check if the data plus is finished or not */
+	msleep(8);
+	val = readl(xotg->base + CI_OTGSC);
+	if (val & (OTGSC_HADP | OTGSC_DP))
+		dev_dbg(xotg->dev, "DataLine SRP Error\n");
+
+	/* If Vbus is valid, then update the hsm */
+	if (val & OTGSC_BSV) {
+		dev_dbg(xotg->dev, "no b_sess_vld interrupt\n");
+
+		xotg->hsm.b_sess_vld = 1;
+		xusbps_update_transceiver();
+		return 0;
+	}
+
+	dev_warn(xotg->dev, "Starting VBUS Pulsing...\n");
+
+	/* Disable interrupt - b_sess_vld */
+	val = readl(xotg->base + CI_OTGSC);
+	val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
+	writel(val, xotg->base + CI_OTGSC);
+
+	/* Start VBus SRP, drive vbus to generate VBus pulse */
+	xusbps_otg_chrg_vbus(1);
+	msleep(15);
+	xusbps_otg_chrg_vbus(0);
+
+	/* Enable interrupt - b_sess_vld*/
+	val = readl(xotg->base + CI_OTGSC);
+	dev_dbg(xotg->dev, "after VBUS pulse otgsc = %x\n", val);
+
+	val |= (OTGSC_BSVIE | OTGSC_BSEIE);
+	writel(val, xotg->base + CI_OTGSC);
+
+	/* If Vbus is valid, then update the hsm */
+	if (val & OTGSC_BSV) {
+		dev_dbg(xotg->dev, "no b_sess_vld interrupt\n");
+
+		xotg->hsm.b_sess_vld = 1;
+		xusbps_update_transceiver();
+	}
+
+	dev_dbg(xotg->dev, "%s <---\n", __func__);
+	return 0;
+}
+
+/* Start HNP */
+static int xusbps_otg_start_hnp(struct usb_otg *otg)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	unsigned long flag = 0;
+
+	dev_warn(xotg->dev, "Starting HNP...\n");
+	dev_dbg(xotg->dev, "%s --->\n", __func__);
+
+	if (xotg->otg.otg->default_a && xotg->otg.otg->host &&
+			xotg->otg.otg->host->b_hnp_enable) {
+		xotg->hsm.a_suspend_req = 1;
+		flag = 1;
+	}
+
+	if (!xotg->otg.otg->default_a && xotg->otg.otg->host &&
+			xotg->hsm.b_bus_req) {
+		xotg->hsm.b_bus_req = 0;
+		flag = 1;
+	}
+
+	if (flag) {
+		if (spin_trylock(&xotg->wq_lock)) {
+			xusbps_update_transceiver();
+			spin_unlock(&xotg->wq_lock);
+		}
+	} else
+		dev_warn(xotg->dev, "HNP not supported\n");
+
+	dev_dbg(xotg->dev, "%s <---\n", __func__);
+	return 0;
+}
+
+/* stop SOF via bus_suspend */
+static void xusbps_otg_loc_sof(int on)
+{
+	/* Not used */
+}
+
+static void xusbps_otg_phy_low_power(int on)
+{
+	/* Not used */
+}
+
+/* After drv vbus, add 2 ms delay to set PHCD */
+static void xusbps_otg_phy_low_power_wait(int on)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+
+	dev_dbg(xotg->dev, "add 2ms delay before programing PHCD\n");
+
+	mdelay(2);
+	xusbps_otg_phy_low_power(on);
+}
+
+#ifdef CONFIG_PM_SLEEP
+/* Enable/Disable OTG interrupt */
+static void xusbps_otg_intr(int on)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32				val;
+
+	dev_dbg(xotg->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+
+	val = readl(xotg->base + CI_OTGSC);
+
+	/* OTGSC_INT_MASK doesn't contains 1msInt */
+	if (on) {
+		val = val | (OTGSC_INT_MASK);
+		writel(val, xotg->base + CI_OTGSC);
+	} else {
+		val = val & ~(OTGSC_INT_MASK);
+		writel(val, xotg->base + CI_OTGSC);
+	}
+
+	dev_dbg(xotg->dev, "%s <---\n", __func__);
+}
+#endif
+
+/* set HAAR: Hardware Assist Auto-Reset */
+static void xusbps_otg_HAAR(int on)
+{
+	/* Not used */
+}
+
+/* set HABA: Hardware Assist B-Disconnect to A-Connect */
+static void xusbps_otg_HABA(int on)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32				val;
+
+	dev_dbg(xotg->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+
+	val = readl(xotg->base + CI_OTGSC);
+	if (on)
+		writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
+					xotg->base + CI_OTGSC);
+	else
+		writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
+					xotg->base + CI_OTGSC);
+
+	dev_dbg(xotg->dev, "%s <---\n", __func__);
+}
+
+static int xusbps_otg_check_se0_srp(int on)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	int			delay_time = TB_SE0_SRP * 10;
+	u32			val;
+
+	dev_dbg(xotg->dev, "%s --->\n", __func__);
+
+	do {
+		udelay(100);
+		if (!delay_time--)
+			break;
+		val = readl(xotg->base + CI_PORTSC1);
+		val &= PORTSC_LS;
+	} while (!val);
+
+	dev_dbg(xotg->dev, "%s <---\n", __func__);
+	return val;
+}
+
+/* The timeout callback function to set time out bit */
+static void set_tmout(unsigned long indicator)
+{
+	*(int *)indicator = 1;
+}
+
+static void xusbps_otg_msg(unsigned long indicator)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+
+	switch (indicator) {
+	case 2:
+	case 4:
+	case 6:
+	case 7:
+		dev_warn(xotg->dev,
+			"OTG:%lu - deivce not responding\n", indicator);
+		break;
+	case 3:
+		dev_warn(xotg->dev,
+			"OTG:%lu - deivce not supported\n", indicator);
+		break;
+	default:
+		dev_warn(xotg->dev, "Do not have this msg\n");
+		break;
+	}
+}
+
+/* Initialize timers */
+static int xusbps_otg_init_timers(struct otg_hsm *hsm)
+{
+	/* HSM used timers */
+	a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
+				(unsigned long)&hsm->a_wait_vrise_tmout);
+	if (a_wait_vrise_tmr == NULL)
+		return -ENOMEM;
+	a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
+				(unsigned long)&hsm->a_aidl_bdis_tmout);
+	if (a_aidl_bdis_tmr == NULL)
+		return -ENOMEM;
+	b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
+				(unsigned long)&hsm->b_se0_srp);
+	if (b_se0_srp_tmr == NULL)
+		return -ENOMEM;
+	b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT,
+				(unsigned long)&hsm->b_srp_init_tmout);
+	if (b_srp_init_tmr == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/* Free timers */
+static void xusbps_otg_free_timers(void)
+{
+	kfree(a_wait_vrise_tmr);
+	kfree(a_aidl_bdis_tmr);
+	kfree(b_se0_srp_tmr);
+	kfree(b_srp_init_tmr);
+}
+
+/* The timeout callback function to set time out bit */
+static void xusbps_otg_timer_fn(unsigned long indicator)
+{
+	struct xusbps_otg *xotg = the_transceiver;
+
+	*(int *)indicator = 1;
+
+	dev_dbg(xotg->dev, "kernel timer - timeout\n");
+
+	xusbps_update_transceiver();
+}
+
+/* kernel timer used instead of HW based interrupt */
+static void xusbps_otg_add_ktimer(enum xusbps_otg_timer_type timers)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	unsigned long		j = jiffies;
+	unsigned long		data, time;
+
+	switch (timers) {
+	case TA_WAIT_VRISE_TMR:
+		xotg->hsm.a_wait_vrise_tmout = 0;
+		data = (unsigned long)&xotg->hsm.a_wait_vrise_tmout;
+		time = TA_WAIT_VRISE;
+		break;
+	case TA_WAIT_BCON_TMR:
+		xotg->hsm.a_wait_bcon_tmout = 0;
+		data = (unsigned long)&xotg->hsm.a_wait_bcon_tmout;
+		time = TA_WAIT_BCON;
+		break;
+	case TA_AIDL_BDIS_TMR:
+		xotg->hsm.a_aidl_bdis_tmout = 0;
+		data = (unsigned long)&xotg->hsm.a_aidl_bdis_tmout;
+		time = TA_AIDL_BDIS;
+		break;
+	case TB_ASE0_BRST_TMR:
+		xotg->hsm.b_ase0_brst_tmout = 0;
+		data = (unsigned long)&xotg->hsm.b_ase0_brst_tmout;
+		time = TB_ASE0_BRST;
+		break;
+	case TB_SRP_INIT_TMR:
+		xotg->hsm.b_srp_init_tmout = 0;
+		data = (unsigned long)&xotg->hsm.b_srp_init_tmout;
+		time = TB_SRP_INIT;
+		break;
+	case TB_SRP_FAIL_TMR:
+		xotg->hsm.b_srp_fail_tmout = 0;
+		data = (unsigned long)&xotg->hsm.b_srp_fail_tmout;
+		time = TB_SRP_FAIL;
+		break;
+	case TB_BUS_SUSPEND_TMR:
+		xotg->hsm.b_bus_suspend_tmout = 0;
+		data = (unsigned long)&xotg->hsm.b_bus_suspend_tmout;
+		time = TB_BUS_SUSPEND;
+		break;
+	default:
+		dev_dbg(xotg->dev, "unkown timer, cannot enable it\n");
+		return;
+	}
+
+	xotg->hsm_timer.data = data;
+	xotg->hsm_timer.function = xusbps_otg_timer_fn;
+	xotg->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */
+
+	add_timer(&xotg->hsm_timer);
+
+	dev_dbg(xotg->dev, "add timer successfully\n");
+}
+
+/* Add timer to timer list */
+static void xusbps_otg_add_timer(void *gtimer)
+{
+	struct xusbps_otg *xotg = the_transceiver;
+	struct xusbps_otg_timer *timer = (struct xusbps_otg_timer *)gtimer;
+	struct xusbps_otg_timer *tmp_timer;
+	u32	val32;
+
+	/* Check if the timer is already in the active list,
+	 * if so update timer count
+	 */
+	list_for_each_entry(tmp_timer, &active_timers, list)
+		if (tmp_timer == timer) {
+			timer->count = timer->expires;
+			return;
+		}
+	timer->count = timer->expires;
+
+	if (list_empty(&active_timers)) {
+		val32 = readl(xotg->base + CI_OTGSC);
+		writel(val32 | OTGSC_1MSE, xotg->base + CI_OTGSC);
+	}
+
+	list_add_tail(&timer->list, &active_timers);
+}
+
+/* Remove timer from the timer list; clear timeout status */
+static void xusbps_otg_del_timer(void *gtimer)
+{
+	struct xusbps_otg *xotg = the_transceiver;
+	struct xusbps_otg_timer *timer = (struct xusbps_otg_timer *)gtimer;
+	struct xusbps_otg_timer *tmp_timer, *del_tmp;
+	u32 val32;
+
+	list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
+		if (tmp_timer == timer)
+			list_del(&timer->list);
+
+	if (list_empty(&active_timers)) {
+		val32 = readl(xotg->base + CI_OTGSC);
+		writel(val32 & ~OTGSC_1MSE, xotg->base + CI_OTGSC);
+	}
+}
+
+/* Reduce timer count by 1, and find timeout conditions.*/
+static int xusbps_otg_tick_timer(u32 *int_sts)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	struct xusbps_otg_timer *tmp_timer, *del_tmp;
+	int expired = 0;
+
+	list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
+		tmp_timer->count--;
+		/* check if timer expires */
+		if (!tmp_timer->count) {
+			list_del(&tmp_timer->list);
+			tmp_timer->function(tmp_timer->data);
+			expired = 1;
+		}
+	}
+
+	if (list_empty(&active_timers)) {
+		dev_dbg(xotg->dev, "tick timer: disable 1ms int\n");
+		*int_sts = *int_sts & ~OTGSC_1MSE;
+	}
+	return expired;
+}
+
+static void reset_otg(void)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	int			delay_time = 1000;
+	u32			val;
+
+	dev_dbg(xotg->dev, "reseting OTG controller ...\n");
+	val = readl(xotg->base + CI_USBCMD);
+	writel(val | USBCMD_RST, xotg->base + CI_USBCMD);
+	do {
+		udelay(100);
+		if (!delay_time--)
+			dev_dbg(xotg->dev, "reset timeout\n");
+		val = readl(xotg->base + CI_USBCMD);
+		val &= USBCMD_RST;
+	} while (val != 0);
+	dev_dbg(xotg->dev, "reset done.\n");
+}
+
+static void set_host_mode(void)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	u32			val;
+
+	reset_otg();
+	val = readl(xotg->base + CI_USBMODE);
+	val = (val & (~USBMODE_CM)) | USBMODE_HOST;
+	writel(val, xotg->base + CI_USBMODE);
+}
+
+static void set_client_mode(void)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	u32			val;
+
+	reset_otg();
+	val = readl(xotg->base + CI_USBMODE);
+	val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
+	writel(val, xotg->base + CI_USBMODE);
+}
+
+static void init_hsm(void)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32				val32;
+
+	/* read OTGSC after reset */
+	val32 = readl(xotg->base + CI_OTGSC);
+
+	/* set init state */
+	if (val32 & OTGSC_ID) {
+		xotg->hsm.id = 1;
+		xotg->otg.otg->default_a = 0;
+		set_client_mode();
+		xotg->otg.state = OTG_STATE_B_IDLE;
+	} else {
+		xotg->hsm.id = 0;
+		xotg->otg.otg->default_a = 1;
+		set_host_mode();
+		xotg->otg.state = OTG_STATE_A_IDLE;
+	}
+
+	/* set session indicator */
+	if (!xotg->otg.otg->default_a) {
+		if (val32 & OTGSC_BSE)
+			xotg->hsm.b_sess_end = 1;
+		if (val32 & OTGSC_BSV)
+			xotg->hsm.b_sess_vld = 1;
+	} else {
+		if (val32 & OTGSC_ASV)
+			xotg->hsm.a_sess_vld = 1;
+		if (val32 & OTGSC_AVV)
+			xotg->hsm.a_vbus_vld = 1;
+	}
+
+	/* defautly power the bus */
+	xotg->hsm.a_bus_req = 0;
+	xotg->hsm.a_bus_drop = 0;
+	/* defautly don't request bus as B device */
+	xotg->hsm.b_bus_req = 0;
+	/* no system error */
+	xotg->hsm.a_clr_err = 0;
+
+	xusbps_otg_phy_low_power_wait(1);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void update_hsm(void)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	u32				val32;
+
+	/* read OTGSC */
+	val32 = readl(xotg->base + CI_OTGSC);
+
+	xotg->hsm.id = !!(val32 & OTGSC_ID);
+	if (!xotg->otg.otg->default_a) {
+		xotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
+		xotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
+	} else {
+		xotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
+		xotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
+	}
+}
+#endif
+
+static irqreturn_t otg_dummy_irq(int irq, void *_dev)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	void __iomem		*reg_base = _dev;
+	u32			val;
+	u32			int_mask = 0;
+
+	val = readl(reg_base + CI_USBMODE);
+	if ((val & USBMODE_CM) != USBMODE_DEVICE)
+		return IRQ_NONE;
+
+	val = readl(reg_base + CI_USBSTS);
+	int_mask = val & INTR_DUMMY_MASK;
+
+	if (int_mask == 0)
+		return IRQ_NONE;
+
+	/* Clear interrupts */
+	writel(int_mask, reg_base + CI_USBSTS);
+
+	/* clear hsm.b_conn here since host driver can't detect it
+	*  otg_dummy_irq called means B-disconnect happened.
+	*/
+	if (xotg->hsm.b_conn) {
+		xotg->hsm.b_conn = 0;
+		if (spin_trylock(&xotg->wq_lock)) {
+			xusbps_update_transceiver();
+			spin_unlock(&xotg->wq_lock);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t otg_irq(int irq, void *_dev)
+{
+	struct xusbps_otg		*xotg = _dev;
+	u32				int_sts, int_en;
+	u32				int_mask = 0;
+	int				flag = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&xotg->lock, flags);
+	int_sts = readl(xotg->base + CI_OTGSC);
+	int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
+	int_mask = int_sts & int_en;
+
+	if (int_mask == 0) {
+		spin_unlock_irqrestore(&xotg->lock, flags);
+		return IRQ_NONE;
+	}
+
+	writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
+					xotg->base + CI_OTGSC);
+	if (int_mask & OTGSC_IDIS) {
+		dev_dbg(xotg->dev, "%s: id change int\n", __func__);
+		xotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
+		dev_dbg(xotg->dev, "id = %d\n", xotg->hsm.id);
+		flag = 1;
+	}
+	if (int_mask & OTGSC_DPIS) {
+		dev_dbg(xotg->dev, "%s: data pulse int\n", __func__);
+		if (xotg->otg.otg->default_a)
+			xotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
+		dev_dbg(xotg->dev, "data pulse = %d\n", xotg->hsm.a_srp_det);
+		flag = 1;
+	}
+	if (int_mask & OTGSC_BSEIS) {
+		dev_dbg(xotg->dev, "%s: b session end int\n", __func__);
+		if (!xotg->otg.otg->default_a)
+			xotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
+		dev_dbg(xotg->dev, "b_sess_end = %d\n", xotg->hsm.b_sess_end);
+		flag = 1;
+	}
+	if (int_mask & OTGSC_BSVIS) {
+		dev_dbg(xotg->dev, "%s: b session valid int\n", __func__);
+		if (!xotg->otg.otg->default_a)
+			xotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
+		dev_dbg(xotg->dev, "b_sess_vld = %d\n", xotg->hsm.b_sess_vld);
+		flag = 1;
+	}
+	if (int_mask & OTGSC_ASVIS) {
+		dev_dbg(xotg->dev, "%s: a session valid int\n", __func__);
+		if (xotg->otg.otg->default_a)
+			xotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
+		dev_dbg(xotg->dev, "a_sess_vld = %d\n", xotg->hsm.a_sess_vld);
+		flag = 1;
+	}
+	if (int_mask & OTGSC_AVVIS) {
+		dev_dbg(xotg->dev, "%s: a vbus valid int\n", __func__);
+		if (xotg->otg.otg->default_a)
+			xotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
+		dev_dbg(xotg->dev, "a_vbus_vld = %d\n", xotg->hsm.a_vbus_vld);
+		flag = 1;
+	}
+
+	if (int_mask & OTGSC_1MSS) {
+		/* need to schedule otg_work if any timer is expired */
+		if (xusbps_otg_tick_timer(&int_sts))
+			flag = 1;
+	}
+
+	if (flag)
+		xusbps_update_transceiver();
+
+	spin_unlock_irqrestore(&xotg->lock, flags);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xotg_usbdev_notify - Notifier function called by usb core.
+ * @self:	Pointer to notifier_block structure
+ * @action:	action which caused the notifier function call.
+ * @dev:	Pointer to the usb device structure.
+ *
+ * This function is a call back function used by usb core to notify
+ * device attach/detach events. This is used by OTG state machine.
+ *
+ * returns:	Always returns NOTIFY_OK.
+ **/
+static int xotg_usbdev_notify(struct notifier_block *self,
+			       unsigned long action, void *dev)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	struct usb_phy *otg = &xotg->otg;
+	unsigned long otg_port;
+	struct usb_device *udev_otg = NULL;
+	struct usb_device *udev;
+	u32 flag;
+
+	udev = (struct usb_device *)dev;
+
+	if (!otg->otg->host)
+		return NOTIFY_OK;
+
+	otg_port = otg->otg->host->otg_port;
+
+	if (otg->otg->host->root_hub)
+		udev_otg = usb_hub_find_child(otg->otg->host->root_hub,
+								otg_port - 1);
+
+	/* Not otg device notification */
+	if (udev != udev_otg)
+		return NOTIFY_OK;
+
+	switch (action) {
+	case USB_DEVICE_ADD:
+		if (xotg->otg.otg->default_a == 1)
+			xotg->hsm.b_conn = 1;
+		else
+			xotg->hsm.a_conn = 1;
+		flag = 1;
+		break;
+	case USB_DEVICE_REMOVE:
+		if (xotg->otg.otg->default_a == 1)
+			xotg->hsm.b_conn = 0;
+		else
+			xotg->hsm.a_conn = 0;
+		flag = 1;
+		break;
+	}
+	if (flag)
+		xusbps_update_transceiver();
+
+	return NOTIFY_OK;
+}
+
+static void xusbps_otg_work(struct work_struct *work)
+{
+	struct xusbps_otg		*xotg;
+	int				retval;
+
+	xotg = container_of(work, struct xusbps_otg, work);
+
+	dev_dbg(xotg->dev, "%s: old state = %s\n", __func__,
+		usb_otg_state_string(xotg->otg.state));
+
+	switch (xotg->otg.state) {
+	case OTG_STATE_UNDEFINED:
+	case OTG_STATE_B_IDLE:
+		if (!xotg->hsm.id) {
+			xusbps_otg_del_timer(b_srp_init_tmr);
+			del_timer_sync(&xotg->hsm_timer);
+
+			xotg->otg.otg->default_a = 1;
+			xotg->hsm.a_srp_det = 0;
+
+			xusbps_otg_chrg_vbus(0);
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+
+			xotg->otg.state = OTG_STATE_A_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.b_sess_vld) {
+			xusbps_otg_del_timer(b_srp_init_tmr);
+			del_timer_sync(&xotg->hsm_timer);
+			xotg->hsm.b_bus_req = 0;
+			xotg->hsm.b_sess_end = 0;
+			xotg->hsm.a_bus_suspend = 0;
+			xusbps_otg_chrg_vbus(0);
+
+			if (xotg->start_peripheral) {
+				xotg->start_peripheral(&xotg->otg);
+				xotg->otg.state = OTG_STATE_B_PERIPHERAL;
+			} else
+				dev_dbg(xotg->dev,
+					"client driver not loaded\n");
+		} else if (xotg->hsm.b_srp_init_tmout) {
+			xotg->hsm.b_srp_init_tmout = 0;
+			dev_warn(xotg->dev, "SRP init timeout\n");
+		} else if (xotg->hsm.b_srp_fail_tmout) {
+			xotg->hsm.b_srp_fail_tmout = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			/* No silence failure */
+			xusbps_otg_msg(6);
+			dev_warn(xotg->dev, "SRP failed\n");
+		} else if (xotg->hsm.b_bus_req && xotg->hsm.b_sess_end) {
+			del_timer_sync(&xotg->hsm_timer);
+			/* workaround for b_se0_srp detection */
+			retval = xusbps_otg_check_se0_srp(0);
+			if (retval) {
+				xotg->hsm.b_bus_req = 0;
+				dev_dbg(xotg->dev, "LS isn't SE0, try later\n");
+			} else {
+				/* clear the PHCD before start srp */
+				xusbps_otg_phy_low_power(0);
+
+				/* Start SRP */
+				xusbps_otg_add_timer(b_srp_init_tmr);
+				xotg->otg.otg->start_srp(xotg->otg.otg);
+				xusbps_otg_del_timer(b_srp_init_tmr);
+				xusbps_otg_add_ktimer(TB_SRP_FAIL_TMR);
+
+				/* reset PHY low power mode here */
+				xusbps_otg_phy_low_power_wait(1);
+			}
+		}
+		break;
+	case OTG_STATE_B_SRP_INIT:
+		if (!xotg->hsm.id) {
+			xotg->otg.otg->default_a = 1;
+			xotg->hsm.a_srp_det = 0;
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xusbps_otg_chrg_vbus(0);
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_A_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.b_sess_vld) {
+			xusbps_otg_chrg_vbus(0);
+			if (xotg->start_peripheral) {
+				xotg->start_peripheral(&xotg->otg);
+				xotg->otg.state = OTG_STATE_B_PERIPHERAL;
+			} else
+				dev_dbg(xotg->dev,
+					"client driver not loaded\n");
+		}
+		break;
+	case OTG_STATE_B_PERIPHERAL:
+		if (!xotg->hsm.id) {
+			xotg->otg.otg->default_a = 1;
+			xotg->hsm.a_srp_det = 0;
+
+			xusbps_otg_chrg_vbus(0);
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_A_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.b_sess_vld) {
+			xotg->hsm.b_hnp_enable = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			xotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (xotg->hsm.b_bus_req && xotg->otg.otg->gadget &&
+					xotg->otg.otg->gadget->b_hnp_enable &&
+					xotg->hsm.a_bus_suspend) {
+			dev_warn(xotg->dev, "HNP detected\n");
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			xusbps_otg_HAAR(1);
+			xotg->hsm.a_conn = 0;
+
+			xotg->otg.state = OTG_STATE_B_WAIT_ACON;
+			if (xotg->start_host) {
+				xotg->start_host(&xotg->otg);
+			} else
+				dev_dbg(xotg->dev,
+						"host driver not loaded.\n");
+
+			xotg->hsm.a_bus_resume = 0;
+			xusbps_otg_add_ktimer(TB_ASE0_BRST_TMR);
+		}
+		break;
+
+	case OTG_STATE_B_WAIT_ACON:
+		if (!xotg->hsm.id) {
+			/* delete hsm timer for b_ase0_brst_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xotg->otg.otg->default_a = 1;
+			xotg->hsm.a_srp_det = 0;
+
+			xusbps_otg_chrg_vbus(0);
+
+			xusbps_otg_HAAR(0);
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_A_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.b_sess_vld) {
+			/* delete hsm timer for b_ase0_brst_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xotg->hsm.b_hnp_enable = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			xusbps_otg_chrg_vbus(0);
+			xusbps_otg_HAAR(0);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (xotg->hsm.a_conn) {
+			/* delete hsm timer for b_ase0_brst_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xusbps_otg_HAAR(0);
+			xotg->otg.state = OTG_STATE_B_HOST;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.a_bus_resume ||
+				xotg->hsm.b_ase0_brst_tmout) {
+			dev_warn(xotg->dev, "A device connect failed\n");
+			/* delete hsm timer for b_ase0_brst_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xusbps_otg_HAAR(0);
+			xusbps_otg_msg(7);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			xotg->hsm.a_bus_suspend = 0;
+			xotg->hsm.b_bus_req = 0;
+			xotg->otg.state = OTG_STATE_B_PERIPHERAL;
+			if (xotg->start_peripheral)
+				xotg->start_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver not loaded.\n");
+		}
+		break;
+
+	case OTG_STATE_B_HOST:
+		if (!xotg->hsm.id) {
+			xotg->otg.otg->default_a = 1;
+			xotg->hsm.a_srp_det = 0;
+
+			xusbps_otg_chrg_vbus(0);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_A_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.b_sess_vld) {
+			xotg->hsm.b_hnp_enable = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			xusbps_otg_chrg_vbus(0);
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+		} else if ((!xotg->hsm.b_bus_req) ||
+				(!xotg->hsm.a_conn)) {
+			xotg->hsm.b_bus_req = 0;
+			xusbps_otg_loc_sof(0);
+
+			/* Fix: The kernel crash in usb_port_suspend
+				during HNP */
+			msleep(20);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			xotg->hsm.a_bus_suspend = 0;
+			xotg->otg.state = OTG_STATE_B_PERIPHERAL;
+			if (xotg->start_peripheral)
+				xotg->start_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+						"client driver not loaded.\n");
+		}
+		break;
+
+	case OTG_STATE_A_IDLE:
+		xotg->otg.otg->default_a = 1;
+		if (xotg->hsm.id) {
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.b_bus_req = 0;
+			xotg->hsm.vbus_srp_up = 0;
+
+			xusbps_otg_chrg_vbus(0);
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.a_bus_drop &&
+			(xotg->hsm.a_srp_det || xotg->hsm.a_bus_req)) {
+			dev_warn(xotg->dev,
+			"SRP detected or User has requested for the Bus\n");
+			xusbps_otg_phy_low_power(0);
+
+			/* Turn on VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, true);
+
+			xotg->hsm.vbus_srp_up = 0;
+			xotg->hsm.a_wait_vrise_tmout = 0;
+			xusbps_otg_add_timer(a_wait_vrise_tmr);
+			xotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.a_bus_drop && xotg->hsm.a_sess_vld) {
+			xotg->hsm.vbus_srp_up = 1;
+		} else if (!xotg->hsm.a_sess_vld && xotg->hsm.vbus_srp_up) {
+			msleep(10);
+			xusbps_otg_phy_low_power(0);
+
+			/* Turn on VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, true);
+			xotg->hsm.a_srp_det = 1;
+			xotg->hsm.vbus_srp_up = 0;
+			xotg->hsm.a_wait_vrise_tmout = 0;
+			xusbps_otg_add_timer(a_wait_vrise_tmr);
+			xotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.a_sess_vld &&
+				!xotg->hsm.vbus_srp_up) {
+			xusbps_otg_phy_low_power(1);
+		}
+		break;
+	case OTG_STATE_A_WAIT_VRISE:
+		if (xotg->hsm.id) {
+			xusbps_otg_del_timer(a_wait_vrise_tmr);
+			xotg->hsm.b_bus_req = 0;
+			xotg->otg.otg->default_a = 0;
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			set_client_mode();
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (xotg->hsm.a_vbus_vld) {
+			xusbps_otg_del_timer(a_wait_vrise_tmr);
+			xotg->hsm.b_conn = 0;
+			if (xotg->start_host)
+				xotg->start_host(&xotg->otg);
+			else {
+				dev_dbg(xotg->dev, "host driver not loaded.\n");
+				break;
+			}
+			xusbps_otg_add_ktimer(TA_WAIT_BCON_TMR);
+			xotg->otg.state = OTG_STATE_A_WAIT_BCON;
+		} else if (xotg->hsm.a_wait_vrise_tmout) {
+			xotg->hsm.b_conn = 0;
+			if (xotg->hsm.a_vbus_vld) {
+				if (xotg->start_host)
+					xotg->start_host(&xotg->otg);
+				else {
+					dev_dbg(xotg->dev,
+						"host driver not loaded.\n");
+					break;
+				}
+				xusbps_otg_add_ktimer(TA_WAIT_BCON_TMR);
+				xotg->otg.state = OTG_STATE_A_WAIT_BCON;
+			} else {
+
+				/* Turn off VBus */
+				xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+				xusbps_otg_phy_low_power_wait(1);
+				xotg->otg.state = OTG_STATE_A_VBUS_ERR;
+			}
+		}
+		break;
+	case OTG_STATE_A_WAIT_BCON:
+		if (xotg->hsm.id) {
+			/* delete hsm timer for a_wait_bcon_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			set_client_mode();
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.a_vbus_vld) {
+			/* delete hsm timer for a_wait_bcon_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (xotg->hsm.a_bus_drop ||
+				(xotg->hsm.a_wait_bcon_tmout &&
+				!xotg->hsm.a_bus_req)) {
+			dev_warn(xotg->dev, "B connect timeout\n");
+			/* delete hsm timer for a_wait_bcon_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (xotg->hsm.b_conn) {
+			/* delete hsm timer for a_wait_bcon_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			xotg->hsm.a_suspend_req = 0;
+			/* Make it zero as it should not be used by driver */
+			xotg->hsm.a_bus_req = 0;
+			xotg->hsm.a_srp_det = 0;
+			xotg->otg.state = OTG_STATE_A_HOST;
+		}
+		break;
+	case OTG_STATE_A_HOST:
+		if (xotg->hsm.id) {
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			set_client_mode();
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.a_bus_drop ||
+				(xotg->otg.otg->host &&
+				!xotg->otg.otg->host->b_hnp_enable &&
+					!xotg->hsm.a_bus_req)) {
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (!xotg->hsm.a_vbus_vld) {
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (xotg->otg.otg->host &&
+				xotg->otg.otg->host->b_hnp_enable &&
+				(!xotg->hsm.a_bus_req ||
+					xotg->hsm.a_suspend_req)) {
+			/* Set HABA to enable hardware assistance to signal
+			 *  A-connect after receiver B-disconnect. Hardware
+			 *  will then set client mode and enable URE, SLE and
+			 *  PCE after the assistance. otg_dummy_irq is used to
+			 *  clean these ints when client driver is not resumed.
+			 */
+			if (request_irq(xotg->irq, otg_dummy_irq, IRQF_SHARED,
+					driver_name, xotg->base) != 0) {
+				dev_dbg(xotg->dev,
+					"request interrupt %d failed\n",
+						xotg->irq);
+			}
+			/* set HABA */
+			xusbps_otg_HABA(1);
+			xotg->hsm.b_bus_resume = 0;
+			xotg->hsm.a_aidl_bdis_tmout = 0;
+			xusbps_otg_loc_sof(0);
+			/* clear PHCD to enable HW timer */
+			xusbps_otg_phy_low_power(0);
+			xusbps_otg_add_timer(a_aidl_bdis_tmr);
+			xotg->otg.state = OTG_STATE_A_SUSPEND;
+		} else if (!xotg->hsm.b_conn || !xotg->hsm.a_bus_req) {
+			xusbps_otg_add_ktimer(TA_WAIT_BCON_TMR);
+			xotg->otg.state = OTG_STATE_A_WAIT_BCON;
+		}
+		break;
+	case OTG_STATE_A_SUSPEND:
+		if (xotg->hsm.id) {
+			xusbps_otg_del_timer(a_aidl_bdis_tmr);
+			xusbps_otg_HABA(0);
+			free_irq(xotg->irq, xotg->base);
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.b_bus_req = 0;
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.a_bus_req ||
+				xotg->hsm.b_bus_resume) {
+			xusbps_otg_del_timer(a_aidl_bdis_tmr);
+			xusbps_otg_HABA(0);
+			free_irq(xotg->irq, xotg->base);
+			xotg->hsm.a_suspend_req = 0;
+			xusbps_otg_loc_sof(1);
+			xotg->otg.state = OTG_STATE_A_HOST;
+		} else if (xotg->hsm.a_aidl_bdis_tmout ||
+				xotg->hsm.a_bus_drop) {
+			dev_warn(xotg->dev, "B disconnect timeout\n");
+			xusbps_otg_del_timer(a_aidl_bdis_tmr);
+			xusbps_otg_HABA(0);
+			free_irq(xotg->irq, xotg->base);
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (!xotg->hsm.b_conn && xotg->otg.otg->host &&
+				xotg->otg.otg->host->b_hnp_enable) {
+			xusbps_otg_del_timer(a_aidl_bdis_tmr);
+			xusbps_otg_HABA(0);
+			free_irq(xotg->irq, xotg->base);
+
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			xotg->hsm.b_bus_suspend = 0;
+			xotg->hsm.b_bus_suspend_vld = 0;
+
+			xotg->otg.state = OTG_STATE_A_PERIPHERAL;
+			/* msleep(200); */
+			if (xotg->start_peripheral)
+				xotg->start_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver not loaded.\n");
+			xusbps_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
+			break;
+		} else if (!xotg->hsm.a_vbus_vld) {
+			xusbps_otg_del_timer(a_aidl_bdis_tmr);
+			xusbps_otg_HABA(0);
+			free_irq(xotg->irq, xotg->base);
+			if (xotg->stop_host)
+				xotg->stop_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"host driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		}
+		break;
+	case OTG_STATE_A_PERIPHERAL:
+		if (xotg->hsm.id) {
+			/* delete hsm timer for b_bus_suspend_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.b_bus_req = 0;
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			set_client_mode();
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (!xotg->hsm.a_vbus_vld) {
+			/* delete hsm timer for b_bus_suspend_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xusbps_otg_phy_low_power_wait(1);
+			xotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (xotg->hsm.a_bus_drop) {
+			/* delete hsm timer for b_bus_suspend_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			/* Turn off VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+			xotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (xotg->hsm.b_bus_suspend) {
+			dev_warn(xotg->dev, "HNP detected\n");
+			/* delete hsm timer for b_bus_suspend_tmr */
+			del_timer_sync(&xotg->hsm_timer);
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			xotg->otg.state = OTG_STATE_A_WAIT_BCON;
+			if (xotg->start_host)
+				xotg->start_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+						"host driver not loaded.\n");
+			xusbps_otg_add_ktimer(TA_WAIT_BCON_TMR);
+		} else if (xotg->hsm.b_bus_suspend_tmout) {
+			u32	val;
+			val = readl(xotg->base + CI_PORTSC1);
+			if (!(val & PORTSC_SUSP))
+				break;
+
+			if (xotg->stop_peripheral)
+				xotg->stop_peripheral(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+					"client driver has been removed.\n");
+
+			xotg->otg.state = OTG_STATE_A_WAIT_BCON;
+			if (xotg->start_host)
+				xotg->start_host(&xotg->otg);
+			else
+				dev_dbg(xotg->dev,
+						"host driver not loaded.\n");
+			xusbps_otg_add_ktimer(TA_WAIT_BCON_TMR);
+		}
+		break;
+	case OTG_STATE_A_VBUS_ERR:
+		if (xotg->hsm.id) {
+			xotg->otg.otg->default_a = 0;
+			xotg->hsm.a_clr_err = 0;
+			xotg->hsm.a_srp_det = 0;
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.a_clr_err) {
+			xotg->hsm.a_clr_err = 0;
+			xotg->hsm.a_srp_det = 0;
+			reset_otg();
+			init_hsm();
+			if (xotg->otg.state == OTG_STATE_A_IDLE)
+				xusbps_update_transceiver();
+		} else {
+			/* FW will clear PHCD bit when any VBus
+			 * event detected. Reset PHCD to 1 again */
+			xusbps_otg_phy_low_power(1);
+		}
+		break;
+	case OTG_STATE_A_WAIT_VFALL:
+		if (xotg->hsm.id) {
+			xotg->otg.otg->default_a = 0;
+			set_client_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_B_IDLE;
+			xusbps_update_transceiver();
+		} else if (xotg->hsm.a_bus_req) {
+
+			/* Turn on VBus */
+			xotg->otg.otg->set_vbus(xotg->otg.otg, true);
+			xotg->hsm.a_wait_vrise_tmout = 0;
+			xusbps_otg_add_timer(a_wait_vrise_tmr);
+			xotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+		} else if (!xotg->hsm.a_sess_vld) {
+			xotg->hsm.a_srp_det = 0;
+			set_host_mode();
+			xusbps_otg_phy_low_power(1);
+			xotg->otg.state = OTG_STATE_A_IDLE;
+		}
+		break;
+	default:
+		;
+	}
+
+	dev_dbg(xotg->dev, "%s: new state = %s\n", __func__,
+		usb_otg_state_string(xotg->otg.state));
+}
+
+static ssize_t
+show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	char			*next;
+	unsigned		size, t;
+
+	next = buf;
+	size = PAGE_SIZE;
+
+	t = scnprintf(next, size,
+		"\n"
+		"USBCMD = 0x%08x\n"
+		"USBSTS = 0x%08x\n"
+		"USBINTR = 0x%08x\n"
+		"ASYNCLISTADDR = 0x%08x\n"
+		"PORTSC1 = 0x%08x\n"
+		"OTGSC = 0x%08x\n"
+		"USBMODE = 0x%08x\n",
+		readl(xotg->base + 0x140),
+		readl(xotg->base + 0x144),
+		readl(xotg->base + 0x148),
+		readl(xotg->base + 0x158),
+		readl(xotg->base + 0x184),
+		readl(xotg->base + 0x1a4),
+		readl(xotg->base + 0x1a8)
+	     );
+	size -= t;
+	next += t;
+
+	return PAGE_SIZE - size;
+}
+static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
+
+static ssize_t
+show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	char				*next;
+	unsigned			size, t;
+
+	next = buf;
+	size = PAGE_SIZE;
+
+	if (xotg->otg.otg->host)
+		xotg->hsm.a_set_b_hnp_en = xotg->otg.otg->host->b_hnp_enable;
+
+	if (xotg->otg.otg->gadget)
+		xotg->hsm.b_hnp_enable = xotg->otg.otg->gadget->b_hnp_enable;
+
+	t = scnprintf(next, size,
+		"\n"
+		"current state = %s\n"
+		"a_bus_resume = \t%d\n"
+		"a_bus_suspend = \t%d\n"
+		"a_conn = \t%d\n"
+		"a_sess_vld = \t%d\n"
+		"a_srp_det = \t%d\n"
+		"a_vbus_vld = \t%d\n"
+		"b_bus_resume = \t%d\n"
+		"b_bus_suspend = \t%d\n"
+		"b_conn = \t%d\n"
+		"b_se0_srp = \t%d\n"
+		"b_sess_end = \t%d\n"
+		"b_sess_vld = \t%d\n"
+		"id = \t%d\n"
+		"a_set_b_hnp_en = \t%d\n"
+		"b_srp_done = \t%d\n"
+		"b_hnp_enable = \t%d\n"
+		"a_wait_vrise_tmout = \t%d\n"
+		"a_wait_bcon_tmout = \t%d\n"
+		"a_aidl_bdis_tmout = \t%d\n"
+		"b_ase0_brst_tmout = \t%d\n"
+		"a_bus_drop = \t%d\n"
+		"a_bus_req = \t%d\n"
+		"a_clr_err = \t%d\n"
+		"a_suspend_req = \t%d\n"
+		"b_bus_req = \t%d\n"
+		"b_bus_suspend_tmout = \t%d\n"
+		"b_bus_suspend_vld = \t%d\n",
+		usb_otg_state_string(xotg->otg.state),
+		xotg->hsm.a_bus_resume,
+		xotg->hsm.a_bus_suspend,
+		xotg->hsm.a_conn,
+		xotg->hsm.a_sess_vld,
+		xotg->hsm.a_srp_det,
+		xotg->hsm.a_vbus_vld,
+		xotg->hsm.b_bus_resume,
+		xotg->hsm.b_bus_suspend,
+		xotg->hsm.b_conn,
+		xotg->hsm.b_se0_srp,
+		xotg->hsm.b_sess_end,
+		xotg->hsm.b_sess_vld,
+		xotg->hsm.id,
+		xotg->hsm.a_set_b_hnp_en,
+		xotg->hsm.b_srp_done,
+		xotg->hsm.b_hnp_enable,
+		xotg->hsm.a_wait_vrise_tmout,
+		xotg->hsm.a_wait_bcon_tmout,
+		xotg->hsm.a_aidl_bdis_tmout,
+		xotg->hsm.b_ase0_brst_tmout,
+		xotg->hsm.a_bus_drop,
+		xotg->hsm.a_bus_req,
+		xotg->hsm.a_clr_err,
+		xotg->hsm.a_suspend_req,
+		xotg->hsm.b_bus_req,
+		xotg->hsm.b_bus_suspend_tmout,
+		xotg->hsm.b_bus_suspend_vld
+		);
+	size -= t;
+	next += t;
+
+	return PAGE_SIZE - size;
+}
+static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
+
+static ssize_t
+get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	char			*next;
+	unsigned		size, t;
+
+	next = buf;
+	size = PAGE_SIZE;
+
+	t = scnprintf(next, size, "%d", xotg->hsm.a_bus_req);
+	size -= t;
+	next += t;
+
+	return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_a_bus_req(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+
+	if (!xotg->otg.otg->default_a)
+		return -1;
+	if (count > 2)
+		return -1;
+
+	if (buf[0] == '0') {
+		xotg->hsm.a_bus_req = 0;
+		dev_dbg(xotg->dev, "User request: a_bus_req = 0\n");
+	} else if (buf[0] == '1') {
+		/* If a_bus_drop is TRUE, a_bus_req can't be set */
+		if (xotg->hsm.a_bus_drop)
+			return -1;
+		xotg->hsm.a_bus_req = 1;
+		dev_dbg(xotg->dev, "User request: a_bus_req = 1\n");
+	}
+	if (spin_trylock(&xotg->wq_lock)) {
+		xusbps_update_transceiver();
+		spin_unlock(&xotg->wq_lock);
+	}
+	return count;
+}
+static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req);
+
+static ssize_t
+get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	char			*next;
+	unsigned		size, t;
+
+	next = buf;
+	size = PAGE_SIZE;
+
+	t = scnprintf(next, size, "%d", xotg->hsm.a_bus_drop);
+	size -= t;
+	next += t;
+
+	return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_a_bus_drop(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+
+	if (!xotg->otg.otg->default_a)
+		return -1;
+	if (count > 2)
+		return -1;
+
+	if (buf[0] == '0') {
+		xotg->hsm.a_bus_drop = 0;
+		dev_dbg(xotg->dev, "User request: a_bus_drop = 0\n");
+	} else if (buf[0] == '1') {
+		xotg->hsm.a_bus_drop = 1;
+		xotg->hsm.a_bus_req = 0;
+		dev_dbg(xotg->dev, "User request: a_bus_drop = 1\n");
+		dev_dbg(xotg->dev, "User request: and a_bus_req = 0\n");
+	}
+	if (spin_trylock(&xotg->wq_lock)) {
+		xusbps_update_transceiver();
+		spin_unlock(&xotg->wq_lock);
+	}
+	return count;
+}
+static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop,
+		set_a_bus_drop);
+
+static ssize_t
+get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct xusbps_otg	*xotg = the_transceiver;
+	char			*next;
+	unsigned		size, t;
+
+	next = buf;
+	size = PAGE_SIZE;
+
+	t = scnprintf(next, size, "%d", xotg->hsm.b_bus_req);
+	size -= t;
+	next += t;
+
+	return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_b_bus_req(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+
+	if (xotg->otg.otg->default_a)
+		return -1;
+
+	if (count > 2)
+		return -1;
+
+	if (buf[0] == '0') {
+		xotg->hsm.b_bus_req = 0;
+		dev_dbg(xotg->dev, "User request: b_bus_req = 0\n");
+	} else if (buf[0] == '1') {
+		xotg->hsm.b_bus_req = 1;
+		dev_dbg(xotg->dev, "User request: b_bus_req = 1\n");
+	}
+	if (spin_trylock(&xotg->wq_lock)) {
+		xusbps_update_transceiver();
+		spin_unlock(&xotg->wq_lock);
+	}
+	return count;
+}
+static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req);
+
+static ssize_t
+set_a_clr_err(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+
+	if (!xotg->otg.otg->default_a)
+		return -1;
+	if (count > 2)
+		return -1;
+
+	if (buf[0] == '1') {
+		xotg->hsm.a_clr_err = 1;
+		dev_dbg(xotg->dev, "User request: a_clr_err = 1\n");
+	}
+	if (spin_trylock(&xotg->wq_lock)) {
+		xusbps_update_transceiver();
+		spin_unlock(&xotg->wq_lock);
+	}
+	return count;
+}
+static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err);
+
+/**
+ * suspend_otg_device - suspend the otg device.
+ *
+ * @otg:	Pointer to the otg transceiver structure.
+ *
+ * This function suspends usb devices connected to the otg port
+ * of the host controller.
+ *
+ * returns:	0 on success or error value on failure
+ **/
+static int suspend_otg_device(struct usb_phy *otg)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	unsigned long otg_port = otg->otg->host->otg_port;
+	struct usb_device *udev;
+	int err;
+
+	udev = usb_hub_find_child(otg->otg->host->root_hub, otg_port - 1);
+
+	if (udev) {
+		err = usb_port_suspend(udev, PMSG_SUSPEND);
+		if (err < 0)
+			dev_dbg(xotg->dev, "HNP fail, %d\n", err);
+
+		/* Change the state of the usb device if HNP is successful */
+		usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+	} else {
+		err = -ENODEV;
+		dev_dbg(xotg->dev, "No device connected to roothub\n");
+	}
+	return err;
+}
+
+static ssize_t
+do_hnp(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct xusbps_otg		*xotg = the_transceiver;
+	unsigned long ret;
+
+	if (count > 2)
+		return -1;
+
+	if (buf[0] == '1') {
+		if (xotg->otg.otg->default_a && xotg->otg.otg->host &&
+				xotg->otg.otg->host->b_hnp_enable &&
+				(xotg->otg.state == OTG_STATE_A_HOST)) {
+			ret = suspend_otg_device(&xotg->otg);
+			if (ret)
+				return -1;
+		}
+
+		if (!xotg->otg.otg->default_a && xotg->otg.otg->host &&
+				xotg->hsm.b_bus_req) {
+			ret = suspend_otg_device(&xotg->otg);
+			if (ret)
+				return -1;
+		}
+	}
+	return count;
+}
+static DEVICE_ATTR(do_hnp, S_IWUSR, NULL, do_hnp);
+
+static int xusbps_otg_clk_notifier_cb(struct notifier_block *nb,
+		unsigned long event, void *data)
+{
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		/* if a rate change is announced we need to check whether we can
+		 * maintain the current frequency by changing the clock
+		 * dividers.
+		 */
+		/* fall through */
+	case POST_RATE_CHANGE:
+		return NOTIFY_OK;
+	case ABORT_RATE_CHANGE:
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static struct attribute *inputs_attrs[] = {
+	&dev_attr_a_bus_req.attr,
+	&dev_attr_a_bus_drop.attr,
+	&dev_attr_b_bus_req.attr,
+	&dev_attr_a_clr_err.attr,
+	&dev_attr_do_hnp.attr,
+	NULL,
+};
+
+static struct attribute_group debug_dev_attr_group = {
+	.name = "inputs",
+	.attrs = inputs_attrs,
+};
+
+static int xusbps_otg_remove(struct platform_device *pdev)
+{
+	struct xusbps_otg *xotg = the_transceiver;
+
+	if (xotg->qwork) {
+		flush_workqueue(xotg->qwork);
+		destroy_workqueue(xotg->qwork);
+	}
+	xusbps_otg_free_timers();
+
+	/* disable OTGSC interrupt as OTGSC doesn't change in reset */
+	writel(0, xotg->base + CI_OTGSC);
+
+	usb_remove_phy(&xotg->otg);
+	sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
+	device_remove_file(&pdev->dev, &dev_attr_hsm);
+	device_remove_file(&pdev->dev, &dev_attr_registers);
+	clk_notifier_unregister(xotg->clk, &xotg->clk_rate_change_nb);
+	clk_disable_unprepare(xotg->clk);
+
+	return 0;
+}
+
+static int xusbps_otg_probe(struct platform_device *pdev)
+{
+	int			retval;
+	u32			val32;
+	struct xusbps_otg	*xotg;
+	char			qname[] = "xusbps_otg_queue";
+	struct xusbps_usb2_platform_data *pdata;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		return -ENODEV;
+
+	dev_dbg(&pdev->dev, "\notg controller is detected.\n");
+
+	xotg = devm_kzalloc(&pdev->dev, sizeof(*xotg), GFP_KERNEL);
+	if (xotg == NULL)
+		return -ENOMEM;
+
+	the_transceiver = xotg;
+
+	/* Setup ulpi phy for OTG */
+	xotg->ulpi = pdata->ulpi;
+
+	xotg->otg.otg = devm_kzalloc(&pdev->dev, sizeof(*xotg->otg.otg),
+			GFP_KERNEL);
+	if (!xotg->otg.otg)
+		return -ENOMEM;
+
+	xotg->base = pdata->regs;
+	xotg->irq = pdata->irq;
+	if (!xotg->base || !xotg->irq) {
+		retval = -ENODEV;
+		goto err;
+	}
+
+	xotg->qwork = create_singlethread_workqueue(qname);
+	if (!xotg->qwork) {
+		dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname);
+		retval = -ENOMEM;
+		goto err;
+	}
+	INIT_WORK(&xotg->work, xusbps_otg_work);
+
+	xotg->clk = pdata->clk;
+	retval = clk_prepare_enable(xotg->clk);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to enable APER clock.\n");
+		goto err;
+	}
+
+	xotg->clk_rate_change_nb.notifier_call = xusbps_otg_clk_notifier_cb;
+	xotg->clk_rate_change_nb.next = NULL;
+	if (clk_notifier_register(xotg->clk, &xotg->clk_rate_change_nb))
+		dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
+
+	/* OTG common part */
+	xotg->dev = &pdev->dev;
+	xotg->otg.dev = xotg->dev;
+	xotg->otg.label = driver_name;
+	xotg->otg.otg->set_host = xusbps_otg_set_host;
+	xotg->otg.otg->set_peripheral = xusbps_otg_set_peripheral;
+	xotg->otg.set_power = xusbps_otg_set_power;
+	xotg->otg.otg->set_vbus = xusbps_otg_set_vbus;
+	xotg->otg.otg->start_srp = xusbps_otg_start_srp;
+	xotg->otg.otg->start_hnp = xusbps_otg_start_hnp;
+	xotg->otg.state = OTG_STATE_UNDEFINED;
+
+	if (usb_add_phy(&xotg->otg, USB_PHY_TYPE_USB2)) {
+		dev_dbg(xotg->dev, "can't set transceiver\n");
+		retval = -EBUSY;
+		goto err_out_clk_disable;
+	}
+
+	pdata->otg = &xotg->otg;
+	reset_otg();
+	init_hsm();
+
+	spin_lock_init(&xotg->lock);
+	spin_lock_init(&xotg->wq_lock);
+	INIT_LIST_HEAD(&active_timers);
+	retval = xusbps_otg_init_timers(&xotg->hsm);
+	if (retval) {
+		dev_dbg(&pdev->dev, "Failed to init timers\n");
+		goto err_out_clk_disable;
+	}
+
+	init_timer(&xotg->hsm_timer);
+
+	xotg->xotg_notifier.notifier_call = xotg_usbdev_notify;
+	usb_register_notify((struct notifier_block *)
+					&xotg->xotg_notifier.notifier_call);
+
+	retval = devm_request_irq(&pdev->dev, xotg->irq, otg_irq, IRQF_SHARED,
+				driver_name, xotg);
+	if (retval) {
+		dev_dbg(xotg->dev, "request interrupt %d failed\n", xotg->irq);
+		retval = -EBUSY;
+		goto err_out_clk_disable;
+	}
+
+	/* enable OTGSC int */
+	val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
+		OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
+	writel(val32, xotg->base + CI_OTGSC);
+
+	retval = device_create_file(&pdev->dev, &dev_attr_registers);
+	if (retval < 0) {
+		dev_dbg(xotg->dev,
+			"Can't register sysfs attribute: %d\n", retval);
+		goto err_out_clk_disable;
+	}
+
+	retval = device_create_file(&pdev->dev, &dev_attr_hsm);
+	if (retval < 0) {
+		dev_dbg(xotg->dev, "Can't hsm sysfs attribute: %d\n", retval);
+		goto err_out_clk_disable;
+	}
+
+	retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
+	if (retval < 0) {
+		dev_dbg(xotg->dev,
+			"Can't register sysfs attr group: %d\n", retval);
+		goto err_out_clk_disable;
+	}
+
+	if (xotg->otg.state == OTG_STATE_A_IDLE)
+		xusbps_update_transceiver();
+
+	return 0;
+
+err_out_clk_disable:
+	clk_notifier_unregister(xotg->clk, &xotg->clk_rate_change_nb);
+	clk_disable_unprepare(xotg->clk);
+err:
+	xusbps_otg_remove(pdev);
+
+	return retval;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void transceiver_suspend(struct platform_device *pdev)
+{
+	xusbps_otg_phy_low_power(1);
+}
+
+static int xusbps_otg_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xusbps_otg		*xotg = the_transceiver;
+	int				ret = 0;
+
+	/* Disbale OTG interrupts */
+	xusbps_otg_intr(0);
+
+	if (xotg->irq)
+		free_irq(xotg->irq, xotg);
+
+	/* Prevent more otg_work */
+	flush_workqueue(xotg->qwork);
+	destroy_workqueue(xotg->qwork);
+	xotg->qwork = NULL;
+
+	/* start actions */
+	switch (xotg->otg.state) {
+	case OTG_STATE_A_WAIT_VFALL:
+		xotg->otg.state = OTG_STATE_A_IDLE;
+	case OTG_STATE_A_IDLE:
+	case OTG_STATE_B_IDLE:
+	case OTG_STATE_A_VBUS_ERR:
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_A_WAIT_VRISE:
+		xusbps_otg_del_timer(a_wait_vrise_tmr);
+		xotg->hsm.a_srp_det = 0;
+
+		/* Turn off VBus */
+		xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+		xotg->otg.state = OTG_STATE_A_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_A_WAIT_BCON:
+		del_timer_sync(&xotg->hsm_timer);
+		if (xotg->stop_host)
+			xotg->stop_host(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev, "host driver has been removed.\n");
+
+		xotg->hsm.a_srp_det = 0;
+
+		/* Turn off VBus */
+		xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+		xotg->otg.state = OTG_STATE_A_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_A_HOST:
+		if (xotg->stop_host)
+			xotg->stop_host(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev, "host driver has been removed.\n");
+
+		xotg->hsm.a_srp_det = 0;
+
+		/* Turn off VBus */
+		xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+
+		xotg->otg.state = OTG_STATE_A_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_A_SUSPEND:
+		xusbps_otg_del_timer(a_aidl_bdis_tmr);
+		xusbps_otg_HABA(0);
+		if (xotg->stop_host)
+			xotg->stop_host(&xotg->otg);
+		else
+			dev_dbg(xotg->dev, "host driver has been removed.\n");
+		xotg->hsm.a_srp_det = 0;
+
+		/* Turn off VBus */
+		xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+		xotg->otg.state = OTG_STATE_A_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_A_PERIPHERAL:
+		del_timer_sync(&xotg->hsm_timer);
+
+		if (xotg->stop_peripheral)
+			xotg->stop_peripheral(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev,
+				"client driver has been removed.\n");
+		xotg->hsm.a_srp_det = 0;
+
+		/* Turn off VBus */
+		xotg->otg.otg->set_vbus(xotg->otg.otg, false);
+		xotg->otg.state = OTG_STATE_A_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_B_HOST:
+		if (xotg->stop_host)
+			xotg->stop_host(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev, "host driver has been removed.\n");
+		xotg->hsm.b_bus_req = 0;
+		xotg->otg.state = OTG_STATE_B_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_B_PERIPHERAL:
+		if (xotg->stop_peripheral)
+			xotg->stop_peripheral(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev,
+				"client driver has been removed.\n");
+		xotg->otg.state = OTG_STATE_B_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	case OTG_STATE_B_WAIT_ACON:
+		/* delete hsm timer for b_ase0_brst_tmr */
+		del_timer_sync(&xotg->hsm_timer);
+
+		xusbps_otg_HAAR(0);
+
+		if (xotg->stop_host)
+			xotg->stop_host(&xotg->otg);
+		else
+			dev_dbg(&pdev->dev, "host driver has been removed.\n");
+		xotg->hsm.b_bus_req = 0;
+		xotg->otg.state = OTG_STATE_B_IDLE;
+		transceiver_suspend(pdev);
+		break;
+	default:
+		dev_dbg(xotg->dev, "error state before suspend\n");
+		break;
+	}
+
+	if (!ret)
+		clk_disable(xotg->clk);
+	return ret;
+}
+
+static void transceiver_resume(struct platform_device *pdev)
+{
+	/* Not used */
+}
+
+static int xusbps_otg_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xusbps_otg	*xotg = the_transceiver;
+	int			ret = 0;
+
+	ret = clk_enable(xotg->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot enable clock. resume failed.\n");
+		return ret;
+	}
+
+	transceiver_resume(pdev);
+
+	xotg->qwork = create_singlethread_workqueue("xusbps_otg_queue");
+	if (!xotg->qwork) {
+		dev_dbg(&pdev->dev, "cannot create xusbps otg workqueuen");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	if (request_irq(xotg->irq, otg_irq, IRQF_SHARED,
+				driver_name, xotg) != 0) {
+		dev_dbg(&pdev->dev, "request interrupt %d failed\n", xotg->irq);
+		ret = -EBUSY;
+		goto error;
+	}
+
+	/* enable OTG interrupts */
+	xusbps_otg_intr(1);
+
+	update_hsm();
+
+	xusbps_update_transceiver();
+
+	return ret;
+error:
+	xusbps_otg_intr(0);
+	transceiver_suspend(pdev);
+	return ret;
+}
+
+static const struct dev_pm_ops xusbps_otg_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xusbps_otg_suspend, xusbps_otg_resume)
+};
+#define XUSBPS_OTG_PM	(&xusbps_otg_dev_pm_ops)
+
+#else /* ! CONFIG_PM_SLEEP */
+#define XUSBPS_OTG_PM	NULL
+#endif /* ! CONFIG_PM_SLEEP */
+
+#ifndef CONFIG_USB_XUSBPS_DR_OF
+static struct platform_driver xusbps_otg_driver = {
+#else
+struct platform_driver xusbps_otg_driver = {
+#endif
+	.probe		= xusbps_otg_probe,
+	.remove		= xusbps_otg_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRIVER_NAME,
+		.pm	= XUSBPS_OTG_PM,
+	},
+};
+
+#ifndef CONFIG_USB_XUSBPS_DR_OF
+module_platform_driver(xusbps_otg_driver);
+#endif
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx PS USB OTG driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
Index: linux-3.12.24-rt38-xilinx/drivers/video/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/video/Kconfig	2014-07-20 22:05:50.244066489 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/video/Kconfig	2014-07-20 22:06:38.366272564 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2469 @
 	  Configuration re: surface address, size, and format must be provided
 	  through device tree, or plain old platform data.
 
+source "drivers/video/xylon/Kconfig"
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
 source "drivers/video/exynos/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/video/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/video/Makefile	2014-07-20 22:05:50.243066505 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/video/Makefile	2014-07-20 22:06:38.377272383 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:153 @
 obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
 obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
 obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o
+obj-y                             += xylon/
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
Index: linux-3.12.24-rt38-xilinx/drivers/video/xilinxfb.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/video/xilinxfb.c	2014-07-20 22:05:50.245066473 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/video/xilinxfb.c	2014-07-20 22:06:38.458271046 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:372 @
 
 err_region:
 	kfree(drvdata);
-	dev_set_drvdata(dev, NULL);
 
 	return rc;
 }
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:406 @
 #endif
 
 	kfree(drvdata);
-	dev_set_drvdata(dev, NULL);
 
 	return 0;
 }
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/Kconfig	2014-07-20 22:06:38.470270848 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+source "drivers/video/xylon/xylonfb/Kconfig"
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/Makefile	2014-07-20 22:06:38.476270749 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+obj-$(CONFIG_FB_XYLON) += xylonfb/
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logiclk.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logiclk.c	2014-07-20 22:06:38.491270502 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver:
+ *   pixel clock generation using logiCLK IP core
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: goran.pantar@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include "logiclk.h"
+
+
+#define FRAC_PRECISION              10
+
+#define FVCO_MIN                    800
+#define FVCO_MAX                    1600
+
+#define NUM_OF_MULT_STEPS           64
+#define NUM_OF_DIV_INPUT_STEPS      56
+#define NUM_OF_DIV_OUTPUT_STEPS     128
+
+#define CLK_FB_OUT_DUTY             50000
+#define DIV_CLK_PHASE               0
+
+
+static inline u32 get_bits(u64 input, u32 msb, u32 lsb)
+{
+	return (input >> lsb) & ((1 << (msb-lsb+1)) - 1);
+}
+
+static u32 round_frac(u32 decimal, u32 precision)
+{
+	u32 ret;
+
+	if (decimal & (1 << (FRAC_PRECISION-precision-1)))
+		ret = decimal + (1 << (FRAC_PRECISION-precision-1));
+	else
+		ret = decimal;
+
+	return ret;
+}
+
+static u32 pll_divider(u32 divide, u32 duty_cycle)
+{
+	u32 duty_cycle_fix;
+	u32 high_time;
+	u32 low_time;
+	u32 w_edge;
+	u32 no_count;
+	u32 temp;
+
+	if (duty_cycle <= 0 || duty_cycle >= 100000) {
+		pr_err("%s: invalid duty_cycle %d", __func__, duty_cycle);
+		return -1;
+	}
+	duty_cycle_fix = (duty_cycle << FRAC_PRECISION) / 100000;
+
+	if (divide == 1) {
+		high_time = 1;
+		w_edge = 0;
+		low_time = 1;
+		no_count = 1;
+	} else {
+		temp = round_frac(duty_cycle_fix * divide, 1);
+		high_time = get_bits(temp, FRAC_PRECISION+6, FRAC_PRECISION);
+		w_edge = get_bits(temp, FRAC_PRECISION-1, FRAC_PRECISION-1);
+
+		if (high_time == 0) {
+			high_time = 1;
+			w_edge = 0;
+		}
+		if (high_time == divide) {
+			high_time = divide - 1;
+			w_edge = 1;
+		}
+		low_time = divide - high_time;
+		no_count = 0;
+	}
+
+	return (((low_time  & 0x3F) <<  0) |
+			((high_time & 0x3F) <<  6) |
+			((no_count  & 0x01) << 12) |
+			((w_edge    & 0x01) << 13));
+}
+
+static u32 pll_phase(u32 divide, s32 phase)
+{
+	u32 phase_in_cycles;
+	u32 phase_fixed;
+	u32 mx;
+	u32 delay_time;
+	u32 phase_mux;
+	u32 temp;
+
+	if ((phase < -360000) || (phase > 360000))
+		return -1;
+
+	if (phase < 0)
+		phase_fixed = ((phase + 360000) << FRAC_PRECISION) / 1000;
+	else
+		phase_fixed = (phase << FRAC_PRECISION) / 1000;
+
+	phase_in_cycles = (phase_fixed * divide) / 360;
+
+	temp = round_frac(phase_in_cycles, 3);
+
+	mx = 0;
+	phase_mux = get_bits(temp, FRAC_PRECISION-1, FRAC_PRECISION-3);
+	delay_time = get_bits(temp, FRAC_PRECISION+5, FRAC_PRECISION);
+
+	return ((delay_time & 0x3F) << 0) |
+			((phase_mux & 0x07) << 6) |
+			((mx        & 0x03) << 9);
+}
+
+static u64 pll_lock_lookup(u32 divide)
+{
+	u64 lookup[] = {
+		0x31BE8FA401,
+		0x31BE8FA401,
+		0x423E8FA401,
+		0x5AFE8FA401,
+		0x73BE8FA401,
+		0x8C7E8FA401,
+		0x9CFE8FA401,
+		0xB5BE8FA401,
+		0xCE7E8FA401,
+		0xE73E8FA401,
+		0xFFF84FA401,
+		0xFFF39FA401,
+		0xFFEEEFA401,
+		0xFFEBCFA401,
+		0xFFE8AFA401,
+		0xFFE71FA401,
+		0xFFE3FFA401,
+		0xFFE26FA401,
+		0xFFE0DFA401,
+		0xFFDF4FA401,
+		0xFFDDBFA401,
+		0xFFDC2FA401,
+		0xFFDA9FA401,
+		0xFFD90FA401,
+		0xFFD90FA401,
+		0xFFD77FA401,
+		0xFFD5EFA401,
+		0xFFD5EFA401,
+		0xFFD45FA401,
+		0xFFD45FA401,
+		0xFFD2CFA401,
+		0xFFD2CFA401,
+		0xFFD2CFA401,
+		0xFFD13FA401,
+		0xFFD13FA401,
+		0xFFD13FA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401,
+		0xFFCFAFA401
+	};
+	return lookup[divide-1];
+}
+
+static u32 pll_filter_lookup(u32 divide, bool bw_low)
+{
+	u32 lookup_entry;
+	u32 lookup_low[] = {
+		0x5F,
+		0x57,
+		0x7B,
+		0x5B,
+		0x6B,
+		0x73,
+		0x73,
+		0x73,
+		0x73,
+		0x4B,
+		0x4B,
+		0x4B,
+		0xB3,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x53,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x63,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0x93,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3,
+		0xA3
+	};
+	u32 lookup_high[] = {
+		0x17C,
+		0x3FC,
+		0x3F4,
+		0x3E4,
+		0x3F8,
+		0x3C4,
+		0x3C4,
+		0x3D8,
+		0x3E8,
+		0x3E8,
+		0x3E8,
+		0x3B0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3F0,
+		0x3B0,
+		0x3B0,
+		0x3B0,
+		0x3E8,
+		0x370,
+		0x308,
+		0x370,
+		0x370,
+		0x3E8,
+		0x3E8,
+		0x3E8,
+		0x1C8,
+		0x330,
+		0x330,
+		0x3A8,
+		0x188,
+		0x188,
+		0x188,
+		0x1F0,
+		0x188,
+		0x110,
+		0x110,
+		0x110,
+		0x110,
+		0x110,
+		0x110,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0,
+		0x0E0
+	};
+
+	if (bw_low)
+		lookup_entry = lookup_low[divide-1];
+	else
+		lookup_entry = lookup_high[divide-1];
+
+	return lookup_entry;
+}
+
+static u32 calc_pll_count(u32 divide, s32 phase, u32 duty_cycle)
+{
+	u32 div_calc;
+	u32 phase_calc;
+	u32 ret;
+
+	div_calc = pll_divider(divide, duty_cycle);
+	phase_calc = pll_phase(divide, phase);
+
+	ret = ((get_bits(div_calc,   11,  0) << 0)  |
+		   (get_bits(phase_calc,  8,  6) << 13) |
+		   (get_bits(phase_calc,  5,  0) << 16) |
+		   (get_bits(div_calc,   13, 12) << 22) |
+		   (get_bits(phase_calc, 10,  9) << 24));
+
+	return ret;
+}
+
+static void calc_pll_mult(u32 osc_clk_freq, u32 out_clk_freq,
+	u32 *p_mult, u32 *p_div_in)
+{
+	u32 freq_err = 0xFFFFFFFF;
+	u32 din;
+	u32 dout;
+	u32 mult;
+	u32 fvco;
+	u64 freq_err_new;
+	u64 freq_hz;
+	u32 remainder;
+
+	*p_mult = 0;
+	*p_div_in = 0;
+
+	for (din = 1; din <= NUM_OF_DIV_INPUT_STEPS; din++) {
+		for (mult = 2; mult <= NUM_OF_MULT_STEPS; mult++) {
+			for (dout = 1; dout <= NUM_OF_DIV_OUTPUT_STEPS; dout++) {
+				freq_hz = osc_clk_freq;
+				freq_hz *= mult;
+				freq_hz = div_u64_rem(freq_hz, din, &remainder);
+				fvco = (u32)(div_u64_rem(freq_hz, 1000000, &remainder));
+				if ((fvco >= FVCO_MIN) && (fvco <= FVCO_MAX)) {
+					freq_hz = div_u64_rem(freq_hz, dout, &remainder);
+					if (((u64)out_clk_freq) >= freq_hz)
+						freq_err_new = ((u64)out_clk_freq) - freq_hz;
+					else
+						freq_err_new = freq_hz - ((u64)out_clk_freq);
+					if (freq_err_new < freq_err) {
+						freq_err = (u32)freq_err_new;
+						*p_mult = mult;
+						*p_div_in = din;
+					}
+				}
+			}
+		}
+	}
+}
+
+static u32 calc_pll_div(u32 osc_clk_freq, u32 out_clk_freq,
+	u32 mult, u32 div_in)
+{
+	u32 div_out = 0;
+	u32 freq_err = 0xFFFFFFFF;
+	u32 dout;
+	u32 khz;
+	u32 freq_err_new;
+
+	for (dout = 1; dout <= NUM_OF_DIV_OUTPUT_STEPS; dout++) {
+		khz = (osc_clk_freq / 1000 * mult) / (dout * div_in);
+		freq_err_new = abs((int)(out_clk_freq - (1000 * khz)));
+		if (freq_err_new < freq_err) {
+			freq_err = freq_err_new;
+			div_out = dout;
+		}
+	}
+
+	return div_out;
+}
+
+int logiclk_calc_regs(struct logiclk_freq_out *freq_out,
+	u32 c_osc_clk_freq_hz, u32 *regs_out)
+{
+	u32 clkout_phase = 0;
+	u32 clkfbout_phase = 0;
+	u32 clkout_duty = 50000;
+	u32 bandwith = 0;
+	u32 divclk_divide = 1;
+	u64 lock;
+	u32 clkout_divide[LOGICLK_OUTPUTS];
+	u32 clkfbout_mult;
+	u32 clkout[LOGICLK_OUTPUTS];
+	u32 divclk;
+	u32 clkfbout;
+	u32 digital_filt;
+	int i;
+
+	calc_pll_mult(c_osc_clk_freq_hz, (u32)freq_out->freq_out_hz[0],
+		&clkfbout_mult, &divclk_divide);
+	if ((clkfbout_mult == 0) || (divclk_divide == 0))
+		return -EINVAL;
+
+	for (i = 0; i < LOGICLK_OUTPUTS; i++)
+		clkout_divide[i] = calc_pll_div(c_osc_clk_freq_hz,
+			freq_out->freq_out_hz[i], clkfbout_mult, divclk_divide);
+
+	for (i = 0; i < LOGICLK_OUTPUTS; i++)
+		clkout[i] = calc_pll_count(
+			clkout_divide[i], clkout_phase, clkout_duty);
+
+	divclk = calc_pll_count(divclk_divide, DIV_CLK_PHASE, CLK_FB_OUT_DUTY);
+	clkfbout = calc_pll_count(clkfbout_mult, clkfbout_phase, clkout_duty);
+
+	digital_filt = pll_filter_lookup(clkfbout_mult-1, bandwith);
+	lock = pll_lock_lookup(clkfbout_mult-1);
+
+	regs_out[0] = 0xFFFF;
+	for (i = 0; i < LOGICLK_OUTPUTS; i++) {
+		regs_out[1 + i*2 + 0] = get_bits(clkout[i], 15, 0);
+		regs_out[1 + i*2 + 1] = get_bits(clkout[i], 31, 16);
+	}
+
+	/* DIVCLK[23:22] & DIVCLK[11:0] */
+	regs_out[13] = (get_bits(divclk, 23, 22) << 12) |
+					(get_bits(divclk, 11, 0) << 0);
+	/* CLKFBOUT[15:0] */
+	regs_out[14] = get_bits(clkfbout, 15, 0);
+	/* CLKFBOUT[31:16] */
+	regs_out[15] = get_bits(clkfbout, 31, 16);
+	/* LOCK[29:20] */
+	regs_out[16] = get_bits(lock, 29, 20);
+	/* LOCK[34:30] & LOCK[9:0] */
+	regs_out[17] = (get_bits(lock, 34, 30) << 10) |
+					get_bits(lock, 9, 0);
+	/* LOCK[39:35] & S10_LOCK[19:10] */
+	regs_out[18] = (get_bits(lock, 39, 35) << 10) |
+					get_bits(lock, 19, 10);
+	/* DIGITAL_FILT[9] & 00 & DIGITAL_FILT[8:7] & 00 &
+	   DIGITAL_FILT[6] & 0000000 */
+	regs_out[19] = (get_bits(digital_filt, 6, 6) << 8)  |
+				   (get_bits(digital_filt, 8, 7) << 11) |
+				   (get_bits(digital_filt, 9, 9) << 15);
+	/* DIGITAL_FILT[5] & 00 & DIGITAL_FILT[4:3] & 00 &
+	   DIGITAL_FILT[2:1] & 00 & DIGITAL_FILT[0] & 0000  */
+	regs_out[20] = (get_bits(digital_filt, 0, 0) << 4)  |
+				   (get_bits(digital_filt, 2, 1) << 7)  |
+				   (get_bits(digital_filt, 4, 3) << 11) |
+				   (get_bits(digital_filt, 5, 5) << 15);
+
+#ifdef LOGICLK_DUMP_REGS
+	for (i = 0; i < LOGICLK_REGS; i++)
+		pr_info("reg[%d]=0x%lx\n", i, regs_out[i]);
+#endif
+
+	return 0;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logiclk.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logiclk.h	2014-07-20 22:06:38.497270403 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC pixel clock generation logiCLK IP core interface
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: goran.pantar@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/types.h>
+
+
+#define LOGICLK_REGS                21
+#define LOGICLK_OUTPUTS             6
+#define LOGICLK_RST_REG_OFF         0
+#define LOGICLK_PLL_REG_OFF         1
+#define LOGICLK_PLL_MANUAL_REG_OFF  3
+#define LOGICLK_PLL_RDY             0x01
+#define LOGICLK_PLL_EN              0x01
+#define LOGICLK_PLL_REG_EN          0x02
+
+
+struct logiclk_freq_out {
+	u32 freq_out_hz[LOGICLK_OUTPUTS];
+};
+
+/*
+	Calculates the output register valuess depending on the
+	"freq_out" and "c_osc_clk_freq_hz" inputs.
+	Writes them to array of LOGICLK_REGS over "regs_out" pointer.
+*/
+int logiclk_calc_regs(struct logiclk_freq_out *freq_out,
+	u32 c_osc_clk_freq_hz, u32 *regs_out);
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logicvc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/logicvc.h	2014-07-20 22:06:38.505270271 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC IP core v2.05c definitions
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __LOGICVC_H__
+#define __LOGICVC_H__
+
+/* All logiCVC registers are 32 bit registers */
+/* All logiCVC registers are at 8 byte distance */
+#define LOGICVC_REG_DIST_USED      8
+/* R_HSY_FP */
+#define LOGICVC_SHSY_FP_ROFF      (0  * LOGICVC_REG_DIST_USED)
+/* R_HSY */
+#define LOGICVC_SHSY_ROFF         (1  * LOGICVC_REG_DIST_USED)
+/* R_HSY_BP */
+#define LOGICVC_SHSY_BP_ROFF      (2  * LOGICVC_REG_DIST_USED)
+/* R_HSY_RES */
+#define LOGICVC_SHSY_RES_ROFF     (3  * LOGICVC_REG_DIST_USED)
+/* R_VSY_FP */
+#define LOGICVC_SVSY_FP_ROFF      (4  * LOGICVC_REG_DIST_USED)
+/* R_VSY */
+#define LOGICVC_SVSY_ROFF         (5  * LOGICVC_REG_DIST_USED)
+/* R_VSY_BP */
+#define LOGICVC_SVSY_BP_ROFF      (6  * LOGICVC_REG_DIST_USED)
+/* R_VSY_RES */
+#define LOGICVC_SVSY_RES_ROFF     (7  * LOGICVC_REG_DIST_USED)
+/* R_CTRL */
+#define LOGICVC_SCTRL_ROFF        (8  * LOGICVC_REG_DIST_USED)
+/* R_DTYPE */
+#define LOGICVC_SDTYPE_ROFF       (9  * LOGICVC_REG_DIST_USED)
+/* R_BACKGROUND */
+#define LOGICVC_BACKCOL_ROFF      (10 * LOGICVC_REG_DIST_USED)
+/* R_DOUBLE_VBUFF */
+#define LOGICVC_DOUBLE_VBUFF_ROFF (11 * LOGICVC_REG_DIST_USED)
+/* R_DOUBLE_CLUT */
+#define LOGICVC_DOUBLE_CLUT_ROFF  (12 * LOGICVC_REG_DIST_USED)
+/* R_INT_STAT */
+#define LOGICVC_INT_STAT_ROFF     (13 * LOGICVC_REG_DIST_USED)
+/* R_INT_MASK */
+#define LOGICVC_INT_MASK_ROFF     (14 * LOGICVC_REG_DIST_USED)
+/* R_PWRCTRL */
+#define LOGICVC_SPWRCTRL_ROFF     (15 * LOGICVC_REG_DIST_USED)
+/* R_IPVER */
+#define LOGICVC_IPVER_ROFF        (18 * LOGICVC_REG_DIST_USED)
+
+/* logiCVC layer registers base and distance between the layers */
+/* distance between groups of layer registers */
+#define LOGICVC_LAYER_DISTANCE   (16  * LOGICVC_REG_DIST_USED)
+/* offset to the beginning of layer 0 registers */
+#define LOGICVC_LAYER0_BASE_ROFF (32  * LOGICVC_REG_DIST_USED)
+/* offset to the beginning of layer 1 registers */
+#define LOGICVC_LAYER1_BASE_ROFF \
+	(LOGICVC_LAYER0_BASE_ROFF + LOGICVC_LAYER_DISTANCE * 1)
+/* offset to the beginning of layer 2 registers */
+#define LOGICVC_LAYER2_BASE_ROFF \
+	(LOGICVC_LAYER0_BASE_ROFF + LOGICVC_LAYER_DISTANCE * 2)
+/* offset to the beginning of layer 3 registers */
+#define LOGICVC_LAYER3_BASE_ROFF \
+	(LOGICVC_LAYER0_BASE_ROFF + LOGICVC_LAYER_DISTANCE * 3)
+/* offset to the beginning of layer 4 registers */
+#define LOGICVC_LAYER4_BASE_ROFF \
+	(LOGICVC_LAYER0_BASE_ROFF + LOGICVC_LAYER_DISTANCE * 4)
+
+/* logiCVC layer registers offsets (common for each layer) */
+/*  LH_OFFSET */
+#define LOGICVC_LAYER_HOR_OFF_ROFF (0 * LOGICVC_REG_DIST_USED)
+/*  LV_OFFSET */
+#define LOGICVC_LAYER_VER_OFF_ROFF (1 * LOGICVC_REG_DIST_USED)
+/*  LH_POSITION */
+#define LOGICVC_LAYER_HOR_POS_ROFF (2 * LOGICVC_REG_DIST_USED)
+/*  LV_POSITION */
+#define LOGICVC_LAYER_VER_POS_ROFF (3 * LOGICVC_REG_DIST_USED)
+/*  LH_WIDTH */
+#define LOGICVC_LAYER_WIDTH_ROFF   (4 * LOGICVC_REG_DIST_USED)
+/*  LV_HEIGHT */
+#define LOGICVC_LAYER_HEIGHT_ROFF  (5 * LOGICVC_REG_DIST_USED)
+/*  ALPHA */
+#define LOGICVC_LAYER_ALPHA_ROFF   (6 * LOGICVC_REG_DIST_USED)
+/*  CTRL */
+#define LOGICVC_LAYER_CTRL_ROFF    (7 * LOGICVC_REG_DIST_USED)
+/*  TRANSPARENT */
+#define LOGICVC_LAYER_TRANSP_ROFF  (8 * LOGICVC_REG_DIST_USED)
+
+/* logiCVC interrupt bits */
+#define LOGICVC_L0_VBUFF_SW_INT   0x01
+#define LOGICVC_L1_VBUFF_SW_INT   0x02
+#define LOGICVC_L2_VBUFF_SW_INT   0x04
+#define LOGICVC_L3_VBUFF_SW_INT   0x08
+#define LOGICVC_L4_VBUFF_SW_INT   0x10
+#define LOGICVC_V_SYNC_INT        0x20
+#define LOGICVC_E_VIDEO_VALID_INT 0x40
+#define LOGICVC_L0_CLUT_SW_INT    0x100
+#define LOGICVC_L1_CLUT_SW_INT    0x200
+#define LOGICVC_L2_CLUT_SW_INT    0x400
+#define LOGICVC_L3_CLUT_SW_INT    0x800
+#define LOGICVC_L4_CLUT_SW_INT    0x1000
+
+/* logiCVC layer base offsets */
+#define LOGICVC_LAYER_OFFSET      0x80
+#define LOGICVC_LAYER_BASE_OFFSET 0x100
+#define LOGICVC_LAYER_0_OFFSET    0
+#define LOGICVC_LAYER_1_OFFSET \
+	(LOGICVC_LAYER_0_OFFSET + LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_2_OFFSET \
+	(LOGICVC_LAYER_1_OFFSET + LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_3_OFFSET \
+	(LOGICVC_LAYER_2_OFFSET + LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_4_OFFSET \
+	(LOGICVC_LAYER_3_OFFSET + LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_BASE_END    0x338
+
+/* logiCVC layer CLUT base offsets */
+#define LOGICVC_CLUT_OFFSET           0x800
+#define LOGICVC_CLUT_BASE_OFFSET      0x1000
+#define LOGICVC_CLUT_L0_CLUT_0_OFFSET 0
+#define LOGICVC_CLUT_L0_CLUT_1_OFFSET \
+	(LOGICVC_CLUT_L0_CLUT_0_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L1_CLUT_0_OFFSET \
+	(LOGICVC_CLUT_L0_CLUT_1_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L1_CLUT_1_OFFSET \
+	(LOGICVC_CLUT_L1_CLUT_0_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L2_CLUT_0_OFFSET \
+	(LOGICVC_CLUT_L1_CLUT_1_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L2_CLUT_1_OFFSET \
+	(LOGICVC_CLUT_L2_CLUT_0_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L3_CLUT_0_OFFSET \
+	(LOGICVC_CLUT_L2_CLUT_1_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L3_CLUT_1_OFFSET \
+	(LOGICVC_CLUT_L3_CLUT_0_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L4_CLUT_0_OFFSET \
+	(LOGICVC_CLUT_L3_CLUT_1_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L4_CLUT_1_OFFSET \
+	(LOGICVC_CLUT_L4_CLUT_0_OFFSET + LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_REGISTER_SIZE    8
+#define LOGICVC_CLUT_0_INDEX_OFFSET   2
+#define LOGICVC_CLUT_1_INDEX_OFFSET   1
+
+/* logiCVC register and CLUT base offsets */
+#define LOGICVC_GENERAL_REGISTERS_RANGE 0x100
+#define LOGICVC_REGISTERS_RANGE         0x6000
+
+/* logiCVC register initial values */
+#define CTRL_REG_INIT 0x001F
+#define SD_REG_INIT   0
+
+/* logiCVC display power signals */
+#define LOGICVC_EN_BLIGHT_MSK 0x01
+#define LOGICVC_EN_VDD_MSK    0x02
+#define LOGICVC_EN_VEE_MSK    0x04
+#define LOGICVC_V_EN_MSK      0x08
+
+/* logiCVC various definitions */
+#define LOGICVC_PIX_DATA_INVERT        0x80
+#define LOGICVC_PIX_ACT_HIGH           0x100
+#define LOGICVC_LAYER_ON               0x01
+#define LOGICVC_SWAP_RB                0x10
+#define LOGICVC_MAX_LAYERS             5
+#define LOGICVC_MAX_LAYER_BUFFERS      3
+#define LOGICVC_MIN_XRES               64
+#define LOGICVC_MAX_XRES               2048
+#define LOGICVC_MIN_VRES               1
+#define LOGICVC_MAX_VRES               2048
+#define LOGICVC_MAX_LINES              4096
+#define LOGICVC_CLUT_SIZE              256
+#define TRANSPARENT_COLOR_8BPP         0x25       /* dummy */
+#define TRANSPARENT_COLOR_8BPP_CLUT_16 0xF813     /* dummy */
+#define TRANSPARENT_COLOR_8BPP_CLUT_24 0x00FF009C /* dummy */
+#define TRANSPARENT_COLOR_16BPP        0xF813     /* dummy */
+#define TRANSPARENT_COLOR_24BPP        0x00FF009C /* dummy */
+#define BACKGROUND_COLOR               0x00000000
+
+#define LOGICVC_READABLE_REGS 0x01
+
+enum xylonfb_layer_type {
+	LOGICVC_RGB_LAYER = 0,
+	LOGICVC_YCBCR_LAYER,
+	LOGICVC_ALPHA_LAYER
+};
+
+enum xylonfb_alpha_format {
+	LOGICVC_LAYER_ALPHA = 0,
+	LOGICVC_PIXEL_ALPHA,
+	LOGICVC_CLUT_16BPP_ALPHA,
+	LOGICVC_CLUT_32BPP_ALPHA
+};
+
+enum xylonfb_display_interface {
+	LOGICVC_DI_PARALLEL = 0,
+	LOGICVC_DI_ITU656,
+	LOGICVC_DI_LVDS_4bit,
+	LOGICVC_DI_CAMERA_LINK_4bit,
+	LOGICVC_DI_LVDS_3bit,
+	LOGICVC_DI_DVI
+};
+
+enum xylonfb_display_color_space {
+	LOGICVC_DCS_RGB = 0,
+	LOGICVC_DCS_YUV422,
+	LOGICVC_DCS_YUV444
+};
+
+#endif /* __LOGICVC_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/Makefile	2014-07-20 22:06:38.511270172 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+xylonfb_core-y := xylonfb.o xylonfb-ioctl.o xylonfb-pixclk.o
+xylonfb_core-$(CONFIG_FB_XYLON_PIXCLK_LOGICLK) += logiclk.o
+
+xylonfb_core-$(CONFIG_FB_XYLON_MISC) += ../misc/xylonfb-misc.o
+xylonfb_core-$(CONFIG_FB_XYLON_MISC_ADV7511) += ../misc/xylonfb-adv7511.o
+
+obj-y += xylonfb_core.o
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb.c	2014-07-20 22:06:38.532269826 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver core functions
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * This driver was based on skeletonfb.c and other framebuffer video drivers.
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/console.h>
+#include <linux/videodev2.h>
+#include "xylonfb.h"
+#if defined(CONFIG_FB_XYLON_MISC)
+#include "../misc/xylonfb-misc.h"
+#endif
+
+
+#define XYLONFB_PSEUDO_PALETTE_SZ 256
+
+#define LOGICVC_PIX_FMT_AYUV  v4l2_fourcc('A', 'Y', 'U', 'V')
+#define LOGICVC_PIX_FMT_AVUY  v4l2_fourcc('A', 'V', 'U', 'Y')
+#define LOGICVC_PIX_FMT_ALPHA v4l2_fourcc('A', '8', ' ', ' ')
+
+
+static struct xylonfb_vmode_data xylonfb_vmode = {
+	.fb_vmode = {
+		.refresh = 60,
+		.xres = 1024,
+		.yres = 768,
+		.pixclock = KHZ2PICOS(65000),
+		.left_margin = 160,
+		.right_margin = 24,
+		.upper_margin = 29,
+		.lower_margin = 3,
+		.hsync_len = 136,
+		.vsync_len = 6,
+		.vmode = FB_VMODE_NONINTERLACED
+	},
+	.fb_vmode_name = "1024x768"
+};
+
+static unsigned short logicvc_layer_reg_offset[] = {
+	(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_0_OFFSET),
+	(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_1_OFFSET),
+	(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_2_OFFSET),
+	(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_3_OFFSET),
+	(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_4_OFFSET)
+};
+
+static unsigned short logicvc_clut_reg_offset[] = {
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L0_CLUT_0_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L0_CLUT_1_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L1_CLUT_0_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L1_CLUT_1_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L2_CLUT_0_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L2_CLUT_1_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L3_CLUT_0_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L3_CLUT_1_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L4_CLUT_0_OFFSET),
+	(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L4_CLUT_1_OFFSET)
+};
+
+static char *xylonfb_mode_option;
+
+/* Function declarations */
+static int xylonfb_set_timings(struct fb_info *fbi, int bpp);
+static void xylonfb_logicvc_disp_ctrl(struct fb_info *fbi, bool enable);
+static void xylonfb_enable_logicvc_output(struct fb_info *fbi);
+static void xylonfb_disable_logicvc_output(struct fb_info *fbi);
+static void xylonfb_enable_logicvc_layer(struct fb_info *fbi);
+static void xylonfb_disable_logicvc_layer(struct fb_info *fbi);
+static void xylonfb_fbi_update(struct fb_info *fbi);
+
+/******************************************************************************/
+
+static u32 xylonfb_get_reg(void *base_virt, unsigned long offset,
+	struct xylonfb_layer_data *ld)
+{
+	return readl(base_virt + offset);
+}
+
+static void xylonfb_set_reg(u32 value,
+	void *base_virt, unsigned long offset,
+	struct xylonfb_layer_data *ld)
+{
+	writel(value, (base_virt + offset));
+}
+
+static unsigned long xylonfb_get_reg_mem_addr(
+	void *base_virt, unsigned long offset,
+	struct xylonfb_layer_data *ld)
+{
+	unsigned long ordinal = offset >> 3;
+
+	if ((unsigned long)base_virt - (unsigned long)ld->reg_base_virt) {
+		return (unsigned long)(&ld->layer_reg_list->hpos_reg) +
+			(ordinal * sizeof(unsigned long));
+	} else {
+		return (unsigned long)(&ld->xylonfb_cd->reg_list->dtype_reg) +
+			(ordinal * sizeof(unsigned long));
+	}
+}
+
+static u32 xylonfb_get_reg_mem(
+	void *base_virt, unsigned long offset,
+	struct xylonfb_layer_data *ld)
+{
+	return *((unsigned long *)xylonfb_get_reg_mem_addr(
+		base_virt, offset, ld));
+}
+
+static void xylonfb_set_reg_mem(u32 value,
+	void *base_virt, unsigned long offset,
+	struct xylonfb_layer_data *ld)
+{
+	unsigned long *reg_mem_addr =
+		(unsigned long *)xylonfb_get_reg_mem_addr(
+			base_virt, offset, ld);
+	*reg_mem_addr = value;
+	writel((*reg_mem_addr), (base_virt + offset));
+}
+
+/******************************************************************************/
+
+static irqreturn_t xylonfb_isr(int irq, void *dev_id)
+{
+	struct fb_info **afbi = dev_get_drvdata(dev_id);
+	struct fb_info *fbi = afbi[0];
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 isr;
+
+	driver_devel("%s IRQ %d\n", __func__, irq);
+
+	isr = readl(ld->reg_base_virt + LOGICVC_INT_STAT_ROFF);
+	if (isr & LOGICVC_V_SYNC_INT) {
+		writel(LOGICVC_V_SYNC_INT,
+			ld->reg_base_virt + LOGICVC_INT_STAT_ROFF);
+		cd->vsync.cnt++;
+		wake_up_interruptible(&cd->vsync.wait);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+/******************************************************************************/
+
+static int xylonfb_open(struct fb_info *fbi, int user)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+
+	driver_devel("%s\n", __func__);
+
+	if (ld->layer_use_ref == 0) {
+		/* turn on layer */
+		xylonfb_enable_logicvc_layer(fbi);
+	}
+	ld->layer_use_ref++;
+	ld->xylonfb_cd->xylonfb_use_ref++;
+
+	return 0;
+}
+
+static int xylonfb_release(struct fb_info *fbi, int user)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+
+	driver_devel("%s\n", __func__);
+
+	ld->layer_use_ref--;
+	if (ld->layer_use_ref == 0) {
+		/* turn off layer */
+		xylonfb_disable_logicvc_layer(fbi);
+	}
+	ld->xylonfb_cd->xylonfb_use_ref--;
+
+	return 0;
+}
+
+/******************************************************************************/
+
+static int xylonfb_check_var(struct fb_var_screeninfo *var,
+	struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_layer_fix_data *lfdata = &ld->layer_fix;
+
+	driver_devel("%s\n", __func__);
+
+	if (var->xres < LOGICVC_MIN_XRES)
+		var->xres = LOGICVC_MIN_XRES;
+	if (var->xres > LOGICVC_MAX_XRES)
+		var->xres = LOGICVC_MAX_XRES;
+	if (var->yres < LOGICVC_MIN_VRES)
+		var->yres = LOGICVC_MIN_VRES;
+	if (var->yres > LOGICVC_MAX_VRES)
+		var->yres = LOGICVC_MAX_VRES;
+
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->xres_virtual > lfdata->width)
+		var->xres_virtual = lfdata->width;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+	if (var->yres_virtual > lfdata->height)
+		var->yres_virtual = lfdata->height;
+
+	if ((var->xoffset + var->xres) >= var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres - 1;
+	if ((var->yoffset + var->yres) >= var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres - 1;
+
+	if (var->bits_per_pixel != fbi->var.bits_per_pixel) {
+		if (var->bits_per_pixel == 24)
+			var->bits_per_pixel = 32;
+		else
+			var->bits_per_pixel = fbi->var.bits_per_pixel;
+	}
+
+	var->grayscale = fbi->var.grayscale;
+
+	var->transp.offset = fbi->var.transp.offset;
+	var->transp.length = fbi->var.transp.length;
+	var->transp.msb_right = fbi->var.transp.msb_right;
+	var->red.offset = fbi->var.red.offset;
+	var->red.length = fbi->var.red.length;
+	var->red.msb_right = fbi->var.red.msb_right;
+	var->green.offset = fbi->var.green.offset;
+	var->green.length = fbi->var.green.length;
+	var->green.msb_right = fbi->var.green.msb_right;
+	var->blue.offset = fbi->var.blue.offset;
+	var->blue.length = fbi->var.blue.length;
+	var->blue.msb_right = fbi->var.blue.msb_right;
+	var->height = fbi->var.height;
+	var->width = fbi->var.width;
+	var->sync = fbi->var.sync;
+	var->rotate = fbi->var.rotate;
+
+	return 0;
+}
+
+static int xylonfb_set_par(struct fb_info *fbi)
+{
+	struct fb_info **afbi = NULL;
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	int rc = 0;
+	int i;
+	char vmode_opt[VMODE_NAME_SZ];
+	bool resolution_change, layer_on[LOGICVC_MAX_LAYERS];
+
+	driver_devel("%s\n", __func__);
+
+	if (cd->xylonfb_flags & XYLONFB_FLAG_VMODE_SET)
+		return 0;
+
+	if (!(cd->xylonfb_flags & XYLONFB_FLAG_EDID_VMODE) &&
+		((fbi->var.xres ==
+			cd->vmode_data_current.fb_vmode.xres) ||
+		(fbi->var.yres ==
+			cd->vmode_data_current.fb_vmode.yres))) {
+		resolution_change = false;
+	} else {
+		resolution_change = true;
+	}
+
+	if (resolution_change ||
+		(cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT)) {
+
+		if (!(cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT)) {
+			struct xylonfb_layer_data *ld;
+			/* store id's of enabled layers */
+			afbi = dev_get_drvdata(fbi->device);
+			for (i = 0; i < cd->xylonfb_layers; i++) {
+				ld = afbi[i]->par;
+				if (ld->layer_ctrl_flags & LOGICVC_LAYER_ON)
+					layer_on[i] = true;
+				else
+					layer_on[i] = false;
+			}
+		}
+
+		xylonfb_disable_logicvc_output(fbi);
+		xylonfb_logicvc_disp_ctrl(fbi, false);
+
+		if (!(cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT)) {
+			/* we want 60Hz refresh rate */
+			cd->vmode_data_current.fb_vmode.refresh = 60;
+			sprintf(vmode_opt, "%dx%d%s-%d@%d%s",
+				fbi->var.xres, fbi->var.yres,
+				cd->vmode_data_current.fb_vmode_opts_cvt,
+				fbi->var.bits_per_pixel,
+				cd->vmode_data_current.fb_vmode.refresh,
+				cd->vmode_data_current.fb_vmode_opts_ext);
+			if (!strcmp(cd->vmode_data.fb_vmode_name, vmode_opt)) {
+				cd->vmode_data_current = cd->vmode_data;
+			} else {
+				xylonfb_mode_option = vmode_opt;
+				rc = xylonfb_set_timings(
+					fbi, fbi->var.bits_per_pixel);
+				xylonfb_mode_option = NULL;
+			}
+		}
+		if (!rc) {
+			if (cd->xylonfb_flags & XYLONFB_FLAG_PIXCLK_VALID) {
+				rc = xylonfb_hw_pixclk_set(
+					cd->xylonfb_pixclk_src_id,
+					PICOS2KHZ(cd->vmode_data_current.fb_vmode.pixclock));
+				if (rc)
+					pr_err("Error xylonfb changing pixel clock\n");
+			}
+			xylonfb_fbi_update(fbi);
+			pr_info("xylonfb video mode: %dx%d%s-%d@%d%s\n",
+				fbi->var.xres, fbi->var.yres,
+				cd->vmode_data_current.fb_vmode_opts_cvt,
+				fbi->var.bits_per_pixel,
+				cd->vmode_data_current.fb_vmode.refresh,
+				cd->vmode_data_current.fb_vmode_opts_ext);
+		}
+
+		xylonfb_enable_logicvc_output(fbi);
+		xylonfb_logicvc_disp_ctrl(fbi, true);
+
+		/* set flag used for finding video mode only once */
+		if (cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT)
+			cd->xylonfb_flags |= XYLONFB_FLAG_VMODE_SET;
+		/* used only when resolution is changed */
+		if (!(cd->xylonfb_flags & XYLONFB_FLAG_VMODE_SET)) {
+			if (afbi) {
+				for (i = 0; i < cd->xylonfb_layers; i++)
+					if (layer_on[i])
+						xylonfb_enable_logicvc_layer(afbi[i]);
+			} else {
+				xylonfb_enable_logicvc_layer(fbi);
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int xylonfb_set_color_hw_rgb_to_yuv(
+	u16 *transp, u16 *red, u16 *green, u16 *blue, int len, int idx,
+	struct xylonfb_layer_data *ld)
+{
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 yuv_pixel;
+	u32 y, cb, cr;
+	u32 ykr, ykg, ykb, yk;
+	u32 crkr, crkg, crkb;
+	u32 cbkr, cbkg, cbkb;
+
+	driver_devel("%s\n", __func__);
+
+	if (idx > (LOGICVC_CLUT_SIZE-1) || len > LOGICVC_CLUT_SIZE)
+		return -EINVAL;
+
+	if ((cd->xylonfb_display_interface_type >> 4) == LOGICVC_DI_ITU656) {
+		ykr  = 29900;
+		ykg  = 58700;
+		ykb  = 11400;
+		yk   = 1600000;
+		crkr = 51138;
+		crkg = 42820;
+		crkb = 8316;
+		cbkr = 17258;
+		cbkg = 33881;
+		cbkb = 51140;
+	} else {
+		ykr  = 29900;
+		ykg  = 58700;
+		ykb  = 11400;
+		yk   = 0;
+		crkr = 49980;
+		crkg = 41850;
+		crkb = 8128;
+		cbkr = 16868;
+		cbkg = 33107;
+		cbkb = 49970;
+	}
+
+	while (len > 0) {
+		y = (
+				(ykr * (red[idx] & 0xFF))
+					+
+				(ykg * (green[idx] & 0xFF))
+					+
+				(ykb * (blue[idx] & 0xFF))
+					+
+				 yk
+			)
+				/
+			100000;
+		cr = (
+				(crkr * (red[idx] & 0xFF))
+					-
+				(crkg * (green[idx] & 0xFF))
+					-
+				(crkb * (blue[idx] & 0xFF))
+					+
+				 12800000
+			 )
+				/
+			100000;
+		cb = (
+				(-cbkr * (red[idx] & 0xFF))
+					-
+				(cbkg * (green[idx] & 0xFF))
+					+
+				(cbkb * (blue[idx] & 0xFF))
+					+
+				12800000
+			 )
+				/
+			100000;
+		if (transp) {
+			yuv_pixel = (((u32)transp[idx] & 0xFF) << 24) |
+				(y << 16) | (cb << 8) | cr;
+		} else {
+			yuv_pixel =
+				(0xFF << 24) | (y << 16) | (cb << 8) | cr;
+		}
+		writel(yuv_pixel, ld->layer_clut_base_virt +
+			(idx*LOGICVC_CLUT_REGISTER_SIZE));
+		len--;
+		idx++;
+	}
+
+	return 0;
+}
+
+static int xylonfb_set_color_hw(u16 *transp, u16 *red, u16 *green, u16 *blue,
+	int len, int idx, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_layer_fix_data *lfdata = &ld->layer_fix;
+	u32 pixel;
+	int bpp_virt, toff, roff, goff, boff;
+
+	driver_devel("%s\n", __func__);
+
+	if ((fbi->fix.visual == FB_VISUAL_FOURCC) &&
+		(fbi->var.grayscale == LOGICVC_PIX_FMT_AYUV)) {
+		return xylonfb_set_color_hw_rgb_to_yuv(
+			transp, red, green, blue, len, idx, ld);
+	}
+
+	bpp_virt = lfdata->bpp_virt;
+
+	toff = fbi->var.transp.offset;
+	roff = fbi->var.red.offset;
+	goff = fbi->var.green.offset;
+	boff = fbi->var.blue.offset;
+
+	if (fbi->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
+		u32 clut_value;
+
+		if (idx > (LOGICVC_CLUT_SIZE-1) || len > LOGICVC_CLUT_SIZE)
+			return -EINVAL;
+
+		if (lfdata->alpha_mode == LOGICVC_CLUT_16BPP_ALPHA) {
+			if (transp) {
+				while (len > 0) {
+					clut_value =
+						((((transp[idx] & 0xFC) >> 2) << toff) |
+						(((red[idx] & 0xF8) >> 3) << roff) |
+						(((green[idx] & 0xFC) >> 2) << goff) |
+						(((blue[idx] & 0xF8) >> 3) << boff));
+					writel(clut_value,
+						ld->layer_clut_base_virt +
+						(idx*LOGICVC_CLUT_REGISTER_SIZE));
+					len--;
+					idx++;
+				}
+			} else {
+				while (len > 0) {
+					clut_value =
+						((0x3F << toff) |
+						(((red[idx] & 0xF8) >> 3) << roff) |
+						(((green[idx] & 0xFC) >> 2) << goff) |
+						(((blue[idx] & 0xF8) >> 3) << boff));
+					writel(clut_value,
+						ld->layer_clut_base_virt +
+						(idx*LOGICVC_CLUT_REGISTER_SIZE));
+					len--;
+					idx++;
+				}
+			}
+		} else if (lfdata->alpha_mode == LOGICVC_CLUT_32BPP_ALPHA) {
+			if (transp) {
+				while (len > 0) {
+					clut_value =
+						(((transp[idx] & 0xFF) << toff) |
+						((red[idx] & 0xFF) << roff) |
+						((green[idx] & 0xFF) << goff) |
+						((blue[idx] & 0xFF) << boff));
+					writel(clut_value,
+						ld->layer_clut_base_virt +
+						(idx*LOGICVC_CLUT_REGISTER_SIZE));
+					len--;
+					idx++;
+				}
+			} else {
+				while (len > 0) {
+					clut_value =
+						((0xFF << toff) |
+						((red[idx] & 0xFF) << roff) |
+						((green[idx] & 0xFF) << goff) |
+						((blue[idx] & 0xFF) << boff));
+					writel(clut_value,
+						ld->layer_clut_base_virt +
+						(idx*LOGICVC_CLUT_REGISTER_SIZE));
+					len--;
+					idx++;
+				}
+			}
+		}
+	} else if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
+		if (bpp_virt == 8) {
+			if (lfdata->alpha_mode == LOGICVC_LAYER_ALPHA) {
+				while (len > 0) {
+					pixel = ((((red[idx] & 0xE0) >> 5) << roff) |
+						(((green[idx] & 0xE0) >> 5) << goff) |
+						(((blue[idx] & 0xC0) >> 6) << boff));
+					((u32 *)(fbi->pseudo_palette))[idx] =
+						(pixel << 24) | (pixel << 16) | (pixel << 8) | pixel;
+					len--;
+					idx++;
+				}
+			} else if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA) {
+				if (transp) {
+					while (len > 0) {
+						pixel = ((((transp[idx] & 0xE0) >> 5) << toff) |
+							(((red[idx] & 0xE0) >> 5) << roff) |
+							(((green[idx] & 0xE0) >> 5) << goff) |
+							(((blue[idx] & 0xC0) >> 6) << boff));
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							(pixel << 16) | pixel;
+						len--;
+						idx++;
+					}
+				} else {
+					while (len > 0) {
+						pixel = ((0x07 << toff) |
+							(((red[idx] & 0xE0) >> 5) << roff) |
+							(((green[idx] & 0xE0) >> 5) << goff) |
+							(((blue[idx] & 0xC0) >> 6) << boff));
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							(pixel << 16) | pixel;
+						len--;
+						idx++;
+					}
+				}
+			}
+		} else if (bpp_virt == 16) {
+			if (lfdata->alpha_mode == LOGICVC_LAYER_ALPHA) {
+				while (len > 0) {
+					pixel = ((((red[idx] & 0xF8) >> 3) << roff) |
+						(((green[idx] & 0xFC) >> 2) << goff) |
+						(((blue[idx] & 0xF8) >> 3) << boff));
+					((u32 *)(fbi->pseudo_palette))[idx] =
+						(pixel << 16) | pixel;
+					len--;
+					idx++;
+				}
+			} else if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA) {
+				if (transp) {
+					while (len > 0) {
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							((((transp[idx] & 0xFC) >> 2) << toff) |
+							(((red[idx] & 0xF8) >> 3) << roff) |
+							(((green[idx] & 0xFC) >> 2) << goff) |
+							(((blue[idx] & 0xF8) >> 3) << boff));
+						len--;
+						idx++;
+					}
+				} else {
+					while (len > 0) {
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							((0x3F << toff) |
+							(((red[idx] & 0xF8) >> 3) << roff) |
+							(((green[idx] & 0xFC) >> 2) << goff) |
+							(((blue[idx] & 0xF8) >> 3) << boff));
+						len--;
+						idx++;
+					}
+				}
+			}
+		} else if (bpp_virt == 32) {
+			if (lfdata->alpha_mode == LOGICVC_LAYER_ALPHA) {
+				while (len > 0) {
+					((u32 *)(fbi->pseudo_palette))[idx] =
+						(((red[idx] & 0xFF) << roff) |
+						((green[idx] & 0xFF) << goff) |
+						((blue[idx] & 0xFF) << boff));
+					len--;
+					idx++;
+				}
+			} else if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA) {
+				if (transp) {
+					while (len > 0) {
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							(((transp[idx] & 0xFF) << toff) |
+							((red[idx] & 0xFF) << roff) |
+							((green[idx] & 0xFF) << goff) |
+							((blue[idx] & 0xFF) << boff));
+						len--;
+						idx++;
+					}
+				} else {
+					while (len > 0) {
+						((u32 *)(fbi->pseudo_palette))[idx] =
+							((0xFF << toff) |
+							((red[idx] & 0xFF) << roff) |
+							((green[idx] & 0xFF) << goff) |
+							((blue[idx] & 0xFF) << boff));
+						len--;
+						idx++;
+					}
+				}
+			}
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int xylonfb_set_color_reg(unsigned regno, unsigned red, unsigned green,
+	unsigned blue, unsigned transp, struct fb_info *fbi)
+{
+	driver_devel("%s\n", __func__);
+
+	return xylonfb_set_color_hw(
+		(u16 *)&transp, (u16 *)&red, (u16 *)&green, (u16 *)&blue,
+		1, regno, fbi);
+}
+
+static int xylonfb_set_cmap(struct fb_cmap *cmap, struct fb_info *fbi)
+{
+	driver_devel("%s\n", __func__);
+
+	return xylonfb_set_color_hw(
+		cmap->transp, cmap->red, cmap->green, cmap->blue,
+		cmap->len, cmap->start, fbi);
+}
+
+static void xylonfb_set_pixels(struct fb_info *fbi,
+	struct xylonfb_layer_data *ld, int bpp, unsigned int pix)
+{
+	u32 *vmem;
+	u8 *vmem8;
+	u16 *vmem16;
+	u32 *vmem32;
+	int x, y, pix_off;
+
+	driver_devel("%s\n", __func__);
+
+	vmem = ld->fb_virt +
+		(fbi->var.xoffset * (fbi->var.bits_per_pixel/4)) +
+		(fbi->var.yoffset * fbi->var.xres_virtual *
+		(fbi->var.bits_per_pixel/4));
+
+	switch (bpp) {
+	case 8:
+		vmem8 = (u8 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pix_off = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem8[pix_off+x] = pix;
+		}
+		break;
+	case 16:
+		vmem16 = (u16 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pix_off = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem16[pix_off+x] = pix;
+		}
+		break;
+	case 32:
+		vmem32 = (u32 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pix_off = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem32[pix_off+x] = pix;
+		}
+		break;
+	}
+}
+
+static int xylonfb_blank(int blank_mode, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_layer_fix_data *lfdata = &ld->layer_fix;
+	u32 reg;
+
+	driver_devel("%s\n", __func__);
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		driver_devel("FB_BLANK_UNBLANK\n");
+		reg = readl(ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		reg |= LOGICVC_V_EN_MSK;
+		writel(reg, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		mdelay(50);
+		break;
+
+	case FB_BLANK_NORMAL:
+		driver_devel("FB_BLANK_NORMAL\n");
+		switch (lfdata->bpp_virt) {
+		case 8:
+			switch (lfdata->alpha_mode) {
+			case LOGICVC_LAYER_ALPHA:
+				xylonfb_set_pixels(fbi, ld, 8, 0x00);
+				break;
+			case LOGICVC_PIXEL_ALPHA:
+				xylonfb_set_pixels(fbi, ld, 16, 0xFF00);
+				break;
+			case LOGICVC_CLUT_16BPP_ALPHA:
+			case LOGICVC_CLUT_32BPP_ALPHA:
+				xylonfb_set_color_reg(0, 0, 0, 0, 0xFF, fbi);
+				xylonfb_set_pixels(fbi, ld, 8, 0);
+				break;
+			}
+			break;
+		case 16:
+			switch (lfdata->alpha_mode) {
+			case LOGICVC_LAYER_ALPHA:
+				xylonfb_set_pixels(fbi, ld, 16, 0x0000);
+				break;
+			case LOGICVC_PIXEL_ALPHA:
+				xylonfb_set_pixels(fbi, ld, 32, 0xFF000000);
+				break;
+			}
+			break;
+		case 32:
+			xylonfb_set_pixels(fbi, ld, 32, 0xFF000000);
+			break;
+		}
+		break;
+
+	case FB_BLANK_POWERDOWN:
+		driver_devel("FB_BLANK_POWERDOWN\n");
+		reg = readl(ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		reg &= ~LOGICVC_V_EN_MSK;
+		writel(reg, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		mdelay(50);
+		break;
+
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	default:
+		driver_devel("FB_BLANK_ not supported!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int xylonfb_pan_display(struct fb_var_screeninfo *var,
+	struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+
+	driver_devel("%s\n", __func__);
+
+	if (fbi->var.xoffset == var->xoffset &&
+		fbi->var.yoffset == var->yoffset)
+		return 0;
+
+	if (fbi->var.vmode & FB_VMODE_YWRAP) {
+		return -EINVAL;
+	} else {
+		if (var->xoffset + fbi->var.xres > fbi->var.xres_virtual ||
+			var->yoffset + fbi->var.yres > fbi->var.yres_virtual) {
+			/* if smaller then physical layer video memory
+			   allow panning */
+			if ((var->xoffset + fbi->var.xres > ld->layer_fix.width)
+					||
+				(var->yoffset + fbi->var.yres > ld->layer_fix.height)) {
+				return -EINVAL;
+			}
+		}
+	}
+	/* YCbCr 4:2:2 layer type can only have even layer xoffset */
+	if (ld->layer_fix.layer_type == LOGICVC_YCBCR_LAYER &&
+		ld->layer_fix.bpp_virt == 16) {
+		var->xoffset &= ~1;
+	}
+
+	fbi->var.xoffset = var->xoffset;
+	fbi->var.yoffset = var->yoffset;
+	/* set layer memory X offset */
+	cd->reg_access.xylonfb_set_reg_val(var->xoffset,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_HOR_OFF_ROFF,
+		ld);
+	/* set layer memory Y offset */
+	cd->reg_access.xylonfb_set_reg_val(var->yoffset,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_VER_OFF_ROFF,
+		ld);
+	cd->reg_access.xylonfb_set_reg_val((fbi->var.xres-1),
+		ld->layer_reg_base_virt, LOGICVC_LAYER_HOR_POS_ROFF,
+		ld);
+	/* apply changes in logiCVC */
+	cd->reg_access.xylonfb_set_reg_val((fbi->var.yres-1),
+		ld->layer_reg_base_virt, LOGICVC_LAYER_VER_POS_ROFF,
+		ld);
+
+	return 0;
+}
+
+
+static struct fb_ops xylonfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_open = xylonfb_open,
+	.fb_release = xylonfb_release,
+	.fb_check_var = xylonfb_check_var,
+	.fb_set_par = xylonfb_set_par,
+	.fb_setcolreg = xylonfb_set_color_reg,
+	.fb_setcmap = xylonfb_set_cmap,
+	.fb_blank = xylonfb_blank,
+	.fb_pan_display = xylonfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_cursor = NULL,
+	.fb_rotate = NULL,
+	.fb_sync = NULL,
+	.fb_ioctl = xylonfb_ioctl,
+	.fb_mmap = NULL,
+	.fb_get_caps = NULL,
+	.fb_destroy = NULL,
+};
+
+/******************************************************************************/
+
+static int xylonfb_find_next_layer(struct xylonfb_layer_fix_data *lfdata,
+	int layers, int curr)
+{
+	unsigned long address, temp_address, loop_address;
+	int i, next;
+
+	driver_devel("%s\n", __func__);
+
+	address = lfdata[curr].offset * lfdata[curr].width * lfdata[curr].bpp;
+	temp_address = ~0;
+	next = -1;
+
+	for (i = 0; i < layers; i++) {
+		loop_address =
+			lfdata[i].offset * lfdata[i].width * lfdata[i].bpp;
+		if (address < loop_address
+				&&
+			loop_address < temp_address) {
+			next = i;
+			temp_address = loop_address;
+		}
+	}
+
+	return next;
+}
+
+static void xylonfb_set_yvirt(struct xylonfb_init_data *init_data,
+	int layers, int curr)
+{
+	struct xylonfb_layer_fix_data *lfdata;
+	unsigned long vmem_base_addr, vmem_high_addr;
+	int next;
+
+	driver_devel("%s\n", __func__);
+
+	lfdata = init_data->lfdata;
+	vmem_base_addr = init_data->vmem_base_addr;
+	vmem_high_addr = init_data->vmem_high_addr;
+
+	next = xylonfb_find_next_layer(lfdata, layers, curr);
+
+	if (next != -1) {
+		lfdata[curr].height =
+			((lfdata[next].width * (lfdata[next].bpp/8) *
+			lfdata[next].offset)
+				-
+			(lfdata[curr].width * (lfdata[curr].bpp/8) *
+			lfdata[curr].offset))
+				/
+			(lfdata[curr].width * (lfdata[curr].bpp/8));
+	} else { /* last physical logiCVC layer */
+		lfdata[curr].height = LOGICVC_MAX_LINES + 1;
+		while (1) {
+			if (((lfdata[curr].width * (lfdata[curr].bpp/8) *
+				lfdata[curr].height)
+					+
+				(lfdata[curr].width * (lfdata[curr].bpp/8) *
+				lfdata[curr].offset))
+					<=
+				(vmem_high_addr - vmem_base_addr))
+				break;
+			/* FIXME - magic decrease step */
+			lfdata[curr].height -= 64;
+		}
+	}
+
+	if (lfdata[curr].height >
+		(lfdata[curr].buffer_offset * LOGICVC_MAX_LAYER_BUFFERS)) {
+		lfdata[curr].height =
+			lfdata[curr].buffer_offset * LOGICVC_MAX_LAYER_BUFFERS;
+	}
+
+	lfdata[curr].layer_fix_info |=
+		((lfdata[curr].height / lfdata[curr].buffer_offset) << 4);
+}
+
+static int xylonfb_map(int id, int layers, struct device *dev,
+	struct xylonfb_layer_data *ld,
+	unsigned long vmem_base_addr,
+	unsigned long reg_base_phys, void *reg_base_virt,
+	int memmap)
+{
+	struct xylonfb_layer_fix_data *lfdata = &ld->layer_fix;
+
+	driver_devel("%s\n", __func__);
+
+	/* logiCVC register mapping */
+	ld->reg_base_phys = reg_base_phys;
+	ld->reg_base_virt = reg_base_virt;
+	/* check register mappings */
+	if (!ld->reg_base_virt) {
+		pr_err("Error xylonfb registers mapping\n");
+		return -ENOMEM;
+	}
+	/* Video memory mapping */
+	ld->fb_phys = vmem_base_addr +
+		(lfdata->width * (lfdata->bpp/8) * lfdata->offset);
+	ld->fb_size =
+		lfdata->width * (lfdata->bpp/8) * lfdata->height;
+
+	if (memmap) {
+		if (ld->xylonfb_cd->xylonfb_flags & XYLONFB_FLAG_DMA_BUFFER) {
+			/* NOT USED FOR NOW! */
+			ld->fb_virt = dma_alloc_coherent(NULL,
+				PAGE_ALIGN(ld->fb_size),
+				&ld->fb_phys, GFP_KERNEL);
+		} else {
+			ld->fb_virt =
+				ioremap_wc(ld->fb_phys, ld->fb_size);
+		}
+		/* check memory mappings */
+		if (!ld->fb_virt) {
+			pr_err("Error xylonfb vmem mapping\n");
+			return -ENOMEM;
+		}
+	}
+	ld->layer_reg_base_virt = ld->reg_base_virt +
+		logicvc_layer_reg_offset[id];
+	ld->layer_clut_base_virt = ld->reg_base_virt +
+		logicvc_clut_reg_offset[id*LOGICVC_CLUT_0_INDEX_OFFSET];
+	ld->layer_use_ref = 0;
+	ld->layer_ctrl_flags = 0;
+
+	return 0;
+}
+
+static void xylonfb_set_fbi_var_screeninfo(struct fb_var_screeninfo *var,
+	struct xylonfb_common_data *cd)
+{
+	driver_devel("%s\n", __func__);
+
+	var->xres = cd->vmode_data_current.fb_vmode.xres;
+	var->yres = cd->vmode_data_current.fb_vmode.yres;
+	var->pixclock = cd->vmode_data_current.fb_vmode.pixclock;
+	var->left_margin = cd->vmode_data_current.fb_vmode.left_margin;
+	var->right_margin = cd->vmode_data_current.fb_vmode.right_margin;
+	var->upper_margin = cd->vmode_data_current.fb_vmode.upper_margin;
+	var->lower_margin = cd->vmode_data_current.fb_vmode.lower_margin;
+	var->hsync_len = cd->vmode_data_current.fb_vmode.hsync_len;
+	var->vsync_len = cd->vmode_data_current.fb_vmode.vsync_len;
+	var->sync = cd->vmode_data_current.fb_vmode.sync;
+	var->vmode = cd->vmode_data_current.fb_vmode.vmode;
+}
+
+static void xylonfb_fbi_update(struct fb_info *fbi)
+{
+	struct fb_info **afbi = dev_get_drvdata(fbi->device);
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	int i, layers, layer_id;
+
+	driver_devel("%s\n", __func__);
+
+	if (!(cd->xylonfb_flags & XYLONFB_FLAG_EDID_VMODE) ||
+		!(cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY) ||
+		!afbi)
+		return;
+
+	layers = cd->xylonfb_layers;
+	layer_id = ld->layer_fix.layer_fix_info & 0x0F;
+
+	for (i = 0; i < layers; i++) {
+		if (i == layer_id)
+			continue;
+		xylonfb_set_fbi_var_screeninfo(&afbi[i]->var, cd);
+		afbi[i]->monspecs = afbi[layer_id]->monspecs;
+	}
+}
+
+static void xylonfb_set_hw_specifics(struct fb_info *fbi,
+	struct xylonfb_layer_data *ld,
+	struct xylonfb_layer_fix_data *lfdata,
+	unsigned long reg_base_phys)
+{
+	driver_devel("%s\n", __func__);
+
+	fbi->fix.smem_start = ld->fb_phys;
+	fbi->fix.smem_len = ld->fb_size;
+	if (lfdata->layer_type == LOGICVC_RGB_LAYER)
+		fbi->fix.type = FB_TYPE_PACKED_PIXELS;
+	else if (lfdata->layer_type == LOGICVC_YCBCR_LAYER)
+		fbi->fix.type = FB_TYPE_FOURCC;
+	if ((lfdata->layer_type == LOGICVC_YCBCR_LAYER) ||
+		(lfdata->layer_type == LOGICVC_ALPHA_LAYER)) {
+		fbi->fix.visual = FB_VISUAL_FOURCC;
+	} else if ((lfdata->layer_type == LOGICVC_RGB_LAYER) &&
+		(lfdata->bpp == 8) &&
+		((lfdata->alpha_mode == LOGICVC_CLUT_16BPP_ALPHA) ||
+		(lfdata->alpha_mode == LOGICVC_CLUT_32BPP_ALPHA))) {
+		fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	} else {
+		/*
+			Other logiCVC layer pixel formats:
+			- 8 bpp: LAYER or PIXEL alpha
+			  It is not true color, RGB triplet is stored in 8 bits.
+			- 16 bpp:
+			  LAYER alpha: RGB triplet is stored in 16 bits
+			  PIXEL alpha: ARGB quadriplet is stored in 32 bits
+			- 32 bpp: LAYER or PIXEL alpha
+			  True color, RGB triplet or ARGB quadriplet
+			  is stored in 32 bits.
+		*/
+		fbi->fix.visual = FB_VISUAL_TRUECOLOR;
+	}
+	/* sanity check */
+	if ((lfdata->bpp != 8) &&
+		((lfdata->alpha_mode == LOGICVC_CLUT_16BPP_ALPHA) ||
+		(lfdata->alpha_mode == LOGICVC_CLUT_32BPP_ALPHA))) {
+		pr_warn("xylonfb invalid layer alpha!\n");
+		lfdata->alpha_mode = LOGICVC_LAYER_ALPHA;
+	}
+	fbi->fix.xpanstep = 1;
+	fbi->fix.ypanstep = 1;
+	fbi->fix.ywrapstep = 0;
+	fbi->fix.line_length = lfdata->width * (lfdata->bpp/8);
+	fbi->fix.mmio_start = reg_base_phys;
+	fbi->fix.mmio_len = LOGICVC_REGISTERS_RANGE;
+	fbi->fix.accel = FB_ACCEL_NONE;
+
+	fbi->var.xres_virtual = lfdata->width;
+	if (lfdata->height <= LOGICVC_MAX_LINES)
+		fbi->var.yres_virtual = lfdata->height;
+	else
+		fbi->var.yres_virtual = LOGICVC_MAX_LINES;
+	fbi->var.bits_per_pixel = lfdata->bpp;
+	switch (lfdata->layer_type) {
+	case LOGICVC_RGB_LAYER:
+		fbi->var.grayscale = 0;
+		break;
+	case LOGICVC_YCBCR_LAYER:
+		if (lfdata->bpp == 8) {
+			fbi->var.grayscale = LOGICVC_PIX_FMT_AYUV;
+		} else if (lfdata->bpp == 16) {
+			if (ld->layer_ctrl_flags & LOGICVC_SWAP_RB)
+				fbi->var.grayscale = V4L2_PIX_FMT_YVYU;
+			else
+				fbi->var.grayscale = V4L2_PIX_FMT_VYUY;
+		} else if (lfdata->bpp == 32) {
+			if (ld->layer_ctrl_flags & LOGICVC_SWAP_RB)
+				fbi->var.grayscale = LOGICVC_PIX_FMT_AVUY;
+			else
+				fbi->var.grayscale = LOGICVC_PIX_FMT_AYUV;
+		}
+		break;
+	case LOGICVC_ALPHA_LAYER:
+		/* logiCVC Alpha layer 8bpp */
+		fbi->var.grayscale = LOGICVC_PIX_FMT_ALPHA;
+		break;
+	}
+
+	/*
+		Set values according to logiCVC layer data width configuration:
+		- layer data width can be 1, 2, 4 bytes
+		- layer data width for 16 bpp can be 2 or 4 bytes
+	*/
+	if (lfdata->alpha_mode == LOGICVC_LAYER_ALPHA) {
+		fbi->var.transp.offset = 0;
+		fbi->var.transp.length = 0;
+	}
+	switch (lfdata->bpp_virt) {
+	case 8:
+		switch (lfdata->alpha_mode) {
+		case LOGICVC_PIXEL_ALPHA:
+			fbi->var.transp.offset = 8;
+			fbi->var.transp.length = 3;
+
+		case LOGICVC_LAYER_ALPHA:
+			fbi->var.red.offset = 5;
+			fbi->var.red.length = 3;
+			fbi->var.green.offset = 2;
+			fbi->var.green.length = 3;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 2;
+			break;
+
+		case LOGICVC_CLUT_16BPP_ALPHA:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 6;
+			fbi->var.red.offset = 19;
+			fbi->var.red.length = 5;
+			fbi->var.green.offset = 10;
+			fbi->var.green.length = 6;
+			fbi->var.blue.offset = 3;
+			fbi->var.blue.length = 5;
+			break;
+
+		case LOGICVC_CLUT_32BPP_ALPHA:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 8;
+			fbi->var.red.offset = 16;
+			fbi->var.red.length = 8;
+			fbi->var.green.offset = 8;
+			fbi->var.green.length = 8;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 8;
+			break;
+		}
+		break;
+	case 16:
+		switch (lfdata->alpha_mode) {
+		case LOGICVC_PIXEL_ALPHA:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 6;
+
+		case LOGICVC_LAYER_ALPHA:
+			fbi->var.red.offset = 11;
+			fbi->var.red.length = 5;
+			fbi->var.green.offset = 5;
+			fbi->var.green.length = 6;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 5;
+			break;
+		}
+		break;
+	case 32:
+		switch (lfdata->alpha_mode) {
+		case LOGICVC_PIXEL_ALPHA:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 8;
+
+		case LOGICVC_LAYER_ALPHA:
+			fbi->var.red.offset = 16;
+			fbi->var.red.length = 8;
+			fbi->var.green.offset = 8;
+			fbi->var.green.length = 8;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 8;
+			break;
+		}
+		break;
+	}
+	fbi->var.transp.msb_right = 0;
+	fbi->var.red.msb_right = 0;
+	fbi->var.green.msb_right = 0;
+	fbi->var.blue.msb_right = 0;
+	fbi->var.activate = FB_ACTIVATE_NOW;
+	fbi->var.height = 0;
+	fbi->var.width = 0;
+	fbi->var.sync = 0;
+	fbi->var.rotate = 0;
+}
+
+static int xylonfb_set_timings(struct fb_info *fbi, int bpp)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	struct fb_var_screeninfo fb_var;
+	int rc;
+
+	driver_devel("%s\n", __func__);
+
+	if ((cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT) &&
+		(!(cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY)) &&
+		memchr(cd->vmode_data.fb_vmode_name, 'x', 10)) {
+		cd->vmode_data_current = cd->vmode_data;
+		return 0;
+	}
+
+	/* switch-case to default */
+	rc = 255;
+	if ((cd->xylonfb_flags & XYLONFB_FLAG_EDID_VMODE) &&
+		(cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY)) {
+		if (cd->xylonfb_flags & XYLONFB_FLAG_VMODE_INIT) {
+#if defined(CONFIG_FB_XYLON_MISC)
+			fb_var = *(cd->xylonfb_misc->var_screeninfo);
+#endif
+		} else {
+			rc = fb_find_mode(&fb_var, fbi, xylonfb_mode_option,
+				fbi->monspecs.modedb, fbi->monspecs.modedb_len,
+				&xylonfb_vmode.fb_vmode, bpp);
+			if ((rc != 1) && (rc != 2))
+				return -EINVAL;
+#if defined(CONFIG_FB_XYLON_MISC)
+			if (fbi->monspecs.modedb &&
+				cd->xylonfb_misc->monspecs->misc & FB_MISC_1ST_DETAIL)
+				if ((fbi->var.xres == fbi->monspecs.modedb[0].xres) &&
+					(fbi->var.yres == fbi->monspecs.modedb[0].yres)) {
+					fb_videomode_to_var(&fb_var, &fbi->monspecs.modedb[0]);
+				}
+#endif
+		}
+	} else {
+		rc = fb_find_mode(&fb_var, fbi, xylonfb_mode_option, NULL, 0,
+			&xylonfb_vmode.fb_vmode, bpp);
+	}
+#ifdef DEBUG
+	switch (rc) {
+	case 0:
+		pr_err("Error xylonfb video mode\n"
+			"using driver default mode %dx%dM-%d@%d\n",
+			xylonfb_vmode.fb_vmode.xres,
+			xylonfb_vmode.fb_vmode.yres,
+			bpp,
+			xylonfb_vmode.fb_vmode.refresh);
+		break;
+	case 1:
+		driver_devel("xylonfb video mode %s\n", xylonfb_mode_option);
+		break;
+	case 2:
+		pr_notice("xylonfb video mode %s with ignored refresh rate\n",
+			xylonfb_mode_option);
+		break;
+	case 3:
+		pr_notice("xylonfb default video mode %dx%dM-%d@%d\n",
+			xylonfb_vmode.fb_vmode.xres,
+			xylonfb_vmode.fb_vmode.yres,
+			bpp,
+			xylonfb_vmode.fb_vmode.refresh);
+		break;
+	case 4:
+		pr_notice("xylonfb video mode fallback\n");
+		break;
+	default:
+		break;
+	}
+#endif
+
+	cd->vmode_data_current.ctrl_reg = cd->vmode_data.ctrl_reg;
+	cd->vmode_data_current.fb_vmode.xres = fb_var.xres;
+	cd->vmode_data_current.fb_vmode.yres = fb_var.yres;
+	cd->vmode_data_current.fb_vmode.pixclock = fb_var.pixclock;
+	cd->vmode_data_current.fb_vmode.left_margin = fb_var.left_margin;
+	cd->vmode_data_current.fb_vmode.right_margin = fb_var.right_margin;
+	cd->vmode_data_current.fb_vmode.upper_margin = fb_var.upper_margin;
+	cd->vmode_data_current.fb_vmode.lower_margin = fb_var.lower_margin;
+	cd->vmode_data_current.fb_vmode.hsync_len = fb_var.hsync_len;
+	cd->vmode_data_current.fb_vmode.vsync_len = fb_var.vsync_len;
+	cd->vmode_data_current.fb_vmode.sync = fb_var.sync;
+	cd->vmode_data_current.fb_vmode.vmode = fb_var.vmode;
+	cd->vmode_data_current.fb_vmode.refresh =
+		DIV_ROUND_CLOSEST(
+			(PICOS2KHZ(fb_var.pixclock) * 1000),
+			((fb_var.xres + fb_var.left_margin +
+			fb_var.right_margin + fb_var.hsync_len)
+				*
+			(fb_var.yres + fb_var.upper_margin +
+			fb_var.lower_margin + fb_var.vsync_len)));
+	strcpy(cd->vmode_data_current.fb_vmode_opts_cvt,
+		cd->vmode_data.fb_vmode_opts_cvt);
+	strcpy(cd->vmode_data_current.fb_vmode_opts_ext,
+		cd->vmode_data.fb_vmode_opts_ext);
+	sprintf(cd->vmode_data_current.fb_vmode_name,
+		"%dx%d%s-%d@%d%s",
+		fb_var.xres, fb_var.yres,
+		cd->vmode_data_current.fb_vmode_opts_cvt,
+		fb_var.bits_per_pixel,
+		cd->vmode_data_current.fb_vmode.refresh,
+		cd->vmode_data_current.fb_vmode_opts_ext);
+
+	if ((cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY) ||
+		!memchr(cd->vmode_data.fb_vmode_name, 'x', 10)) {
+		cd->vmode_data = cd->vmode_data_current;
+	}
+
+	return 0;
+}
+
+static int xylonfb_register_fb(struct fb_info *fbi,
+	struct xylonfb_layer_data *ld,
+	unsigned long reg_base_phys, int id, int *regfb)
+{
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	struct xylonfb_layer_fix_data *lfdata = &ld->layer_fix;
+	int alpha;
+
+	driver_devel("%s\n", __func__);
+
+	fbi->flags = FBINFO_DEFAULT;
+	fbi->screen_base = (char __iomem *)ld->fb_virt;
+	fbi->screen_size = ld->fb_size;
+	fbi->pseudo_palette =
+		kzalloc(sizeof(u32) * XYLONFB_PSEUDO_PALETTE_SZ, GFP_KERNEL);
+	fbi->fbops = &xylonfb_ops;
+
+	sprintf(fbi->fix.id, "Xylon FB%d", id);
+	xylonfb_set_hw_specifics(fbi, ld, lfdata, reg_base_phys);
+	if (!(cd->xylonfb_flags & XYLONFB_FLAG_DEFAULT_VMODE_SET)) {
+		xylonfb_set_timings(fbi, fbi->var.bits_per_pixel);
+		cd->xylonfb_flags |= XYLONFB_FLAG_DEFAULT_VMODE_SET;
+	}
+	xylonfb_set_fbi_var_screeninfo(&fbi->var, cd);
+	fbi->mode = &cd->vmode_data_current.fb_vmode;
+	fbi->mode->name = cd->vmode_data_current.fb_vmode_name;
+
+	if (lfdata->alpha_mode == LOGICVC_LAYER_ALPHA)
+		alpha = 0;
+	else
+		alpha = 1;
+	if (fb_alloc_cmap(&fbi->cmap, XYLONFB_PSEUDO_PALETTE_SZ, alpha))
+		return -ENOMEM;
+
+	*regfb = register_framebuffer(fbi);
+	if (*regfb) {
+		pr_err("Error xylonfb registering xylonfb %d\n", id);
+		return -EINVAL;
+	}
+	pr_info("xylonfb %d registered\n", id);
+	/* after fb driver registration, values in struct fb_info
+		must not be changed anywhere else except in xylonfb_set_par */
+
+	return 0;
+}
+
+static void xylonfb_init_layer_regs(struct xylonfb_layer_data *ld)
+{
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 reg_val;
+
+	switch (ld->layer_fix.bpp_virt) {
+	case 8:
+		switch (ld->layer_fix.alpha_mode) {
+		case LOGICVC_CLUT_16BPP_ALPHA:
+			reg_val = TRANSPARENT_COLOR_8BPP_CLUT_16;
+			break;
+		case LOGICVC_CLUT_32BPP_ALPHA:
+			reg_val = TRANSPARENT_COLOR_8BPP_CLUT_24;
+			break;
+		default:
+			reg_val = TRANSPARENT_COLOR_8BPP;
+			break;
+		}
+		break;
+	case 16:
+		reg_val = TRANSPARENT_COLOR_16BPP;
+		break;
+	case 32:
+		reg_val = TRANSPARENT_COLOR_24BPP;
+		break;
+	default:
+		reg_val = TRANSPARENT_COLOR_24BPP;
+		break;
+	}
+	cd->reg_access.xylonfb_set_reg_val(reg_val,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_TRANSP_ROFF,
+		ld);
+
+	if (!(cd->xylonfb_flags & LOGICVC_READABLE_REGS))
+		cd->reg_access.xylonfb_set_reg_val(0xFF,
+			ld->layer_reg_base_virt, LOGICVC_LAYER_ALPHA_ROFF,
+			ld);
+
+	reg_val = ld->layer_ctrl_flags;
+	cd->reg_access.xylonfb_set_reg_val(reg_val,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF,
+		ld);
+}
+
+static void xylonfb_logicvc_disp_ctrl(struct fb_info *fbi, bool enable)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 val;
+
+	driver_devel("%s\n", __func__);
+
+	if (enable) {
+		val = LOGICVC_EN_VDD_MSK;
+		writel(val, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		mdelay(cd->power_on_delay);
+		val |= LOGICVC_V_EN_MSK;
+		writel(val, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+		mdelay(cd->signal_on_delay);
+		val |= LOGICVC_EN_BLIGHT_MSK;
+		writel(val, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+	} else {
+		writel(0, ld->reg_base_virt + LOGICVC_SPWRCTRL_ROFF);
+	}
+}
+
+static void xylonfb_enable_logicvc_layer(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+
+	driver_devel("%s\n", __func__);
+
+	ld->layer_ctrl_flags |= LOGICVC_LAYER_ON;
+	ld->xylonfb_cd->reg_access.xylonfb_set_reg_val(
+		ld->layer_ctrl_flags,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF,
+		ld);
+}
+
+static void xylonfb_disable_logicvc_layer(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+
+	driver_devel("%s\n", __func__);
+
+	ld->layer_ctrl_flags &= (~LOGICVC_LAYER_ON);
+	ld->xylonfb_cd->reg_access.xylonfb_set_reg_val(
+		ld->layer_ctrl_flags,
+		ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF,
+		ld);
+}
+
+static void xylonfb_enable_logicvc_output(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+
+	driver_devel("%s\n", __func__);
+
+	writel(cd->vmode_data_current.fb_vmode.right_margin-1,
+		ld->reg_base_virt + LOGICVC_SHSY_FP_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.hsync_len-1,
+		ld->reg_base_virt + LOGICVC_SHSY_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.left_margin-1,
+		ld->reg_base_virt + LOGICVC_SHSY_BP_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.xres-1,
+		ld->reg_base_virt + LOGICVC_SHSY_RES_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.lower_margin-1,
+		ld->reg_base_virt + LOGICVC_SVSY_FP_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.vsync_len-1,
+		ld->reg_base_virt + LOGICVC_SVSY_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.upper_margin-1,
+		ld->reg_base_virt + LOGICVC_SVSY_BP_ROFF);
+	writel(cd->vmode_data_current.fb_vmode.yres-1,
+		ld->reg_base_virt + LOGICVC_SVSY_RES_ROFF);
+	cd->reg_access.xylonfb_set_reg_val(
+		cd->vmode_data_current.ctrl_reg,
+		ld->reg_base_virt,
+		LOGICVC_SCTRL_ROFF,
+		ld);
+	writel(SD_REG_INIT, ld->reg_base_virt + LOGICVC_SDTYPE_ROFF);
+
+	driver_devel("\n" \
+		"logiCVC HW parameters:\n" \
+		"    Horizontal Front Porch: %d pixclks\n" \
+		"    Horizontal Sync:        %d pixclks\n" \
+		"    Horizontal Back Porch:  %d pixclks\n" \
+		"    Vertical Front Porch:   %d pixclks\n" \
+		"    Vertical Sync:          %d pixclks\n" \
+		"    Vertical Back Porch:    %d pixclks\n" \
+		"    Pixel Clock:            %d ps\n" \
+		"    Horizontal Res:         %d\n" \
+		"    Vertical Res:           %d\n" \
+		"\n", \
+		cd->vmode_data_current.fb_vmode.right_margin,
+		cd->vmode_data_current.fb_vmode.hsync_len,
+		cd->vmode_data_current.fb_vmode.left_margin,
+		cd->vmode_data_current.fb_vmode.lower_margin,
+		cd->vmode_data_current.fb_vmode.vsync_len,
+		cd->vmode_data_current.fb_vmode.upper_margin,
+		cd->vmode_data_current.fb_vmode.pixclock,
+		cd->vmode_data_current.fb_vmode.xres,
+		cd->vmode_data_current.fb_vmode.yres);
+}
+
+static void xylonfb_disable_logicvc_output(struct fb_info *fbi)
+{
+	struct fb_info **afbi = dev_get_drvdata(fbi->device);
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	int i;
+
+	driver_devel("%s\n", __func__);
+
+	if (afbi) {
+		for (i = 0; i < cd->xylonfb_layers; i++)
+			xylonfb_disable_logicvc_layer(afbi[i]);
+	}
+}
+
+static void xylonfb_start(struct fb_info **afbi, int layers)
+{
+	struct xylonfb_layer_data *ld;
+	int i;
+
+	driver_devel("%s\n", __func__);
+
+	/* turn OFF all layers except already used ones */
+	for (i = 0; i < layers; i++) {
+		ld = afbi[i]->par;
+		if (ld->layer_ctrl_flags & LOGICVC_LAYER_ON)
+			continue;
+		/* turn off layer */
+		xylonfb_disable_logicvc_layer(afbi[i]);
+	}
+	/* print layer parameters */
+	for (i = 0; i < layers; i++) {
+		ld = afbi[i]->par;
+		driver_devel("logiCVC layer %d\n" \
+			"    Registers Base Address:     0x%lX\n" \
+			"    Layer Video Memory Address: 0x%lX\n" \
+			"    X resolution:               %d\n" \
+			"    Y resolution:               %d\n" \
+			"    X resolution (virtual):     %d\n" \
+			"    Y resolution (virtual):     %d\n" \
+			"    Line length (bytes):        %d\n" \
+			"    Bits per Pixel:             %d\n" \
+			"\n", \
+			i,
+			(unsigned long)ld->reg_base_phys,
+			(unsigned long)ld->fb_phys,
+			afbi[i]->var.xres,
+			afbi[i]->var.yres,
+			afbi[i]->var.xres_virtual,
+			afbi[i]->var.yres_virtual,
+			afbi[i]->fix.line_length,
+			afbi[i]->var.bits_per_pixel);
+	}
+}
+
+/******************************************************************************/
+
+static int xylonfb_event_notify(struct notifier_block *nb,
+	unsigned long event, void *data)
+{
+	struct fb_event *fbe = data;
+	struct fb_info *fbi = fbe->info;
+	int ret = 0;
+
+	driver_devel("%s\n", __func__);
+
+	switch (event) {
+	case XYLONFB_EVENT_FBI_UPDATE:
+		xylonfb_fbi_update(fbi);
+		break;
+	}
+
+	return ret;
+}
+
+/******************************************************************************/
+
+static void xylonfb_get_vmode_opts(
+	struct xylonfb_init_data *init_data,
+	struct xylonfb_common_data *cd)
+{
+	char cvt_opt[VMODE_OPTS_SZ] = "MR";
+	char ext_opt[VMODE_OPTS_SZ] = "im";
+	char *s, *opt, *ext, *c, *pco, *peo;
+
+	if (cd->xylonfb_flags & XYLONFB_FLAG_EDID_VMODE)
+		return;
+
+	s = init_data->vmode_data.fb_vmode_name;
+	opt = cd->vmode_data.fb_vmode_opts_cvt;
+	ext = cd->vmode_data.fb_vmode_opts_ext;
+	pco = cvt_opt;
+	peo = ext_opt;
+
+	while (*pco) {
+		c = strchr(s, (int)(*pco));
+		if (c)
+			*opt++ = *c;
+		pco++;
+	}
+	while (*peo) {
+		c = strchr(s, (int)(*peo));
+		if (c)
+			*ext++ = *c;
+		peo++;
+	}
+}
+
+int xylonfb_init_driver(struct xylonfb_init_data *init_data)
+{
+	struct device *dev;
+	struct fb_info **afbi;
+	struct fb_info *fbi;
+	struct xylonfb_common_data *cd;
+	struct xylonfb_layer_data *ld;
+	struct resource *reg_res, *irq_res;
+	void *reg_base_virt;
+	unsigned long reg_base_phys;
+	int reg_range, layers, active_layer;
+	int i, rc, memmap;
+	int regfb[LOGICVC_MAX_LAYERS];
+
+	driver_devel("%s\n", __func__);
+
+	dev = &init_data->pdev->dev;
+
+	reg_res = platform_get_resource(init_data->pdev, IORESOURCE_MEM, 0);
+	irq_res = platform_get_resource(init_data->pdev, IORESOURCE_IRQ, 0);
+	if ((!reg_res) || (!irq_res)) {
+		pr_err("Error xylonfb resources\n");
+		return -ENODEV;
+	}
+
+	layers = init_data->layers;
+	if (layers == 0) {
+		pr_err("Error xylonfb zero layers\n");
+		return -ENODEV;
+	}
+	active_layer = init_data->active_layer;
+	if (active_layer >= layers) {
+		pr_err("Error xylonfb default layer: set to 0\n");
+		active_layer = 0;
+	}
+
+	afbi = kzalloc(sizeof(struct fb_info *) * layers, GFP_KERNEL);
+	cd = kzalloc(sizeof(struct xylonfb_common_data), GFP_KERNEL);
+	if (!afbi || !cd) {
+		pr_err("Error xylonfb allocating internal data\n");
+		rc = -ENOMEM;
+		goto err_mem;
+	}
+
+	BLOCKING_INIT_NOTIFIER_HEAD(&cd->xylonfb_notifier_list);
+	cd->xylonfb_nb.notifier_call = xylonfb_event_notify;
+	blocking_notifier_chain_register(
+		&cd->xylonfb_notifier_list, &cd->xylonfb_nb);
+
+	cd->xylonfb_display_interface_type =
+		init_data->display_interface_type;
+	cd->xylonfb_layers = layers;
+	cd->xylonfb_flags |= XYLONFB_FLAG_VMODE_INIT;
+	cd->xylonfb_console_layer = active_layer;
+	if (init_data->flags & XYLONFB_FLAG_ADV7511_SKIP) {
+		cd->xylonfb_flags |= XYLONFB_FLAG_ADV7511_SKIP;
+	} else {
+		if (init_data->flags & XYLONFB_FLAG_EDID_VMODE)
+			cd->xylonfb_flags |= XYLONFB_FLAG_EDID_VMODE;
+		if (init_data->flags & XYLONFB_FLAG_EDID_PRINT)
+			cd->xylonfb_flags |= XYLONFB_FLAG_EDID_PRINT;
+	}
+	if (init_data->flags & LOGICVC_READABLE_REGS) {
+		cd->xylonfb_flags |= LOGICVC_READABLE_REGS;
+		cd->reg_access.xylonfb_get_reg_val = xylonfb_get_reg;
+		cd->reg_access.xylonfb_set_reg_val = xylonfb_set_reg;
+	} else {
+		cd->reg_list =
+			kzalloc(sizeof(struct xylonfb_registers), GFP_KERNEL);
+		cd->reg_access.xylonfb_get_reg_val = xylonfb_get_reg_mem;
+		cd->reg_access.xylonfb_set_reg_val = xylonfb_set_reg_mem;
+	}
+
+	sprintf(init_data->vmode_data.fb_vmode_name, "%s-%d@%d",
+		init_data->vmode_data.fb_vmode_name,
+		init_data->lfdata[active_layer].bpp,
+		init_data->vmode_data.fb_vmode.refresh);
+	if (init_data->vmode_params_set) {
+		cd->vmode_data = init_data->vmode_data;
+	} else {
+		xylonfb_mode_option = init_data->vmode_data.fb_vmode_name;
+		cd->vmode_data.ctrl_reg = init_data->vmode_data.ctrl_reg;
+		cd->vmode_data.fb_vmode.refresh =
+			init_data->vmode_data.fb_vmode.refresh;
+	}
+	xylonfb_get_vmode_opts(init_data, cd);
+
+	if (init_data->pixclk_src_id) {
+		if (xylonfb_hw_pixclk_supported(init_data->pixclk_src_id)) {
+			cd->xylonfb_pixclk_src_id = init_data->pixclk_src_id;
+			cd->xylonfb_flags |= XYLONFB_FLAG_PIXCLK_VALID;
+		} else {
+			pr_info("xylonfb pixel clock not supported\n");
+		}
+	} else {
+		pr_info("xylonfb external pixel clock\n");
+	}
+
+	ld = NULL;
+
+	reg_base_phys = reg_res->start;
+	reg_range = resource_size(reg_res);
+	reg_base_virt = ioremap_nocache(reg_base_phys, reg_range);
+
+	/* load layer parameters for all layers */
+	for (i = 0; i < layers; i++)
+		regfb[i] = -1;
+	memmap = 1;
+
+	/* make /dev/fb0 to be default active layer
+	   regardless how logiCVC layers are organized */
+	for (i = active_layer; i < layers; i++) {
+		if (regfb[i] != -1)
+			continue;
+
+		fbi = framebuffer_alloc(sizeof(struct xylonfb_layer_data), dev);
+		if (!fbi) {
+			pr_err("Error xylonfb allocate info\n");
+			rc = -ENOMEM;
+			goto err_fb;
+		}
+		afbi[i] = fbi;
+		ld = fbi->par;
+		ld->xylonfb_cd = cd;
+
+#if defined(CONFIG_FB_XYLON_MISC)
+		if (!cd->xylonfb_misc) {
+			cd->xylonfb_misc = kzalloc(
+				sizeof(struct xylonfb_misc_data), GFP_KERNEL);
+			if (cd->xylonfb_misc) {
+				xylonfb_misc_init(fbi);
+			} else {
+				pr_err("Error xylonfb allocating misc internal data\n");
+				goto err_fb;
+			}
+		}
+#endif
+
+		xylonfb_set_yvirt(init_data, layers, i);
+
+		ld->layer_fix = init_data->lfdata[i];
+		if (!(cd->xylonfb_flags & LOGICVC_READABLE_REGS)) {
+			ld->layer_reg_list =
+				kzalloc(sizeof(struct xylonfb_layer_registers), GFP_KERNEL);
+		}
+
+		rc = xylonfb_map(i, layers, dev, ld, init_data->vmem_base_addr,
+			reg_base_phys, reg_base_virt, memmap);
+		if (rc)
+			goto err_fb;
+		memmap = 0;
+
+		ld->layer_ctrl_flags = init_data->layer_ctrl_flags[i];
+		xylonfb_init_layer_regs(ld);
+
+		rc = xylonfb_register_fb(fbi, ld, reg_base_phys, i, &regfb[i]);
+		if (rc)
+			goto err_fb;
+
+		fbi->monspecs = afbi[cd->xylonfb_console_layer]->monspecs;
+
+		mutex_init(&ld->layer_mutex);
+
+		/* register following layers in HW configuration order */
+		if (active_layer > 0) {
+			i = -1; /* after for loop increment i will be zero */
+			active_layer = -1;
+		}
+
+		driver_devel( \
+			"    Layer ID %d\n" \
+			"    Layer offset %u\n" \
+			"    Layer buffer offset %hd\n" \
+			"    Layer buffers %d\n" \
+			"    Layer width %d pixels\n" \
+			"    Layer height %d lines\n" \
+			"    Layer bits per pixel %d\n" \
+			"    Layer bits per pixel (virtual) %d\n" \
+			"    Layer FB size %ld bytes\n", \
+			(ld->layer_fix.layer_fix_info & 0x0F),
+			ld->layer_fix.offset,
+			ld->layer_fix.buffer_offset,
+			(ld->layer_fix.layer_fix_info >> 4),
+			ld->layer_fix.width,
+			ld->layer_fix.height,
+			ld->layer_fix.bpp,
+			ld->layer_fix.bpp_virt,
+			ld->fb_size);
+	}
+
+	if (ld) {
+		if (!(cd->xylonfb_flags & LOGICVC_READABLE_REGS))
+			cd->reg_access.xylonfb_set_reg_val(0xFFFF,
+				ld->reg_base_virt, LOGICVC_INT_MASK_ROFF,
+				ld);
+	} else {
+		pr_warn("Warning xylonfb initialization not completed\n");
+	}
+
+	cd->xylonfb_bg_layer_bpp = init_data->bg_layer_bpp;
+	cd->xylonfb_bg_layer_alpha_mode = init_data->bg_layer_alpha_mode;
+	driver_devel("BG layer %dbpp\n", init_data->bg_layer_bpp);
+
+	cd->xylonfb_irq = irq_res->start;
+	rc = request_irq(cd->xylonfb_irq, xylonfb_isr,
+		IRQF_TRIGGER_HIGH, DEVICE_NAME, dev);
+	if (rc) {
+		cd->xylonfb_irq = 0;
+		goto err_fb;
+	}
+
+#if defined(__LITTLE_ENDIAN)
+	cd->xylonfb_flags |= XYLONFB_FLAG_MEMORY_LE;
+#endif
+	mutex_init(&cd->irq_mutex);
+	init_waitqueue_head(&cd->vsync.wait);
+	cd->xylonfb_use_ref = 0;
+
+	dev_set_drvdata(dev, (void *)afbi);
+
+	cd->xylonfb_flags &= ~(XYLONFB_FLAG_VMODE_INIT |
+		XYLONFB_FLAG_DEFAULT_VMODE_SET | XYLONFB_FLAG_VMODE_SET);
+	xylonfb_mode_option = NULL;
+
+	/* start HW */
+	xylonfb_start(afbi, layers);
+
+	return 0;
+
+err_fb:
+	if (cd->xylonfb_irq != 0)
+		free_irq(cd->xylonfb_irq, dev);
+	for (i = layers-1; i >= 0; i--) {
+		fbi = afbi[i];
+		if (!fbi)
+			continue;
+		ld = fbi->par;
+		if (regfb[i] == 0)
+			unregister_framebuffer(fbi);
+		else
+			regfb[i] = 0;
+		if (fbi->cmap.red)
+			fb_dealloc_cmap(&fbi->cmap);
+		if (ld) {
+			if (cd->xylonfb_flags & XYLONFB_FLAG_DMA_BUFFER) {
+				/* NOT USED FOR NOW! */
+				dma_free_coherent(dev,
+					PAGE_ALIGN(fbi->fix.smem_len),
+					ld->fb_virt, ld->fb_phys);
+			} else {
+				if (ld->fb_virt)
+					iounmap(ld->fb_virt);
+			}
+			kfree(ld->layer_reg_list);
+			kfree(fbi->pseudo_palette);
+			framebuffer_release(fbi);
+		}
+	}
+	if (reg_base_virt)
+		iounmap(reg_base_virt);
+
+err_mem:
+	if (cd) {
+		kfree(cd->reg_list);
+#if defined(CONFIG_FB_XYLON_MISC)
+		kfree(cd->xylonfb_misc);
+#endif
+		kfree(cd);
+	}
+	kfree(afbi);
+
+	dev_set_drvdata(dev, NULL);
+
+	return rc;
+}
+
+int xylonfb_deinit_driver(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fb_info **afbi = dev_get_drvdata(dev);
+	struct fb_info *fbi = afbi[0];
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	void *reg_base_virt = NULL;
+	int i;
+	bool logicvc_unmap = false;
+
+	driver_devel("%s\n", __func__);
+
+	if (cd->xylonfb_use_ref) {
+		pr_err("Error xylonfb in use\n");
+		return -EINVAL;
+	}
+
+	xylonfb_disable_logicvc_output(fbi);
+
+#if defined(CONFIG_FB_XYLON_MISC)
+	xylonfb_misc_deinit(fbi);
+	kfree(cd->xylonfb_misc);
+#endif
+
+	free_irq(cd->xylonfb_irq, dev);
+	for (i = cd->xylonfb_layers-1; i >= 0; i--) {
+		fbi = afbi[i];
+		ld = fbi->par;
+
+		if (!logicvc_unmap) {
+			reg_base_virt = ld->reg_base_virt;
+			logicvc_unmap = true;
+		}
+		unregister_framebuffer(fbi);
+		fb_dealloc_cmap(&fbi->cmap);
+		if (cd->xylonfb_flags & XYLONFB_FLAG_DMA_BUFFER) {
+			dma_free_coherent(dev, PAGE_ALIGN(fbi->fix.smem_len),
+				ld->fb_virt, ld->fb_phys);
+		} else {
+			iounmap(ld->fb_virt);
+		}
+		if (!(cd->xylonfb_flags & LOGICVC_READABLE_REGS))
+			kfree(ld->layer_reg_list);
+		kfree(fbi->pseudo_palette);
+		framebuffer_release(fbi);
+	}
+
+	if (reg_base_virt)
+		iounmap(reg_base_virt);
+
+	if (!(cd->xylonfb_flags & LOGICVC_READABLE_REGS))
+		kfree(cd->reg_list);
+	kfree(cd);
+	kfree(afbi);
+
+	dev_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+#ifndef MODULE
+int xylonfb_get_params(char *options)
+{
+	char *this_opt;
+
+	driver_devel("%s\n", __func__);
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt)
+			continue;
+		xylonfb_mode_option = this_opt;
+	}
+	return 0;
+}
+#endif
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb.h	2014-07-20 22:06:38.542269661 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver internal data structures
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __XYLON_FB_DATA_H__
+#define __XYLON_FB_DATA_H__
+
+
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#include <linux/xylonfb.h>
+#include "logicvc.h"
+
+
+#define DRIVER_NAME "xylonfb"
+#define DEVICE_NAME "logicvc"
+#define DRIVER_DESCRIPTION "Xylon logiCVC frame buffer driver"
+#define DRIVER_VERSION "2.1"
+
+/* XylonFB driver flags */
+#define XYLONFB_FLAG_RESERVED_0x01     LOGICVC_READABLE_REGS
+#define XYLONFB_FLAG_DMA_BUFFER        0x02
+#define XYLONFB_FLAG_MEMORY_LE         0x04
+#define XYLONFB_FLAG_PIXCLK_VALID      0x08
+#define XYLONFB_FLAG_VMODE_INIT        0x10
+#define XYLONFB_FLAG_EDID_VMODE        0x20
+#define XYLONFB_FLAG_EDID_PRINT        0x40
+#define XYLONFB_FLAG_DEFAULT_VMODE_SET 0x80
+#define XYLONFB_FLAG_VMODE_SET         0x100
+/*
+	Following flags must be updated in xylonfb miscellaneous
+	header files for every functionality specifically
+*/
+#define XYLONFB_FLAG_MISC_ADV7511 0x1000
+#define XYLONFB_FLAG_ADV7511_SKIP 0x2000
+#define XYLONFB_FLAG_EDID_RDY     0x4000
+#define XYLONFB_EDID_SIZE         256
+#define XYLONFB_EDID_WAIT_TOUT    60
+
+
+#ifdef DEBUG
+#define driver_devel(format, ...) pr_info(format, ## __VA_ARGS__);
+#else
+#define driver_devel(format, ...)
+#endif
+
+struct xylonfb_layer_data;
+
+#define VMODE_NAME_SZ (20+1)
+#define VMODE_OPTS_SZ (2+1)
+struct xylonfb_vmode_data {
+	u32 ctrl_reg;
+	struct fb_videomode fb_vmode;
+	char fb_vmode_name[VMODE_NAME_SZ];
+	char fb_vmode_opts_cvt[VMODE_OPTS_SZ];
+	char fb_vmode_opts_ext[VMODE_OPTS_SZ];
+};
+
+struct xylonfb_registers {
+	u32 ctrl_reg;
+	u32 dtype_reg;
+	u32 bg_reg;
+	u32 unused_reg[3];
+	u32 int_mask_reg;
+};
+
+struct xylonfb_layer_registers {
+	u32 hoff_reg;
+	u32 voff_reg;
+	u32 hpos_reg;
+	u32 vpos_reg;
+	u32 width_reg;
+	u32 height_reg;
+	u32 alpha_reg;
+	u32 ctrl_reg;
+	u32 trans_reg;
+};
+
+struct xylonfb_register_access {
+	u32 (*xylonfb_get_reg_val)
+		(void *reg_base_virt, unsigned long offset,
+		 struct xylonfb_layer_data *layer_data);
+	void (*xylonfb_set_reg_val)
+		(u32 value, void *reg_base_virt, unsigned long offset,
+		 struct xylonfb_layer_data *layer_data);
+};
+
+struct xylonfb_layer_fix_data {
+	unsigned int offset;
+	unsigned short buffer_offset;
+	unsigned short width;
+	unsigned short height;
+	unsigned char bpp;
+	unsigned char bpp_virt;
+	unsigned char layer_type;
+	unsigned char alpha_mode;
+	/* higher 4 bits: number of layer buffers, lower 4 bits: layer ID */
+	unsigned char layer_fix_info;
+};
+
+struct xylonfb_sync {
+	wait_queue_head_t wait;
+	unsigned int cnt;
+};
+
+struct xylonfb_common_data {
+	struct mutex irq_mutex;
+	struct xylonfb_register_access reg_access;
+	struct xylonfb_registers *reg_list;
+	struct xylonfb_sync vsync;
+	struct xylonfb_vmode_data vmode_data;
+	struct xylonfb_vmode_data vmode_data_current;
+	struct blocking_notifier_head xylonfb_notifier_list;
+	struct notifier_block xylonfb_nb;
+	/* Delay after applying display power and
+		before applying display signals */
+	unsigned int power_on_delay;
+	/* Delay after applying display signal and
+		before applying display backlight power supply */
+	unsigned int signal_on_delay;
+	unsigned long xylonfb_flags;
+	unsigned char xylonfb_pixclk_src_id;
+	unsigned char xylonfb_layers;
+	unsigned char xylonfb_irq;
+	unsigned char xylonfb_use_ref;
+	unsigned char xylonfb_console_layer;
+	unsigned char xylonfb_bg_layer_bpp;
+	unsigned char xylonfb_bg_layer_alpha_mode;
+	/* higher 4 bits: display interface
+	   lower 4 bits: display color space */
+	unsigned char xylonfb_display_interface_type;
+#if defined(CONFIG_FB_XYLON_MISC)
+	struct xylonfb_misc_data *xylonfb_misc;
+#endif
+};
+
+struct xylonfb_layer_data {
+	struct xylonfb_common_data *xylonfb_cd;
+	struct mutex layer_mutex;
+	dma_addr_t reg_base_phys;
+	dma_addr_t fb_phys;
+	void *reg_base_virt;
+	void *fb_virt;
+	unsigned long fb_size;
+	void *layer_reg_base_virt;
+	void *layer_clut_base_virt;
+	struct xylonfb_layer_fix_data layer_fix;
+	struct xylonfb_layer_registers *layer_reg_list;
+	unsigned char layer_ctrl_flags;
+	unsigned char layer_use_ref;
+};
+
+struct xylonfb_init_data {
+	struct platform_device *pdev;
+	struct xylonfb_vmode_data vmode_data;
+	struct xylonfb_layer_fix_data lfdata[LOGICVC_MAX_LAYERS];
+	unsigned long vmem_base_addr;
+	unsigned long vmem_high_addr;
+	unsigned char pixclk_src_id;
+	unsigned char layer_ctrl_flags[LOGICVC_MAX_LAYERS];
+	unsigned char layers;
+	unsigned char active_layer;
+	unsigned char bg_layer_bpp;
+	unsigned char bg_layer_alpha_mode;
+	unsigned char display_interface_type;
+	unsigned short flags;
+	bool vmode_params_set;
+};
+
+
+/* xylonfb core pixel clock interface functions */
+extern bool xylonfb_hw_pixclk_supported(int);
+extern int xylonfb_hw_pixclk_set(int, unsigned long);
+
+/* xylonfb core interface functions */
+extern int xylonfb_get_params(char *options);
+extern int xylonfb_init_driver(struct xylonfb_init_data *init_data);
+extern int xylonfb_deinit_driver(struct platform_device *pdev);
+extern int xylonfb_ioctl(struct fb_info *fbi,
+	unsigned int cmd, unsigned long arg);
+
+#endif /* __XYLON_FB_DATA_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb-ioctl.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb-ioctl.c	2014-07-20 22:06:38.553269479 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver IOCTL functionality
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/uaccess.h>
+#include "logicvc.h"
+#include "xylonfb.h"
+#if defined(CONFIG_FB_XYLON_MISC)
+#include "../misc/xylonfb-misc.h"
+#endif
+
+
+static int xylonfb_get_vblank(struct fb_vblank *vblank, struct fb_info *fbi)
+{
+	vblank->flags |= FB_VBLANK_HAVE_VSYNC;
+
+	return 0;
+}
+
+static int xylonfb_wait_for_vsync(u32 crt, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 imr;
+	int ret, cnt;
+
+	mutex_lock(&cd->irq_mutex);
+
+	cnt = cd->vsync.cnt;
+
+	/* prepare LOGICVC V-sync interrupt */
+	imr = cd->reg_access.xylonfb_get_reg_val(
+		ld->reg_base_virt, LOGICVC_INT_MASK_ROFF, ld);
+	imr &= (~LOGICVC_V_SYNC_INT);
+	/* clear LOGICVC V-sync interrupt */
+	writel(LOGICVC_V_SYNC_INT,
+		ld->reg_base_virt + LOGICVC_INT_STAT_ROFF);
+	/* enable LOGICVC V-sync interrupt */
+	cd->reg_access.xylonfb_set_reg_val(imr,
+		ld->reg_base_virt, LOGICVC_INT_MASK_ROFF, ld);
+
+	ret = wait_event_interruptible_timeout(cd->vsync.wait,
+		(cnt != cd->vsync.cnt), HZ/10);
+
+	/* disable LOGICVC V-sync interrupt */
+	imr |= LOGICVC_V_SYNC_INT;
+	cd->reg_access.xylonfb_set_reg_val(imr,
+		ld->reg_base_virt, LOGICVC_INT_MASK_ROFF, ld);
+
+	mutex_unlock(&cd->irq_mutex);
+
+	if (ret < 0)
+		return ret;
+	else if (ret == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static unsigned int alpha_normalized(unsigned int alpha,
+	unsigned int used_bits, bool get)
+{
+	if (get)
+		return (((255 << 16) / ((1 << used_bits)-1)) * alpha) >> 16;
+	else
+		return alpha / (255 / ((1 << used_bits)-1));
+}
+
+static int xylonfb_layer_alpha(struct xylonfb_layer_data *ld,
+	unsigned int *alpha, bool get)
+{
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	unsigned int used_bits;
+
+	if (ld->layer_fix.alpha_mode != LOGICVC_LAYER_ALPHA)
+		return -EPERM;
+
+	switch (ld->layer_fix.layer_type) {
+	case LOGICVC_YCBCR_LAYER:
+		used_bits = 8;
+		break;
+	case LOGICVC_RGB_LAYER:
+		switch (ld->layer_fix.bpp_virt) {
+		case 8:
+			used_bits = 3;
+			break;
+		case 16:
+			used_bits = 6;
+			break;
+		case 32:
+			used_bits = 8;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (get) {
+		*alpha = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_ALPHA_ROFF, ld);
+		*alpha &= (0xFF >> (8-used_bits));
+	}
+
+	/* get/set normalized alpha value */
+	*alpha = alpha_normalized(*alpha, used_bits, get);
+
+	if (!get)
+		cd->reg_access.xylonfb_set_reg_val(*alpha,
+			ld->layer_reg_base_virt, LOGICVC_LAYER_ALPHA_ROFF, ld);
+
+	return 0;
+}
+
+static int xylonfb_layer_color_rgb(struct xylonfb_layer_data *ld,
+	struct xylonfb_layer_color *layer_color, unsigned int reg_offset,
+	bool get)
+{
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	void *base;
+	u32 raw_rgb, r, g, b;
+	int bpp, alpha_mode;
+
+	if (reg_offset == LOGICVC_LAYER_TRANSP_ROFF) {
+		base = ld->layer_reg_base_virt;
+		bpp = ld->layer_fix.bpp_virt;
+		alpha_mode = ld->layer_fix.alpha_mode;
+	} else /* if (reg_offset == LOGICVC_BACKCOL_ROFF) */ {
+		base = ld->reg_base_virt;
+		bpp = ld->xylonfb_cd->xylonfb_bg_layer_bpp;
+		alpha_mode = ld->xylonfb_cd->xylonfb_bg_layer_alpha_mode;
+	}
+
+	if (get) {
+		raw_rgb = cd->reg_access.xylonfb_get_reg_val(
+			base, reg_offset, ld);
+check_bpp_get:
+		/* convert HW color format to RGB-888 */
+		switch (bpp) {
+		case 8:
+			switch (alpha_mode) {
+			case LOGICVC_CLUT_16BPP_ALPHA:
+				/* RGB-565 */
+				bpp = 16;
+				goto check_bpp_get;
+				break;
+			case LOGICVC_CLUT_32BPP_ALPHA:
+				/* RGB-888 */
+				bpp = 32;
+				goto check_bpp_get;
+				break;
+			default:
+				/* RGB-332 */
+				r = raw_rgb >> 5;
+				r = (((r << 3) | r) << 2) | (r >> 1);
+				g = (raw_rgb >> 2) & 0x07;
+				g = (((g << 3) | g) << 2) | (g >> 1);
+				b = raw_rgb & 0x03;
+				b = (b << 6) | (b << 4) | (b << 2) | b;
+				break;
+			}
+			break;
+		case 16:
+			/* RGB-565 */
+			r = raw_rgb >> 11;
+			r = (r << 3) | (r >> 2);
+			g = (raw_rgb >> 5) & 0x3F;
+			g = (g << 2) | (g >> 4);
+			b = raw_rgb & 0x1F;
+			b = (b << 3) | (b >> 2);
+			break;
+		case 32:
+			/* RGB-888 */
+			r = raw_rgb >> 16;
+			g = (raw_rgb >> 8) & 0xFF;
+			b = raw_rgb & 0xFF;
+			break;
+		default:
+			raw_rgb = r = g = b = 0;
+		}
+		layer_color->raw_rgb = raw_rgb;
+		layer_color->r = (u8)r;
+		layer_color->g = (u8)g;
+		layer_color->b = (u8)b;
+	} else {
+		if (layer_color->use_raw) {
+			raw_rgb = layer_color->raw_rgb;
+		} else {
+			r = layer_color->r;
+			g = layer_color->g;
+			b = layer_color->b;
+check_bpp_set:
+			/* convert RGB-888 to HW color format */
+			switch (bpp) {
+			case 8:
+				switch (alpha_mode) {
+				case LOGICVC_CLUT_16BPP_ALPHA:
+					/* RGB-565 */
+					bpp = 16;
+					goto check_bpp_set;
+					break;
+				case LOGICVC_CLUT_32BPP_ALPHA:
+					/* RGB-888 */
+					bpp = 32;
+					goto check_bpp_set;
+					break;
+				default:
+					raw_rgb =
+						(r & 0xE0) |
+						((g & 0xE0) >> 3) |
+						((b & 0xC0) >> 6);
+					break;
+				}
+				break;
+			case 16:
+				raw_rgb =
+					((r & 0xF8) << 8) |
+					((g & 0xFC) << 3) |
+					((b & 0xF8) >> 3);
+				break;
+			case 32:
+				raw_rgb =
+					(r << 16) |
+					(g << 8) |
+					b;
+				break;
+			default:
+				raw_rgb = 0;
+			}
+		}
+		cd->reg_access.xylonfb_set_reg_val(raw_rgb,
+			base, reg_offset, ld);
+	}
+
+	return 0;
+}
+
+static int xylonfb_layer_pos_sz(struct fb_info *fbi,
+	struct xylonfb_layer_pos_size *layer_pos_sz, bool get)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	u32 x, y, width, height, xres, yres;
+
+	xres = fbi->var.xres;
+	yres = fbi->var.yres;
+
+	if (get) {
+		x = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_HOR_POS_ROFF, ld);
+		layer_pos_sz->x = xres - (x + 1);
+		y = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_VER_POS_ROFF, ld);
+		layer_pos_sz->y = yres - (y + 1);
+		layer_pos_sz->width = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_WIDTH_ROFF, ld);
+		layer_pos_sz->width += 1;
+		layer_pos_sz->height = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_HEIGHT_ROFF, ld);
+		layer_pos_sz->height += 1;
+	} else {
+		x = layer_pos_sz->x;
+		y = layer_pos_sz->y;
+		width = layer_pos_sz->width;
+		height = layer_pos_sz->height;
+
+		if ((x > xres) || (y > yres))
+			return -EINVAL;
+
+		if ((width == 0) || (height == 0))
+			return -EINVAL;
+
+		if ((x + width) > xres) {
+			width = xres - x;
+			layer_pos_sz->width = width;
+		}
+		if ((y + height) > yres) {
+			height = yres - y;
+			layer_pos_sz->height = height;
+		}
+		/* YCbCr 4:2:2 layer type can only have even layer width */
+		if ((width > 2)
+				&&
+			(ld->layer_fix.layer_type == LOGICVC_YCBCR_LAYER)
+				&&
+			(ld->layer_fix.bpp_virt == 16)) {
+			width &= ~1;
+		}
+
+		cd->reg_access.xylonfb_set_reg_val((width - 1),
+			ld->layer_reg_base_virt, LOGICVC_LAYER_WIDTH_ROFF, ld);
+		cd->reg_access.xylonfb_set_reg_val((height - 1),
+			ld->layer_reg_base_virt, LOGICVC_LAYER_HEIGHT_ROFF, ld);
+		cd->reg_access.xylonfb_set_reg_val((xres - (x + 1)),
+			ld->layer_reg_base_virt, LOGICVC_LAYER_HOR_POS_ROFF, ld);
+		cd->reg_access.xylonfb_set_reg_val((yres - (y + 1)),
+			ld->layer_reg_base_virt, LOGICVC_LAYER_VER_POS_ROFF, ld);
+	}
+
+	return 0;
+}
+
+static int xylonfb_layer_reg_access(
+	struct xylonfb_layer_data *ld,
+	struct xylonfb_common_data *cd,
+	struct xylonfb_hw_access *hw_access,
+	bool read)
+{
+	u32 rel_offset;
+
+	if ((hw_access->offset < LOGICVC_LAYER_BASE_OFFSET) ||
+		(hw_access->offset > LOGICVC_LAYER_BASE_END))
+		return -EPERM;
+
+	rel_offset = hw_access->offset -
+		((ld->layer_fix.layer_fix_info & 0x0F) * 0x80) -
+		LOGICVC_LAYER_BASE_OFFSET;
+
+	if (read) {
+		hw_access->value = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, rel_offset, ld);
+	} else {
+		cd->reg_access.xylonfb_set_reg_val(hw_access->value,
+			ld->layer_reg_base_virt, rel_offset, ld);
+	}
+
+	return 0;
+}
+
+int xylonfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	union {
+		struct fb_vblank vblank;
+		struct xylonfb_layer_color layer_color;
+		struct xylonfb_layer_pos_size layer_pos_sz;
+		struct xylonfb_hw_access hw_access;
+	} ioctl;
+	void __user *argp = (void __user *)arg;
+	u32 var32;
+	unsigned long val, layer_buffs, layer_id;
+	int ret = 0;
+
+	switch (cmd) {
+	case FBIOGET_VBLANK:
+		driver_devel("FBIOGET_VBLANK\n");
+		if (copy_from_user(&ioctl.vblank, argp, sizeof(ioctl.vblank)))
+			return -EFAULT;
+		ret = xylonfb_get_vblank(&ioctl.vblank, fbi);
+		if (!ret && copy_to_user(argp, &ioctl.vblank, sizeof(ioctl.vblank)))
+			ret = -EFAULT;
+		break;
+
+	case FBIO_WAITFORVSYNC:
+		driver_devel("FBIO_WAITFORVSYNC\n");
+		if (get_user(var32, (u32 __user *)arg))
+			return -EFAULT;
+		ret = xylonfb_wait_for_vsync(var32, fbi);
+		break;
+
+	case XYLONFB_GET_LAYER_IDX:
+		driver_devel("XYLONFB_GET_LAYER_IDX\n");
+		val = ld->layer_fix.layer_fix_info & 0x0F;
+		put_user(val, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_GET_LAYER_ALPHA:
+		driver_devel("XYLONFB_GET_LAYER_ALPHA\n");
+		ret = xylonfb_layer_alpha(ld, (unsigned int *)&val, true);
+		if (!ret)
+			put_user(val, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_SET_LAYER_ALPHA:
+		driver_devel("XYLONFB_SET_LAYER_ALPHA\n");
+		if (get_user(val, (unsigned long __user *)arg))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		ret = xylonfb_layer_alpha(ld, (unsigned int *)&val, false);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_LAYER_COLOR_TRANSP:
+		driver_devel("XYLONFB_LAYER_COLOR_TRANSP\n");
+		if (get_user(val, (unsigned long __user *)arg))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		var32 = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF, ld);
+		if (val)
+			var32 |= (1 << 1); /* transparency disabled */
+		else
+			var32 &= ~(1 << 1); /* transparency enabled */
+		cd->reg_access.xylonfb_set_reg_val(var32,
+			ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF, ld);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_GET_LAYER_COLOR_TRANSP:
+		driver_devel("XYLONFB_GET_LAYER_COLOR_TRANSP\n");
+		if (copy_from_user(&ioctl.layer_color, argp,
+			sizeof(ioctl.layer_color)))
+			return -EFAULT;
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+			LOGICVC_LAYER_TRANSP_ROFF, true);
+		if (!ret)
+			if (copy_to_user(argp, &ioctl.layer_color,
+				sizeof(ioctl.layer_color)))
+				ret = -EFAULT;
+		break;
+
+	case XYLONFB_SET_LAYER_COLOR_TRANSP:
+		driver_devel("XYLONFB_SET_LAYER_COLOR_TRANSP\n");
+		if (copy_from_user(&ioctl.layer_color, argp,
+			sizeof(ioctl.layer_color)))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+			LOGICVC_LAYER_TRANSP_ROFF, false);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_GET_LAYER_SIZE_POS:
+		driver_devel("XYLONFB_GET_LAYER_SIZE_POS\n");
+		if (copy_from_user(&ioctl.layer_pos_sz, argp,
+			sizeof(ioctl.layer_pos_sz)))
+			return -EFAULT;
+		ret = xylonfb_layer_pos_sz(fbi, &ioctl.layer_pos_sz, true);
+		if (!ret)
+			if (copy_to_user(argp, &ioctl.layer_pos_sz,
+				sizeof(ioctl.layer_pos_sz)))
+				ret = -EFAULT;
+		break;
+
+	case XYLONFB_SET_LAYER_SIZE_POS:
+		driver_devel("XYLONFB_SET_LAYER_SIZE_POS\n");
+		if (copy_from_user(&ioctl.layer_pos_sz, argp,
+			sizeof(ioctl.layer_pos_sz)))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		ret = xylonfb_layer_pos_sz(fbi, &ioctl.layer_pos_sz, false);
+		if (!ret)
+			if (copy_to_user(argp, &ioctl.layer_pos_sz,
+				sizeof(ioctl.layer_pos_sz)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_GET_LAYER_BUFFER:
+		driver_devel("XYLONFB_GET_LAYER_BUFFER\n");
+		layer_id = ld->layer_fix.layer_fix_info & 0x0F;
+		var32 = readl(ld->reg_base_virt + LOGICVC_DOUBLE_VBUFF_ROFF);
+		var32 >>= ((layer_id << 1)); /* get buffer */
+		val = var32 & 0x03;
+		put_user(val, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_SET_LAYER_BUFFER:
+		driver_devel("XYLONFB_SET_LAYER_BUFFER\n");
+		if (get_user(val, (unsigned long __user *)arg))
+			return -EFAULT;
+		layer_buffs = ld->layer_fix.layer_fix_info >> 4;
+		if (val >= layer_buffs)
+			return -EINVAL;
+		layer_id = ld->layer_fix.layer_fix_info & 0x0F;
+		mutex_lock(&ld->layer_mutex);
+		var32 = readl(ld->reg_base_virt + LOGICVC_DOUBLE_VBUFF_ROFF);
+		var32 |= (1 << (10 + layer_id)); /* set layer */
+		var32 &= ~(0x03 << (layer_id << 1)); /* clear previous buffer */
+		var32 |= (val << (layer_id << 1)); /* set buffer */
+		writel(var32, ld->reg_base_virt + LOGICVC_DOUBLE_VBUFF_ROFF);
+		ret = xylonfb_wait_for_vsync(var32, fbi);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_GET_LAYER_BUFFER_OFFSET:
+		driver_devel("XYLONFB_GET_LAYER_BUFFER_OFFSET\n");
+		layer_id = ld->layer_fix.layer_fix_info & 0x0F;
+		var32 = readl(ld->reg_base_virt + LOGICVC_DOUBLE_VBUFF_ROFF);
+		var32 >>= ((layer_id << 1)); /* get buffer */
+		var32 &= 0x03;
+		val = ld->layer_fix.buffer_offset;
+		val *= var32;
+		put_user(val, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_GET_LAYER_BUFFERS_NUM:
+		driver_devel("XYLONFB_GET_LAYER_BUFFERS_NUM\n");
+		layer_buffs = ld->layer_fix.layer_fix_info >> 4;
+		put_user(layer_buffs, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_GET_BACKGROUND_COLOR:
+		driver_devel("XYLONFB_GET_BACKGROUND_COLOR\n");
+		if (ld->xylonfb_cd->xylonfb_bg_layer_bpp == 0)
+			return -EPERM;
+		if (copy_from_user(&ioctl.layer_color, argp,
+			sizeof(ioctl.layer_color)))
+			return -EFAULT;
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+			LOGICVC_BACKCOL_ROFF, true);
+		if (!ret)
+			if (copy_to_user(argp, &ioctl.layer_color,
+				sizeof(ioctl.layer_color)))
+				ret = -EFAULT;
+		break;
+
+	case XYLONFB_SET_BACKGROUND_COLOR:
+		driver_devel("XYLONFB_SET_BACKGROUND_COLOR\n");
+		if (ld->xylonfb_cd->xylonfb_bg_layer_bpp == 0)
+			return -EPERM;
+		if (copy_from_user(&ioctl.layer_color, argp,
+			sizeof(ioctl.layer_color)))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+			LOGICVC_BACKCOL_ROFF, false);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_LAYER_EXT_BUFF_SWITCH:
+		driver_devel("XYLONFB_LAYER_EXT_BUFF_SWITCH\n");
+		if (get_user(val, (unsigned long __user *)arg))
+			return -EFAULT;
+		mutex_lock(&ld->layer_mutex);
+		var32 = cd->reg_access.xylonfb_get_reg_val(
+			ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF, ld);
+		if (val)
+			var32 |= (1 << 2);
+		else
+			var32 &= ~(1 << 2);
+		cd->reg_access.xylonfb_set_reg_val(var32,
+			ld->layer_reg_base_virt, LOGICVC_LAYER_CTRL_ROFF, ld);
+		mutex_unlock(&ld->layer_mutex);
+		break;
+
+	case XYLONFB_READ_HW_REG:
+		driver_devel("XYLONFB_READ_HW_REG\n");
+		if (copy_from_user(&ioctl.hw_access, argp,
+			sizeof(ioctl.hw_access)))
+			return -EFAULT;
+		if (cd->xylonfb_flags & LOGICVC_READABLE_REGS) {
+			ioctl.hw_access.value =
+				cd->reg_access.xylonfb_get_reg_val(
+					ld->reg_base_virt, ioctl.hw_access.offset, ld);
+		} else {
+			ret = xylonfb_layer_reg_access(ld, cd, &ioctl.hw_access, true);
+			if (ret)
+				break;
+		}
+		if (copy_to_user(argp, &ioctl.hw_access,
+			sizeof(ioctl.hw_access)))
+			ret = -EFAULT;
+		break;
+
+	case XYLONFB_WRITE_HW_REG:
+		driver_devel("XYLONFB_WRITE_HW_REG\n");
+		if (copy_from_user(&ioctl.hw_access, argp,
+			sizeof(ioctl.hw_access)))
+			return -EFAULT;
+		if (cd->xylonfb_flags & LOGICVC_READABLE_REGS) {
+			cd->reg_access.xylonfb_set_reg_val(ioctl.hw_access.value,
+				ld->reg_base_virt, ioctl.hw_access.offset, ld);
+		} else {
+			ret = xylonfb_layer_reg_access(ld, cd, &ioctl.hw_access, false);
+			if (ret)
+				break;
+		}
+		if (copy_to_user(argp, &ioctl.hw_access,
+			sizeof(ioctl.hw_access)))
+			ret = -EFAULT;
+		break;
+
+	case XYLONFB_WAIT_EDID:
+		driver_devel("XYLONFB_WAIT_EDID\n");
+#if defined(CONFIG_FB_XYLON_MISC)
+		if (cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY)
+			break;
+		if (get_user(val, (unsigned long __user *)arg))
+			return -EFAULT;
+		if ((val == 0) || (val < 0))
+			val = XYLONFB_EDID_WAIT_TOUT;
+		ret = wait_event_interruptible_timeout(cd->xylonfb_misc->wait,
+			(cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY), (val * HZ));
+		if (ret == 0)
+			return -ETIMEDOUT;
+		else
+			ret = 0;
+#else
+			return -EPERM;
+#endif
+		break;
+
+	case XYLONFB_GET_EDID:
+		driver_devel("XYLONFB_GET_EDID\n");
+#if defined(CONFIG_FB_XYLON_MISC)
+		if (cd->xylonfb_flags & XYLONFB_FLAG_EDID_RDY) {
+			if (cd->xylonfb_misc->edid) {
+				if (copy_to_user(argp, cd->xylonfb_misc->edid,
+					XYLONFB_EDID_SIZE))
+					ret = -EFAULT;
+			} else {
+				return -EPERM;
+			}
+		} else {
+			return -EPERM;
+		}
+#else
+		return -EPERM;
+#endif
+		break;
+
+	default:
+		driver_devel("UNKNOWN_IOCTL\n");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb-pixclk.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/core/xylonfb-pixclk.c	2014-07-20 22:06:38.561269347 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver pixel clock generation
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+/*
+ * This file implements HW dependent functionality for controlling pixel clock
+ * generation on various HW platforms.
+ */
+
+
+#include <linux/kernel.h>
+
+
+#define XYLONFB_PIXCLK_GEN_DEVS 8
+
+static int (*xylonfb_hw_pixclk_set_fn[XYLONFB_PIXCLK_GEN_DEVS])(unsigned long);
+static bool xylonfb_hw_pixclk_init;
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_ZYNQ_PS)
+
+#define XYLONFB_PIXCLK_ZYNQ_PS 1
+
+#include <linux/io.h>
+#include <linux/errno.h>
+
+int xylonfb_hw_pixclk_set_zynq_ps(unsigned long pixclk_khz)
+{
+	unsigned long pllclk, sysclk;
+	unsigned long div, delta, delta_dec, delta_inc;
+	void *slcr_regs, *clk_regs, *rst_reg;
+
+	/* all clock values are in kHz */
+	pllclk = 1000000;
+	sysclk = 100000;
+
+	slcr_regs = ioremap_nocache(0xF8000004, 8);
+	if (!slcr_regs) {
+		pr_err("Error mapping SLCR\n");
+		return -EBUSY;
+	}
+	clk_regs = ioremap_nocache(0xF8000170, 32);
+	if (!clk_regs) {
+		pr_err("Error setting xylonfb pixelclock\n");
+		iounmap(slcr_regs);
+		return -EBUSY;
+	}
+	rst_reg = ioremap_nocache(0xF8000240, 4);
+	if (!rst_reg) {
+		pr_err("Error setting xylonfb pixelclock\n");
+		iounmap(clk_regs);
+		iounmap(slcr_regs);
+		return -EBUSY;
+	}
+
+	/* unlock register access */
+	writel(0xDF0D, (slcr_regs+4));
+#if 0
+	/* calculate system clock divisor */
+	div = pllclk / sysclk;
+	/* prepare for register writting */
+	div = (div + 0x1000) << 8;
+	/* set system clock */
+	writel(div, clk_regs);
+	/* calculate video clock divisor */
+#endif
+	div = pllclk / pixclk_khz;
+	delta = (pllclk / div) - pixclk_khz;
+	if (delta != 0) {
+		delta_inc = pixclk_khz - (pllclk / (div+1));
+		delta_dec = (pllclk / (div-1)) - pixclk_khz;
+		if (delta < delta_inc) {
+			if (delta > delta_dec)
+				div--;
+#if 0
+			else
+				div = div;
+#endif
+		} else {
+			if (delta > delta_dec) {
+				if (delta_inc > delta_dec)
+					div--;
+				else
+					div++;
+			} else {
+				div++;
+			}
+		}
+	}
+	/* prepare for register writting */
+	div = (div + 0x1000) << 8;
+	/* set video clock */
+	writel(div, (clk_regs+0x10));
+	/* lock register access */
+	writel(0x767B, slcr_regs);
+
+	iounmap(rst_reg);
+	iounmap(clk_regs);
+	iounmap(slcr_regs);
+
+	return 0;
+}
+
+#endif /* #if defined(CONFIG_FB_XYLON_PIXCLK_ZYNQ_PS) */
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK)
+
+#define XYLONFB_PIXCLK_LOGICLK 2
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#ifdef CONFIG_OF
+/* For open firmware. */
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#endif
+#include "logiclk.h"
+
+int xylonfb_hw_pixclk_set_logiclk(unsigned long pixclk_khz)
+{
+#ifdef CONFIG_OF
+	struct device_node *dn;
+	const unsigned int *val;
+	int len;
+#endif
+	u32 *logiclk_regs;
+	struct logiclk_freq_out freq_out;
+	u32 logiclk[LOGICLK_REGS];
+	u32 address, osc_freq_hz;
+	int i, size;
+
+	address = 0x40010000;
+	size = LOGICLK_REGS * sizeof(u32);
+	osc_freq_hz = 100000000;
+
+#ifdef CONFIG_OF
+	dn = of_find_node_by_name(NULL, "logiclk");
+	if (dn) {
+		val = of_get_property(dn, "reg", &len);
+		address = be32_to_cpu(val[0]);
+		size = be32_to_cpu(val[1]);
+		val = of_get_property(dn, "osc-clk-freq-hz", &len);
+		osc_freq_hz = be32_to_cpu(val[0]);
+	}
+#endif
+
+	logiclk_regs = ioremap_nocache(address, size);
+	if (!logiclk_regs) {
+		pr_err("Error mapping logiCLK\n");
+		return -EBUSY;
+	}
+
+	for (i = 0; i < LOGICLK_OUTPUTS; i++)
+		freq_out.freq_out_hz[i] = pixclk_khz * 1000;
+
+	if (logiclk_calc_regs(&freq_out, osc_freq_hz, logiclk)) {
+		pr_err("Error calculating logiCLK parameters\n");
+		return -EINVAL;
+	}
+	writel(1, logiclk_regs+LOGICLK_RST_REG_OFF);
+	udelay(10);
+	writel(0, logiclk_regs+LOGICLK_RST_REG_OFF);
+
+	for (i = 0; i < LOGICLK_REGS; i++)
+		writel(logiclk[i], logiclk_regs+LOGICLK_PLL_MANUAL_REG_OFF+i);
+
+	while (1) {
+		if (readl(logiclk_regs+LOGICLK_PLL_REG_OFF) & LOGICLK_PLL_RDY) {
+			writel((LOGICLK_PLL_REG_EN | LOGICLK_PLL_EN),
+				logiclk_regs+LOGICLK_PLL_REG_OFF);
+			break;
+		}
+	}
+
+	iounmap(logiclk_regs);
+
+	return 0;
+}
+
+#endif /* #if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK) */
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_SI570)
+
+#define XYLONFB_PIXCLK_SI570 3
+
+#include <linux/i2c/si570.h>
+
+int xylonfb_hw_pixclk_set_si570(unsigned long pixclk_khz)
+{
+	struct i2c_client *si570_client;
+
+	si570_client = get_i2c_client_si570();
+	if (si570_client)
+		return set_frequency_si570(&si570_client->dev, (pixclk_khz * 1000));
+	else
+		return -EPERM;
+}
+
+#endif /* #if defined(CONFIG_FB_XYLON_PIXCLK_SI570) */
+
+
+bool xylonfb_hw_pixclk_supported(int id)
+{
+	if (!xylonfb_hw_pixclk_init) {
+#if defined(XYLONFB_PIXCLK_ZYNQ_PS)
+		xylonfb_hw_pixclk_set_fn[XYLONFB_PIXCLK_ZYNQ_PS] =
+			xylonfb_hw_pixclk_set_zynq_ps;
+#endif
+#if defined(XYLONFB_PIXCLK_LOGICLK)
+		xylonfb_hw_pixclk_set_fn[XYLONFB_PIXCLK_LOGICLK] =
+			xylonfb_hw_pixclk_set_logiclk;
+#endif
+#if defined(XYLONFB_PIXCLK_SI570)
+		xylonfb_hw_pixclk_set_fn[XYLONFB_PIXCLK_SI570] =
+			xylonfb_hw_pixclk_set_si570;
+#endif
+		xylonfb_hw_pixclk_init = true;
+	}
+
+	return xylonfb_hw_pixclk_set_fn[id] ? true : false;
+}
+
+#if !defined(CONFIG_FB_XYLON_PIXCLK)
+
+int xylonfb_hw_pixclk_set(int id, unsigned long pixclk_khz)
+{
+	pr_info("Pixel clock change not supported\n");
+	return 0;
+}
+
+#else
+
+int xylonfb_hw_pixclk_set(int id, unsigned long pixclk_khz)
+{
+	return xylonfb_hw_pixclk_set_fn[id](pixclk_khz);
+}
+
+#endif /* #if defined(CONFIG_FB_XYLON_PIXCLK) */
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/Kconfig	2014-07-20 22:06:38.567269248 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+menuconfig FB_XYLON
+	tristate "Xylon logiCVC frame buffer support"
+	depends on FB
+	default n
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Choose this option if you want to use the Xylon logiCVC as frame
+	  buffer device. Without the support of PCI & AGP.
+
+choice
+	prompt "Xylon frame buffer driver type"
+	depends on FB_XYLON
+	default FB_XYLON_PLATFORM
+
+config FB_XYLON_PLATFORM
+	bool "Xylon logiCVC frame buffer platform driver"
+	help
+	  Choose this option if you want to use the Xylon frame buffer driver
+	  as platform driver type. This is usefull if OpenFirmware support is
+	  not compiled in the kernel.
+	  This is default selection.
+
+config FB_XYLON_OF
+	bool "Xylon logiCVC frame buffer Open Firmware driver"
+	help
+	  Choose this option if you want to use the Xylon frame buffer driver
+	  as Open Firmware driver type. Driver reads hardware configuration
+	  from Device Tree Blob binary file which must be loaded to
+	  system memory.
+endchoice
+
+config FB_XYLON_PIXCLK
+	bool "Xylon logiCVC pixel clock"
+	depends on FB_XYLON
+	default n
+	help
+	  logiCVC pixel clock generated from:
+	  - External generator not controllable by Xylon framebuffer driver
+	    This is default selection.
+	  - Generators controllable by Xylon framebuffer driver
+
+config FB_XYLON_PIXCLK_ZYNQ_PS
+	bool "Zynq PS PLL pixel clock generator"
+	depends on FB_XYLON && FB_XYLON_PIXCLK
+	default n
+	help
+	  Support for controlling pixel clock generation from
+	  Zynq-PS internal PLL clock generator.
+
+config FB_XYLON_PIXCLK_LOGICLK
+	bool "Xylon logiCLK pixel clock generator"
+	depends on FB_XYLON && FB_XYLON_PIXCLK
+	default n
+	help
+	  Support for controlling pixel clock generation from
+	  Xylon logiCLK FGPA IP core.
+
+config FB_XYLON_PIXCLK_SI570
+	bool "SI570 pixel clock generator"
+	depends on FB_XYLON && FB_XYLON_PIXCLK
+	default n
+	select SYSFS
+	select I2C
+	select MISC_DEVICES
+	select SI570
+	help
+	  Support for controlling pixel clock generation from
+	  SI570 clock generator.
+
+menuconfig FB_XYLON_MISC
+	bool "Xylon logiCVC frame buffer miscellaneous support"
+	depends on FB_XYLON
+	default n
+	help
+	  Choose this option if you want to use the Xylon logiCVC with
+	  miscellaneous device functionality for various improvements.
+	  Currently supported:
+	  - ADV7511 HDMI transmitter
+
+config FB_XYLON_MISC_ADV7511
+	bool "Xylon logiCVC frame buffer ADV7511"
+	depends on FB_XYLON_MISC && VIDEO_ADV7511
+	select FB_MODE_HELPERS
+	default n
+	---help---
+	  Support for ADV7511 HDMI transmitter so that logiCVC can be configured
+	  with parameters read from monitor EDID.
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/Makefile	2014-07-20 22:06:38.590268869 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+obj-$(CONFIG_FB_XYLON_OF) += of/
+obj-$(CONFIG_FB_XYLON_PLATFORM) += platform/
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-adv7511.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-adv7511.c	2014-07-20 22:06:38.605268622 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver miscellaneous ADV7511 functionality
+ * interface for V4L2 adv7511 (Copyright 2012 Cisco Systems, Inc.
+ * and/or its affiliates) driver
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/interrupt.h>
+#include <linux/atomic.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/console.h>
+#include <linux/notifier.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/adv7511.h>
+#include "xylonfb-misc.h"
+#include "xylonfb-adv7511.h"
+
+
+#define ADV7511_NAME "adv7511"
+#define ADV7511_FLAG_INIT 0x01
+
+
+struct xylonfb_adv7511 {
+	atomic_t edid_lock;
+	struct completion edid_done;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_subdev *sd;
+	struct work_struct irq_work;
+	struct workqueue_struct *irq_work_queue;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var_screeninfo;
+	struct fb_monspecs *monspecs;
+	wait_queue_head_t *misc_wait;
+	unsigned long *xfb_flags;
+	unsigned long timeout;
+	unsigned char flags;
+	u8 edid[256];
+};
+
+
+static struct xylonfb_adv7511 *xfb_adv7511;
+
+
+static void xylonfb_adv7511_get_monspecs(u8 *edid,
+	struct fb_monspecs *monspecs, struct fb_var_screeninfo *var)
+{
+	driver_devel("%s\n", __func__);
+
+	fb_edid_to_monspecs(edid, monspecs);
+
+	if (*(xfb_adv7511->xfb_flags) & XYLONFB_FLAG_EDID_PRINT) {
+		pr_info("========================================\n");
+		pr_info("Display Information (EDID)\n");
+		pr_info("========================================\n");
+		pr_info("EDID Version %d.%d\n",
+			(int)monspecs->version, (int)monspecs->revision);
+		pr_info("Manufacturer: %s\n", monspecs->manufacturer);
+		pr_info("Model: %x\n", monspecs->model);
+		pr_info("Serial Number: %u\n", monspecs->serial);
+		pr_info("Year: %u Week %u\n", monspecs->year, monspecs->week);
+		pr_info("Display Characteristics:\n");
+		pr_info("   Monitor Operating Limits from EDID\n");
+		pr_info("   H: %d-%dKHz V: %d-%dHz DCLK: %dMHz\n",
+			monspecs->hfmin/1000, monspecs->hfmax/1000,
+			monspecs->vfmin, monspecs->vfmax,
+			monspecs->dclkmax/1000000);
+		if (monspecs->input & FB_DISP_DDI) {
+			pr_info("   Digital Display Input\n");
+		} else {
+			pr_info("   Analog Display Input:\n");
+			pr_info("   Input Voltage:\n");
+			if (monspecs->input & FB_DISP_ANA_700_300)
+				pr_info("      0.700V/0.300V");
+			else if (monspecs->input & FB_DISP_ANA_714_286)
+				pr_info("      0.714V/0.286V");
+			else if (monspecs->input & FB_DISP_ANA_1000_400)
+				pr_info("      1.000V/0.400V");
+			else if (monspecs->input & FB_DISP_ANA_700_000)
+				pr_info("      0.700V/0.000V");
+		}
+		if (monspecs->signal) {
+			pr_info("   Synchronization:\n");
+			if (monspecs->signal & FB_SIGNAL_BLANK_BLANK)
+				pr_info("      Blank to Blank\n");
+			if (monspecs->signal & FB_SIGNAL_SEPARATE)
+				pr_info("      Separate\n");
+			if (monspecs->signal & FB_SIGNAL_COMPOSITE)
+				pr_info("      Composite\n");
+			if (monspecs->signal & FB_SIGNAL_SYNC_ON_GREEN)
+				pr_info("      Sync on Green\n");
+			if (monspecs->signal & FB_SIGNAL_SERRATION_ON)
+				pr_info("      Serration on\n");
+		}
+		if (monspecs->max_x)
+			pr_info("   Max H-size %dcm\n", monspecs->max_x);
+		else
+			pr_info("   Variable H-size\n");
+		if (monspecs->max_y)
+			pr_info("   Max V-size %dcm\n", monspecs->max_y);
+		else
+			pr_info("   Variable V-size\n");
+		pr_info("   Display Gamma %d.%d\n",
+			monspecs->gamma/100, monspecs->gamma % 100);
+		pr_info("   DPMS: Active %s, Suspend %s, Standby %s\n",
+			(monspecs->dpms & FB_DPMS_ACTIVE_OFF) ? "yes" : "no",
+			(monspecs->dpms & FB_DPMS_SUSPEND)    ? "yes" : "no",
+			(monspecs->dpms & FB_DPMS_STANDBY)    ? "yes" : "no");
+		if (monspecs->input & FB_DISP_MONO)
+			pr_info("   Monochrome/Grayscale\n");
+		else if (monspecs->input & FB_DISP_RGB)
+			pr_info("   RGB Color Display\n");
+		else if (monspecs->input & FB_DISP_MULTI)
+			pr_info("   Non-RGB Multicolor Display\n");
+		else if (monspecs->input & FB_DISP_UNKNOWN)
+			pr_info("   Unknown\n");
+		pr_info("   Chromaticity coordinates:\n");
+		pr_info("      RedX:   0.%03d\n", monspecs->chroma.redx);
+		pr_info("      RedY:   0.%03d\n", monspecs->chroma.redy);
+		pr_info("      GreenX: 0.%03d\n", monspecs->chroma.greenx);
+		pr_info("      GreenY: 0.%03d\n", monspecs->chroma.greeny);
+		pr_info("      BlueX:  0.%03d\n", monspecs->chroma.bluex);
+		pr_info("      BlueY:  0.%03d\n", monspecs->chroma.bluey);
+		pr_info("      WhiteX: 0.%03d\n", monspecs->chroma.whitex);
+		pr_info("      WhiteY: 0.%03d\n", monspecs->chroma.whitey);
+		if (monspecs->misc) {
+			if (monspecs->misc & FB_MISC_PRIM_COLOR)
+				pr_info("   Default color format is primary\n");
+			if (monspecs->misc & FB_MISC_1ST_DETAIL)
+				pr_info("   First DETAILED Timing is preferred\n");
+			if (monspecs->gtf == 1)
+				pr_info("   Display is GTF capable\n");
+		}
+		pr_info("Monitor Timings\n");
+		pr_info("   Resolution %dx%d\n", var->xres, var->yres);
+		pr_info("   Pixel Clock %d MHz ",
+			(int)PICOS2KHZ(var->pixclock)/1000);
+		pr_info("   H sync:\n");
+		pr_info("      Front porch %d Length %d Back porch %d\n",
+			var->right_margin, var->hsync_len, var->left_margin);
+		pr_info("   V sync:\n");
+		pr_info("      Front porch %d Length %d Back porch %d\n",
+			var->lower_margin, var->vsync_len, var->upper_margin);
+		pr_info("   %sHSync %sVSync\n",
+			(var->sync & FB_SYNC_HOR_HIGH_ACT) ? "+" : "-",
+			(var->sync & FB_SYNC_VERT_HIGH_ACT) ? "+" : "-");
+		pr_info("========================================\n");
+	}
+}
+
+static void xylonfb_adv7511_set_v4l2_timings(struct v4l2_subdev *sd,
+	struct fb_var_screeninfo *var)
+{
+	struct v4l2_dv_timings dv_timings;
+
+	driver_devel("%s\n", __func__);
+
+	dv_timings.type = V4L2_DV_BT_656_1120;
+
+	dv_timings.bt.width = var->xres;
+	dv_timings.bt.height = var->yres;
+	dv_timings.bt.interlaced = 0;
+	dv_timings.bt.polarities = 0;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		dv_timings.bt.polarities |= V4L2_DV_VSYNC_POS_POL;
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		dv_timings.bt.polarities |= V4L2_DV_HSYNC_POS_POL;
+	dv_timings.bt.pixelclock = (__u64)PICOS2KHZ(var->pixclock) * 1000;
+	dv_timings.bt.hfrontporch = var->right_margin;
+	dv_timings.bt.hsync = var->hsync_len;
+	dv_timings.bt.hbackporch = var->left_margin;
+	dv_timings.bt.vfrontporch = var->lower_margin;
+	dv_timings.bt.vsync = var->vsync_len;
+	dv_timings.bt.vbackporch = var->upper_margin;
+	dv_timings.bt.il_vfrontporch = 0;
+	dv_timings.bt.il_vsync = 0;
+	dv_timings.bt.il_vbackporch = 0;
+	dv_timings.bt.standards = 0;
+	dv_timings.bt.standards = V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861;
+	dv_timings.bt.flags = 0;
+
+	sd->ops->video->s_dv_timings(sd, &dv_timings);
+}
+
+static int xylonfb_adv7511_update(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_misc_data *misc_data =
+		ld->xylonfb_cd->xylonfb_misc;
+	int ret;
+
+	driver_devel("%s\n", __func__);
+
+	fbi->monspecs = *(misc_data->monspecs);
+
+	console_lock();
+	misc_data->var_screeninfo->xres_virtual = fbi->var.xres_virtual;
+	misc_data->var_screeninfo->yres_virtual = fbi->var.yres_virtual;
+	misc_data->var_screeninfo->xoffset = fbi->var.xoffset;
+	misc_data->var_screeninfo->yoffset = fbi->var.yoffset;
+	misc_data->var_screeninfo->bits_per_pixel = fbi->var.bits_per_pixel;
+	fbi->flags |= FBINFO_MISC_USEREVENT;
+	misc_data->var_screeninfo->activate |= FB_ACTIVATE_ALL;
+	ret = fb_set_var(fbi, misc_data->var_screeninfo);
+	misc_data->var_screeninfo->activate &= ~FB_ACTIVATE_ALL;
+	console_unlock();
+
+	return ret;
+}
+
+static irqreturn_t xylonfb_adv7511_isr(int irq, void *dev_id)
+{
+	struct xylonfb_adv7511 *xfb_adv7511 = dev_id;
+
+	driver_devel("%s\n", __func__);
+
+	queue_work(xfb_adv7511->irq_work_queue, &xfb_adv7511->irq_work);
+
+	return IRQ_HANDLED;
+}
+
+static void xylonfb_adv7511_handler(struct work_struct *work)
+{
+	struct xylonfb_adv7511 *xfb_adv7511 =
+		container_of(work, struct xylonfb_adv7511, irq_work);
+
+	driver_devel("%s\n", __func__);
+
+	xfb_adv7511->sd->ops->core->interrupt_service_routine(
+		xfb_adv7511->sd, 0, NULL);
+}
+
+static void xylonfb_adv7511_notify(struct v4l2_subdev *sd,
+	unsigned int notification, void *arg)
+{
+	union notify_data {
+		struct adv7511_monitor_detect *md;
+		struct adv7511_edid_detect *ed;
+	} nd;
+	struct v4l2_subdev_edid sd_edid;
+	int ret;
+
+	driver_devel("%s\n", __func__);
+
+	switch (notification) {
+	case ADV7511_MONITOR_DETECT:
+		nd.md = arg;
+		driver_devel("ADV7511 monitor%sdetected\n",
+			nd.md->present ? " " : " not ");
+		if (nd.md->present) {
+			xfb_adv7511->timeout = HZ;
+		} else {
+			xfb_adv7511->timeout = 0;
+			*(xfb_adv7511->xfb_flags) &= ~XYLONFB_FLAG_EDID_RDY;
+			atomic_set(&xfb_adv7511->edid_lock, 0);
+		}
+		break;
+	case ADV7511_EDID_DETECT:
+		if (*(xfb_adv7511->xfb_flags) & XYLONFB_FLAG_EDID_VMODE) {
+			if (!atomic_read(&xfb_adv7511->edid_lock)) {
+				nd.ed = arg;
+				driver_devel("ADV7511 EDID%sread\n",
+					nd.ed->present ? " " : " not ");
+				if (nd.ed->present) {
+					atomic_set(&xfb_adv7511->edid_lock, 1);
+					pr_debug("EDID segment: %d\n", nd.ed->segment);
+
+					memset(xfb_adv7511->edid, 0, XYLONFB_EDID_SIZE);
+
+					sd_edid.pad = 0;
+					sd_edid.start_block = 0;
+					sd_edid.blocks = 1;
+					sd_edid.edid = xfb_adv7511->edid;
+					ret = xfb_adv7511->sd->ops->core->ioctl(
+						sd, VIDIOC_SUBDEV_G_EDID, (void *)&sd_edid);
+					if (ret) {
+						pr_warn("xylonfb ADV7511 IOCTL error %d\n", ret);
+						break;
+					}
+
+					fb_parse_edid(xfb_adv7511->edid,
+						xfb_adv7511->var_screeninfo);
+					xylonfb_adv7511_get_monspecs(xfb_adv7511->edid,
+						xfb_adv7511->monspecs, xfb_adv7511->var_screeninfo);
+					xylonfb_adv7511_set_v4l2_timings(xfb_adv7511->sd,
+						xfb_adv7511->var_screeninfo);
+
+					*(xfb_adv7511->xfb_flags) |= XYLONFB_FLAG_EDID_RDY;
+
+					wake_up_interruptible(xfb_adv7511->misc_wait);
+
+					if (xfb_adv7511->flags & ADV7511_FLAG_INIT)
+						complete(&xfb_adv7511->edid_done);
+					else
+						xylonfb_adv7511_update(xfb_adv7511->fbi);
+				}
+			}
+		} else {
+			*(xfb_adv7511->xfb_flags) |= XYLONFB_FLAG_EDID_RDY;
+			wake_up_interruptible(xfb_adv7511->misc_wait);
+		}
+		break;
+	default:
+		pr_warn("xylonfb ADV7511 false notify (%d)\n", notification);
+		break;
+	}
+}
+
+extern struct v4l2_subdev *adv7511_subdev(struct v4l2_subdev *sd);
+
+int xylonfb_adv7511_register(struct fb_info *fbi)
+{
+	struct v4l2_subdev *sd;
+	struct i2c_client *client;
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	struct xylonfb_misc_data *misc_data = cd->xylonfb_misc;
+	int ret;
+
+	driver_devel("%s\n", __func__);
+
+	if (xfb_adv7511)
+		return -EEXIST;
+
+	xfb_adv7511 = kzalloc(sizeof(struct xylonfb_adv7511), GFP_KERNEL);
+	if (!xfb_adv7511) {
+		pr_err("xylonfb ADV7511 error allocating data\n");
+		return -ENOMEM;
+	}
+
+	strlcpy(xfb_adv7511->v4l2_dev.name, DRIVER_NAME,
+		sizeof(xfb_adv7511->v4l2_dev.name));
+	ret = v4l2_device_register(NULL, &xfb_adv7511->v4l2_dev);
+	if (ret) {
+		pr_err("xylonfb ADV7511 registering V4L2 device error\n");
+		return ret;
+	}
+
+	xfb_adv7511->flags |= ADV7511_FLAG_INIT;
+	xfb_adv7511->v4l2_dev.notify = xylonfb_adv7511_notify;
+
+	init_completion(&xfb_adv7511->edid_done);
+
+	xfb_adv7511->var_screeninfo =
+		kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
+	xfb_adv7511->monspecs =
+		kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL);
+	xfb_adv7511->xfb_flags = &cd->xylonfb_flags;
+	xfb_adv7511->fbi = fbi;
+
+	misc_data->var_screeninfo = xfb_adv7511->var_screeninfo;
+	misc_data->monspecs = xfb_adv7511->monspecs;
+	misc_data->edid = xfb_adv7511->edid;
+
+	xfb_adv7511->misc_wait = &misc_data->wait;
+
+	sd = adv7511_subdev(NULL);
+	if (!sd) {
+		pr_err("xylonfb ADV7511 getting V4L2 subdevice error %s\n",
+			ADV7511_NAME);
+		ret = -ENODEV;
+		goto error_subdev;
+	}
+	sd->v4l2_dev = &xfb_adv7511->v4l2_dev;
+	xfb_adv7511->sd = sd;
+
+	client = v4l2_get_subdevdata(sd);
+	if (!client) {
+		pr_err("xylonfb ADV7511 getting V4L2 subdevice client error\n");
+		ret = -ENODEV;
+		goto error_subdev;
+	}
+
+	xfb_adv7511->irq_work_queue = create_singlethread_workqueue(ADV7511_NAME);
+	if (xfb_adv7511->irq_work_queue == NULL) {
+		pr_err("xylonfb ADV7511 workqueue error\n");
+		goto error_subdev;
+	}
+	INIT_WORK(&xfb_adv7511->irq_work, xylonfb_adv7511_handler);
+
+	if (client->irq > 0) {
+		ret = request_irq(client->irq, xylonfb_adv7511_isr,
+			IRQF_TRIGGER_RISING, ADV7511_NAME, xfb_adv7511);
+		if (ret) {
+			pr_err("xylonfb ADV7511 registering interrupt error %d at %d\n",
+				ret, client->irq);
+			goto error_irq;
+		}
+	} else {
+		pr_err("xylonfb ADV7511 error no IRQ registered\n");
+	}
+
+	sd->ops->core->interrupt_service_routine(sd, 0, NULL);
+
+	if (*(xfb_adv7511->xfb_flags) & XYLONFB_FLAG_EDID_VMODE) {
+		if (xfb_adv7511->timeout) {
+			ret = wait_for_completion_timeout(
+				&xfb_adv7511->edid_done, xfb_adv7511->timeout);
+		} else {
+			ret = 0;
+		}
+		xfb_adv7511->flags &= ~ADV7511_FLAG_INIT;
+		if (ret == 0) {
+			if (xfb_adv7511->timeout) {
+				pr_err("xylonfb ADV7511 EDID error\n");
+				return -ETIMEDOUT;
+			} else {
+				return -ENODEV;
+			}
+		}
+	}
+
+	return 0;
+
+error_irq:
+	flush_work(&xfb_adv7511->irq_work);
+	flush_workqueue(xfb_adv7511->irq_work_queue);
+	destroy_workqueue(xfb_adv7511->irq_work_queue);
+error_subdev:
+	v4l2_device_unregister(&xfb_adv7511->v4l2_dev);
+
+	kfree(xfb_adv7511->monspecs);
+	kfree(xfb_adv7511->var_screeninfo);
+	misc_data->edid = NULL;
+	misc_data->monspecs = NULL;
+	misc_data->var_screeninfo = NULL;
+
+	kfree(xfb_adv7511);
+
+	return ret;
+}
+
+void xylonfb_adv7511_unregister(struct fb_info *fbi)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(xfb_adv7511->sd);
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	struct xylonfb_misc_data *misc_data = cd->xylonfb_misc;
+
+	driver_devel("%s\n", __func__);
+
+	if (!xfb_adv7511)
+		return;
+
+	free_irq(client->irq, xfb_adv7511);
+	flush_work(&xfb_adv7511->irq_work);
+	flush_workqueue(xfb_adv7511->irq_work_queue);
+	destroy_workqueue(xfb_adv7511->irq_work_queue);
+
+	kfree(xfb_adv7511->monspecs);
+	kfree(xfb_adv7511->var_screeninfo);
+	misc_data->edid = NULL;
+	misc_data->monspecs = NULL;
+	misc_data->var_screeninfo = NULL;
+
+	v4l2_device_unregister(&xfb_adv7511->v4l2_dev);
+
+	kfree(xfb_adv7511);
+	xfb_adv7511 = NULL;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-adv7511.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-adv7511.h	2014-07-20 22:06:38.611268523 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver miscellaneous ADV7511 functionality
+ * header file
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#ifndef __XYLON_FB_MISC_ADV7511_H__
+#define __XYLON_FB_MISC_ADV7511_H__
+
+
+#include <linux/types.h>
+
+
+int xylonfb_adv7511_register(struct fb_info *fbi);
+void xylonfb_adv7511_unregister(struct fb_info *fbi);
+
+
+#endif /* #ifndef __XYLON_FB_MISC_ADV7511_H__ */
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-misc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-misc.c	2014-07-20 22:06:38.618268407 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver miscellaneous interface functionality
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include "xylonfb-misc.h"
+
+#if defined(CONFIG_FB_XYLON_MISC_ADV7511)
+
+#include "../misc/xylonfb-adv7511.h"
+
+static void xylonfb_misc_adv7511(struct fb_info *fbi, bool init)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_common_data *cd = ld->xylonfb_cd;
+	struct xylonfb_misc_data *misc_data = cd->xylonfb_misc;
+
+	driver_devel("%s\n", __func__);
+
+	if (cd->xylonfb_flags & XYLONFB_FLAG_ADV7511_SKIP)
+		return;
+
+	if (init) {
+		if (cd->xylonfb_flags & XYLONFB_FLAG_MISC_ADV7511)
+			return;
+
+		if (!xylonfb_adv7511_register(fbi)) {
+			fbi->monspecs = *(misc_data->monspecs);
+			cd->xylonfb_flags |= XYLONFB_FLAG_MISC_ADV7511;
+		} else {
+			pr_warn("Warning xylonfb ADV7511 already initialized\n");
+		}
+	} else {
+		xylonfb_adv7511_unregister(fbi);
+		cd->xylonfb_flags &= ~XYLONFB_FLAG_MISC_ADV7511;
+	}
+}
+#endif
+
+static void xylonfb_misc_init_wait(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+
+	driver_devel("%s\n", __func__);
+
+	init_waitqueue_head(&ld->xylonfb_cd->xylonfb_misc->wait);
+}
+
+void xylonfb_misc_init(struct fb_info *fbi)
+{
+	xylonfb_misc_init_wait(fbi);
+#if defined(CONFIG_FB_XYLON_MISC_ADV7511)
+	xylonfb_misc_adv7511(fbi, true);
+#endif
+}
+
+void xylonfb_misc_deinit(struct fb_info *fbi)
+{
+#if defined(CONFIG_FB_XYLON_MISC_ADV7511)
+	xylonfb_misc_adv7511(fbi, false);
+#endif
+}
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-misc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/misc/xylonfb-misc.h	2014-07-20 22:06:38.623268325 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver miscellaneous interface functionality
+ * header file
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#ifndef __XYLON_FB_MISC__
+#define __XYLON_FB_MISC__
+
+
+#include "../core/xylonfb.h"
+
+
+struct xylonfb_misc_data {
+	wait_queue_head_t wait;
+	struct fb_var_screeninfo *var_screeninfo;
+	struct fb_monspecs *monspecs;
+	u8 *edid;
+};
+
+
+void xylonfb_misc_init(struct fb_info *fbi);
+void xylonfb_misc_deinit(struct fb_info *fbi);
+
+#endif /* #ifndef __XYLON_FB_MISC__ */
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/of/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/of/Makefile	2014-07-20 22:06:38.634268143 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+obj-y += ../core/
+
+xylonfb_of-objs := xylonfb-of.o
+ifeq ($(CONFIG_FB_XYLON),m)
+xylonfb_of-objs += ../core/xylonfb_core.o
+endif
+obj-$(CONFIG_FB_XYLON) += xylonfb_of.o
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/of/xylonfb-of.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/of/xylonfb-of.c	2014-07-20 22:06:38.644267978 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer Open Firmware driver
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include "../core/xylonfb.h"
+
+
+static void xylonfb_set_ctrl_reg(struct xylonfb_init_data *init_data,
+	unsigned long pix_data_invert, unsigned long pix_clk_act_high)
+{
+	u32 sync = init_data->vmode_data.fb_vmode.sync;
+	u32 ctrl = CTRL_REG_INIT;
+
+	driver_devel("%s\n", __func__);
+
+	/* FB_SYNC_HOR_HIGH_ACT */
+	if (!(sync & (1<<0)))
+		ctrl &= (~(1<<1));
+	/* FB_SYNC_VERT_HIGH_ACT */
+	if (!(sync & (1<<1)))
+		ctrl &= (~(1<<3));
+	if (pix_data_invert)
+		ctrl |= LOGICVC_PIX_DATA_INVERT;
+	if (pix_clk_act_high)
+		ctrl |= LOGICVC_PIX_ACT_HIGH;
+
+	init_data->vmode_data.ctrl_reg = ctrl;
+}
+
+static int xylonfb_parse_hw_info(struct device_node *np,
+	struct xylonfb_init_data *init_data)
+{
+	u32 const *prop;
+	int size;
+
+	driver_devel("%s\n", __func__);
+
+	prop = of_get_property(np, "xlnx,display-interface", &size);
+	if (!prop) {
+		pr_err("Error xylonfb getting display interface\n");
+		return -EINVAL;
+	}
+	init_data->display_interface_type = be32_to_cpup(prop) << 4;
+
+	prop = of_get_property(np, "xlnx,display-color-space", &size);
+	if (!prop) {
+		pr_err("Error xylonfb getting display color space\n");
+		return -EINVAL;
+	}
+	init_data->display_interface_type |= be32_to_cpup(prop);
+
+	prop = of_get_property(np, "xlnx,readable-regs", &size);
+	if (!prop) {
+		pr_warn("xylonfb registers not readable\n");
+	} else {
+		if (be32_to_cpup(prop))
+			init_data->flags |= LOGICVC_READABLE_REGS;
+	}
+
+	return 0;
+}
+
+static int xylonfb_parse_vram_info(struct device_node *np,
+	unsigned long *vmem_base_addr, unsigned long *vmem_high_addr)
+{
+	u32 const *prop;
+	int size;
+
+	driver_devel("%s\n", __func__);
+
+	prop = of_get_property(np, "xlnx,vmem-baseaddr", &size);
+	if (!prop) {
+		pr_err("Error xylonfb getting VRAM address begin\n");
+		return -EINVAL;
+	}
+	*vmem_base_addr = be32_to_cpup(prop);
+
+	prop = of_get_property(np, "xlnx,vmem-highaddr", &size);
+	if (!prop) {
+		pr_err("Error xylonfb getting VRAM address end\n");
+		return -EINVAL;
+	}
+	*vmem_high_addr = be32_to_cpup(prop);
+
+	return 0;
+}
+
+static int xylonfb_parse_layer_info(struct device_node *np,
+	struct xylonfb_init_data *init_data)
+{
+	u32 const *prop;
+	unsigned int layers, bg_bpp, bg_alpha_mode;
+	int size;
+	char bg_layer_name[25];
+
+	driver_devel("%s\n", __func__);
+
+	prop = of_get_property(np, "xlnx,num-of-layers", &size);
+	if (!prop) {
+		pr_err("Error getting number of layers\n");
+		return -EINVAL;
+	}
+	layers = be32_to_cpup(prop);
+
+	bg_bpp = 0;
+	bg_alpha_mode = 0;
+	prop = of_get_property(np, "xlnx,use-background", &size);
+	if (!prop) {
+		pr_warn("xylonfb no BG layer\n");
+	} else {
+		if (be32_to_cpup(prop) == 1) {
+			layers--;
+
+			sprintf(bg_layer_name, "xlnx,layer-%d-data-width", layers);
+			prop = of_get_property(np, bg_layer_name, &size);
+			if (!prop)
+				bg_bpp = 16;
+			else
+				bg_bpp = be32_to_cpup(prop);
+			if (bg_bpp == 24)
+				bg_bpp = 32;
+
+			sprintf(bg_layer_name, "xlnx,layer-%d-alpha-mode", layers);
+			prop = of_get_property(np, bg_layer_name, &size);
+			if (!prop)
+				bg_alpha_mode = LOGICVC_LAYER_ALPHA;
+			else
+				bg_alpha_mode = be32_to_cpup(prop);
+		} else {
+			pr_debug("xylonfb no BG layer\n");
+		}
+	}
+
+	init_data->layers = (unsigned char)layers;
+	init_data->bg_layer_bpp = (unsigned char)bg_bpp;
+	init_data->bg_layer_alpha_mode = (unsigned char)bg_alpha_mode;
+
+	return 0;
+}
+
+static int xylonfb_parse_vmode_info(struct device_node *np,
+	struct xylonfb_init_data *init_data)
+{
+	struct device_node *dn, *vmode_np;
+	u32 const *prop;
+	char *c;
+	unsigned long pix_data_invert, pix_clk_act_high;
+	int size, tmp;
+
+	driver_devel("%s\n", __func__);
+
+	vmode_np = NULL;
+	init_data->vmode_data.fb_vmode.refresh = 60;
+	init_data->active_layer = 0;
+	init_data->vmode_params_set = false;
+
+	prop = of_get_property(np, "pixel-clock-source", &size);
+	if (!prop) {
+		pr_info("No pixel clock source\n");
+		init_data->pixclk_src_id = 0;
+	} else {
+		tmp = be32_to_cpup(prop);
+		init_data->pixclk_src_id = (u16)tmp;
+	}
+	pix_data_invert = 0;
+	prop = of_get_property(np, "pixel-data-invert", &size);
+	if (!prop)
+		pr_err("Error getting pixel data invert\n");
+	else
+		pix_data_invert = be32_to_cpup(prop);
+	pix_clk_act_high = 0;
+	prop = of_get_property(np, "pixel-clock-active-high", &size);
+	if (!prop)
+		pr_err("Error getting pixel active edge\n");
+	else
+		pix_clk_act_high = be32_to_cpup(prop);
+
+	prop = of_get_property(np, "pixel-component-format", &size);
+	if (prop) {
+		if (!strcmp("ABGR", (char *)prop)) {
+			prop = of_get_property(np, "pixel-component-layer", &size);
+			if (prop) {
+				while (size > 0) {
+					tmp = be32_to_cpup(prop);
+					init_data->layer_ctrl_flags[tmp] = LOGICVC_SWAP_RB;
+					prop++;
+					size -= sizeof(prop);
+				}
+			}
+		}
+	}
+
+	prop = of_get_property(np, "active-layer", &size);
+	if (prop) {
+		tmp = be32_to_cpup(prop);
+		init_data->active_layer = (unsigned char)tmp;
+	} else {
+		pr_info("xylonfb setting default layer to %d\n",
+			init_data->active_layer);
+	}
+
+	dn = of_get_child_by_name(np, "edid");
+	if (dn) {
+		prop = of_get_property(dn, "preffered-videomode", &size);
+		if (prop) {
+			tmp = be32_to_cpup(prop);
+			if (tmp)
+				init_data->flags |= XYLONFB_FLAG_EDID_VMODE;
+		}
+		prop = of_get_property(dn, "display-data", &size);
+		if (prop) {
+			tmp = be32_to_cpup(prop);
+			if (tmp)
+				init_data->flags |= XYLONFB_FLAG_EDID_PRINT;
+		}
+	} else {
+		init_data->flags |= XYLONFB_FLAG_ADV7511_SKIP;
+	}
+	of_node_put(dn);
+
+	prop = of_get_property(np, "videomode", &size);
+	if (prop) {
+		if (strlen((char *)prop) <= VMODE_NAME_SZ) {
+			dn = NULL;
+			dn = of_find_node_by_name(NULL, "xylon-video-params");
+			if (dn) {
+				strcpy(init_data->vmode_data.fb_vmode_name,
+					(char *)prop);
+				vmode_np = of_find_node_by_name(dn,
+					init_data->vmode_data.fb_vmode_name);
+				c = strchr((char *)prop, '_');
+				if (c)
+					*c = 0;
+				strcpy(init_data->vmode_data.fb_vmode_name, (char *)prop);
+			} else {
+				strcpy(init_data->vmode_data.fb_vmode_name, (char *)prop);
+			}
+			of_node_put(dn);
+		} else {
+			pr_err("Error videomode name to long\n");
+		}
+		if (vmode_np) {
+			prop = of_get_property(vmode_np, "refresh", &size);
+			if (!prop)
+				pr_err("Error getting refresh rate\n");
+			else
+				init_data->vmode_data.fb_vmode.refresh =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "xres", &size);
+			if (!prop)
+				pr_err("Error getting xres\n");
+			else
+				init_data->vmode_data.fb_vmode.xres =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "yres", &size);
+			if (!prop)
+				pr_err("Error getting yres\n");
+			else
+				init_data->vmode_data.fb_vmode.yres =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "pixclock-khz", &size);
+			if (!prop)
+				pr_err("Error getting pixclock-khz\n");
+			else
+				init_data->vmode_data.fb_vmode.pixclock =
+					KHZ2PICOS(be32_to_cpup(prop));
+
+			prop = of_get_property(vmode_np, "left-margin", &size);
+			if (!prop)
+				pr_err("Error getting left-margin\n");
+			else
+				init_data->vmode_data.fb_vmode.left_margin =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "right-margin", &size);
+			if (!prop)
+				pr_err("Error getting right-margin\n");
+			else
+				init_data->vmode_data.fb_vmode.right_margin =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "upper-margin", &size);
+			if (!prop)
+				pr_err("Error getting upper-margin\n");
+			else
+				init_data->vmode_data.fb_vmode.upper_margin =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "lower-margin", &size);
+			if (!prop)
+				pr_err("Error getting lower-margin\n");
+			else
+				init_data->vmode_data.fb_vmode.lower_margin =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "hsync-len", &size);
+			if (!prop)
+				pr_err("Error getting hsync-len\n");
+			else
+				init_data->vmode_data.fb_vmode.hsync_len =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "vsync-len", &size);
+			if (!prop)
+				pr_err("Error getting vsync-len\n");
+			else
+				init_data->vmode_data.fb_vmode.vsync_len =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "sync", &size);
+			if (!prop)
+				pr_err("Error getting sync\n");
+			else
+				init_data->vmode_data.fb_vmode.sync =
+					be32_to_cpup(prop);
+
+			prop = of_get_property(vmode_np, "vmode", &size);
+			if (!prop)
+				pr_err("Error getting vmode\n");
+			else
+				init_data->vmode_data.fb_vmode.vmode =
+					be32_to_cpup(prop);
+
+			init_data->vmode_params_set = true;
+		}
+	} else {
+		pr_info("xylonfb using default driver video mode\n");
+	}
+
+	xylonfb_set_ctrl_reg(init_data, pix_data_invert, pix_clk_act_high);
+
+	return 0;
+}
+
+static int xylonfb_parse_layer_params(struct device_node *np,
+	int id, struct xylonfb_layer_fix_data *lfdata)
+{
+	u32 const *prop;
+	int size;
+	char layer_property_name[25];
+
+	driver_devel("%s\n", __func__);
+
+	sprintf(layer_property_name, "xlnx,layer-%d-offset", id);
+	prop = of_get_property(np, layer_property_name, &size);
+	if (!prop) {
+		pr_err("Error getting layer offset\n");
+		return -EINVAL;
+	} else {
+		lfdata->offset = be32_to_cpup(prop);
+	}
+
+	sprintf(layer_property_name, "xlnx,buffer-%d-offset", id);
+	prop = of_get_property(np, layer_property_name, &size);
+	if (!prop) {
+		pr_err("Error getting buffer offset\n");
+		return -EINVAL;
+	} else {
+		lfdata->buffer_offset = be32_to_cpup(prop);
+	}
+
+	prop = of_get_property(np, "xlnx,row-stride", &size);
+	if (!prop)
+		lfdata->width = 1024;
+	else
+		lfdata->width = be32_to_cpup(prop);
+
+	sprintf(layer_property_name, "xlnx,layer-%d-type", id);
+	prop = of_get_property(np, layer_property_name, &size);
+	if (!prop) {
+		pr_err("Error getting layer type\n");
+		return -EINVAL;
+	} else {
+		lfdata->layer_type = be32_to_cpup(prop);
+	}
+
+	sprintf(layer_property_name, "xlnx,layer-%d-alpha-mode", id);
+	prop = of_get_property(np, layer_property_name, &size);
+	if (!prop) {
+		pr_err("Error getting layer alpha mode\n");
+		return -EINVAL;
+	} else {
+		lfdata->alpha_mode = be32_to_cpup(prop);
+		/* If logiCVC layer is Alpha layer, override DT value */
+		if (lfdata->layer_type == LOGICVC_ALPHA_LAYER)
+			lfdata->alpha_mode = LOGICVC_LAYER_ALPHA;
+	}
+
+	sprintf(layer_property_name, "xlnx,layer-%d-data-width", id);
+	prop = of_get_property(np, layer_property_name, &size);
+	if (!prop)
+		lfdata->bpp = 16;
+	else
+		lfdata->bpp = be32_to_cpup(prop);
+	if (lfdata->bpp == 24)
+		lfdata->bpp = 32;
+
+	lfdata->bpp_virt = lfdata->bpp;
+
+	switch (lfdata->bpp) {
+	case 8:
+		if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA)
+			lfdata->bpp = 16;
+		break;
+	case 16:
+		if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA)
+			lfdata->bpp = 32;
+		break;
+	}
+
+	lfdata->layer_fix_info = id;
+
+	return 0;
+}
+
+
+static int xylonfb_of_probe(struct platform_device *pdev)
+{
+	struct xylonfb_init_data init_data;
+	int i, rc;
+
+	driver_devel("%s\n", __func__);
+
+	memset(&init_data, 0, sizeof(struct xylonfb_init_data));
+
+	init_data.pdev = pdev;
+
+	rc = xylonfb_parse_hw_info(pdev->dev.of_node, &init_data);
+	if (rc)
+		return rc;
+	rc = xylonfb_parse_vram_info(pdev->dev.of_node,
+		&init_data.vmem_base_addr, &init_data.vmem_high_addr);
+	if (rc)
+		return rc;
+	rc = xylonfb_parse_layer_info(pdev->dev.of_node, &init_data);
+	if (rc)
+		return rc;
+	/* if Device-Tree contains video mode options do not use
+	   kernel command line video mode options */
+	xylonfb_parse_vmode_info(pdev->dev.of_node, &init_data);
+
+	for (i = 0; i < init_data.layers; i++) {
+		rc = xylonfb_parse_layer_params(pdev->dev.of_node, i,
+			&init_data.lfdata[i]);
+		if (rc)
+			return rc;
+	}
+
+	return xylonfb_init_driver(&init_data);
+}
+
+static int xylonfb_of_remove(struct platform_device *pdev)
+{
+	driver_devel("%s\n", __func__);
+
+	return xylonfb_deinit_driver(pdev);
+}
+
+
+static struct of_device_id xylonfb_of_match[] = {
+	{ .compatible = "xylon,logicvc-3.00.a" },
+	{ .compatible = "xylon,logicvc-3.01.a" },
+	{ .compatible = "xylon,logicvc-3.02.a" },
+	{/* end of table */},
+};
+MODULE_DEVICE_TABLE(of, xylonfb_of_match);
+
+
+static struct platform_driver xylonfb_of_driver = {
+	.probe = xylonfb_of_probe,
+	.remove = xylonfb_of_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DEVICE_NAME,
+		.of_match_table = xylonfb_of_match,
+	},
+};
+
+
+static int xylonfb_of_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+	/*
+	 *  For kernel boot options (in 'video=xxxfb:<options>' format)
+	 */
+	if (fb_get_options(DRIVER_NAME, &option))
+		return -ENODEV;
+	/* Set internal module parameters */
+	xylonfb_get_params(option);
+#endif
+	if (platform_driver_register(&xylonfb_of_driver)) {
+		pr_err("Error xylonfb driver registration\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit xylonfb_of_exit(void)
+{
+	platform_driver_unregister(&xylonfb_of_driver);
+}
+
+
+#ifndef MODULE
+late_initcall(xylonfb_of_init);
+#else
+module_init(xylonfb_of_init);
+module_exit(xylonfb_of_exit);
+#endif
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_VERSION(DRIVER_VERSION);
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/platform/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/platform/Makefile	2014-07-20 22:06:38.655267797 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+obj-y += ../core/
+
+xylonfb_platform-objs := xylonfb-platform.o
+ifeq ($(CONFIG_FB_XYLON),m)
+xylonfb_platform-objs += ../core/xylonfb_core.o
+endif
+obj-$(CONFIG_FB_XYLON) += xylonfb_platform.o
Index: linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/platform/xylonfb-platform.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/video/xylon/xylonfb/platform/xylonfb-platform.c	2014-07-20 22:06:38.663267665 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer platform driver
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * This driver was primarily based on skeletonfb.c and other fb video drivers.
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/xylonfb_platform.h>
+#include "../core/xylonfb.h"
+
+
+static void xylonfb_get_platform_layer_params(
+	struct xylonfb_platform_layer_params *lparams,
+	struct xylonfb_layer_fix_data *lfdata, int id)
+{
+	driver_devel("%s\n", __func__);
+
+	lfdata->offset = lparams->offset;
+	lfdata->buffer_offset = lparams->buffer_offset;
+	lfdata->layer_type = lparams->type;
+	lfdata->bpp = lparams->bpp;
+	lfdata->bpp_virt = lparams->bpp;
+	lfdata->alpha_mode = lparams->alpha_mode;
+	if (lfdata->layer_type == LOGICVC_ALPHA_LAYER)
+		lfdata->alpha_mode = LOGICVC_LAYER_ALPHA;
+
+	switch (lfdata->bpp) {
+	case 8:
+		if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA)
+			lfdata->bpp = 16;
+		break;
+	case 16:
+		if (lfdata->alpha_mode == LOGICVC_PIXEL_ALPHA)
+			lfdata->bpp = 32;
+		break;
+	}
+
+	lfdata->layer_fix_info = id;
+}
+
+static int xylonfb_platform_probe(struct platform_device *pdev)
+{
+	struct xylonfb_init_data init_data;
+	struct xylonfb_platform_data *pdata;
+	int i;
+
+	driver_devel("%s\n", __func__);
+
+	memset(&init_data, 0, sizeof(struct xylonfb_init_data));
+
+	init_data.pdev = pdev;
+
+	pdata = (struct xylonfb_platform_data *)pdev->dev.platform_data;
+	init_data.vmem_base_addr = pdata->vmem_base_addr;
+	init_data.vmem_high_addr = pdata->vmem_high_addr;
+	init_data.pixclk_src_id = pdata->pixclk_src_id;
+	init_data.vmode_data.ctrl_reg = pdata->ctrl_reg;
+	strcpy(init_data.vmode_data.fb_vmode_name, pdata->vmode);
+	init_data.vmode_data.fb_vmode.refresh = 60;
+	init_data.layers = pdata->num_layers;
+	init_data.active_layer = pdata->active_layer;
+	init_data.bg_layer_bpp = pdata->bg_layer_bpp;
+	init_data.bg_layer_alpha_mode = pdata->bg_layer_alpha_mode;
+	init_data.display_interface_type = pdata->display_interface_type;
+	init_data.flags = pdata->flags;
+	init_data.vmode_params_set = false;
+
+	for (i = 0; i < init_data.layers; i++) {
+		xylonfb_get_platform_layer_params(
+			&pdata->layer_params[i], &init_data.lfdata[i], i);
+		init_data.lfdata[i].width = pdata->row_stride;
+		init_data.layer_ctrl_flags[i] = pdata->layer_params[i].ctrl_flags;
+	}
+
+	return xylonfb_init_driver(&init_data);
+}
+
+static int xylonfb_platform_remove(struct platform_device *pdev)
+{
+	driver_devel("%s\n", __func__);
+
+	return xylonfb_deinit_driver(pdev);
+}
+
+
+void xylonfb_platform_release(struct device *dev)
+{
+	driver_devel("%s\n", __func__);
+
+	return;
+}
+
+
+/* logiCVC parameters for Xylon Zynq-ZC702 2D3D referent design */
+static struct xylonfb_platform_layer_params
+	logicvc_0_layer_params[] = {
+	{
+		.offset = 7290,
+		.buffer_offset = 1080,
+		.type = LOGICVC_RGB_LAYER,
+		.bpp = 32,
+		.alpha_mode = LOGICVC_PIXEL_ALPHA,
+		.ctrl_flags = 0,
+	},
+	{
+		.offset = 4050,
+		.buffer_offset = 1080,
+		.type = LOGICVC_RGB_LAYER,
+		.bpp = 32,
+		.alpha_mode = LOGICVC_LAYER_ALPHA,
+		.ctrl_flags = 0,
+	},
+	{
+		.offset = 0,
+		.buffer_offset = 1080,
+		.type = LOGICVC_RGB_LAYER,
+		.bpp = 32,
+		.alpha_mode = LOGICVC_LAYER_ALPHA,
+		.ctrl_flags = 0,
+	},
+	{
+		.offset = 12960,
+		.buffer_offset = 1080,
+		.type = LOGICVC_RGB_LAYER,
+		.bpp = 8,
+		.alpha_mode = LOGICVC_CLUT_32BPP_ALPHA,
+		.ctrl_flags = 0,
+	},
+};
+
+static struct xylonfb_platform_data logicvc_0_platform_data = {
+	.layer_params = logicvc_0_layer_params,
+	.vmode = "1024x768",
+	.ctrl_reg = (CTRL_REG_INIT | LOGICVC_PIX_ACT_HIGH),
+	.vmem_base_addr = 0x30000000,
+	.vmem_high_addr = 0x3FFFFFFF,
+	.pixclk_src_id = 3,
+	.row_stride = 2048,
+	.num_layers = ARRAY_SIZE(logicvc_0_layer_params),
+	.active_layer = 3,
+	.bg_layer_bpp = 32,
+	.bg_layer_alpha_mode = LOGICVC_LAYER_ALPHA,
+	.display_interface_type =
+		(LOGICVC_DI_PARALLEL << 4) | (LOGICVC_DCS_YUV422),
+	/*
+		Available flags:
+		LOGICVC_READABLE_REGS
+		XYLONFB_FLAG_EDID_VMODE
+		XYLONFB_FLAG_EDID_PRINT
+	*/
+	.flags = 0,
+};
+
+static struct resource logicvc_0_resource[] = {
+	{
+		.start = 0x40030000,
+		.end = (0x40030000 + LOGICVC_REGISTERS_RANGE),
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 90,
+		.end = 90,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device logicvc_0_device = {
+	.name = DEVICE_NAME,
+	.id = 0,
+	.dev = {
+		.platform_data = &logicvc_0_platform_data,
+		.release = xylonfb_platform_release,
+	},
+	.resource = logicvc_0_resource,
+	.num_resources = ARRAY_SIZE(logicvc_0_resource),
+};
+
+
+static struct platform_driver xylonfb_driver = {
+	.probe = xylonfb_platform_probe,
+	.remove = xylonfb_platform_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DEVICE_NAME,
+	},
+};
+
+
+static int xylonfb_platform_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+#endif
+	int err;
+
+	driver_devel("%s\n", __func__);
+
+#ifndef MODULE
+	/*
+	 *  For kernel boot options (in 'video=xxxfb:<options>' format)
+	 */
+	if (fb_get_options(DRIVER_NAME, &option))
+		return -ENODEV;
+	/* Set internal module parameters */
+	xylonfb_get_params(option);
+#endif
+	err = platform_device_register(&logicvc_0_device);
+	if (err) {
+		pr_err("Error xylonfb device registration\n");
+		return err;
+	}
+	err = platform_driver_register(&xylonfb_driver);
+	if (err) {
+		pr_err("Error xylonfb driver registration\n");
+		platform_device_unregister(&logicvc_0_device);
+		return err;
+	}
+
+	return 0;
+}
+
+static void __exit xylonfb_platform_exit(void)
+{
+	platform_driver_unregister(&xylonfb_driver);
+	platform_device_unregister(&logicvc_0_device);
+}
+
+
+#ifndef MODULE
+late_initcall(xylonfb_platform_init);
+#else
+module_init(xylonfb_platform_init);
+module_exit(xylonfb_platform_exit);
+#endif
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_VERSION(DRIVER_VERSION);
Index: linux-3.12.24-rt38-xilinx/drivers/watchdog/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/watchdog/Kconfig	2014-07-20 22:05:50.201067198 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/watchdog/Kconfig	2014-07-20 22:06:38.680267385 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:341 @
 	  To compile this driver as a module, choose M here: the
 	  module will be called nuc900_wdt.
 
+config ZYNQ_WATCHDOG
+	tristate "Xilinx PS Watchdog Timer"
+	depends on ARCH_ZYNQ
+	select WATCHDOG_CORE
+	help
+	  Say Y here if you want to include support for the watchdog
+	  timer in the Xilinx Zynq.
+
 config TS72XX_WATCHDOG
 	tristate "TS-72XX SBC Watchdog"
 	depends on MACH_TS72XX
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:999 @
 
 config XILINX_WATCHDOG
 	tristate "Xilinx Watchdog timer"
-	depends on MICROBLAZE
+	depends on MICROBLAZE || ARCH_ZYNQ
+	select WATCHDOG_CORE
 	---help---
 	  Watchdog driver for the xps_timebase_wdt ip core.
 
-	  IMPORTANT: The xps_timebase_wdt parent must have the property
-	  "clock-frequency" at device tree.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called of_xilinx_wdt.
 
Index: linux-3.12.24-rt38-xilinx/drivers/watchdog/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/watchdog/Makefile	2014-07-20 22:05:50.200067215 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/watchdog/Makefile	2014-07-20 22:06:38.691267203 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:53 @
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
 obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
+obj-$(CONFIG_ZYNQ_WATCHDOG) += zynq_wdt.o
 obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
 obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
 obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
Index: linux-3.12.24-rt38-xilinx/drivers/watchdog/of_xilinx_wdt.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/drivers/watchdog/of_xilinx_wdt.c	2014-07-20 22:05:50.202067182 +0200
+++ linux-3.12.24-rt38-xilinx/drivers/watchdog/of_xilinx_wdt.c	2014-07-20 22:06:38.704266989 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
 /*
  * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt
  *
+ * (C) Copyright 2013 Xilinx, Inc.
  * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.com>)
  *
  * This program is free software; you can redistribute it and/or
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:13 @
  * 2 of the License, or (at your option) any later version.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/watchdog.h>
 #include <linux/io.h>
-#include <linux/uaccess.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:43 @
 #define XWT_TIMER_FAILED            0xFFFFFFFF
 
 #define WATCHDOG_NAME     "Xilinx Watchdog"
-#define PFX WATCHDOG_NAME ": "
 
-struct xwdt_device {
-	struct resource  res;
+struct xilinx_wdt_device {
 	void __iomem *base;
-	u32 nowayout;
 	u32 wdt_interval;
-	u32 boot_status;
+	spinlock_t spinlock;
+	struct watchdog_device xilinx_wdt_wdd;
 };
 
-static struct xwdt_device xdev;
-
-static  u32 timeout;
-static  u32 control_status_reg;
-static  u8  expect_close;
-static  u8  no_timeout;
-static unsigned long driver_open;
-
-static  DEFINE_SPINLOCK(spinlock);
-
-static void xwdt_start(void)
+static int xilinx_wdt_start(struct watchdog_device *wdd)
 {
-	spin_lock(&spinlock);
+	u32 control_status_reg;
+	struct xilinx_wdt_device *xilinx_wdt = watchdog_get_drvdata(wdd);
+
+	spin_lock(&xilinx_wdt->spinlock);
 
 	/* Clean previous status and enable the watchdog timer */
-	control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET);
+	control_status_reg = ioread32(xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 	control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK);
 
 	iowrite32((control_status_reg | XWT_CSR0_EWDT1_MASK),
-				xdev.base + XWT_TWCSR0_OFFSET);
+		  xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 
-	iowrite32(XWT_CSRX_EWDT2_MASK, xdev.base + XWT_TWCSR1_OFFSET);
+	iowrite32(XWT_CSRX_EWDT2_MASK, xilinx_wdt->base + XWT_TWCSR1_OFFSET);
 
-	spin_unlock(&spinlock);
+	spin_unlock(&xilinx_wdt->spinlock);
+
+	return 0;
 }
 
-static void xwdt_stop(void)
+static int xilinx_wdt_stop(struct watchdog_device *wdd)
 {
-	spin_lock(&spinlock);
+	u32 control_status_reg;
+	struct xilinx_wdt_device *xilinx_wdt = watchdog_get_drvdata(wdd);
+
+	spin_lock(&xilinx_wdt->spinlock);
 
-	control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET);
+	control_status_reg = ioread32(xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 
 	iowrite32((control_status_reg & ~XWT_CSR0_EWDT1_MASK),
-				xdev.base + XWT_TWCSR0_OFFSET);
+		  xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 
-	iowrite32(0, xdev.base + XWT_TWCSR1_OFFSET);
+	iowrite32(0, xilinx_wdt->base + XWT_TWCSR1_OFFSET);
 
-	spin_unlock(&spinlock);
+	spin_unlock(&xilinx_wdt->spinlock);
 	pr_info("Stopped!\n");
+
+	return 0;
 }
 
-static void xwdt_keepalive(void)
+static int xilinx_wdt_keepalive(struct watchdog_device *wdd)
 {
-	spin_lock(&spinlock);
+	u32 control_status_reg;
+	struct xilinx_wdt_device *xilinx_wdt = watchdog_get_drvdata(wdd);
 
-	control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET);
+	spin_lock(&xilinx_wdt->spinlock);
+
+	control_status_reg = ioread32(xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 	control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK);
-	iowrite32(control_status_reg, xdev.base + XWT_TWCSR0_OFFSET);
+	iowrite32(control_status_reg, xilinx_wdt->base + XWT_TWCSR0_OFFSET);
 
-	spin_unlock(&spinlock);
-}
+	spin_unlock(&xilinx_wdt->spinlock);
 
-static void xwdt_get_status(int *status)
-{
-	int new_status;
+	return 0;
+}
 
-	spin_lock(&spinlock);
+static const struct watchdog_info xilinx_wdt_ident = {
+	.options =  WDIOF_MAGICCLOSE |
+		    WDIOF_KEEPALIVEPING,
+	.firmware_version =	1,
+	.identity =	WATCHDOG_NAME,
+};
 
-	control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET);
-	new_status = ((control_status_reg &
-			(XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK)) != 0);
-	spin_unlock(&spinlock);
-
-	*status = 0;
-	if (new_status & 1)
-		*status |= WDIOF_CARDRESET;
-}
+static const struct watchdog_ops xilinx_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = xilinx_wdt_start,
+	.stop = xilinx_wdt_stop,
+	.ping = xilinx_wdt_keepalive,
+};
 
-static u32 xwdt_selftest(void)
+static u32 xilinx_wdt_selftest(struct xilinx_wdt_device *xilinx_wdt)
 {
 	int i;
 	u32 timer_value1;
 	u32 timer_value2;
 
-	spin_lock(&spinlock);
+	spin_lock(&xilinx_wdt->spinlock);
 
-	timer_value1 = ioread32(xdev.base + XWT_TBR_OFFSET);
-	timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET);
+	timer_value1 = ioread32(xilinx_wdt->base + XWT_TBR_OFFSET);
+	timer_value2 = ioread32(xilinx_wdt->base + XWT_TBR_OFFSET);
 
 	for (i = 0;
 		((i <= XWT_MAX_SELFTEST_LOOP_COUNT) &&
 			(timer_value2 == timer_value1)); i++) {
-		timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET);
+		timer_value2 = ioread32(xilinx_wdt->base + XWT_TBR_OFFSET);
 	}
 
-	spin_unlock(&spinlock);
+	spin_unlock(&xilinx_wdt->spinlock);
 
 	if (timer_value2 != timer_value1)
 		return ~XWT_TIMER_FAILED;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:147 @
 		return XWT_TIMER_FAILED;
 }
 
-static int xwdt_open(struct inode *inode, struct file *file)
-{
-	/* Only one process can handle the wdt at a time */
-	if (test_and_set_bit(0, &driver_open))
-		return -EBUSY;
-
-	/* Make sure that the module are always loaded...*/
-	if (xdev.nowayout)
-		__module_get(THIS_MODULE);
-
-	xwdt_start();
-	pr_info("Started...\n");
-
-	return nonseekable_open(inode, file);
-}
-
-static int xwdt_release(struct inode *inode, struct file *file)
-{
-	if (expect_close == 42) {
-		xwdt_stop();
-	} else {
-		pr_crit("Unexpected close, not stopping watchdog!\n");
-		xwdt_keepalive();
-	}
-
-	clear_bit(0, &driver_open);
-	expect_close = 0;
-	return 0;
-}
-
-/*
- *      xwdt_write:
- *      @file: file handle to the watchdog
- *      @buf: buffer to write (unused as data does not matter here
- *      @count: count of bytes
- *      @ppos: pointer to the position to write. No seeks allowed
- *
- *      A write to a watchdog device is defined as a keepalive signal. Any
- *      write of data will do, as we don't define content meaning.
- */
-static ssize_t xwdt_write(struct file *file, const char __user *buf,
-						size_t len, loff_t *ppos)
-{
-	if (len) {
-		if (!xdev.nowayout) {
-			size_t i;
-
-			/* In case it was set long ago */
-			expect_close = 0;
-
-			for (i = 0; i != len; i++) {
-				char c;
-
-				if (get_user(c, buf + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_close = 42;
-			}
-		}
-		xwdt_keepalive();
-	}
-	return len;
-}
-
-static const struct watchdog_info ident = {
-	.options =  WDIOF_MAGICCLOSE |
-		    WDIOF_KEEPALIVEPING,
-	.firmware_version =	1,
-	.identity =	WATCHDOG_NAME,
-};
-
-/*
- *      xwdt_ioctl:
- *      @file: file handle to the device
- *      @cmd: watchdog command
- *      @arg: argument pointer
- *
- *      The watchdog API defines a common set of functions for all watchdogs
- *      according to their available features.
- */
-static long xwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int status;
-
-	union {
-		struct watchdog_info __user *ident;
-		int __user *i;
-	} uarg;
-
-	uarg.i = (int __user *)arg;
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		return copy_to_user(uarg.ident, &ident,
-					sizeof(ident)) ? -EFAULT : 0;
-
-	case WDIOC_GETBOOTSTATUS:
-		return put_user(xdev.boot_status, uarg.i);
-
-	case WDIOC_GETSTATUS:
-		xwdt_get_status(&status);
-		return put_user(status, uarg.i);
-
-	case WDIOC_KEEPALIVE:
-		xwdt_keepalive();
-		return 0;
-
-	case WDIOC_GETTIMEOUT:
-		if (no_timeout)
-			return -ENOTTY;
-		else
-			return put_user(timeout, uarg.i);
-
-	default:
-		return -ENOTTY;
-	}
-}
-
-static const struct file_operations xwdt_fops = {
-	.owner      = THIS_MODULE,
-	.llseek     = no_llseek,
-	.write      = xwdt_write,
-	.open       = xwdt_open,
-	.release    = xwdt_release,
-	.unlocked_ioctl = xwdt_ioctl,
-};
-
-static struct miscdevice xwdt_miscdev = {
-	.minor      = WATCHDOG_MINOR,
-	.name       = "watchdog",
-	.fops       = &xwdt_fops,
-};
-
-static int xwdt_probe(struct platform_device *pdev)
+static int xilinx_wdt_probe(struct platform_device *pdev)
 {
 	int rc;
-	u32 *tmptr;
-	u32 *pfreq;
-
-	no_timeout = 0;
-
-	pfreq = (u32 *)of_get_property(pdev->dev.of_node,
-					"clock-frequency", NULL);
+	u32 pfreq, enable_once;
+	struct resource *res;
+	struct xilinx_wdt_device *xilinx_wdt;
+	bool no_timeout = false;
+	struct watchdog_device *xilinx_wdt_wdd;
+
+	xilinx_wdt = devm_kzalloc(&pdev->dev, sizeof(*xilinx_wdt), GFP_KERNEL);
+	if (!xilinx_wdt)
+		return -ENOMEM;
+
+	xilinx_wdt_wdd = &xilinx_wdt->xilinx_wdt_wdd;
+	xilinx_wdt_wdd->info = &xilinx_wdt_ident;
+	xilinx_wdt_wdd->ops = &xilinx_wdt_ops;
+	xilinx_wdt_wdd->parent = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xilinx_wdt->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xilinx_wdt->base))
+		return PTR_ERR(xilinx_wdt->base);
 
-	if (pfreq == NULL) {
-		pr_warn("The watchdog clock frequency cannot be obtained!\n");
-		no_timeout = 1;
-	}
-
-	rc = of_address_to_resource(pdev->dev.of_node, 0, &xdev.res);
+	rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &pfreq);
 	if (rc) {
-		pr_warn("invalid address!\n");
-		return rc;
+		dev_warn(&pdev->dev,
+			 "The watchdog clock frequency cannot be obtained\n");
+		no_timeout = true;
 	}
 
-	tmptr = (u32 *)of_get_property(pdev->dev.of_node,
-					"xlnx,wdt-interval", NULL);
-	if (tmptr == NULL) {
-		pr_warn("Parameter \"xlnx,wdt-interval\" not found in device tree!\n");
-		no_timeout = 1;
-	} else {
-		xdev.wdt_interval = *tmptr;
+	rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval",
+				  &xilinx_wdt->wdt_interval);
+	if (rc) {
+		dev_warn(&pdev->dev,
+			 "Parameter \"xlnx,wdt-interval\" not found\n");
+		no_timeout = true;
 	}
 
-	tmptr = (u32 *)of_get_property(pdev->dev.of_node,
-					"xlnx,wdt-enable-once", NULL);
-	if (tmptr == NULL) {
-		pr_warn("Parameter \"xlnx,wdt-enable-once\" not found in device tree!\n");
-		xdev.nowayout = WATCHDOG_NOWAYOUT;
+	/* FIXME this is weird */
+	rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-enable-once",
+				  &enable_once);
+	if (rc || enable_once) {
+		dev_warn(&pdev->dev,
+			 "Parameter \"xlnx,wdt-enable-once\" not found\n");
+		watchdog_set_nowayout(xilinx_wdt_wdd, true);
 	}
 
 /*
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:199 @
  *  ignored (interrupt), reset is only generated at second wdt overflow
  */
 	if (!no_timeout)
-		timeout = 2 * ((1<<xdev.wdt_interval) / *pfreq);
+		xilinx_wdt_wdd->timeout = 2 * ((1 << xilinx_wdt->wdt_interval) /
+					  pfreq);
 
-	if (!request_mem_region(xdev.res.start,
-			xdev.res.end - xdev.res.start + 1, WATCHDOG_NAME)) {
-		rc = -ENXIO;
-		pr_err("memory request failure!\n");
-		goto err_out;
-	}
-
-	xdev.base = ioremap(xdev.res.start, xdev.res.end - xdev.res.start + 1);
-	if (xdev.base == NULL) {
-		rc = -ENOMEM;
-		pr_err("ioremap failure!\n");
-		goto release_mem;
-	}
+	spin_lock_init(&xilinx_wdt->spinlock);
+	watchdog_set_drvdata(xilinx_wdt_wdd, xilinx_wdt);
 
-	rc = xwdt_selftest();
+	rc = xilinx_wdt_selftest(xilinx_wdt);
 	if (rc == XWT_TIMER_FAILED) {
-		pr_err("SelfTest routine error!\n");
-		goto unmap_io;
+		dev_err(&pdev->dev, "SelfTest routine error\n");
+		return rc;
 	}
 
-	xwdt_get_status(&xdev.boot_status);
-
-	rc = misc_register(&xwdt_miscdev);
+	rc = watchdog_register_device(xilinx_wdt_wdd);
 	if (rc) {
-		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
-		       xwdt_miscdev.minor, rc);
-		goto unmap_io;
+		dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc);
+		return rc;
 	}
 
-	if (no_timeout)
-		pr_info("driver loaded (timeout=? sec, nowayout=%d)\n",
-			xdev.nowayout);
-	else
-		pr_info("driver loaded (timeout=%d sec, nowayout=%d)\n",
-			timeout, xdev.nowayout);
+	dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
+		 xilinx_wdt->base, xilinx_wdt_wdd->timeout);
 
-	expect_close = 0;
-	clear_bit(0, &driver_open);
+	platform_set_drvdata(pdev, xilinx_wdt);
 
 	return 0;
-
-unmap_io:
-	iounmap(xdev.base);
-release_mem:
-	release_mem_region(xdev.res.start, resource_size(&xdev.res));
-err_out:
-	return rc;
 }
 
-static int xwdt_remove(struct platform_device *dev)
+static int xilinx_wdt_remove(struct platform_device *pdev)
 {
-	misc_deregister(&xwdt_miscdev);
-	iounmap(xdev.base);
-	release_mem_region(xdev.res.start, resource_size(&xdev.res));
+	struct xilinx_wdt_device *xilinx_wdt = platform_get_drvdata(pdev);
+
+	watchdog_unregister_device(&xilinx_wdt->xilinx_wdt_wdd);
 
 	return 0;
 }
 
 /* Match table for of_platform binding */
-static struct of_device_id xwdt_of_match[] = {
+static struct of_device_id xilinx_wdt_of_match[] = {
 	{ .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
 	{ .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
 	{},
 };
-MODULE_DEVICE_TABLE(of, xwdt_of_match);
+MODULE_DEVICE_TABLE(of, xilinx_wdt_of_match);
 
-static struct platform_driver xwdt_driver = {
-	.probe       = xwdt_probe,
-	.remove      = xwdt_remove,
+static struct platform_driver xilinx_wdt_driver = {
+	.probe       = xilinx_wdt_probe,
+	.remove      = xilinx_wdt_remove,
 	.driver = {
 		.owner = THIS_MODULE,
 		.name  = WATCHDOG_NAME,
-		.of_match_table = xwdt_of_match,
+		.of_match_table = xilinx_wdt_of_match,
 	},
 };
 
-module_platform_driver(xwdt_driver);
+module_platform_driver(xilinx_wdt_driver);
 
 MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
 MODULE_DESCRIPTION("Xilinx Watchdog driver");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
Index: linux-3.12.24-rt38-xilinx/drivers/watchdog/zynq_wdt.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/watchdog/zynq_wdt.c	2014-07-20 22:06:38.716266791 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq WDT driver
+ *
+ * Copyright (c) 2010-2013 Xilinx 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define ZYNQ_WDT_DEFAULT_TIMEOUT	10
+/* Supports 1 - 516 sec */
+#define ZYNQ_WDT_MIN_TIMEOUT	1
+#define ZYNQ_WDT_MAX_TIMEOUT	516
+
+static int wdt_timeout = ZYNQ_WDT_DEFAULT_TIMEOUT;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+		 "Watchdog time in seconds. (default="
+		 __MODULE_STRING(ZYNQ_WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Watchdog cannot be stopped once started (default="
+		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+/**
+ * struct zynq_wdt - Watchdog device structure.
+ * @regs: baseaddress of device.
+ * @busy: flag for the device.
+ *
+ * Structure containing parameters specific to ps watchdog.
+ */
+struct zynq_wdt {
+	void __iomem		*regs;		/* Base address */
+	u32			rst;		/* Reset flag */
+	struct clk		*clk;
+	u32			prescalar;
+	u32			ctrl_clksel;
+	spinlock_t		io_lock;
+};
+static struct zynq_wdt *wdt;
+
+/*
+ * Info structure used to indicate the features supported by the device
+ * to the upper layers. This is defined in watchdog.h header file.
+ */
+static struct watchdog_info zynq_wdt_info = {
+	.identity	= "zynq_wdt watchdog",
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+				WDIOF_MAGICCLOSE,
+};
+
+/* Write access to Registers */
+#define zynq_wdt_writereg(val, offset) __raw_writel(val, (wdt->regs) + offset)
+
+/*************************Register Map**************************************/
+
+/* Register Offsets for the WDT */
+#define ZYNQ_WDT_ZMR_OFFSET	0x0	/* Zero Mode Register */
+#define ZYNQ_WDT_CCR_OFFSET	0x4	/* Counter Control Register */
+#define ZYNQ_WDT_RESTART_OFFSET	0x8	/* Restart Register */
+#define ZYNQ_WDT_SR_OFFSET	0xC	/* Status Register */
+
+/*
+ * Zero Mode Register - This register controls how the time out is indicated
+ * and also contains the access code to allow writes to the register (0xABC).
+ */
+#define ZYNQ_WDT_ZMR_WDEN_MASK	0x00000001 /* Enable the WDT */
+#define ZYNQ_WDT_ZMR_RSTEN_MASK	0x00000002 /* Enable the reset output */
+#define ZYNQ_WDT_ZMR_IRQEN_MASK	0x00000004 /* Enable IRQ output */
+#define ZYNQ_WDT_ZMR_RSTLEN_16	0x00000030 /* Reset pulse of 16 pclk cycles */
+#define ZYNQ_WDT_ZMR_ZKEY_VAL	0x00ABC000 /* Access key, 0xABC << 12 */
+/*
+ * Counter Control register - This register controls how fast the timer runs
+ * and the reset value and also contains the access code to allow writes to
+ * the register.
+ */
+#define ZYNQ_WDT_CCR_CRV_MASK	0x00003FFC /* Counter reset value */
+
+/**
+ * zynq_wdt_stop -  Stop the watchdog.
+ *
+ * Read the contents of the ZMR register, clear the WDEN bit
+ * in the register and set the access key for successful write.
+ */
+static int zynq_wdt_stop(struct watchdog_device *wdd)
+{
+	spin_lock(&wdt->io_lock);
+	zynq_wdt_writereg((ZYNQ_WDT_ZMR_ZKEY_VAL & (~ZYNQ_WDT_ZMR_WDEN_MASK)),
+			 ZYNQ_WDT_ZMR_OFFSET);
+	spin_unlock(&wdt->io_lock);
+	return 0;
+}
+
+/**
+ * zynq_wdt_reload -  Reload the watchdog timer (i.e. pat the watchdog).
+ *
+ * Write the restart key value (0x00001999) to the restart register.
+ */
+static int zynq_wdt_reload(struct watchdog_device *wdd)
+{
+	spin_lock(&wdt->io_lock);
+	zynq_wdt_writereg(0x00001999, ZYNQ_WDT_RESTART_OFFSET);
+	spin_unlock(&wdt->io_lock);
+	return 0;
+}
+
+/**
+ * zynq_wdt_start -  Enable and start the watchdog.
+ *
+ * The counter value is calculated according to the formula:
+ *		calculated count = (timeout * clock) / prescalar + 1.
+ * The calculated count is divided by 0x1000 to obtain the field value
+ * to write to counter control register.
+ * Clears the contents of prescalar and counter reset value. Sets the
+ * prescalar to 4096 and the calculated count and access key
+ * to write to CCR Register.
+ * Sets the WDT (WDEN bit) and either the Reset signal(RSTEN bit)
+ * or Interrupt signal(IRQEN) with a specified cycles and the access
+ * key to write to ZMR Register.
+ */
+static int zynq_wdt_start(struct watchdog_device *wdd)
+{
+	unsigned int data = 0;
+	unsigned short count;
+	unsigned long clock_f = clk_get_rate(wdt->clk);
+
+	/*
+	 * 0x1000	- Counter Value Divide, to obtain the value of counter
+	 *		  reset to write to control register.
+	 */
+	count = (wdd->timeout * (clock_f / (wdt->prescalar))) / 0x1000 + 1;
+
+	/* Check for boundary conditions of counter value */
+	if (count > 0xFFF)
+		count = 0xFFF;
+
+	spin_lock(&wdt->io_lock);
+	zynq_wdt_writereg(ZYNQ_WDT_ZMR_ZKEY_VAL, ZYNQ_WDT_ZMR_OFFSET);
+
+	/* Shift the count value to correct bit positions */
+	count = (count << 2) & ZYNQ_WDT_CCR_CRV_MASK;
+
+	/* 0x00920000 - Counter register key value. */
+	data = (count | 0x00920000 | (wdt->ctrl_clksel));
+	zynq_wdt_writereg(data, ZYNQ_WDT_CCR_OFFSET);
+	data = ZYNQ_WDT_ZMR_WDEN_MASK | ZYNQ_WDT_ZMR_RSTLEN_16 |
+			ZYNQ_WDT_ZMR_ZKEY_VAL;
+
+	/* Reset on timeout if specified in device tree. */
+	if (wdt->rst) {
+		data |= ZYNQ_WDT_ZMR_RSTEN_MASK;
+		data &= ~ZYNQ_WDT_ZMR_IRQEN_MASK;
+	} else {
+		data &= ~ZYNQ_WDT_ZMR_RSTEN_MASK;
+		data |= ZYNQ_WDT_ZMR_IRQEN_MASK;
+	}
+	zynq_wdt_writereg(data, ZYNQ_WDT_ZMR_OFFSET);
+	spin_unlock(&wdt->io_lock);
+	zynq_wdt_writereg(0x00001999, ZYNQ_WDT_RESTART_OFFSET);
+	return 0;
+}
+
+/**
+ * zynq_wdt_settimeout -  Set a new timeout value for the watchdog device.
+ *
+ * @new_time: new timeout value that needs to be set.
+ * Returns 0 on success.
+ *
+ * Update the watchdog_device timeout with new value which is used when
+ * zynq_wdt_start is called.
+ */
+static int zynq_wdt_settimeout(struct watchdog_device *wdd,
+			       unsigned int new_time)
+{
+	wdd->timeout = new_time;
+	return zynq_wdt_start(wdd);
+}
+
+/**
+ * zynq_wdt_irq_handler - Notifies of watchdog timeout.
+ *
+ * @irq: interrupt number
+ * @dev_id: pointer to a platform device structure
+ * Returns IRQ_HANDLED
+ *
+ * The handler is invoked when the watchdog times out and a
+ * reset on timeout has not been enabled.
+ */
+static irqreturn_t zynq_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct platform_device *pdev = dev_id;
+	dev_info(&pdev->dev, "Watchdog timed out.\n");
+	return IRQ_HANDLED;
+}
+
+/* Watchdog Core Ops */
+static struct watchdog_ops zynq_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = zynq_wdt_start,
+	.stop = zynq_wdt_stop,
+	.ping = zynq_wdt_reload,
+	.set_timeout = zynq_wdt_settimeout,
+};
+
+/* Watchdog Core Device */
+static struct watchdog_device zynq_wdt_device = {
+	.info = &zynq_wdt_info,
+	.ops = &zynq_wdt_ops,
+	.timeout = ZYNQ_WDT_DEFAULT_TIMEOUT,
+	.min_timeout = ZYNQ_WDT_MIN_TIMEOUT,
+	.max_timeout = ZYNQ_WDT_MAX_TIMEOUT,
+};
+
+/**
+ * zynq_wdt_notify_sys -  Notifier for reboot or shutdown.
+ *
+ * @this: handle to notifier block.
+ * @code: turn off indicator.
+ * @unused: unused.
+ * Returns NOTIFY_DONE.
+ *
+ * This notifier is invoked whenever the system reboot or shutdown occur
+ * because we need to disable the WDT before system goes down as WDT might
+ * reset on the next boot.
+ */
+static int zynq_wdt_notify_sys(struct notifier_block *this, unsigned long code,
+			      void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		/* Stop the watchdog */
+		zynq_wdt_stop(&zynq_wdt_device);
+	return NOTIFY_DONE;
+}
+
+/* Notifier Structure */
+static struct notifier_block zynq_wdt_notifier = {
+	.notifier_call = zynq_wdt_notify_sys,
+};
+
+/************************Platform Operations*****************************/
+/**
+ * zynq_wdt_probe -  Probe call for the device.
+ *
+ * @pdev: handle to the platform device structure.
+ * Returns 0 on success, negative error otherwise.
+ *
+ * It does all the memory allocation and registration for the device.
+ */
+static int zynq_wdt_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	int ret;
+	int irq;
+	unsigned long clock_f;
+
+	/* Check whether WDT is in use, just for safety */
+	if (wdt) {
+		dev_err(&pdev->dev,
+			"Device Busy, only 1 zynq_wdt instance supported.\n");
+		return -EBUSY;
+	}
+
+	/* Allocate an instance of the zynq_wdt structure */
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	wdt->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(wdt->regs))
+		return PTR_ERR(wdt->regs);
+
+	/* Register the reboot notifier */
+	ret = register_reboot_notifier(&zynq_wdt_notifier);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "cannot register reboot notifier err=%d)\n",
+			ret);
+		return ret;
+	}
+
+	/* Register the interrupt */
+	of_property_read_u32(pdev->dev.of_node, "reset", &wdt->rst);
+	irq = platform_get_irq(pdev, 0);
+	if (!wdt->rst && irq >= 0) {
+		ret = devm_request_irq(&pdev->dev, irq, zynq_wdt_irq_handler, 0,
+				       pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				   "cannot register interrupt handler err=%d\n",
+				   ret);
+			goto err_notifier;
+		}
+	}
+
+	/* Initialize the members of zynq_wdt structure */
+	zynq_wdt_device.parent = &pdev->dev;
+	of_get_property(pdev->dev.of_node, "timeout", &zynq_wdt_device.timeout);
+	if (wdt_timeout < ZYNQ_WDT_MAX_TIMEOUT &&
+			wdt_timeout > ZYNQ_WDT_MIN_TIMEOUT)
+		zynq_wdt_device.timeout = wdt_timeout;
+	else
+		dev_info(&pdev->dev,
+			    "timeout limited to 1 - %d sec, using default=%d\n",
+			    ZYNQ_WDT_MAX_TIMEOUT, ZYNQ_WDT_DEFAULT_TIMEOUT);
+
+	watchdog_set_nowayout(&zynq_wdt_device, nowayout);
+	watchdog_set_drvdata(&zynq_wdt_device, &wdt);
+
+	wdt->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(wdt->clk)) {
+		dev_err(&pdev->dev, "input clock not found\n");
+		ret = PTR_ERR(wdt->clk);
+		goto err_notifier;
+	}
+
+	ret = clk_prepare_enable(wdt->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable clock\n");
+		goto err_notifier;
+	}
+
+	clock_f = clk_get_rate(wdt->clk);
+	if (clock_f <= 10000000) {/* For PEEP */
+		wdt->prescalar = 64;
+		wdt->ctrl_clksel = 1;
+	} else if (clock_f <= 75000000) {
+		wdt->prescalar = 256;
+		wdt->ctrl_clksel = 2;
+	} else { /* For Zynq */
+		wdt->prescalar = 4096;
+		wdt->ctrl_clksel = 3;
+	}
+
+	spin_lock_init(&wdt->io_lock);
+
+	/* Register the WDT */
+	ret = watchdog_register_device(&zynq_wdt_device);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register wdt device\n");
+		goto err_clk_disable;
+	}
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
+		 wdt->regs, zynq_wdt_device.timeout,
+		 nowayout ? ", nowayout" : "");
+
+	return 0;
+
+err_clk_disable:
+	clk_disable_unprepare(wdt->clk);
+err_notifier:
+	unregister_reboot_notifier(&zynq_wdt_notifier);
+	return ret;
+}
+
+/**
+ * zynq_wdt_remove -  Probe call for the device.
+ *
+ * @pdev: handle to the platform device structure.
+ * Returns 0 on success, otherwise negative error.
+ *
+ * Unregister the device after releasing the resources.
+ * Stop is allowed only when nowayout is disabled.
+ */
+static int __exit zynq_wdt_remove(struct platform_device *pdev)
+{
+	int res = 0;
+	int irq;
+
+	if (wdt && !nowayout) {
+		zynq_wdt_stop(&zynq_wdt_device);
+		watchdog_unregister_device(&zynq_wdt_device);
+		unregister_reboot_notifier(&zynq_wdt_notifier);
+		irq = platform_get_irq(pdev, 0);
+		clk_disable_unprepare(wdt->clk);
+	} else {
+		dev_err(&pdev->dev, "Cannot stop watchdog, still ticking\n");
+		return -ENOTSUPP;
+	}
+	return res;
+}
+
+/**
+ * zynq_wdt_shutdown -  Stop the device.
+ *
+ * @pdev: handle to the platform structure.
+ *
+ */
+static void zynq_wdt_shutdown(struct platform_device *pdev)
+{
+	/* Stop the device */
+	zynq_wdt_stop(&zynq_wdt_device);
+	clk_disable_unprepare(wdt->clk);
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * zynq_wdt_suspend -  Stop the device.
+ *
+ * @dev: handle to the device structure.
+ * Returns 0 always.
+ */
+static int zynq_wdt_suspend(struct device *dev)
+{
+	/* Stop the device */
+	zynq_wdt_stop(&zynq_wdt_device);
+	clk_disable(wdt->clk);
+	return 0;
+}
+
+/**
+ * zynq_wdt_resume -  Resume the device.
+ *
+ * @dev: handle to the device structure.
+ * Returns 0 on success, errno otherwise.
+ */
+static int zynq_wdt_resume(struct device *dev)
+{
+	int ret;
+
+	ret = clk_enable(wdt->clk);
+	if (ret) {
+		dev_err(dev, "unable to enable clock\n");
+		return ret;
+	}
+	/* Start the device */
+	zynq_wdt_start(&zynq_wdt_device);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(zynq_wdt_pm_ops, zynq_wdt_suspend, zynq_wdt_resume);
+
+static struct of_device_id zynq_wdt_of_match[] = {
+	{ .compatible = "xlnx,ps7-wdt-1.00.a", },
+	{ /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, zynq_wdt_of_match);
+
+/* Driver Structure */
+static struct platform_driver zynq_wdt_driver = {
+	.probe		= zynq_wdt_probe,
+	.remove		= zynq_wdt_remove,
+	.shutdown	= zynq_wdt_shutdown,
+	.driver		= {
+		.name	= "zynq_wdt",
+		.owner	= THIS_MODULE,
+		.of_match_table = zynq_wdt_of_match,
+		.pm	= &zynq_wdt_pm_ops,
+	},
+};
+
+/**
+ * zynq_wdt_init -  Register the WDT.
+ *
+ * Returns 0 on success, otherwise negative error.
+ *
+ * If using noway out, the use count will be incremented.
+ * This will prevent unloading the module. An attempt to
+ * unload the module will result in a warning from the kernel.
+ */
+static int __init zynq_wdt_init(void)
+{
+	int res = platform_driver_register(&zynq_wdt_driver);
+	if (!res && nowayout)
+		try_module_get(THIS_MODULE);
+	return res;
+}
+
+/**
+ * zynq_wdt_exit -  Unregister the WDT.
+ */
+static void __exit zynq_wdt_exit(void)
+{
+	platform_driver_unregister(&zynq_wdt_driver);
+}
+
+module_init(zynq_wdt_init);
+module_exit(zynq_wdt_exit);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Watchdog driver for PS WDT");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform: zynq_wdt");
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/Kconfig	2014-07-20 22:06:38.743266345 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+config XILINX_EDK
+	bool
+	depends on XILINX_VIRTEX || MICROBLAZE
+	default y
+
+config XILINX_LLDMA_USE_DCR
+	bool
+	depends on NEED_XILINX_LLDMA
+	default XILINX_VIRTEX_5_FXT
+
+
+#
+# Xilinx devices and common device driver infrastructure
+#
+
+config XILINX_DRIVERS
+	bool
+	depends on PPC32 || MICROBLAZE
+	default y
+	---help---
+	  This option is used to enable all of the Xilinx drivers on
+	  supported architectures.  This is often useful if you have a
+	  Xilinx FPGA in a system, either using embedded processors
+	  internal to the FPGA or external processors.
+
+config NEED_XILINX_DMAV3
+	bool
+
+config NEED_XILINX_LLDMA
+	bool
+
+config NEED_XILINX_IPIF
+	bool
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/Makefile	2014-07-20 22:06:38.749266246 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+# The Xilinx OS common code
+
+obj-$(CONFIG_XILINX_EDK) += xbasic_types.o xilinx_syms.o					\
+				xversion.o	xpacket_fifo_v2_00_a.o xpacket_fifo_l_v2_00_a.o	\
+				xdma_channel.o xdma_channel_sg.o xio.o xil_assert.o
+
+obj-$(CONFIG_NEED_XILINX_DMAV3) += \
+			    xdmav3.o xdmav3_intr.o xdmav3_sg.o			\
+			    xdmav3_selftest.o xdmav3_simple.o
+
+obj-$(CONFIG_NEED_XILINX_LLDMA) += \
+			    xlldma_bdring.o xlldma.o				\
+			    xllfifo.o xstreamer.o
+
+obj-$(CONFIG_XILINX_LLDMA_USE_DCR) += \
+					xio_dcr.o
+
+obj-$(CONFIG_NEED_XILINX_IPIF) += \
+			    xipif_v1_23_b.o
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbasic_types.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbasic_types.c	2014-07-20 22:06:38.756266131 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2003 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.c
+*
+* This file contains basic functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+unsigned int XAssertStatus;
+
+/**
+ * This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+u32 XWaitInAssert = TRUE;
+
+/* The callback function to be invoked when an assert is taken */
+static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Implements assert. Currently, it calls a user-defined callback function
+* if one has been set.  Then, it potentially enters an infinite loop depending
+* on the value of the XWaitInAssert variable.
+*
+* @param    File is the name of the filename of the source
+* @param    Line is the linenumber within File
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+void XAssert(char *File, int Line)
+{
+	/* if the callback has been set then invoke it */
+	if (XAssertCallbackRoutine != NULL) {
+		(*XAssertCallbackRoutine) (File, Line);
+	}
+
+	/* if specified, wait indefinitely such that the assert will show up
+	 * in testing
+	 */
+	while (XWaitInAssert) {
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets up a callback function to be invoked when an assert occurs. If there
+* was already a callback installed, then it is replaced.
+*
+* @param    Routine is the callback to be invoked when an assert is taken
+*
+* @return   None.
+*
+* @note     This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void XAssertSetCallback(XAssertCallback Routine)
+{
+	XAssertCallbackRoutine = Routine;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Null handler function. This follows the XInterruptHandler signature for
+* interrupt handlers. It can be used to assign a null handler (a stub) to an
+* interrupt controller vector table.
+*
+* @param    NullParameter is an arbitrary void pointer and not used.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+void XNullHandler(void *NullParameter)
+{
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbasic_types.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbasic_types.h	2014-07-20 22:06:38.765265983 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xbasic_types.h,v 1.1 2006/12/13 14:21:22 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2004 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.h
+*
+* This file contains basic types for Xilinx software IP.  These types do not
+* follow the standard naming convention with respect to using the component
+* name in front of each name because they are considered to be primitives.
+*
+* @note
+*
+* This file contains items which are architecture dependent.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rmm  12/14/01 First release
+*       rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
+*                     compiler warnings
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* 1.00a rpm  07/21/04 Added XExceptionHandler typedef for processor exceptions
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XBASIC_TYPES_H		/* prevent circular inclusions */
+#define XBASIC_TYPES_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+#include <linux/types.h>
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE !(TRUE)
+#endif
+
+#define XCOMPONENT_IS_READY     0x11111111  /**< component has been initialized */
+#define XCOMPONENT_IS_STARTED   0x22222222  /**< component has been started */
+
+/* the following constants and declarations are for unit test purposes and are
+ * designed to be used in test applications.
+ */
+#define XTEST_PASSED    0
+#define XTEST_FAILED    1
+
+#define XASSERT_NONE     0
+#define XASSERT_OCCURRED 1
+
+extern unsigned int XAssertStatus;
+extern void XAssert(char *, int);
+
+/**************************** Type Definitions *******************************/
+/**
+ * This data type defines an interrupt handler for a device.
+ * The argument points to the instance of the component
+ */
+typedef void (*XInterruptHandler) (void *InstancePtr);
+
+/**
+ * This data type defines an exception handler for a processor.
+ * The argument points to the instance of the component
+ */
+typedef void (*XExceptionHandler) (void *InstancePtr);
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+#ifndef NDEBUG
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do not return anything
+* (void). This in conjunction with the XWaitInAssert boolean can be used to
+* accomodate tests so that asserts which fail allow execution to continue.
+*
+* @param    expression is the expression to evaluate. If it evaluates to
+*           false, the assert occurs.
+*
+* @return   Returns void unless the XWaitInAssert variable is true, in which
+*           case no return is made and an infinite loop is entered.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XASSERT_VOID(expression)                   \
+{                                                  \
+    if (expression)                                \
+    {                                              \
+        XAssertStatus = XASSERT_NONE;              \
+    }                                              \
+    else                                           \
+    {                                              \
+        XAssert(__FILE__, __LINE__);               \
+                XAssertStatus = XASSERT_OCCURRED;  \
+        return;                                    \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do return a value. This in
+* conjunction with the XWaitInAssert boolean can be used to accomodate tests so
+* that asserts which fail allow execution to continue.
+*
+* @param    expression is the expression to evaluate. If it evaluates to false,
+*           the assert occurs.
+*
+* @return   Returns 0 unless the XWaitInAssert variable is true, in which case
+*           no return is made and an infinite loop is entered.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID(expression)                \
+{                                                  \
+    if (expression)                                \
+    {                                              \
+        XAssertStatus = XASSERT_NONE;              \
+    }                                              \
+    else                                           \
+    {                                              \
+        XAssert(__FILE__, __LINE__);               \
+                XAssertStatus = XASSERT_OCCURRED;  \
+        return 0;                                  \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do not
+* return anything (void). Use for instances where an assert should always
+* occur.
+*
+* @return Returns void unless the XWaitInAssert variable is true, in which case
+*         no return is made and an infinite loop is entered.
+*
+* @note   None.
+*
+******************************************************************************/
+#define XASSERT_VOID_ALWAYS()                      \
+{                                                  \
+   XAssert(__FILE__, __LINE__);                    \
+           XAssertStatus = XASSERT_OCCURRED;       \
+   return;                                         \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do return
+* a value. Use for instances where an assert should always occur.
+*
+* @return Returns void unless the XWaitInAssert variable is true, in which case
+*         no return is made and an infinite loop is entered.
+*
+* @note   None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID_ALWAYS()                   \
+{                                                  \
+   XAssert(__FILE__, __LINE__);                    \
+           XAssertStatus = XASSERT_OCCURRED;       \
+   return 0;                                       \
+}
+
+
+#else
+
+#define XASSERT_VOID(expression)
+#define XASSERT_VOID_ALWAYS()
+#define XASSERT_NONVOID(expression)
+#define XASSERT_NONVOID_ALWAYS()
+#endif
+
+/************************** Function Prototypes ******************************/
+
+void XAssertSetCallback(XAssertCallback Routine);
+void XNullHandler(void *NullParameter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbuf_descriptor.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xbuf_descriptor.h	2014-07-20 22:06:38.790265570 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xbuf_descriptor.h,v 1.1 2006/12/13 14:21:30 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2001-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbuf_descriptor.h
+*
+* <b>Description</b>
+*
+* This file contains the interface for the XBufDescriptor component.
+* The XBufDescriptor component is a passive component that only maps over
+* a buffer descriptor data structure shared by the scatter gather DMA hardware
+* and software. The component's primary purpose is to provide encapsulation of
+* the buffer descriptor processing.  See the source file xbuf_descriptor.c for
+* details.
+*
+* @note
+*
+* Most of the functions of this component are implemented as macros in order
+* to optimize the processing.  The names are not all uppercase such that they
+* can be switched between macros and functions easily.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a xd   10/27/04 Doxygenated for inclusion in API documentation
+* 1.00b ecm  10/31/05 Updated for the check sum offload changes.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XBUF_DESCRIPTOR_H	/* prevent circular inclusions */
+#define XBUF_DESCRIPTOR_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xdma_channel_i.h"
+
+/************************** Constant Definitions *****************************/
+
+/** @name Buffer Descriptor fields
+ *
+ * @{
+ */
+/** This constant allows access to fields of a buffer descriptor
+ * and is necessary at this level of visibility to allow macros to access
+ * and modify the fields of a buffer descriptor.  It is not expected that the
+ * user of a buffer descriptor would need to use this constant.
+ */
+#define XBD_DEVICE_STATUS_OFFSET    0
+#define XBD_CONTROL_OFFSET          1
+#define XBD_SOURCE_OFFSET           2
+#define XBD_DESTINATION_OFFSET      3
+#define XBD_LENGTH_OFFSET           4
+#define XBD_STATUS_OFFSET           5
+#define XBD_NEXT_PTR_OFFSET         6
+#define XBD_ID_OFFSET               7
+#define XBD_FLAGS_OFFSET            8
+#define XBD_RQSTED_LENGTH_OFFSET    9
+#define XBD_SIZE_IN_WORDS           10
+/* @} */
+
+/**
+ * The following constants define the bits of the flags field of a buffer
+ * descriptor
+ */
+#define XBD_FLAGS_LOCKED_MASK       1UL
+
+/**************************** Type Definitions *******************************/
+
+typedef u32 XBufDescriptor[XBD_SIZE_IN_WORDS];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/**
+ * each of the following macros are named the same as functions rather than all
+ * upper case in order to allow either the macros or the functions to be
+ * used, see the source file xbuf_descriptor.c for documentation
+ */
+
+
+/*****************************************************************************/
+/**
+*
+* This function initializes a buffer descriptor component by zeroing all of the
+* fields of the buffer descriptor.  This function should be called prior to
+* using a buffer descriptor.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_Initialize(InstancePtr)                  \
+{                                                               \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = 0);       \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = 0);   \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = 0); \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = 0);      \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = 0);            \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = 0);         \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = 0); \
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the control field of a buffer descriptor component.  The
+* DMA channel hardware transfers the control field from the buffer descriptor
+* into the DMA control register when a buffer descriptor is processed.  It
+* controls the details of the DMA transfer.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The control field contents of the buffer descriptor. One or more of the
+* following values may be contained the field.  Each of the values are
+* unique bit masks.
+*                               <br><br>
+* - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+*                               <br><br>
+* - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+*                               <br><br>
+* - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*                               <br><br>
+* - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+*                               <br><br>
+* - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+*                               <br><br>
+* - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+*                               <br><br>
+* - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetControl(InstancePtr)   \
+    (u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the control field of a buffer descriptor component.  The
+* DMA channel hardware transfers the control field from the buffer descriptor
+* into the DMA control register when a buffer descriptor is processed.  It
+* controls the details of the DMA transfer such as
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Control contains the value to be written to the control field of the buffer
+* descriptor. One or more of the following values may be contained the field.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+* - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+* - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+* - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+* - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+* - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+* - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+* - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetControl(InstancePtr, Control)  \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = (u32)Control)
+
+/*****************************************************************************/
+/**
+*
+* This function determines if this buffer descriptor is marked as being the
+* last in the control field.  A packet may be broken up across multiple
+* buffer descriptors such that the last buffer descriptor is the end of the
+* packet.  The DMA channel hardware copies the control field from the buffer
+* descriptor to the control register of the DMA channel when the buffer
+* descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* TRUE if the buffer descriptor is marked as last in the control field,
+* otherwise, FALSE.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_IsLastControl(InstancePtr) \
+    (u32)((*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) & \
+               XDC_CONTROL_LAST_BD_MASK) == XDC_CONTROL_LAST_BD_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function marks the buffer descriptor as being last in the control
+* field of the buffer descriptor.  A packet may be broken up across multiple
+* buffer descriptors such that the last buffer descriptor is the end of the
+* packet.  The DMA channel hardware copies the control field from the buffer
+* descriptor to the control register of the DMA channel when the buffer
+* descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetLast(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) |= XDC_CONTROL_LAST_BD_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the source address field of the buffer descriptor.
+* The source address indicates the address of memory which is the
+* source of a DMA scatter gather operation.  The DMA channel hardware
+* copies the source address from the buffer descriptor to the source
+* address register of the DMA channel when the buffer descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The source address field of the buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetSrcAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET)))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the source address field of the buffer descriptor.
+* The source address indicates the address of memory which is the
+* source of a DMA scatter gather operation.  The DMA channel hardware
+* copies the source address from the buffer descriptor to the source
+* address register of the DMA channel when the buffer descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* SourceAddress contains the source address field for the buffer descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetSrcAddress(InstancePtr, Source) \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = (u32)Source)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the destination address field of the buffer descriptor.
+* The destination address indicates the address of memory which is the
+* destination of a DMA scatter gather operation.  The DMA channel hardware
+* copies the destination address from the buffer descriptor to the destination
+* address register of the DMA channel when the buffer descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The destination address field of the buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetDestAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the destination address field of the buffer descriptor.
+* The destination address indicates the address of memory which is the
+* destination of a DMA scatter gather operation.  The DMA channel hardware
+* copies the destination address from the buffer descriptor to the destination
+* address register of the DMA channel when the buffer descriptor is processed.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* DestinationAddress contains the destination address field for the buffer
+* descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetDestAddress(InstancePtr, Destination) \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = (u32)Destination)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the length of the data transfer if the buffer descriptor
+* has been processed by the DMA channel hardware.  If the buffer descriptor
+* has not been processed, the return value will be zero indicating that no data
+* has been transferred yet.  This function uses both the length and requested
+* length fields of the buffer descriptor to determine the number of bytes
+* transferred by the DMA operation. The length field of the buffer descriptor
+* contains the number of bytes remaining from the requested length.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The number of bytes which have been transferred by a DMA operation on the
+* buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetLength(InstancePtr)                           \
+    (u32)(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) -    \
+              *((u32 *)InstancePtr + XBD_LENGTH_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the length and the requested length fields of the buffer
+* descriptor.  The length field indicates the number of bytes to transfer for
+* the DMA operation and the requested length is written with the same value.
+* The requested length is not modified by the DMA hardware while the length
+* field is modified by the hardware to indicate the number of bytes remaining
+* in the transfer after the transfer is complete.  The requested length allows
+* the software to calculate the actual number of bytes transferred for the DMA
+* operation.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Length contains the length to put in the length and requested length fields
+* of the buffer descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetLength(InstancePtr, Length)                       \
+{                                                                           \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = (u32)(Length));    \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the status field of a buffer descriptor component. The
+* status field is written to the buffer descriptor by the DMA channel hardware
+* after processing of a buffer descriptor is complete.  The status field
+* indicates the status of the DMA operation.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The status field contents of the buffer descriptor. One or more of the
+* following values may be contained the field. Each of the values are
+* unique bit masks.
+*                               <br><br>
+* - XDC_DMASR_BUSY_MASK         The DMA channel is busy
+*                               <br><br>
+* - XDC_DMASR_BUS_ERROR_MASK    A bus error occurred
+*                               <br><br>
+* - XDC_DMASR_BUS_TIMEOUT_MASK  A bus timeout occurred
+*                               <br><br>
+* - XDC_DMASR_LAST_BD_MASK      The last buffer descriptor of a packet
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetStatus(InstancePtr)    \
+    (u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the status field of a buffer descriptor component.  The
+* status field is written to the buffer descriptor by the DMA channel hardware
+* after processing of a buffer descriptor is complete.  This function would
+* typically be used during debugging of buffer descriptor processing.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Status contains the status field for the buffer descriptor.
+* The status register contents of the DMA channel. One or more of the
+* following values may be contained the register. Each of the values are
+* unique bit masks.
+* - XDC_DMASR_BUSY_MASK         The DMA channel is busy
+* - XDC_DMASR_BUS_ERROR_MASK    A bus error occurred
+* - XDC_DMASR_BUS_TIMEOUT_MASK  A bus timeout occurred
+* - XDC_DMASR_LAST_BD_MASK      The last buffer descriptor of a packet
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetStatus(InstancePtr, Status)    \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = (u32)Status)
+
+/*****************************************************************************/
+/**
+*
+* This function determines if this buffer descriptor is marked as being the
+* last in the status field.  A packet may be broken up across multiple
+* buffer descriptors such that the last buffer descriptor is the end of the
+* packet.  The DMA channel hardware copies the status register contents to
+* the buffer descriptor of the DMA channel after processing of the buffer
+* descriptor is complete.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* TRUE if the buffer descriptor is marked as last in the status field,
+* otherwise, FALSE.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_IsLastStatus(InstancePtr) \
+    (u32)((*((u32 *)InstancePtr + XBD_STATUS_OFFSET) & \
+               XDC_STATUS_LAST_BD_MASK) == XDC_STATUS_LAST_BD_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the device status field of the buffer descriptor.  The
+* device status is device specific such that the definition of the contents
+* of this field are not defined in this function. The device is defined as the
+* device which is using the DMA channel, such as an ethernet controller.  The
+* DMA channel hardware copies the contents of the device status register into
+* the buffer descriptor when processing of the buffer descriptor is complete.
+* This value is typically used by the device driver for the device to determine
+* the status of the DMA operation with respect to the device.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The device status field of the buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetDeviceStatus(InstancePtr) \
+    ((u32)(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the device status field of the buffer descriptor.  The
+* device status is device specific such that the definition of the contents
+* of this field are not defined in this function. The device is defined as the
+* device which is using the DMA channel, such as an ethernet controller.  This
+* function is typically only used for debugging/testing.
+*
+* The DMA channel hardware copies the contents of the device status register
+* into the buffer descriptor when processing of the buffer descriptor is
+* complete.  This value is typically used by the device driver for the device
+* to determine the status of the DMA operation with respect to the device.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Status contains the device status field for the buffer descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetDeviceStatus(InstancePtr, Status) \
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET));     \
+    Register &= XDC_DMASR_RX_CS_RAW_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)) =               \
+              Register | ((u32) (Status));               \
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the next pointer field of the buffer descriptor.  This
+* field is used to link the buffer descriptors together such that multiple DMA
+* operations can be automated for scatter gather.  It also allows a single
+* packet to be broken across multiple buffer descriptors.  The DMA channel
+* hardware traverses the list of buffer descriptors using the next pointer
+* of each buffer descriptor.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The next pointer field of the buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetNextPtr(InstancePtr) \
+    (XBufDescriptor *)(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the next pointer field of the buffer descriptor.  This
+* field is used to link the buffer descriptors together such that many DMA
+* operations can be automated for scatter gather.  It also allows a single
+* packet to be broken across multiple buffer descriptors.  The DMA channel
+* hardware traverses the list of buffer descriptors using the next pointer
+* of each buffer descriptor.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* NextPtr contains the next pointer field for the buffer descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetNextPtr(InstancePtr, NextPtr) \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = (u32)NextPtr)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the ID field of the buffer descriptor.  The ID field is
+* provided to allow a device driver to correlate the buffer descriptor to other
+* data structures which may be operating system specific, such as a pointer to
+* a higher level memory block. The ID field is not used by the DMA channel
+* hardware and is application specific.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The ID field of the buffer descriptor.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetId(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_ID_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the ID field of the buffer descriptor.  The ID field is
+* provided to allow a device driver to correlate the buffer descriptor to other
+* data structures which may be operating system specific, such as a pointer to
+* a higher level memory block. The ID field is not used by the DMA channel
+* hardware and is application specific.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Id contains the ID field for the buffer descriptor.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetId(InstancePtr, Id) \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = (u32)Id)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the flags field of the buffer descriptor.  The flags
+* field is not used by the DMA channel hardware and is used for software
+* processing of buffer descriptors.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* The flags field of the buffer descriptor.  The field may contain one or more
+* of the following values which are bit masks.
+*                               <br><br>
+* - XBD_FLAGS_LOCKED_MASK       Indicates the buffer descriptor is locked
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetFlags(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the flags field of the buffer descriptor.  The flags
+* field is not used by the DMA channel hardware and is used for software
+* processing of buffer descriptors.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @param
+*
+* Flags contains the flags field for the buffer descriptor.  The field may
+* contain one or more of the following values which are bit masks.
+* - XBD_FLAGS_LOCKED_MASK       Indicates the buffer descriptor is locked
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetFlags(InstancePtr, Flags) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = (u32)Flags)
+
+/*****************************************************************************/
+/**
+*
+* This function locks the buffer descriptor. A lock is specific to the
+* scatter gather processing and prevents a buffer descriptor from being
+* overwritten in the scatter gather list.  This field is not used by the DMA
+* channel hardware such that the hardware could still write to the buffer
+* descriptor.  Locking a buffer descriptor is application specific and not
+* necessary to allow the DMA channel to use the buffer descriptor, but is
+* provided for flexibility in designing device drivers.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_Lock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) |= XBD_FLAGS_LOCKED_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function unlocks the buffer descriptor.  A lock is specific to the
+* scatter gather processing and prevents a buffer descriptor from being
+* overwritten in the scatter gather list.  This field is not used by the DMA
+* channel hardware such that the hardware could still write to the buffer
+* descriptor.  Locking a buffer descriptor is application specific and not
+* necessary to allow the DMA channel to use the buffer descriptor, but is
+* provided for flex ability in designing device drivers.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_Unlock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) &= ~XBD_FLAGS_LOCKED_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function determines if the buffer descriptor is locked.  The lock
+* is not used by the DMA channel hardware and is used for software processing
+* of buffer descriptors.
+*
+* @param
+*
+* InstancePtr points to the buffer descriptor to operate on.
+*
+* @return
+*
+* TRUE if the buffer descriptor is locked, otherwise FALSE.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_IsLocked(InstancePtr) \
+    (u32) ((*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) & \
+        XBD_FLAGS_LOCKED_MASK) == XBD_FLAGS_LOCKED_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the Initial value for the CS offload function.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The initial value that will be used for checksum offload operation as DMA
+* moves the data.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetCSInit(InstancePtr)\
+(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) &= XDC_DMACR_TX_CS_INIT_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function Sets the Initial value for the CS offload function.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* None
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetCSInit(InstancePtr, InitialValue)            \
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET));     \
+    Register &= ~XDC_DMACR_TX_CS_INIT_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET)) =               \
+              Register | ((u32) (InitialValue));               \
+}
+/*****************************************************************************/
+/**
+*
+* This function gets the byte position where the CS offload function
+* inserts the calculated checksum.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The insert byte location value that will be used to place the results of
+* the checksum offload.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetCSInsertLoc(InstancePtr)                     \
+(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) &= XDC_DAREG_CS_INSERT_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function sets the byte position where the CS offload function
+* inserts the calculated checksum.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* None
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetCSInsertLoc(InstancePtr, InsertLocation)            \
+{                                                                   \
+    u32 Register;                                               \
+    Register = (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET));      \
+    Register &= ~XDC_DAREG_CS_INSERT_MASK;                         \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) =                \
+              Register | ((u32) (InsertLocation));             \
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the byte position where the CS offload function
+* begins the calculation of the checksum.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The insert byte location value that will be used to place the results of
+* the checksum offload.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetCSBegin(InstancePtr)                      \
+(u16)((*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) >> 16)
+/*****************************************************************************/
+/**
+*
+* This function sets the byte position where the CS offload function
+* begins the calculation of the checksum.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* None
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_SetCSBegin(InstancePtr, BeginLocation)               \
+{                                                                           \
+    u32 Register;                                                       \
+    Register = (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET));             \
+    Register &= ~XDC_DAREG_CS_BEGIN_MASK;                                 \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)) =                       \
+              Register | (((u32) (BeginLocation)) << 16);               \
+}
+/*****************************************************************************/
+/**
+*
+* This function gets the resulting checksum from the rx channel.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The raw checksum calculation from the receive operation. It needs to
+* be adjusted to remove the header and packet FCS to be correct.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XBufDescriptor_GetCSRaw(InstancePtr)                     \
+(u16)((*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)) >> 16)
+
+/************************** Function Prototypes ******************************/
+
+/* The following prototypes are provided to allow each of the functions to
+ * be implemented as a function rather than a macro, and to provide the
+ * syntax to allow users to understand how to call the macros, they are
+ * commented out to prevent linker errors
+ *
+
+u32 XBufDescriptor_Initialize(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetControl(XBufDescriptor* InstancePtr, u32 Control);
+
+u32 XBufDescriptor_IsLastControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLast(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetLength(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLength(XBufDescriptor* InstancePtr, u32 Length);
+
+u32 XBufDescriptor_GetStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetStatus(XBufDescriptor* InstancePtr, u32 Status);
+u32 XBufDescriptor_IsLastStatus(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetDeviceStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDeviceStatus(XBufDescriptor* InstancePtr,
+                                    u32 Status);
+
+u32 XBufDescriptor_GetSrcAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetSrcAddress(XBufDescriptor* InstancePtr,
+                                  u32 SourceAddress);
+
+u32 XBufDescriptor_GetDestAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDestAddress(XBufDescriptor* InstancePtr,
+                                   u32 DestinationAddress);
+
+XBufDescriptor* XBufDescriptor_GetNextPtr(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetNextPtr(XBufDescriptor* InstancePtr,
+                               XBufDescriptor* NextPtr);
+
+u32 XBufDescriptor_GetId(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetId(XBufDescriptor* InstancePtr, u32 Id);
+
+u32 XBufDescriptor_GetFlags(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetFlags(XBufDescriptor* InstancePtr, u32 Flags);
+
+void XBufDescriptor_Lock(XBufDescriptor* InstancePtr);
+void XBufDescriptor_Unlock(XBufDescriptor* InstancePtr);
+u32 XBufDescriptor_IsLocked(XBufDescriptor* InstancePtr);
+
+u16 XBufDescriptor_GetCSInit(XBufDescriptor* InstancePtr)
+void XBufDescriptor_SetCSInit(XBufDescriptor* InstancePtr, u16 InitialValue)
+
+u16 XBufDescriptor_GetCSInsertLoc(XBufDescriptor* InstancePtr)
+void XBufDescriptor_SetCSInsertLoc(XBufDescriptor* InstancePtr, u16 InsertLocation)
+
+u16 XBufDescriptor_GetCSBegin(XBufDescriptor* InstancePtr)
+void XBufDescriptor_SetCSBegin(XBufDescriptor* InstancePtr, u16 BeginLocation)
+
+u16 XBufDescriptor_GetCSRaw(XBufDescriptor* InstancePtr)
+
+void XBufDescriptor_Copy(XBufDescriptor* InstancePtr,
+                         XBufDescriptor* DestinationPtr);
+
+*/
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdebug.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdebug.h	2014-07-20 22:06:38.806265306 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#ifndef XDEBUG
+#define XDEBUG
+
+#undef DEBUG
+
+#if defined(DEBUG) && !defined(NDEBUG)
+
+#ifndef XDEBUG_WARNING
+#define XDEBUG_WARNING
+#warning DEBUG is enabled
+#endif
+
+int printf(const char *format, ...);
+
+#define XDBG_DEBUG_ERROR             0x00000001    /* error condition messages */
+#define XDBG_DEBUG_GENERAL           0x00000002    /* general debug  messages */
+#define XDBG_DEBUG_ALL               0xFFFFFFFF    /* all debugging data */
+
+#define XDBG_DEBUG_FIFO_REG          0x00000100    /* display register reads/writes */
+#define XDBG_DEBUG_FIFO_RX           0x00000101    /* receive debug messages */
+#define XDBG_DEBUG_FIFO_TX           0x00000102    /* transmit debug messages */
+#define XDBG_DEBUG_FIFO_ALL          0x0000010F    /* all fifo debug messages */
+
+#define XDBG_DEBUG_TEMAC_REG         0x00000400    /* display register reads/writes */
+#define XDBG_DEBUG_TEMAC_RX          0x00000401    /* receive debug messages */
+#define XDBG_DEBUG_TEMAC_TX          0x00000402    /* transmit debug messages */
+#define XDBG_DEBUG_TEMAC_ALL         0x0000040F    /* all temac  debug messages */
+
+#define XDBG_DEBUG_TEMAC_ADPT_RX     0x00000800    /* receive debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_TX     0x00000801    /* transmit debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_IOCTL  0x00000802    /* ioctl debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_MISC   0x00000803    /* debug msg for other routines */
+#define XDBG_DEBUG_TEMAC_ADPT_ALL    0x0000080F    /* all temac adapter debug messages */
+
+#define xdbg_current_types (XDBG_DEBUG_ERROR | XDBG_DEBUG_GENERAL | XDBG_DEBUG_FIFO_REG | XDBG_DEBUG_TEMAC_REG)
+
+#define xdbg_stmnt(x)  x
+#define xdbg_printf(type, ...) (if ((type) & xdbg_current_types) printf (__VA_ARGS__) : 0)
+
+#else
+#define xdbg_stmnt(x)
+#define xdbg_printf(...)
+#endif
+
+
+
+
+#endif /* XDEBUG */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmabdv3.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmabdv3.h	2014-07-20 22:06:38.817265125 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xdmabdv3.h
+ *
+ * This header provides operations to manage buffer descriptors in support
+ * of simple and scatter-gather DMA (see xdmav3.h).
+ *
+ * The API exported by this header defines abstracted macros that allow the
+ * user to read/write specific BD fields.
+ *
+ * <b>Buffer Descriptors</b>
+ *
+ * A buffer descriptor (BD) defines a DMA transaction (see "Transaction"
+ * section in xdmav3.h). The macros defined by this header file allow access
+ * to most fields within a BD to tailor a DMA transaction according to user
+ * and HW requirements.  See the HW IP DMA spec for more information on BD
+ * fields and how they affect transfers.
+ *
+ * The XDmaBdV3 structure defines a BD. The organization of this structure is
+ * driven mainly by the hardware for use in scatter-gather DMA transfers.
+ *
+ * <b>Accessor Macros</b>
+ *
+ * Most of the BD attributes can be accessed through macro functions defined
+ * here in this API. Words such as XDMAV3_BD_USR0_OFFSET (see xdmav3_l.h)
+ * should be accessed using XDmaV3_mReadBd() and XDmaV3_mWriteBd() as defined in
+ * xdmav3_l.h. The USR words are implementation dependent. For example, they may
+ * implement checksum offloading fields for Ethernet devices. Accessor macros
+ * may be defined in the device specific API to get at this data.
+ *
+ * <b>Performance</b>
+ *
+ * BDs are typically in a non-cached memory space. Limiting I/O to BDs can
+ * improve overall performance of the DMA channel.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 3.00a rmm  03/11/06 First release
+ *       rmm  06/22/06 Added extern "C"
+ * </pre>
+ *
+ * ***************************************************************************
+ */
+
+#ifndef XDMABD_H		/* prevent circular inclusions */
+#define XDMABD_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include <asm/delay.h>
+#include "xdmav3_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The XDmaBdV3 is the type for buffer descriptors (BDs).
+ */
+typedef u32 XDmaBdV3[XDMAV3_BD_NUM_WORDS];
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+ * Zero out BD fields
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Nothing
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mClear(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mClear(BdPtr)                    \
+    memset((BdPtr), 0, sizeof(XDmaBdV3))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD's Packet DMA transfer status word.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Word at offset XDMAV3_BD_DMASR_OFFSET
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetStatus(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetStatus(BdPtr)              \
+    XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMASR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD's Packet status word. This is the first word of local link
+ * footer information for receive channels.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Word at offset XDMAV3_BD_SR_OFFSET
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetPacketStatus(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetPacketStatus(BdPtr)                \
+    XDmaV3_mReadBd((BdPtr), XDMAV3_BD_SR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length field.
+ *
+ * For Tx channels, the returned value is the same as that written with
+ * XDmaBdV3_mSetLength().
+ *
+ * For Rx channels, the returned value is the size of the received packet.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Bytes processed by HW or set by XDmaBdV3_mSetLength().
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetLength(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetLength(BdPtr)                      \
+    XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LENGTH_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length copy field. See XDmaBdV3_mSetLengthCopy() for
+ * more information.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Value as set by XDmaBdV3_mSetLengthCopy().
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetLengthCopy(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetLengthCopy(BdPtr)                  \
+    XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LENCPY_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Test whether the given BD has been marked as the last BD of a packet.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mIsLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mIsLast(BdPtr)                                         \
+    ((XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & XDMAV3_DMACR_LAST_MASK) ? \
+     TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ * Set the ID field of the given BD. The ID is an arbitrary piece of data the
+ * user can associate with a specific BD.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Id is a 32 bit quantity to set in the BD
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetId(XDmaBdV3* BdPtr, void Id)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetId(BdPtr, Id)                                      \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_ID_OFFSET, (u32)Id))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the ID field of the given BD previously set with XDmaBdV3_mSetId.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetId(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetId(BdPtr) (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_ID_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Causes the DMA engine to increment the buffer address during the DMA
+ * transfer for this BD. This is the desirable setting when the buffer data
+ * occupies a memory range.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetBufIncrement(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufIncrement(BdPtr)                                \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+     XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_AINC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Cause the DMA engine to use the same memory buffer address during the DMA
+ * transfer for this BD. This is the desirable setting when the buffer data
+ * occupies a single address as may be the case if transferring to/from a FIFO.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetBufNoIncrement(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufNoIncrement(BdPtr)                              \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+        XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_AINC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Bypass data realignment engine (DRE) if DMA channel has DRE capability.
+ * Has no effect if channel does not have DRE.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mIgnoreDre(XDmaBdV3* BdPtr)
+ *
+ ******************************************************************************/
+#define XDmaBdV3_mIgnoreDre(BdPtr)                                      \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+        XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_BPDRE_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Use data realignment engine (DRE) if DMA channel has DRE capability.
+ * Has no effect if channel does not have DRE.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mUseDre(XDmaBdV3* BdPtr)
+ *
+ ******************************************************************************/
+#define XDmaBdV3_mUseDre(BdPtr)                                         \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+        XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_BPDRE_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Tell the SG DMA engine that the given BD marks the end of the current packet
+ * to be processed.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLast(BdPtr)                                        \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+        XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Tell the SG DMA engine that the current packet does not end with the given
+ * BD.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mClearLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mClearLast(BdPtr)                                      \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+        XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Set the Device Select field of the given BD.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  DevSel is the IP device select to use with LSB of 1. This value
+ *         selects which IP block the transaction will address. Normally this
+ *         is set to 0, but complex IP may require a specific DEVSEL.
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetDevSel(XDmaBdV3* BdPtr, unsigned DevSel)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetDevSel(BdPtr, DevSel)                              \
+    {                                                                   \
+        u32 Dmacr;                                                  \
+        Dmacr = XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET);        \
+        Dmacr = Dmacr | (((DevSel) << XDMAV3_DMACR_DEVSEL_SHIFT) &      \
+                  XDMAV3_DMACR_DEVSEL_MASK);                            \
+        XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, Dmacr);        \
+    }
+
+
+/*****************************************************************************/
+/**
+ * Set the Page field of the given BD. The Page must be in terms of a physical
+ * address. Use this macro if using 36 bit bus addressing.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Page is the page to set. LSB=1
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetBdPage(XDmaBdV3* BdPtr, unsigned Page)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBdPage(BdPtr, Page)                                \
+    {                                                                   \
+        u32 Dmacr;                                                  \
+        Dmacr = XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET);        \
+        Dmacr = Dmacr | (((Page) << XDMAV3_DMACR_BDPAGE_SHIFT) &        \
+                  XDMAV3_DMACR_BDPAGE_MASK);                            \
+        XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, Dmacr);        \
+    }
+
+
+/*****************************************************************************/
+/**
+ * Set transfer attributes for the given BD.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Type defines whether the transfer occurs with single beat or burst
+ *         transfers on the target bus. This parameter must be one of the
+ *         XDMAV3_DMACR_TYPE_*_MASK constants defined in xdma_l.h.
+ * @param  Width defines the width of the transfer as it occurs on the target
+ *         bus. This parameter must be one of the XDMAV3_DMACR_DSIZE_*_MASK
+ *         constants defined in xdma_l.h
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetTransferType(XDmaBdV3* BdPtr, unsigned Type,
+ *                                   unsigned Width)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetTransferType(BdPtr, Type, Width)                   \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET,                   \
+         XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) |              \
+         ((Type) & XDMAV3_DMACR_TYPE_MASK) | ((Width) & XDMAV3_DMACR_DSIZE_MASK)))
+
+
+/*****************************************************************************/
+/**
+ * Set transfer length in bytes for the given BD. The length must be set each
+ * time a BD is submitted to HW.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetLength(XDmaBdV3* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLength(BdPtr, LenBytes)                            \
+    XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LENGTH_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Write the given length to the length copy offset of the BD. This function
+ * is useful only if an application needs to recover the number of bytes
+ * originally set by XDmaBdV3_mSetLength() for Rx channels.
+ *
+ * To effectively use this function, an application would call
+ * XDmaBdV3_mSetLength() to set the length on a Rx descriptor, followed by a
+ * call to this macro to set the same length. When HW has processed the Rx
+ * descriptor it will overwrite the BD length field with the actual length of
+ * the packet. When the application performs post processing of the Rx
+ * descriptor, it can call XDmaBdV3_mGetLengthCopy() to find out how many bytes
+ * were originally allocated to the descriptor.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetLengthCopy(XDmaBdV3* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLengthCopy(BdPtr, LenBytes)                            \
+    XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LENCPY_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Set the high order address of the BD's buffer address. Use this macro when
+ * the address bus width is greater than 32 bits.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  HighAddr is the high order address bits to set, LSB = 2^32.
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetBufAddrHigh(XDmaBdV3* BdPtr, u32 HighAddr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufAddrHigh(BdPtr, HighAddr)               \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_MSBA_OFFSET, (u32)(HighAddr)))
+
+
+/*****************************************************************************/
+/**
+ * Set the low order address (bits 0..31) of the BD's buffer address.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  LowAddr is the low order address bits to set, LSB = 1.
+ *
+ * @note
+ * C-style signature:
+ *    void XDmaBdV3_mSetBufAddrLow(XDmaBdV3* BdPtr, u32 LowAddr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufAddrLow(BdPtr, LowAddr)                 \
+    (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LSBA_OFFSET, (u32)(LowAddr)))
+
+
+/*****************************************************************************/
+/**
+ * Get the high order address of the BD's buffer address. Use this macro when
+ * the address bus width is greater than 32 bits.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetBufAddrHigh(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetBufAddrHigh(BdPtr)                 \
+    (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_MSBA_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Get the low order address (bits 0..31) of the BD's buffer address.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    u32 XDmaBdV3_mGetBufAddrLow(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetBufAddrLow(BdPtr)                  \
+    (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LSBA_OFFSET))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel.c	2014-07-20 22:06:38.831264894 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xdma_channel.c,v 1.1 2006/12/13 14:21:45 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2001-2004 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdma_channel.c
+*
+* <b>Description</b>
+*
+* This file contains the DMA channel component. This component supports
+* a distributed DMA design in which each device can have it's own dedicated
+* DMA channel, as opposed to a centralized DMA design. This component
+* performs processing for DMA on all devices.
+*
+* See xdma_channel.h for more information about this component.
+*
+* @note
+*
+* None.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a xd  10/27/04  Doxygenated for inclusion in API documentation
+* 1.00b ecm 10/31/05  Updated for the check sum offload changes.
+* 1.00b xd  03/22/06  Fixed a multi-descriptor packet related bug that sgdma
+*                     engine is restarted in case no scatter gather disabled
+*                     bit is set yet
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/*****************************************************************************/
+/**
+*
+* This function initializes a DMA channel.  This function must be called
+* prior to using a DMA channel.  Initialization of a channel includes setting
+* up the registers base address, and resetting the channel such that it's in a
+* known state.  Interrupts for the channel are disabled when the channel is
+* reset.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @param
+*
+* BaseAddress contains the base address of the registers for the DMA channel.
+*
+* @return
+*
+* XST_SUCCESS indicating initialization was successful.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
+{
+	/* assert to verify input arguments, don't assert base address */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* setup the base address of the registers for the DMA channel such
+	 * that register accesses can be done
+	 */
+	InstancePtr->RegBaseAddress = BaseAddress;
+
+	/* initialize the scatter gather list such that it indicates it has not
+	 * been created yet and the DMA channel is ready to use (initialized)
+	 */
+	InstancePtr->GetPtr = NULL;
+	InstancePtr->PutPtr = NULL;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = NULL;
+
+	InstancePtr->TotalDescriptorCount = 0;
+	InstancePtr->ActiveDescriptorCount = 0;
+
+	InstancePtr->ActivePacketCount = 0;
+	InstancePtr->Committed = FALSE;
+
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* initialize the version of the component
+	 */
+	XVersion_FromString(&InstancePtr->Version, "1.00a");
+
+	/* reset the DMA channel such that it's in a known state and ready
+	 * and indicate the initialization occurred with no errors, note that
+	 * the is ready variable must be set before this call or reset will assert
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function determines if a DMA channel component has been successfully
+* initialized such that it's ready to use.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* TRUE if the DMA channel component is ready, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments used by the base component */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	return InstancePtr->IsReady == XCOMPONENT_IS_READY;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the software version for the specified DMA channel
+* component.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* A pointer to the software version of the specified DMA channel.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return a pointer to the version of the DMA channel */
+
+	return &InstancePtr->Version;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function performs a self test on the specified DMA channel.  This self
+* test is destructive as the DMA channel is reset and a register default is
+* verified.
+*
+* @param
+*
+* InstancePtr is a pointer to the DMA channel to be operated on.
+*
+* @return
+*
+* XST_SUCCESS is returned if the self test is successful, or one of the
+* following errors.
+*                                       <br><br>
+* - XST_DMA_RESET_REGISTER_ERROR        Indicates the control register value
+*                                       after a reset was not correct
+*
+* @note
+*
+* This test does not performs a DMA transfer to test the channel because the
+* DMA hardware will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+*
+******************************************************************************/
+
+#define XDC_CONTROL_REG_RESET_MASK  0x98000000UL	/* control reg reset value */
+
+int XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
+{
+	u32 ControlReg;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state before the test
+	 * it resets to no interrupts enabled, the desired state for the test
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	/* this should be the first test to help prevent a lock up with the polling
+	 * loop that occurs later in the test, check the reset value of the DMA
+	 * control register to make sure it's correct, return with an error if not
+	 */
+	ControlReg = XDmaChannel_GetControl(InstancePtr);
+	if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
+		return XST_DMA_RESET_REGISTER_ERROR;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function resets the DMA channel. This is a destructive operation such
+* that it should not be done while a channel is being used.  If the DMA channel
+* is transferring data into other blocks, such as a FIFO, it may be necessary
+* to reset other blocks.  This function does not modify the contents of a
+* scatter gather list for a DMA channel such that the user is responsible for
+* getting buffer descriptors from the list if necessary.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_Reset(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state, the reset
+	 * register is self clearing such that it only has to be set
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
+		  XDC_RESET_MASK);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the control register contents of the DMA channel.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The control register contents of the DMA channel. One or more of the
+* following values may be contained the register.  Each of the values are
+* unique bit masks.
+*                               <br><br>
+* - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+*                               <br><br>
+* - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+*                               <br><br>
+* - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*                               <br><br>
+* - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+*                               <br><br>
+* - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+*                               <br><br>
+* - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+*                               <br><br>
+* - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA control register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the control register of the specified DMA channel.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @param
+*
+* Control contains the value to be written to the control register of the DMA
+* channel. One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+* - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
+* - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
+* - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+* - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
+* - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
+* - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
+* - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
+{
+	u32 Register;
+
+	/* assert to verify input arguments except the control which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * set the DMA control register to the specified value, not altering the
+	 * other fields in the register
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+	Register &= XDC_DMACR_TX_CS_INIT_MASK;
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+		  Register | Control);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the status register contents of the DMA channel.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The status register contents of the DMA channel. One or more of the
+* following values may be contained the register. Each of the values are
+* unique bit masks.
+*                               <br><br>
+* - XDC_DMASR_BUSY_MASK         The DMA channel is busy
+*                               <br><br>
+* - XDC_DMASR_BUS_ERROR_MASK    A bus error occurred
+*                               <br><br>
+* - XDC_DMASR_BUS_TIMEOUT_MASK  A bus timeout occurred
+*                               <br><br>
+* - XDC_DMASR_LAST_BD_MASK      The last buffer descriptor of a packet
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the interrupt status register of the specified DMA channel.
+* Setting any bit of the interrupt status register will clear the bit to
+* indicate the interrupt processing has been completed. The definitions of each
+* bit in the register match the definition of the bits in the interrupt enable
+* register.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @param
+*
+* Status contains the value to be written to the status register of the DMA
+* channel.  One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+* - XDC_IXR_DMA_DONE_MASK       The dma operation is done
+* - XDC_IXR_DMA_ERROR_MASK      The dma operation had an error
+* - XDC_IXR_PKT_DONE_MASK       A packet is complete
+* - XDC_IXR_PKT_THRESHOLD_MASK  The packet count threshold reached
+* - XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+* - XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+* - XDC_IXR_BD_MASK             A buffer descriptor is done
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status)
+{
+	/* assert to verify input arguments except the status which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt status register with the specified value such that
+	 * all bits which are set in the register are cleared effectively clearing
+	 * any active interrupts
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the interrupt status register of the specified DMA channel.
+* The interrupt status register indicates which interrupts are active
+* for the DMA channel.  If an interrupt is active, the status register must be
+* set (written) with the bit set for each interrupt which has been processed
+* in order to clear the interrupts.  The definitions of each bit in the register
+* match the definition of the bits in the interrupt enable register.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The interrupt status register contents of the specified DMA channel.
+* One or more of the following values may be contained the register.
+* Each of the values are unique bit masks.
+*                               <br><br>
+* - XDC_IXR_DMA_DONE_MASK       The dma operation is done
+*                               <br><br>
+* - XDC_IXR_DMA_ERROR_MASK      The dma operation had an error
+*                               <br><br>
+* - XDC_IXR_PKT_DONE_MASK       A packet is complete
+*                               <br><br>
+* - XDC_IXR_PKT_THRESHOLD_MASK  The packet count threshold reached
+*                               <br><br>
+* - XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*                               <br><br>
+* - XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*                               <br><br>
+* - XDC_IXR_SG_END_MASK         Current descriptor was the end of the list
+*                               <br><br>
+* - XDC_IXR_BD_MASK             A buffer descriptor is done
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the interrupt enable register of the specified DMA
+* channel.  The interrupt enable register contains bits which enable
+* individual interrupts for the DMA channel.  The definitions of each bit
+* in the register match the definition of the bits in the interrupt status
+* register.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @param
+*
+* Enable contains the interrupt enable register contents to be written
+* in the DMA channel. One or more of the following values may be contained
+* the register. Each of the values are unique bit masks such that they may be
+* ORed together to enable multiple bits or inverted and ANDed to disable
+* multiple bits.
+* - XDC_IXR_DMA_DONE_MASK       The dma operation is done
+* - XDC_IXR_DMA_ERROR_MASK      The dma operation had an error
+* - XDC_IXR_PKT_DONE_MASK       A packet is complete
+* - XDC_IXR_PKT_THRESHOLD_MASK  The packet count threshold reached
+* - XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+* - XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+* - XDC_IXR_SG_END_MASK         Current descriptor was the end of the list
+* - XDC_IXR_BD_MASK             A buffer descriptor is done
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable)
+{
+	/* assert to verify input arguments except the enable which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt enable register to the specified value */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the interrupt enable of the DMA channel.  The
+* interrupt enable contains flags which enable individual interrupts for the
+* DMA channel. The definitions of each bit in the register match the definition
+* of the bits in the interrupt status register.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @return
+*
+* The interrupt enable of the DMA channel.  One or more of the following values
+* may be contained the register. Each of the values are unique bit masks.
+*                               <br><br>
+* - XDC_IXR_DMA_DONE_MASK       The dma operation is done
+*                               <br><br>
+* - XDC_IXR_DMA_ERROR_MASK      The dma operation had an error
+*                               <br><br>
+* - XDC_IXR_PKT_DONE_MASK       A packet is complete
+*                               <br><br>
+* - XDC_IXR_PKT_THRESHOLD_MASK  The packet count threshold reached
+*                               <br><br>
+* - XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*                               <br><br>
+* - XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*                               <br><br>
+* - XDC_IXR_BD_MASK             A buffer descriptor is done
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt enable register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function starts the DMA channel transferring data from a memory source
+* to a memory destination. This function only starts the operation and returns
+* before the operation may be complete.  If the interrupt is enabled, an
+* interrupt will be generated when the operation is complete, otherwise it is
+* necessary to poll the channel status to determine when it's complete.  It is
+* the responsibility of the caller to determine when the operation is complete
+* by handling the generated interrupt or polling the status.  It is also the
+* responsibility of the caller to ensure that the DMA channel is not busy with
+* another transfer before calling this function.
+*
+* @param
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* @param
+*
+* SourcePtr contains a pointer to the source memory where the data is to
+* be transferred from and must be 32 bit aligned.
+*
+* @param
+*
+* DestinationPtr contains a pointer to the destination memory where the data
+* is to be transferred and must be 32 bit aligned.
+*
+* @param
+*
+* ByteCount contains the number of bytes to transfer during the DMA operation.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* The DMA hw will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+* <br><br>
+* It is the responsibility of the caller to ensure that the cache is
+* flushed and invalidated both before and after the DMA operation completes
+* if the memory pointed to is cached. The caller must also ensure that the
+* pointers contain a physical address rather than a virtual address
+* if address translation is being used.
+*
+******************************************************************************/
+void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+			  u32 *SourcePtr, u32 *DestinationPtr, u32 ByteCount)
+{
+	/* assert to verify input arguments and the alignment of any arguments
+	 * which have expected alignments
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(SourcePtr != NULL);
+	XASSERT_VOID(((u32) SourcePtr & 3) == 0);
+	XASSERT_VOID(DestinationPtr != NULL);
+	XASSERT_VOID(((u32) DestinationPtr & 3) == 0);
+	XASSERT_VOID(ByteCount != 0);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* setup the source and destination address registers for the transfer */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
+		  (u32) SourcePtr);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
+		  (u32) DestinationPtr);
+
+	/* start the DMA transfer to copy from the source buffer to the
+	 * destination buffer by writing the length to the length register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel.h	2014-07-20 22:06:38.841264729 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+*     Author: Xilinx, 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.
+*
+*
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*
+*
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*
+*
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel.h
+*
+* DESCRIPTION:
+*
+* This file contains the DMA channel component implementation. This component
+* supports a distributed DMA design in which each device can have it's own
+* dedicated DMA channel, as opposed to a centralized DMA design.
+* A device which uses DMA typically contains two DMA channels, one for
+* sending data and the other for receiving data.
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* The DMA channel allows a CPU to minimize the CPU interaction required to move
+* data between a memory and a device.  The CPU requests the DMA channel to
+* perform a DMA operation and typically continues performing other processing
+* until the DMA operation completes.  DMA could be considered a primitive form
+* of multiprocessing such that caching and address translation can be an issue.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.  Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.  The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+*    receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.
+*
+* Interrupts
+*
+* Each DMA channel has the ability to generate an interrupt.  This component
+* does not perform processing for the interrupt as this processing is typically
+* tightly coupled with the device which is using the DMA channel.  It is the
+* responsibility of the caller of DMA functions to manage the interrupt
+* including connecting to the interrupt and enabling/disabling the interrupt.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the DMA channel.  This
+* component does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to DMA functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Address Translation
+*
+* All addresses of data structures which are passed to DMA functions must
+* be physical (real) addresses as opposed to logical (virtual) addresses.
+*
+* Caching
+*
+* The memory which is passed to the function which creates the scatter gather
+* list must not be cached such that buffer descriptors are non-cached.  This
+* is necessary because the buffer descriptors are kept in a ring buffer and
+* not directly accessible to the caller of DMA functions.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel are cache-line aligned if
+* necessary.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel have been flushed from the cache.
+*
+* The caller of DMA functions is responsible for ensuring that the cache is
+* invalidated prior to using any data buffers which are the result of a DMA
+* operation.
+*
+* Memory Alignment
+*
+* The addresses of data buffers which are passed to DMA functions must be
+* 32 bit word aligned since the DMA hardware performs 32 bit word transfers.
+*
+* Mutual Exclusion
+*
+* The functions of the DMA channel are not thread safe such that the caller
+* of all DMA functions is responsible for ensuring mutual exclusion for a
+* DMA channel.  Mutual exclusion across multiple DMA channels is not
+* necessary.
+*
+* NOTES:
+*
+* Many of the provided functions which are register accessors don't provide
+* a lot of error detection. The caller is expected to understand the impact
+* of a function call based upon the current state of the DMA channel.  This
+* is done to minimize the overhead in this component.
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_H		/* prevent circular inclusions */
+#define XDMA_CHANNEL_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+#include "xbuf_descriptor.h"
+#include "xdma_channel_i.h"	/* constants shared with buffer descriptor */
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants provide access to the bit fields of the DMA control
+ * register (DMACR)
+ */
+#define XDC_DMACR_SOURCE_INCR_MASK  0x80000000UL	/* increment source address */
+#define XDC_DMACR_DEST_INCR_MASK    0x40000000UL	/* increment dest address */
+#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL	/* local source address */
+#define XDC_DMACR_DEST_LOCAL_MASK   0x10000000UL	/* local dest address */
+#define XDC_DMACR_SG_DISABLE_MASK   0x08000000UL	/* scatter gather disable */
+#define XDC_DMACR_GEN_BD_INTR_MASK  0x04000000UL	/* descriptor interrupt */
+#define XDC_DMACR_LAST_BD_MASK      XDC_CONTROL_LAST_BD_MASK	/* last buffer */
+				    /*     descriptor  */
+#define XDC_DMACR_DRE_MODE_MASK     0x01000000UL	/* DRE/normal mode */
+
+#define XDC_DMACR_TX_CS_INIT_MASK    0x0000FFFFUL	/* Initial value for TX
+							   CS offload */
+#define XDC_DMACR_CS_OFFLOAD_MASK    0x00800000UL	/* Enable CS offload */
+
+/* the following constants provide access to the bit fields of the DMA status
+ * register (DMASR)
+ */
+#define XDC_DMASR_BUSY_MASK         0x80000000UL	/* channel is busy */
+#define XDC_DMASR_BUS_ERROR_MASK    0x40000000UL	/* bus error occurred */
+#define XDC_DMASR_BUS_TIMEOUT_MASK  0x20000000UL	/* bus timeout occurred */
+#define XDC_DMASR_LAST_BD_MASK      XDC_STATUS_LAST_BD_MASK	/* last buffer */
+				/* descriptor  */
+#define XDC_DMASR_SG_BUSY_MASK      0x08000000UL	/* scatter gather is busy */
+/* @} */
+
+/** @name DMA destination address register bit fields when checksum offload is
+ * used
+ *
+ * the following constants provide access to the bit fields of the
+ * Destination Address Register (DAREG)
+ * @{
+ */
+#define XDC_DAREG_CS_BEGIN_MASK      0xFFFF0000UL	/* byte position to begin
+							   checksum calculation */
+#define XDC_DAREG_CS_INSERT_MASK     0x0000FFFFUL	/* byte position to place
+							   calculated checksum */
+/* the following constants provide access to the bit fields of the interrupt
+ * status register (ISR) and the interrupt enable register (IER), bit masks
+ * match for both registers such that they are named IXR
+ */
+#define XDC_IXR_DMA_DONE_MASK       0x1UL	/* dma operation done */
+#define XDC_IXR_DMA_ERROR_MASK      0x2UL	/* dma operation error */
+#define XDC_IXR_PKT_DONE_MASK       0x4UL	/* packet done */
+#define XDC_IXR_PKT_THRESHOLD_MASK  0x8UL	/* packet count threshold */
+#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL	/* packet wait bound reached */
+#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL	/* scatter gather disable
+						   acknowledge occurred */
+#define XDC_IXR_SG_END_MASK         0x40UL	/* last buffer descriptor
+						   disabled scatter gather */
+#define XDC_IXR_BD_MASK             0x80UL	/* buffer descriptor done */
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * the following structure contains data which is on a per instance basis
+ * for the XDmaChannel component
+ */
+typedef struct XDmaChannelTag {
+	XVersion Version;	/* version of the driver */
+	u32 RegBaseAddress;	/* base address of registers */
+	u32 IsReady;		/* device is initialized and ready */
+
+	XBufDescriptor *PutPtr;	/* keep track of where to put into list */
+	XBufDescriptor *GetPtr;	/* keep track of where to get from list */
+	XBufDescriptor *CommitPtr;	/* keep track of where to commit in list */
+	XBufDescriptor *LastPtr;	/* keep track of the last put in the list */
+	void *VirtPtr;		/* virtual base of memory */
+	void *PhyPtr;		/* physical base of memory */
+	u32 TotalDescriptorCount;	/* total # of descriptors in the list */
+	u32 ActiveDescriptorCount;	/* # of descriptors pointing to buffers
+					 * in the buffer descriptor list */
+	u32 ActivePacketCount;	/* # of packets that have been put into
+				   the list and transmission confirmation
+				   have not been received by the driver */
+	u32 Committed;		/* CommitPuts is called? */
+} XDmaChannel;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+int XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
+u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr);
+XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr);
+int XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
+void XDmaChannel_Reset(XDmaChannel * InstancePtr);
+
+/* Control functions */
+
+u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr);
+void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control);
+
+/* Status functions */
+
+u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status);
+u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable);
+u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr);
+
+/* DMA without scatter gather functions */
+
+void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+			  u32 *SourcePtr, u32 *DestinationPtr, u32 ByteCount);
+
+/* Scatter gather functions */
+
+int XDmaChannel_SgStart(XDmaChannel * InstancePtr);
+int XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+		       XBufDescriptor ** BufDescriptorPtr);
+int XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+			     u32 *MemoryPtr, u32 ByteCount, void *PhyPtr);
+u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr);
+
+int XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+			      XBufDescriptor * BufDescriptorPtr);
+int XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
+int XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+			      XBufDescriptor ** BufDescriptorPtr);
+
+/* Packet functions for interrupt collescing */
+
+u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr);
+void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr);
+int XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
+u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr);
+void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound);
+u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr);
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel_i.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel_i.h	2014-07-20 22:06:38.849264597 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xdma_channel_i.h,v 1.1 2006/12/13 14:22:04 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2001-2004 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdma_channel_i.h
+*
+* <b>Description</b>
+*
+* This file contains data which is shared internal data for the DMA channel
+* component. It is also shared with the buffer descriptor component which is
+* very tightly coupled with the DMA channel component.
+*
+* @note
+*
+* The last buffer descriptor constants must be located here to prevent a
+* circular dependency between the DMA channel component and the buffer
+* descriptor component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a xd   10/27/04 Doxygenated for inclusion in API documentation
+* 1.00b ecm  10/31/05 Updated for the check sum offload changes.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_I_H	/* prevent circular inclusions */
+#define XDMA_CHANNEL_I_H	/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_DMA_CHANNEL_V1_00_B     "1.00b"
+
+/** @name DMA control register bit fields
+ *
+ * the following constant provides access to the bit fields of the DMA control
+ * register (DMACR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ * @{
+ */
+#define XDC_CONTROL_LAST_BD_MASK    0x02000000UL /**< last buffer descriptor */
+/* @} */
+
+/** @name DMA status register bit fields
+ *
+ * the following constant provides access to the bit fields of the DMA status
+ * register (DMASR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ * @{
+ */
+#define XDC_STATUS_LAST_BD_MASK     0x10000000UL /**< last buffer descriptor */
+
+#define XDC_DMASR_RX_CS_RAW_MASK    0xFFFF0000UL /**< RAW CS value for RX data */
+/* @} */
+
+/** @name DMA Channel register offsets
+ *
+ * the following constants provide access to each of the registers of a DMA
+ * channel
+ * @{
+ */
+#define XDC_RST_REG_OFFSET  0	/**< reset register */
+#define XDC_MI_REG_OFFSET   0	/**< module information register */
+#define XDC_DMAC_REG_OFFSET 4	/**< DMA control register */
+#define XDC_SA_REG_OFFSET   8	/**< source address register */
+#define XDC_DA_REG_OFFSET   12	/**< destination address register */
+#define XDC_LEN_REG_OFFSET  16	/**< length register */
+#define XDC_DMAS_REG_OFFSET 20	/**< DMA status register */
+#define XDC_BDA_REG_OFFSET  24	/**< buffer descriptor address register */
+#define XDC_SWCR_REG_OFFSET 28	/**< software control register */
+#define XDC_UPC_REG_OFFSET  32	/**< unserviced packet count register */
+#define XDC_PCT_REG_OFFSET  36	/**< packet count threshold register */
+#define XDC_PWB_REG_OFFSET  40	/**< packet wait bound register */
+#define XDC_IS_REG_OFFSET   44	/**< interrupt status register */
+#define XDC_IE_REG_OFFSET   48	/**< interrupt enable register */
+/* @} */
+
+/**
+ * the following constant is written to the reset register to reset the
+ * DMA channel
+ */
+#define XDC_RESET_MASK              0x0000000AUL
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel_sg.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdma_channel_sg.c	2014-07-20 22:06:38.869264267 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+*     Author: Xilinx, 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.
+*
+*
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*
+*
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*
+*
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel_sg.c
+*
+* DESCRIPTION:
+*
+* This file contains the implementation of the XDmaChannel component which is
+* related to scatter gather operations.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.  Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.  The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* The get and put functions only operate on the list and are asynchronous from
+* the hardware which may be using the list of descriptors.  This is important
+* because there are no checks in the get and put functions to ensure that the
+* hardware has processed the descriptors.  This must be handled by the driver
+* using the DMA scatter gather channel through the use of the other functions.
+* When a scatter gather operation is started, the start function does ensure
+* that the descriptor to start has not already been processed by the hardware
+* and is not the first of a series of descriptors that have not been committed
+* yet.
+*
+* Descriptors are put into the list but not marked as ready to use by the
+* hardware until a commit operation is done.  This allows multiple descriptors
+* which may contain a single packet of information for a protocol to be
+* guaranteed not to cause any underflow conditions during transmission. The
+* hardware design only allows descriptors to cause it to stop after a descriptor
+* has been processed rather than before it is processed.  A series of
+* descriptors are put into the list followed by a commit operation, or each
+* descriptor may be commited.  A commit operation is performed by changing a
+* single descriptor, the first of the series of puts, to indicate that the
+* hardware may now use all descriptors after it.  The last descriptor in the
+* list is always set to cause the hardware to stop after it is processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+*    receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.  This may
+*    be accomplished by getting the packet count for the channel and then
+*    getting the appropriate number of descriptors from the list for that
+*    number of packets.
+*
+* Minimizing Interrupts
+*
+* The Scatter Gather operating mode is designed to reduce the amount of CPU
+* throughput necessary to manage the hardware for devices. A key to the CPU
+* throughput is the number and rate of interrupts that the CPU must service.
+* Devices with higher data rates can cause larger numbers of interrupts and
+* higher frequency interrupts. Ideally the number of interrupts can be reduced
+* by only generating an interrupt when a specific amount of data has been
+* received from the interface. This design suffers from a lack of interrupts
+* when the amount of data received is less than the specified amount of data
+* to generate an interrupt. In order to help minimize the number of interrupts
+* which the CPU must service, an algorithm referred to as "interrupt coalescing"
+* is utilized.
+*
+* Interrupt Coalescing
+*
+* The principle of interrupt coalescing is to wait before generating an
+* interrupt until a certain number of packets have been received or sent. An
+* interrupt is also generated if a smaller number of packets have been received
+* followed by a certain period of time with no packet reception. This is a
+* trade-off of latency for bandwidth and is accomplished using several
+* mechanisms of the hardware including a counter for packets received or
+* transmitted and a packet timer. These two hardware mechanisms work in
+* combination to allow a reduction in the number of interrupts processed by the
+* CPU for packet reception.
+*
+* Unserviced Packet Count
+*
+* The purpose of the packet counter is to count the number of packets received
+* or transmitted and provide an interrupt when a specific number of packets
+* have been processed by the hardware. An interrupt is generated whenever the
+* counter is greater than or equal to the Packet Count Threshold. This counter
+* contains an accurate count of the number of packets that the hardware has
+* processed, either received or transmitted, and the software has not serviced.
+*
+* The packet counter allows the number of interrupts to be reduced by waiting
+* to generate an interrupt until enough packets are received. For packet
+* reception, packet counts of less than the number to generate an interrupt
+* would not be serviced without the addition of a packet timer. This counter is
+* continuously updated by the hardware, not latched to the value at the time
+* the interrupt occurred.
+*
+* The packet counter can be used within the interrupt service routine for the
+* device to reduce the number of interrupts. The interrupt service routine
+* loops while performing processing for each packet which has been received or
+* transmitted and decrements the counter by a specified value. At the same time,
+* the hardware is possibly continuing to receive or transmit more packets such
+* that the software may choose, based upon the value in the packet counter, to
+* remain in the interrupt service routine rather than exiting and immediately
+* returning. This feature should be used with caution as reducing the number of
+* interrupts is beneficial, but unbounded interrupt processing is not desirable.
+*
+* Since the hardware may be incrementing the packet counter simultaneously
+* with the software decrementing the counter, there is a need for atomic
+* operations. The hardware ensures that the operation is atomic such that
+* simultaneous accesses are properly handled.
+*
+* Packet Wait Bound
+*
+* The purpose of the packet wait bound is to augment the unserviced packet
+* count. Whenever there is no pending interrupt for the channel and the
+* unserviced packet count is non-zero, a timer starts counting timeout at the
+* value contained the the packet wait bound register.  If the timeout is
+* reached, an interrupt is generated such that the software may service the
+* data which was buffered.
+*
+* NOTES:
+*
+* Special Test Conditions:
+*
+* The scatter gather list processing must be thoroughly tested if changes are
+* made.  Testing should include putting and committing single descriptors and
+* putting multiple descriptors followed by a single commit.  There are some
+* conditions in the code which handle the exception conditions.
+*
+* The Put Pointer points to the next location in the descriptor list to copy
+* in a new descriptor. The Get Pointer points to the next location in the
+* list to get a descriptor from.  The Get Pointer only allows software to
+* have a traverse the list after the hardware has finished processing some
+* number of descriptors.  The Commit Pointer points to the descriptor in the
+* list which is to be committed.  It is also used to determine that no
+* descriptor is waiting to be commited (NULL).  The Last Pointer points to
+* the last descriptor that was put into the list.  It typically points
+* to the previous descriptor to the one pointed to by the Put Pointer.
+* Comparisons are done between these pointers to determine when the following
+* special conditions exist.
+
+* Single Put And Commit
+*
+* The buffer descriptor is ready to be used by the hardware so it is important
+* for the descriptor to not appear to be waiting to be committed.  The commit
+* pointer is reset when a commit is done indicating there are no descriptors
+* waiting to be committed.  In all cases but this one, the descriptor is
+* changed to cause the hardware to go to the next descriptor after processing
+* this one.  But in this case, this is the last descriptor in the list such
+* that it must not be changed.
+*
+* 3 Or More Puts And Commit
+*
+* A series of 3 or more puts followed by a single commit is different in that
+* only the 1st descriptor put into the list is changed when the commit is done.
+* This requires each put starting on the 3rd to change the previous descriptor
+* so that it allows the hardware to continue to the next descriptor in the list.
+*
+* The 1st Put Following A Commit
+*
+* The commit caused the commit pointer to be NULL indicating that there are no
+* descriptors waiting to be committed.  It is necessary for the next put to set
+* the commit pointer so that a commit must follow the put for the hardware to
+* use the descriptor.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 1.00a rpm  02/03/03 Removed the XST_DMA_SG_COUNT_EXCEEDED return code
+*                     from SetPktThreshold.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xbuf_descriptor.h"
+#include "xstatus.h"
+
+/* simple virt<-->phy pointer conversions for a single dma channel */
+#define P_TO_V(p) \
+    ((p) ? \
+     (InstancePtr->VirtPtr + ((u32)(p) - (u32)InstancePtr->PhyPtr)) : \
+     0)
+
+#define V_TO_P(v) \
+    ((v) ? \
+     (InstancePtr->PhyPtr + ((u32)(v) - (u32)InstancePtr->VirtPtr)) : \
+     0)
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL	/* scatter gather enable */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* the following macro copies selected fields of a buffer descriptor to another
+ * buffer descriptor, this was provided by the buffer descriptor component but
+ * was moved here since it is only used internally to this component and since
+ * it does not copy all fields
+ */
+#define CopyBufferDescriptor(InstancePtr, DestinationPtr)          \
+{                                                                  \
+    *((u32 *)DestinationPtr + XBD_CONTROL_OFFSET) =            \
+        *((u32 *)InstancePtr + XBD_CONTROL_OFFSET);            \
+    *((u32 *)DestinationPtr + XBD_SOURCE_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_SOURCE_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_DESTINATION_OFFSET) =        \
+        *((u32 *)InstancePtr + XBD_DESTINATION_OFFSET);        \
+    *((u32 *)DestinationPtr + XBD_LENGTH_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_LENGTH_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_STATUS_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_STATUS_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_DEVICE_STATUS_OFFSET) =      \
+        *((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET);      \
+    *((u32 *)DestinationPtr + XBD_ID_OFFSET) =                 \
+        *((u32 *)InstancePtr + XBD_ID_OFFSET);                 \
+    *((u32 *)DestinationPtr + XBD_FLAGS_OFFSET) =              \
+        *((u32 *)InstancePtr + XBD_FLAGS_OFFSET);              \
+    *((u32 *)DestinationPtr + XBD_RQSTED_LENGTH_OFFSET) =      \
+        *((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET);      \
+}
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStart
+*
+* DESCRIPTION:
+*
+* This function starts a scatter gather operation for a scatter gather
+* DMA channel.  The first buffer descriptor in the buffer descriptor list
+* will be started with the scatter gather operation.  A scatter gather list
+* should have previously been created for the DMA channel and buffer
+* descriptors put into the scatter gather list such that there are scatter
+* operations ready to be performed.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was started successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates scatter gather was not started
+* because the scatter gather list of the DMA channel does not contain any
+* buffer descriptors that are ready to be processed by the hardware.
+*
+* A value of XST_DMA_SG_IS_STARTED indicates scatter gather was not started
+* because the scatter gather was not stopped, but was already started.
+*
+* A value of XST_DMA_SG_BD_NOT_COMMITTED indicates the buffer descriptor of
+* scatter gather list which was to be started is not committed to the list.
+* This status is more likely if this function is being called from an ISR
+* and non-ISR processing is putting descriptors into the list.
+*
+* A value of XST_DMA_SG_NO_DATA indicates that the buffer descriptor of the
+* scatter gather list which was to be started had already been used by the
+* hardware for a DMA transfer that has been completed.
+*
+* NOTES:
+*
+* It is the responsibility of the caller to get all the buffer descriptors
+* after performing a stop operation and before performing a start operation.
+* If buffer descriptors are not retrieved between stop and start operations,
+* buffer descriptors may be processed by the hardware more than once.
+*
+******************************************************************************/
+int XDmaChannel_SgStart(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+	XBufDescriptor *LastDescriptorPtr;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the scatter gather list exists but is empty then return a status */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* if scatter gather is busy for the DMA channel, return a status because
+	 * restarting it could lose data
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+	if (Register & XDC_DMASR_SG_BUSY_MASK) {
+		return XST_DMA_SG_IS_STARTED;
+	}
+
+	/* get the address of the last buffer descriptor which the DMA hardware
+	 * finished processing
+	 */
+	LastDescriptorPtr = (XBufDescriptor *)
+		P_TO_V(XIo_In32
+		       (InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+
+	/* setup the first buffer descriptor that will be sent when the scatter
+	 * gather channel is enabled, this is only necessary one time since
+	 * the BDA register of the channel maintains the last buffer descriptor
+	 * processed
+	 */
+	if (LastDescriptorPtr == NULL) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
+			  (u32) V_TO_P(InstancePtr->GetPtr));
+	}
+	else {
+		XBufDescriptor *NextDescriptorPtr;
+
+		/* get the next descriptor to be started, if the status indicates it
+		 * hasn't already been used by the h/w, then it's OK to start it,
+		 * s/w sets the status of each descriptor to busy and then h/w clears
+		 * the busy when it is complete
+		 */
+		NextDescriptorPtr =
+			P_TO_V(XBufDescriptor_GetNextPtr(LastDescriptorPtr));
+
+		if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
+		     XDC_DMASR_BUSY_MASK) == 0) {
+			return XST_DMA_SG_NO_DATA;
+		}
+		/* don't start the DMA SG channel if the descriptor to be processed
+		 * by h/w is to be committed by the s/w, this function can be called
+		 * such that it interrupts a thread that was putting into the list
+		 */
+		if (NextDescriptorPtr == InstancePtr->CommitPtr) {
+			return XST_DMA_SG_BD_NOT_COMMITTED;
+		}
+	}
+
+	/* start the scatter gather operation by clearing the stop bit in the
+	 * control register and setting the enable bit in the s/w control register,
+	 * both of these are necessary to cause it to start, right now the order of
+	 * these statements is important, the software control register should be
+	 * set 1st.  The other order can cause the CPU to have a loss of sync
+	 * because it cannot read/write the register while the DMA operation is
+	 * running
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register | XDC_SWCR_SG_ENABLE_MASK);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+		  Register & ~XDC_DMACR_SG_DISABLE_MASK);
+
+	/* indicate the DMA channel scatter gather operation was started
+	 * successfully
+	 */
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStop
+*
+* DESCRIPTION:
+*
+* This function stops a scatter gather operation for a scatter gather
+* DMA channel. This function starts the process of stopping a scatter
+* gather operation that is in progress and waits for the stop to be completed.
+* Since it waits for the operation to stopped before returning, this function
+* could take an amount of time relative to the size of the DMA scatter gather
+* operation which is in progress.  The scatter gather list of the DMA channel
+* is not modified by this function such that starting the scatter gather
+* channel after stopping it will cause it to resume.  This operation is
+* considered to be a graceful stop in that the scatter gather operation
+* completes the current buffer descriptor before stopping.
+*
+* If the interrupt is enabled, an interrupt will be generated when the
+* operation is stopped and the caller is responsible for handling the
+* interrupt.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is also a return value which contains a pointer to the
+* buffer descriptor which the scatter gather operation completed when it
+* was stopped.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was stopped successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_IS_STOPPED indicates scatter gather was not stoppped
+* because the scatter gather is not started, but was already stopped.
+*
+* BufDescriptorPtr contains a pointer to the buffer descriptor which was
+* completed when the operation was stopped.
+*
+* NOTES:
+*
+* This function implements a loop which polls the hardware for an infinite
+* amount of time. If the hardware is not operating correctly, this function
+* may never return.
+*
+******************************************************************************/
+int
+XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+		   XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the contents of the software control register, if scatter gather is not
+	 * enabled (started), then return a status because the disable acknowledge
+	 * would not be generated
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
+		return XST_DMA_SG_IS_STOPPED;
+	}
+
+	/* disable scatter gather by writing to the software control register
+	 * without modifying any other bits of the register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register & ~XDC_SWCR_SG_ENABLE_MASK);
+
+	/* scatter gather does not disable immediately, but after the current
+	 * buffer descriptor is complete, so wait for the DMA channel to indicate
+	 * the disable is complete
+	 */
+	do {
+		Register =
+			XIo_In32(InstancePtr->RegBaseAddress +
+				 XDC_DMAS_REG_OFFSET);
+	}
+	while (Register & XDC_DMASR_SG_BUSY_MASK);
+
+	/* set the specified buffer descriptor pointer to point to the buffer
+	 * descriptor that the scatter gather DMA channel was processing
+	 */
+	*BufDescriptorPtr = (XBufDescriptor *)
+		P_TO_V(XIo_In32
+		       (InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CreateSgList
+*
+* DESCRIPTION:
+*
+* This function creates a scatter gather list in the DMA channel.  A scatter
+* gather list consists of a list of buffer descriptors that are available to
+* be used for scatter gather operations.  Buffer descriptors are put into the
+* list to request a scatter gather operation to be performed.
+*
+* A number of buffer descriptors are created from the specified memory and put
+* into a buffer descriptor list as empty buffer descriptors. This function must
+* be called before non-empty buffer descriptors may be put into the DMA channel
+* to request scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* MemoryPtr contains a pointer to the memory which is to be used for buffer
+* descriptors and must not be cached (virtual).
+*
+* ByteCount contains the number of bytes for the specified memory to be used
+* for buffer descriptors.
+*
+* PhyPtr contains a pointer to the physical memory use for buffer descriptors.
+*
+* RETURN VALUE:
+*
+* A status contains XST_SUCCESS if the scatter gather list was successfully
+* created.
+*
+* A value of XST_DMA_SG_LIST_EXISTS indicates that the scatter gather list
+* was not created because the list has already been created.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+int
+XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+			 u32 *MemoryPtr, u32 ByteCount, void *PhyPtr)
+{
+	XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
+	XBufDescriptor *PreviousDescriptorPtr = NULL;
+	XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
+	u32 UsedByteCount;
+
+	/* assert to verify valid input arguments, alignment for those
+	 * arguments that have alignment restrictions, and at least enough
+	 * memory for one buffer descriptor
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(MemoryPtr != NULL);
+	XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(ByteCount >= sizeof(XBufDescriptor));
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the scatter gather list has already been created, then return
+	 * with a status
+	 */
+	if (InstancePtr->TotalDescriptorCount != 0) {
+		return XST_DMA_SG_LIST_EXISTS;
+	}
+
+	/* save this up front so V_TO_P() works correctly */
+	InstancePtr->VirtPtr = MemoryPtr;
+	InstancePtr->PhyPtr = PhyPtr;
+
+	/* loop thru the specified memory block and create as many buffer
+	 * descriptors as possible putting each into the list which is
+	 * implemented as a ring buffer, make sure not to use any memory which
+	 * is not large enough for a complete buffer descriptor
+	 */
+	UsedByteCount = 0;
+	while ((UsedByteCount + sizeof(XBufDescriptor)) <= ByteCount) {
+		/* setup a pointer to the next buffer descriptor in the memory and
+		 * update # of used bytes to know when all of memory is used
+		 */
+		BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
+							  UsedByteCount);
+
+		/* initialize the new buffer descriptor such that it doesn't contain
+		 * garbage which could be used by the DMA hardware
+		 */
+		XBufDescriptor_Initialize(BufferDescriptorPtr);
+
+		/* if this is not the first buffer descriptor to be created,
+		 * then link it to the last created buffer descriptor
+		 */
+		if (PreviousDescriptorPtr != NULL) {
+			XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
+						  V_TO_P(BufferDescriptorPtr));
+		}
+
+		/* always keep a pointer to the last created buffer descriptor such
+		 * that they can be linked together in the ring buffer
+		 */
+		PreviousDescriptorPtr = BufferDescriptorPtr;
+
+		/* keep a count of the number of descriptors in the list to allow
+		 * error processing to be performed
+		 */
+		InstancePtr->TotalDescriptorCount++;
+
+		UsedByteCount += sizeof(XBufDescriptor);
+	}
+
+	/* connect the last buffer descriptor created and inserted in the list
+	 * to the first such that a ring buffer is created
+	 */
+	XBufDescriptor_SetNextPtr(BufferDescriptorPtr, V_TO_P(StartOfListPtr));
+
+	/* initialize the ring buffer to indicate that there are no
+	 * buffer descriptors in the list which point to valid data buffers
+	 */
+	InstancePtr->PutPtr = BufferDescriptorPtr;
+	InstancePtr->GetPtr = BufferDescriptorPtr;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = BufferDescriptorPtr;
+	InstancePtr->ActiveDescriptorCount = 0;
+	InstancePtr->ActivePacketCount = 0;
+	InstancePtr->Committed = FALSE;
+
+	/* indicate the scatter gather list was successfully created */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_IsSgListEmpty
+*
+* DESCRIPTION:
+*
+* This function determines if the scatter gather list of a DMA channel is
+* empty with regard to buffer descriptors which are pointing to buffers to be
+* used for scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A value of TRUE if the scatter gather list is empty, otherwise a value of
+* FALSE.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
+{
+	/* assert to verify valid input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the number of descriptors which are being used in the list is zero
+	 * then the list is empty
+	 */
+	return (InstancePtr->ActiveDescriptorCount == 0);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_PutDescriptor
+*
+* DESCRIPTION:
+*
+* This function puts a buffer descriptor into the DMA channel scatter
+* gather list. A DMA channel maintains a list of buffer descriptors which are
+* to be processed.  This function puts the specified buffer descriptor
+* at the next location in the list.  Note that since the list is already intact,
+* the information in the parameter is copied into the list (rather than modify
+* list pointers on the fly).
+*
+* After buffer descriptors are put into the list, they must also be committed
+* by calling another function.  This allows multiple buffer descriptors which
+* span a single packet to be put into the list while preventing the hardware
+* from starting the first buffer descriptor of the packet.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufferDescriptorPtr is a pointer to the buffer descriptor to be put into
+* the next available location of the scatter gather list.
+*
+* RETURN VALUE:
+*
+* A status which indicates XST_SUCCESS if the buffer descriptor was
+* successfully put into the scatter gather list.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not
+* put into the list because the list was full.
+*
+* A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not
+* put into the list because the buffer descriptor in the list which is to
+* be overwritten was locked.  A locked buffer descriptor indicates the higher
+* layered software is still using the buffer descriptor.
+*
+* NOTES:
+*
+* It is necessary to create a scatter gather list for a DMA channel before
+* putting buffer descriptors into it.
+*
+******************************************************************************/
+int
+XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor * BufferDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify valid input arguments and alignment for those
+	 * arguments that have alignment restrictions
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferDescriptorPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the list is full because all descriptors are pointing to valid
+	 * buffers, then indicate an error, this code assumes no list or an
+	 * empty list is detected above
+	 */
+	if (InstancePtr->ActiveDescriptorCount ==
+	    InstancePtr->TotalDescriptorCount) {
+		return XST_DMA_SG_LIST_FULL;
+	}
+
+	/* if the buffer descriptor in the list which is to be overwritten is
+	 * locked, then don't overwrite it and return a status
+	 */
+	if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
+		return XST_DMA_SG_BD_LOCKED;
+	}
+
+	/* set the scatter gather stop bit in the control word of the descriptor
+	 * to cause the h/w to stop after it processes this descriptor since it
+	 * will be the last in the list
+	 */
+	Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
+	XBufDescriptor_SetControl(BufferDescriptorPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set both statuses in the descriptor so we tell if they are updated with
+	 * the status of the transfer, the hardware should change the busy in the
+	 * DMA status to be false when it completes
+	 */
+	XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
+	XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
+
+	/* copy the descriptor into the next position in the list so it's ready to
+	 * be used by the h/w, this assumes the descriptor in the list prior to this
+	 * one still has the stop bit in the control word set such that the h/w
+	 * use this one yet
+	 */
+	CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
+
+	/* End of a packet is reached. Bump the packet counter */
+	if (XBufDescriptor_IsLastControl(InstancePtr->PutPtr)) {
+		InstancePtr->ActivePacketCount++;
+	}
+
+	/* only the last in the list and the one to be committed have scatter gather
+	 * disabled in the control word, a commit requires only one descriptor
+	 * to be changed, when # of descriptors to commit > 2 all others except the
+	 * 1st and last have scatter gather enabled
+	 */
+	if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
+	    (InstancePtr->CommitPtr != NULL)) {
+		Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
+		XBufDescriptor_SetControl(InstancePtr->LastPtr,
+					  Control & ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+
+	/* update the list data based upon putting a descriptor into the list,
+	 * these operations must be last
+	 */
+	InstancePtr->ActiveDescriptorCount++;
+
+	/* only update the commit pointer if it is not already active, this allows
+	 * it to be deactivated after every commit such that a single descriptor
+	 * which is committed does not appear to be waiting to be committed
+	 */
+	if (InstancePtr->CommitPtr == NULL) {
+		InstancePtr->CommitPtr = InstancePtr->LastPtr;
+	}
+
+	/* these updates MUST BE LAST after the commit pointer update in order for
+	 * the commit pointer to track the correct descriptor to be committed
+	 */
+	InstancePtr->LastPtr = InstancePtr->PutPtr;
+	InstancePtr->PutPtr =
+		P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->PutPtr));
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CommitPuts
+*
+* DESCRIPTION:
+*
+* This function commits the buffer descriptors which have been put into the
+* scatter list for the DMA channel since the last commit operation was
+* performed.  This enables the calling functions to put several buffer
+* descriptors into the list (e.g.,a packet's worth) before allowing the scatter
+* gather operations to start.  This prevents the DMA channel hardware from
+* starting to use the buffer descriptors in the list before they are ready
+* to be used (multiple buffer descriptors for a single packet).
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if the buffer descriptors of the list were
+* successfully committed.
+*
+* A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors
+* were not committed because there was nothing to commit in the list.  All the
+* buffer descriptors which are in the list are commited.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+int XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the buffer descriptor to be committed is already committed or
+	 * the list is empty (none have been put in), then indicate an error
+	 */
+	if ((InstancePtr->CommitPtr == NULL) ||
+	    XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_NOTHING_TO_COMMIT;
+	}
+
+	/* last descriptor in the list must have scatter gather disabled so the end
+	 * of the list is hit by h/w, if descriptor to commit is not last in list,
+	 * commit descriptors by enabling scatter gather in the descriptor
+	 */
+	if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
+		u32 Control;
+
+		Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
+		XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
+					  ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+
+	/* Buffer Descriptors are committed. DMA is ready to be enabled */
+	InstancePtr->Committed = TRUE;
+
+	/* Update the commit pointer to indicate that there is nothing to be
+	 * committed, this state is used by start processing to know that the
+	 * buffer descriptor to start is not waiting to be committed
+	 */
+	InstancePtr->CommitPtr = NULL;
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetDescriptor
+*
+* DESCRIPTION:
+*
+* This function gets a buffer descriptor from the scatter gather list of the
+* DMA channel. The buffer descriptor is retrieved from the scatter gather list
+* and the scatter gather list is updated to not include the retrieved buffer
+* descriptor.  This is typically done after a scatter gather operation
+* completes indicating that a data buffer has been successfully sent or data
+* has been received into the data buffer. The purpose of this function is to
+* allow the device using the scatter gather operation to get the results of the
+* operation.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which
+* was retrieved from the list.  The buffer descriptor is not really removed
+* from the list, but it is changed to a state such that the hardware will not
+* use it again until it is put into the scatter gather list of the DMA channel.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if a buffer descriptor was retrieved from
+* the scatter gather list of the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates no buffer descriptor was
+* retrieved from the list because there are no buffer descriptors to be
+* processed in the list.
+*
+* BufDescriptorPtr is updated to point to the buffer descriptor which was
+* retrieved from the list if the status indicates success.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+int
+XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the buffer descriptor list is empty, then indicate an error */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* retrieve the next buffer descriptor which is ready to be processed from
+	 * the buffer descriptor list for the DMA channel, set the control word
+	 * such that hardware will stop after the descriptor has been processed
+	 */
+	Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
+	XBufDescriptor_SetControl(InstancePtr->GetPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set the input argument, which is also an output, to point to the
+	 * buffer descriptor which is to be retrieved from the list
+	 */
+	*BufDescriptorPtr = InstancePtr->GetPtr;
+
+	/* update the pointer of the DMA channel to reflect the buffer descriptor
+	 * was retrieved from the list by setting it to the next buffer descriptor
+	 * in the list and indicate one less descriptor in the list now
+	 */
+	InstancePtr->GetPtr =
+		P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->GetPtr));
+	InstancePtr->ActiveDescriptorCount--;
+
+	return XST_SUCCESS;
+}
+
+/*********************** Interrupt Collescing Functions **********************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktCount
+*
+* DESCRIPTION:
+*
+* This function returns the value of the unserviced packet count register of
+* the DMA channel.  This count represents the number of packets that have been
+* sent or received by the hardware, but not processed by software.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The unserviced packet counter register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the unserviced packet count from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_DecrementPktCount
+*
+* DESCRIPTION:
+*
+* This function decrements the value of the unserviced packet count register.
+* This informs the hardware that the software has processed a packet.  The
+* unserviced packet count register may only be decremented by one in the
+* hardware.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the unserviced packet count register can be decremented (rather
+	 * than rolling over) decrement it by writing a 1 to the register,
+	 * this is the only valid write to the register as it serves as an
+	 * acknowledge that a packet was handled by the software
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+	if (Register > 0) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
+			  1UL);
+	}
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet count threshold register of the
+* DMA channel.  It reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement
+* a concept called "interrupt coalescing", which is used to reduce the number
+* of interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* Threshold is the value that is written to the threshold register of the
+* DMA channel.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if the packet count threshold was
+* successfully set.
+*
+* NOTES:
+*
+* The packet threshold could be set to larger than the number of descriptors
+* allocated to the DMA channel. In this case, the wait bound will take over
+* and always indicate data arrival. There was a check in this function that
+* returned an error if the treshold was larger than the number of descriptors,
+* but that was removed because users would then have to set the threshold
+* only after they set descriptor space, which is an order dependency that
+* caused confustion.
+*
+******************************************************************************/
+int XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
+{
+	/* assert to verify input arguments, don't assert the threshold since
+	 * it's range is unknown
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet count threshold in the register such that an interrupt
+	 * may be generated, if enabled, when the packet count threshold is
+	 * reached or exceeded
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
+		  (u32) Threshold);
+
+	/* indicate the packet count threshold was successfully set */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet count threshold register of the
+* DMA channel.  This value reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement a concept
+* called "interrupt coalescing", which is used to reduce the number of
+* interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet threshold register contents for the DMA channel and is a value in
+* the range 0 - 1023.  A value of 0 indicates the packet wait bound timer is
+* disabled.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet count threshold from the register and return it,
+	 * since only 8 bits are used, cast it to return only those bits */
+
+	return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet wait bound register of the
+* DMA channel.  This value reflects the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* WaitBound is the value, in milliseconds, to be stored in the wait bound
+* register of the DMA channel and is a value in the range 0  - 1023.  A value
+* of 0 disables the packet wait bound timer.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(WaitBound < 1024);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet wait bound in the register such that interrupt may be
+	 * generated, if enabled, when packets have not been handled for a specific
+	 * amount of time
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet wait bound register of the
+* DMA channel.  This value contains the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet wait bound register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet wait bound from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3.c	2014-07-20 22:06:38.877264135 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3.c
+*
+* This file implements initialization and control related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/05 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+#include <asm/delay.h>
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* This function initializes a DMA channel.  This function must be called
+* prior to using a DMA channel. Initialization of a channel includes setting
+* up the register base address, setting up the instance data, and ensuring the
+* HW is in a quiescent state.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param BaseAddress is where the registers for this channel can be found.
+*        If address translation is being used, then this parameter must
+*        reflect the virtual base address.
+*
+* @return
+* - XST_SUCCESS if initialization was successful
+*
+******************************************************************************/
+int XDmaV3_Initialize(XDmaV3 * InstancePtr, u32 BaseAddress)
+{
+	u32 Dmasr;
+
+	/* Setup the instance */
+	memset(InstancePtr, 0, sizeof(XDmaV3));
+	InstancePtr->RegBase = BaseAddress;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+	InstancePtr->BdRing.RunState = XST_DMA_SG_IS_STOPPED;
+
+	/* If this is SGDMA channel, then make sure it is stopped */
+	Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (Dmasr & (XDMAV3_DMASR_DMACNFG_SGDMARX_MASK |
+		     XDMAV3_DMASR_DMACNFG_SGDMATX_MASK |
+		     XDMAV3_DMASR_DMACNFG_SSGDMA_MASK)) {
+		XDmaV3_SgStop(InstancePtr);
+	}
+
+	return (XST_SUCCESS);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3.h	2014-07-20 22:06:38.889263937 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3.h
+*
+* The Xilinx Simple and Scatter Gather DMA driver.  This component supports a
+* distributed DMA design in which each device can have it's own dedicated DMA
+* channel, as opposed to a centralized DMA design. A device which uses DMA
+* typically contains two DMA channels, one for sending data and the other for
+* receiving data.
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* For a full description of DMA features, please see the HW spec. This driver
+* supports the following features:
+*   - Simple DMA
+*   - Scatter-Gather DMA (SGDMA)
+*   - Interrupts
+*   - Programmable interrupt coalescing for SGDMA
+*   - 36 Bit bus addressing
+*   - Programmable transaction types
+*   - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA
+*     engine
+*   - Virtual memory support
+*
+* <b>Transactions</b>
+*
+* To describe a DMA transaction in its simplest form, you need a source address,
+* destination address, and the number of bytes to transfer. When using a DMA
+* receive channel, the source address is within some piece of IP HW and doesn't
+* require the user explicitly set it. Likewise with a transmit channel and the
+* destination address. So this leaves a user buffer address and the number
+* bytes to transfer as the primary transaction attributes. There are more
+* obscure attributes such as:
+*
+*   - Is the user buffer a fixed address FIFO or a range of memory
+*   - The size of the data bus over which the transaction occurs.
+*   - Does the transfer use single beat or bursting capabilities of the
+*     bus over which the transaction occurs.
+*   - If the transaction occurs on a bus wider than 32 bits, what are the
+*     highest order address bits.
+*   - If SGDMA, does this transaction represent the end of a packet.
+*
+* The object used to describe a transaction is referred to as a Buffer
+* Descriptor (BD). The format of a BD closely matches that of the DMA HW.
+* Many fields within the BD correspond directly with the same fields within the
+* HW registers. See xdmabdv3.h for a detailed description of and the API for
+* manipulation of these objects.
+*
+* <b>Simple DMA</b>
+*
+* Simple DMA is a single transaction type of operation. The user uses this
+* driver to setup a transaction, initiate the transaction, then either wait for
+* an interrupt or poll the HW for completion of the transaction. A new
+* transaction may not be initiated until the current one completes.
+*
+* <b>Scatter-Gather DMA</b>
+*
+* SGDMA is more sophisticated in that it allows the user to define a list of
+* transactions in memory which the HW will process without further user
+* intervention. During this time, the user is free to continue adding more work
+* to keep the HW busy.
+*
+* Notification of completed transactions can be done either by polling the HW,
+* or using interrupts that signal a transaction has completed or a series of
+* transactions have been processed.
+*
+* SGDMA processes in units of packets. A packet is defined as a series of
+* data bytes that represent a message. SGDMA allows a packet of data to be
+* broken up into one or more transactions. For example, take an Ethernet IP
+* packet which consists of a 14 byte header followed by a 1 or more byte
+* payload. With SGDMA, the user may point a BD to the header and another BD to
+* the payload, then transfer them as a single message. This strategy can make a
+* TCP/IP stack more efficient by allowing it to keep packet headers and data in
+* different memory regions instead of assembling packets into contiguous blocks
+* of memory.
+*
+* <b>Interrupt Coalescing</b>
+*
+* SGDMA provides control over the frequency of interrupts. On a high speed link
+* significant processor overhead may be used servicing interrupts. Interrupt
+* coalescing provides two mechanisms that help control interrupt frequency.
+*
+* The packet threshold will hold off interrupting the CPU until a programmable
+* number of packets have been processed by the engine. The packet waitbound
+* timer is used to interrupt the CPU if after a programmable amount of time
+* after processing the last packet, no new packets were processed.
+*
+* <b>Interrupts</b>
+*
+* This driver does not service interrupts. This is done typically within
+* a higher level driver that uses DMA. This driver does provide an API to
+* enable or disable specific interrupts.
+*
+* <b>SGDMA List Management</b>
+*
+* The HW expectes BDs to be setup as a singly linked list. As BDs are completed,
+* the DMA engine will dereference BD.Next and load the next BD to process.
+* This driver uses a fixed buffer ring where all BDs are linked to the next
+* adjacent BD in memory. The last BD in the ring is linked to the first.
+*
+* Within the BD ring, the driver maintains four groups of BDs. Each group
+* consists of 0 or more adjacent BDs:
+*
+*   - Free group: Those BDs that can be allocated by the user with
+*     XDmaV3_SgBdAlloc(). These BDs are under driver control.
+*
+*   - Pre-work group: Those BDs that have been allocated with
+*     XDmaV3_SgBdAlloc(). These BDs are under user control. The user modifies
+*     these BDs in preparation for future DMA transactions.
+*
+*   - Work group: Those BDs that have been enqueued to HW with
+*     XDmaV3_SgBdToHw(). These BDs are under HW control and may be in a
+*     state of awaiting HW processing, in process, or processed by HW.
+*
+*   - Post-work group: Those BDs that have been processed by HW and have been
+*     extracted from the work group with XDmaV3_SgBdFromHw(). These BDs are under
+*     user control. The user may access these BDs to determine the result
+*     of DMA transactions. When the user is finished, XDmaV3_SgBdFree() should
+*     be called to place them back into the Free group.
+*
+* It is considered an error for the user to change BDs while they are in the
+* Work group. Doing so can cause data corruption and lead to system instability.
+*
+* The API provides macros that allow BD list traversal. These macros should be
+* used with care as they do not understand where one group ends and another
+* begins.
+*
+* The driver does not cache or keep copies of any BD. When the user modifies
+* BDs returned by XDmaV3_SgBdAlloc() or XDmaV3_SgBdFromHw(), they are modifying
+* the same BD list that HW accesses.
+*
+* Certain pairs of list modification functions have usage restrictions. See
+* the function headers for XDmaV3_SgBdAlloc() and XDmaV3_SgBdFromHw() for
+* more information.
+*
+* <b>SGDMA List Creation</b>
+*
+* During initialization, the function XDmaV3_SgListCreate() is used to setup
+* a user supplied memory block to contain all BDs for the DMA channel. This
+* function takes as an argument the number of BDs to place in the list. To
+* arrive at this number, the user is given two methods of calculating it.
+*
+* The first method assumes the user has a block of memory and they just
+* want to fit as many BDs as possible into it. The user must calculate the
+* number of BDs that will fit with XDmaV3_mSgListCntCalc(), then supply that
+* number into the list creation function.
+*
+* The second method allows the user to just supply the number directly. The
+* driver assumes the memory block is large enough to contain them all. To
+* double-check, the user should invoke XDmaV3_mSgListMemCalc() to verify the
+* memory block is adequate.
+*
+* Once the list has been created, it can be used right away to perform DMA
+* transactions. However, there are optional steps that can be done to increase
+* throughput and decrease user code complexity by the use of XDmaV3_SgListClone().
+*
+* BDs have many user accessible attributes that affect how DMA transactions are
+* carried out. Many of these attributes (such as the bus width) will probably
+* be constant at run-time. The cloning function can be used to copy a template
+* BD to every BD in the list relieving the user of having to setup transactions
+* from scratch every time a BD is submitted to HW.
+*
+* Ideally, the only transaction parameters that need to be set at run-time
+* should be: buffer address, bytes to transfer, and whether the BD is the
+* "Last" BD of a packet.
+*
+* <b>Adding / Removing BDs from the SGDMA Engine</b>
+*
+* BDs may be enqueued (see XDmaV3_SgBdToHw()) to the engine any time after
+* the SGDMA list is created. If the channel is running (see XDmaV3_SgStart()),
+* then newly added BDs will be processed as soon as the engine reaches them.
+* If the channel is stopped (see XDmaV3_SgStop()), the newly added BDs will
+* be accepted but not processed by the engine until it is restarted.
+*
+* Processed BDs may be removed (see XDmaV3_SgBdFromHw()) at any time
+* after the SGDMA list is created provided the engine has processed any.
+*
+* <b>Address Translation</b>
+*
+* When the BD list is setup with XDmaV3_SgListCreate(), a physical and
+* virtual address is supplied for the segment of memory containing the
+* descriptors. The driver will handle any translations internally. Subsequent
+* access of descriptors by the user is done in terms of the virtual address.
+*
+* <b>Alignment</b>
+*
+* Except for 4 byte alignment of BDs there are no other alignment restrictions
+* imposed by this driver. Individual DMA channels may, based on their
+* capabilities or which bus they are a master of, have more stringent alignment
+* requirements. It is up to the user to match the requirements of the DMA
+* channel being used.
+*
+* Aside from the initial creation of BD list (see XDmaV3_SgListCreate()),
+* there are no other run-time checks for proper alignment. Misaligned user
+* buffers or BDs may result in corrupted data.
+*
+* <b>Cache Coherency</b>
+*
+* This driver expects all user buffers attached to BDs to be in cache coherent
+* memory. Buffers for transmit should be flushed from the cache before passing
+* the associated BD to this driver. Buffers for receive should be invalidated
+* before being accessed.
+*
+* If the user wishes that the BD space itself be in cached memory, then
+* modification of this driver is required. The driver helps the user in
+* this area by: 1) Allowing the user to specify what alignment BDs should
+* use (ie. aligned along cache lines); 2) Provide unimplemented invalidate/flush
+* macro placeholders in the driver source code where needed.
+*
+* <b>Reset After Stopping</b>
+*
+* This driver is designed to allow for stop-reset-start cycles of the DMA
+* HW while keeping the BD list intact. When restarted after a reset, this
+* driver will point the DMA engine to where it left off after stopping it.
+*
+* <b>Limitations</b>
+*
+* This driver requires exclusive use of the hardware DMACR.SGS bit. This
+* applies to the actual HW register and BDs submitted through this driver to
+* be processed. If a BD is encountered with this bit set, then it will be
+* cleared within the driver.
+*
+* This driver does not have any mechanism for mutual exclusion. It is up to the
+* user to provide this protection.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+*       rmm  06/22/06 Added extern "C"
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XDMAV3_H		/* prevent circular inclusions */
+#define XDMAV3_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xdmabdv3.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Minimum alignment */
+#define XDMABDV3_MINIMUM_ALIGNMENT  4
+
+
+/**************************** Type Definitions *******************************/
+
+/** This is an internal structure used to maintain the SGDMA list */
+typedef struct {
+	u32 PhysBaseAddr;
+		       /**< Physical address of 1st BD in list */
+	u32 BaseAddr;  /**< Virtual address of 1st BD in list */
+	u32 HighAddr;  /**< Virtual address of last BD in the list */
+	u32 Length;    /**< Total size of ring in bytes */
+	u32 RunState;  /**< Flag to indicate SGDMA is started */
+	u32 Separation;/**< Number of bytes between the starting address
+                                of adjacent BDs */
+	XDmaBdV3 *FreeHead;/**< First BD in the free group */
+	XDmaBdV3 *PreHead; /**< First BD in the pre-work group */
+	XDmaBdV3 *HwHead;  /**< First BD in the work group */
+	XDmaBdV3 *HwTail;  /**< Last BD in the work group */
+	XDmaBdV3 *PostHead;/**< First BD in the post-work group */
+	XDmaBdV3 *BdaRestart;
+			   /**< BDA to load when channel is started */
+	unsigned HwCnt;	   /**< Number of BDs in work group */
+	unsigned PreCnt;   /**< Number of BDs in pre-work group */
+	unsigned FreeCnt;  /**< Number of allocatable BDs in the free group */
+	unsigned PostCnt;  /**< Number of BDs in post-work group */
+	unsigned AllCnt;   /**< Total Number of BDs for channel */
+} XDmaV3_BdRing;
+
+/**
+ * The XDmaV3 driver instance data. An instance must be allocated for each DMA
+ * channel in use. If address translation is enabled, then all addresses and
+ * pointers excluding PhysBase are expressed in terms of the virtual address.
+ */
+typedef struct XDmaV3 {
+	u32 RegBase;	   /**< Base address of channel registers */
+	u32 IsReady;	   /**< Flag to indicate device is ready to use */
+	XDmaV3_BdRing BdRing;  /**< BD storage for SGDMA */
+} XDmaV3;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many BDs will fit
+* in a BD list within the given memory constraints.
+*
+* The results of this macro can be provided to XDmaV3_SgListCreate().
+*
+* @param Alignment specifies what byte alignment the BDs must fall on and
+*        must be a power of 2 to get an accurate calculation (32, 64, 126,...)
+* @param Bytes is the number of bytes to be used to store BDs.
+*
+* @return Number of BDs that can fit in the given memory area
+*
+* @note
+* C-style signature:
+*    u32 XDmaV3_mSgListCntCalc(u32 Alignment, u32 Bytes)
+*
+******************************************************************************/
+#define XDmaV3_mSgListCntCalc(Alignment, Bytes)                           \
+    (u32)((Bytes) / ((sizeof(XDmaBdV3) + ((Alignment)-1)) & ~((Alignment)-1)))
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many bytes of memory
+* is required to contain a given number of BDs at a given alignment.
+*
+* @param Alignment specifies what byte alignment the BDs must fall on. This
+*        parameter must be a power of 2 to get an accurate calculation (32, 64,
+*        128,...)
+* @param NumBd is the number of BDs to calculate memory size requirements for
+*
+* @return The number of bytes of memory required to create a BD list with the
+*         given memory constraints.
+*
+* @note
+* C-style signature:
+*    u32 XDmaV3_mSgListMemCalc(u32 Alignment, u32 NumBd)
+*
+******************************************************************************/
+#define XDmaV3_mSgListMemCalc(Alignment, NumBd)                           \
+    (u32)((sizeof(XDmaBdV3) + ((Alignment)-1)) & ~((Alignment)-1)) * (NumBd)
+
+
+/****************************************************************************/
+/**
+* Return the total number of BDs allocated by this channel with
+* XDmaV3_SgListCreate().
+*
+* @param  InstancePtr is the DMA channel to operate on.
+*
+* @return The total number of BDs allocated for this channel.
+*
+* @note
+* C-style signature:
+*    u32 XDmaBdV3_mSgGetCnt(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgGetCnt(InstancePtr)       ((InstancePtr)->BdRing.AllCnt)
+
+
+/****************************************************************************/
+/**
+* Return the number of BDs allocatable with XDmaV3_SgBdAlloc() for pre-
+* processing.
+*
+* @param  InstancePtr is the DMA channel to operate on.
+*
+* @return The number of BDs currently allocatable.
+*
+* @note
+* C-style signature:
+*    u32 XDmaBdV3_mSgGetFreeCnt(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgGetFreeCnt(InstancePtr)   ((InstancePtr)->BdRing.FreeCnt)
+
+
+/****************************************************************************/
+/**
+* Return the next BD in a list.
+*
+* @param  InstancePtr is the DMA channel to operate on.
+* @param  BdPtr is the BD to operate on.
+*
+* @return The next BD in the list relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+*    XDmaBdV3 *XDmaV3_mSgBdNext(XDmaV3* InstancePtr, XDmaBdV3 *BdPtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgBdNext(InstancePtr, BdPtr)                            \
+    (((u32)(BdPtr) >= (InstancePtr)->BdRing.HighAddr) ?             \
+     (XDmaBdV3*)(InstancePtr)->BdRing.BaseAddr :                        \
+     (XDmaBdV3*)((u32)(BdPtr) + (InstancePtr)->BdRing.Separation))
+
+
+/****************************************************************************/
+/**
+* Return the previous BD in the list.
+*
+* @param  InstancePtr is the DMA channel to operate on.
+* @param  BdPtr is the BD to operate on
+*
+* @return The previous BD in the list relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+*    XDmaBdV3 *XDmaV3_mSgBdPrev(XDmaV3* InstancePtr, XDmaBdV3 *BdPtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgBdPrev(InstancePtr, BdPtr)                            \
+    (((u32)(BdPtr) <= (InstancePtr)->BdRing.BaseAddr) ?             \
+     (XDmaBdV3*)(InstancePtr)->BdRing.HighAddr :                        \
+     (XDmaBdV3*)((u32)(BdPtr) - (InstancePtr)->BdRing.Separation))
+
+
+/****************************************************************************/
+/**
+* Retrieve the current contents of the DMASR register. This macro can be
+* used to poll the DMA HW for completion of a transaction.
+*
+* @param  InstancePtr is the DMA channel to operate on.
+*
+* @return The current contents of the DMASR register.
+*
+* @note
+* C-style signature:
+*    u32 XDmaV3_mGetStatus(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mGetStatus(InstancePtr)                                  \
+    XDmaV3_mReadReg((InstancePtr)->RegBase, XDMAV3_DMASR_OFFSET)
+
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization and control functions in xdmav3.c
+ */
+int XDmaV3_Initialize(XDmaV3 * InstancePtr, u32 BaseAddress);
+
+/*
+ * Interrupt related functions in xdmav3_intr.c
+ */
+void XDmaV3_SetInterruptStatus(XDmaV3 * InstancePtr, u32 Mask);
+u32 XDmaV3_GetInterruptStatus(XDmaV3 * InstancePtr);
+void XDmaV3_SetInterruptEnable(XDmaV3 * InstancePtr, u32 Mask);
+u32 XDmaV3_GetInterruptEnable(XDmaV3 * InstancePtr);
+
+/*
+ * Simple DMA related functions in xdmav3_simple.c
+ */
+int XDmaV3_SimpleTransfer(XDmaV3 * InstancePtr, XDmaBdV3 * Bdptr);
+
+/*
+ * Scatter gather DMA related functions in xdmav3_sg.c
+ */
+int XDmaV3_SgStart(XDmaV3 * InstancePtr);
+void XDmaV3_SgStop(XDmaV3 * InstancePtr);
+int XDmaV3_SgSetPktThreshold(XDmaV3 * InstancePtr, u16 Threshold);
+int XDmaV3_SgSetPktWaitbound(XDmaV3 * InstancePtr, u16 TimerVal);
+u16 XDmaV3_SgGetPktThreshold(XDmaV3 * InstancePtr);
+u16 XDmaV3_SgGetPktWaitbound(XDmaV3 * InstancePtr);
+
+int XDmaV3_SgListCreate(XDmaV3 * InstancePtr, u32 PhysAddr,
+			u32 VirtAddr, u32 Alignment, unsigned BdCount);
+int XDmaV3_SgListClone(XDmaV3 * InstancePtr, XDmaBdV3 * SrcBdPtr);
+int XDmaV3_SgCheck(XDmaV3 * InstancePtr);
+int XDmaV3_SgBdAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+		     XDmaBdV3 ** BdSetPtr);
+int XDmaV3_SgBdUnAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+		       XDmaBdV3 * BdSetPtr);
+int XDmaV3_SgBdToHw(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr);
+int XDmaV3_SgBdFree(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr);
+unsigned XDmaV3_SgBdFromHw(XDmaV3 * InstancePtr, unsigned BdLimit,
+			   XDmaBdV3 ** BdSetPtr);
+
+/*
+ * Selftest functions in xdmav3_selftest.c
+ */
+int XDmaV3_SelfTest(XDmaV3 * InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_intr.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_intr.c	2014-07-20 22:06:38.896263822 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_intr.c
+*
+* This file implements interrupt control related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Set the interrupt status register for this channel. Use this function
+* to ack pending interrupts.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask is a logical OR of XDMAV3_IPXR_*_MASK constants found in
+*        xdmav3_l.h.
+*
+******************************************************************************/
+void XDmaV3_SetInterruptStatus(XDmaV3 * InstancePtr, u32 Mask)
+{
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_ISR_OFFSET, Mask);
+}
+
+
+/*****************************************************************************/
+/**
+* Retrieve the interrupt status for this channel. OR the results of this
+* function with results from XDmaV3_GetInterruptEnable() to determine which
+* interrupts are currently pending to the processor.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return Mask of interrupt bits made up of XDMAV3_IPXR_*_MASK constants found
+*         in xdmav3_l.h.
+*
+******************************************************************************/
+u32 XDmaV3_GetInterruptStatus(XDmaV3 * InstancePtr)
+{
+	return (XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_ISR_OFFSET));
+}
+
+
+/*****************************************************************************/
+/**
+* Enable specific DMA interrupts.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask is a logical OR of of XDMAV3_IPXR_*_MASK constants found in
+*        xdmav3_l.h.
+*
+******************************************************************************/
+void XDmaV3_SetInterruptEnable(XDmaV3 * InstancePtr, u32 Mask)
+{
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, Mask);
+}
+
+
+/*****************************************************************************/
+/**
+* Retrieve the interrupt enable register for this channel. Use this function to
+* determine which interrupts are currently enabled to the processor.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return Mask of interrupt bits made up of XDMAV3_IPXR_*_MASK constants found in
+*         xdmav3_l.h.
+*
+******************************************************************************/
+u32 XDmaV3_GetInterruptEnable(XDmaV3 * InstancePtr)
+{
+	return (XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET));
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_l.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_l.h	2014-07-20 22:06:38.905263673 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the Direct Memory Access and Scatter
+* Gather (SG DMA) device.
+*
+* For more information about the operation of this device, see the hardware
+* specification and documentation in the higher level driver xdma.h source
+* code file.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+*       rmm  06/22/06 Added extern "C"
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XDMAV3_L_H		/* prevent circular inclusions */
+#define XDMAV3_L_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name DMA channel registers
+ *  @{
+ */
+#define XDMAV3_DMASR_OFFSET  0x00000000	 /**< DMA Status Register */
+#define XDMAV3_DMACR_OFFSET  0x00000004	 /**< DMA Control Register */
+#define XDMAV3_MSBA_OFFSET   0x00000008	 /**< Most Significant Bus Address */
+#define XDMAV3_LSBA_OFFSET   0x0000000C	 /**< Least Significant Bus Address */
+#define XDMAV3_BDA_OFFSET    0x00000010	 /**< Buffer Descriptor Address */
+#define XDMAV3_LENGTH_OFFSET 0x00000014	 /**< DMA Length */
+#define XDMAV3_ISR_OFFSET    0x00000018	 /**< Interrupt Status Register */
+#define XDMAV3_IER_OFFSET    0x0000001C	 /**< Interrupt Enable Register */
+#define XDMAV3_SWCR_OFFSET   0x00000020	 /**< Software Control Register */
+/*@}*/
+
+/** @name Buffer Descriptor register offsets
+ *  @{
+ */
+#define XDMAV3_BD_DMASR_OFFSET     0x00	 /**< Channel DMASR register contents */
+#define XDMAV3_BD_DMACR_OFFSET     0x04	 /**< Channel DMACR register contents */
+#define XDMAV3_BD_MSBA_OFFSET      0x08	 /**< Channel MSBA register contents */
+#define XDMAV3_BD_LSBA_OFFSET      0x0C	 /**< Channel LSBA register contents */
+#define XDMAV3_BD_BDA_OFFSET       0x10	 /**< Next buffer descriptor pointer */
+#define XDMAV3_BD_LENGTH_OFFSET    0x14	 /**< Channel LENGTH register contents */
+#define XDMAV3_BD_SR_OFFSET        0x18	 /**< Packet Status */
+#define XDMAV3_BD_RSVD_OFFSET      0x1C	 /**< Reserved */
+#define XDMAV3_BD_USR0_OFFSET      0x20	 /**< HW User defined */
+#define XDMAV3_BD_USR1_OFFSET      0x24	 /**< HW User defined */
+#define XDMAV3_BD_USR2_OFFSET      0x28	 /**< HW User defined */
+#define XDMAV3_BD_USR3_OFFSET      0x2C	 /**< HW User defined */
+#define XDMAV3_BD_USR4_OFFSET      0x30	 /**< HW User defined */
+#define XDMAV3_BD_USR5_OFFSET      0x34	 /**< HW User defined */
+#define XDMAV3_BD_LENCPY_OFFSET    0x38	 /**< SW Driver usage */
+#define XDMAV3_BD_ID_OFFSET        0x3C	 /**< SW Driver usage */
+
+#define XDMAV3_BD_NUM_WORDS        16	 /**< Number of 32-bit words that make
+                                              up a BD */
+/*@}*/
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+
+/** @name DMA Status Register (DMASR) bitmasks
+ *  @note These bitmasks are identical between XDMAV3_DMASR_OFFSET and
+ *  XDMAV3_BD_DMASR_OFFSET
+ * @{
+ */
+#define XDMAV3_DMASR_DMABSY_MASK  0x80000000  /**< DMA busy */
+#define XDMAV3_DMASR_DBE_MASK     0x40000000  /**< Bus error */
+#define XDMAV3_DMASR_DBT_MASK     0x20000000  /**< Bus timeout */
+#define XDMAV3_DMASR_DMADONE_MASK 0x10000000  /**< DMA done */
+#define XDMAV3_DMASR_SGBSY_MASK   0x08000000  /**< SG channel busy */
+#define XDMAV3_DMASR_LAST_MASK    0x04000000  /**< Last BD of packet */
+#define XDMAV3_DMASR_SGDONE_MASK  0x01000000  /**< SGDMA done */
+#define XDMAV3_DMASR_DMACNFG_MASK 0x00300000  /**< DMA configuration */
+
+#define XDMAV3_DMASR_DMACNFG_SIMPLE_MASK  0x00000000  /**< Simple DMA config */
+#define XDMAV3_DMASR_DMACNFG_SSGDMA_MASK  0x00100000  /**< Simple SGDMA config */
+#define XDMAV3_DMASR_DMACNFG_SGDMATX_MASK 0x00200000  /**< SGDMA xmit config */
+#define XDMAV3_DMASR_DMACNFG_SGDMARX_MASK 0x00300000  /**< SGDMA recv config */
+#define XDMAV3_DMASR_DMACNFG_MASK         0x00300000  /**< Mask for all */
+
+/*@}*/
+
+/** @name DMA Control Register (DMACR) bitmasks
+ *  @note These bitmasks are identical between XDMAV3_DMACR_OFFSET and
+ *  XDMAV3_BD_DMACR_OFFSET
+ * @{
+ */
+#define XDMAV3_DMACR_AINC_MASK    0x80000000  /**< Address increment */
+#define XDMAV3_DMACR_BPDRE_MASK   0x20000000  /**< Bypass DRE */
+#define XDMAV3_DMACR_SGS_MASK     0x08000000  /**< Scatter gather stop */
+#define XDMAV3_DMACR_LAST_MASK    0x04000000  /**< Last BD of packet */
+#define XDMAV3_DMACR_DEVSEL_MASK  0x00FF0000  /**< Device select */
+#define XDMAV3_DMACR_BDPAGE_MASK  0x00000F00  /**< BD page address */
+#define XDMAV3_DMACR_TYPE_MASK    0x00000070  /**< DMA transfer type */
+#define XDMAV3_DMACR_DSIZE_MASK   0x00000007  /**< DMA transfer width */
+
+/* Sub-fields within XDMAV3_DMACR_DIR_MASK */
+#define XDMAV3_DMACR_DIR_RX_MASK       0x40000000  /**< Xfer in Rx direction */
+#define XDMAV3_DMACR_DIR_TX_MASK       0x00000000  /**< Xfer in Tx direction */
+
+/* Sub-fields within XDMAV3_DMACR_TYPE_MASK */
+#define XDMAV3_DMACR_TYPE_BFBURST_MASK 0x00000010  /**< Bounded fixed length
+                                                        burst */
+#define XDMAV3_DMACR_TYPE_BIBURST_MASK 0x00000020  /**< Bounded indeterminate
+                                                        burst */
+
+/* Sub-fields within XDMAV3_DMACR_DSIZE_MASK */
+#define XDMAV3_DMACR_DSIZE_8_MASK      0x00000000  /**< Xfer width = 8 bits */
+#define XDMAV3_DMACR_DSIZE_16_MASK     0x00000001  /**< Xfer width = 16 bits */
+#define XDMAV3_DMACR_DSIZE_32_MASK     0x00000002  /**< Xfer width = 32 bits */
+#define XDMAV3_DMACR_DSIZE_64_MASK     0x00000003  /**< Xfer width = 64 bits */
+#define XDMAV3_DMACR_DSIZE_128_MASK    0x00000004  /**< Xfer width = 128 bits */
+
+/* Left shift values for selected masks */
+#define XDMAV3_DMACR_DEVSEL_SHIFT      16
+#define XDMAV3_DMACR_BDPAGE_SHIFT      8
+/*@}*/
+
+/** @name Interrupt status bits for MAC interrupts
+ *  These bits are associated with XDMAV3_ISR_OFFSET and
+ *  XDMAV3_IER_OFFSET registers.
+ *  @{
+ */
+#define XDMAV3_IPXR_DD_MASK      0x00000040  /**< DMA complete */
+#define XDMAV3_IPXR_DE_MASK      0x00000020  /**< DMA error */
+#define XDMAV3_IPXR_PD_MASK      0x00000010  /**< Pkt done */
+#define XDMAV3_IPXR_PCTR_MASK    0x00000008  /**< Pkt count threshold reached */
+#define XDMAV3_IPXR_PWBR_MASK    0x00000004  /**< Pkt waitbound reached */
+#define XDMAV3_IPXR_SGDA_MASK    0x00000002  /**< SG Disable ack */
+#define XDMAV3_IPXR_SGEND_MASK   0x00000001  /**< SG End */
+/*@}*/
+
+/** @name Software control register (SWCR) bitmasks
+ *  @{
+ */
+#define XDMAV3_SWCR_SGE_MASK     0x80000000  /**< SG Enable */
+#define XDMAV3_SWCR_SGD_MASK     0x40000000  /**< SG Disable */
+#define XDMAV3_SWCR_DSGAR_MASK   0x20000000  /**< SG Disable auto-restart */
+#define XDMAV3_SWCR_PWB_MASK     0x00FFF000  /**< Pkt waitbound */
+#define XDMAV3_SWCR_PCT_MASK     0x00000FFF  /**< Pkt threshold count */
+
+/* Left shift values for selected masks */
+#define XDMAV3_SWCR_PCT_SHIFT    0
+#define XDMAV3_SWCR_PWB_SHIFT    12
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/****************************************************************************/
+/**
+*
+* Read the given IPIF register.
+*
+* @param    BaseAddress is the IPIF base address of the device
+* @param    RegOffset is the register offset to be read
+*
+* @return   The 32-bit value of the register
+*
+* @note
+* C-style signature:
+*    u32 XDmaV3_mReadReg(u32 BaseAddress, u32 RegOffset)
+*
+*****************************************************************************/
+#define XDmaV3_mReadReg(BaseAddress, RegOffset) \
+    XIo_In32((u32)(BaseAddress) + (u32)(RegOffset))
+
+
+/****************************************************************************/
+/**
+*
+* Write the given IPIF register.
+*
+* @param    BaseAddress is the IPIF base address of the device
+* @param    RegOffset is the register offset to be written
+* @param    Data is the 32-bit value to write to the register
+*
+* @return   None.
+*
+* @note
+* C-style signature:
+*    void XDmaV3_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+*****************************************************************************/
+#define XDmaV3_mWriteReg(BaseAddress, RegOffset, Data)  \
+    XIo_Out32((u32)(BaseAddress) + (u32)(RegOffset), (u32)(Data))
+
+
+/****************************************************************************/
+/**
+*
+* Read the given Buffer Descriptor word.
+*
+* @param    BaseAddress is the base address of the BD to read
+* @param    Offset is the word offset to be read
+*
+* @return   The 32-bit value of the field
+*
+* @note
+* C-style signature:
+*    u32 XDmaV3_mReadBd(u32 BaseAddress, u32 Offset)
+*
+*****************************************************************************/
+#define XDmaV3_mReadBd(BaseAddress, Offset)             \
+    (*(u32*)((u32)(BaseAddress) + (u32)(Offset)))
+
+
+/****************************************************************************/
+/**
+*
+* Write the given Buffer Descriptor word.
+*
+* @param    BaseAddress is the base address of the BD to write
+* @param    Offset is the word offset to be written
+* @param    Data is the 32-bit value to write to the field
+*
+* @return   None.
+*
+* @note
+* C-style signature:
+*    void XDmaV3_mWriteReg(u32 BaseAddress, u32 Offset, u32 Data)
+*
+*****************************************************************************/
+#define XDmaV3_mWriteBd(BaseAddress, Offset, Data)              \
+    (*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_selftest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_selftest.c	2014-07-20 22:06:38.914263525 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_selftest.c
+*
+* This file implements DMA selftest related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Selftest is not implemented.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return
+* - XST_SUCCESS if the self test passes
+*
+******************************************************************************/
+int XDmaV3_SelfTest(XDmaV3 * InstancePtr)
+{
+	return (XST_SUCCESS);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_sg.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_sg.c	2014-07-20 22:06:38.932263228 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_sg.c
+*
+* This file implements Scatter-Gather DMA (SGDMA) related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+*       rmm  06/22/06 Fixed C++ compiler warnings
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+#include <asm/delay.h>
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/****************************************************************************
+ * These cache macros are used throughout this source code file to show
+ * users where cache operations should occur if BDs were to be placed in
+ * a cached memory region. Cacheing BD regions, however, is not common.
+ *
+ * The macros are implemented as NULL operations, but may be hooked into
+ * XENV macros in future revisions of this driver.
+ ****************************************************************************/
+#define XDMAV3_CACHE_FLUSH(BdPtr)
+#define XDMAV3_CACHE_INVALIDATE(BdPtr)
+
+/****************************************************************************
+ * Compute the virtual address of a descriptor from its physical address
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @param BdPtr is the physical address of the BD
+ *
+ * @returns Virtual address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ ****************************************************************************/
+#define XDMAV3_PHYS_TO_VIRT(Ring, BdPtr) \
+    ((u32)BdPtr + (Ring->BaseAddr - Ring->PhysBaseAddr))
+
+/****************************************************************************
+ * Compute the physical address of a descriptor from its virtual address
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @param BdPtr is the physical address of the BD
+ *
+ * @returns Physical address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ ****************************************************************************/
+#define XDMAV3_VIRT_TO_PHYS(Ring, BdPtr) \
+    ((u32)BdPtr - (Ring->BaseAddr - Ring->PhysBaseAddr))
+
+/****************************************************************************
+ * Clear or set the SGS bit of the DMACR register
+ ****************************************************************************/
+#define XDMAV3_HW_SGS_CLEAR                                             \
+    XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET,         \
+                     XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET) \
+                     & ~XDMAV3_DMACR_SGS_MASK)
+
+#define XDMAV3_HW_SGS_SET                                               \
+    XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET,         \
+                     XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET) \
+                     | XDMAV3_DMACR_SGS_MASK)
+
+/****************************************************************************
+ * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around
+ * to the beginning of the ring if needed.
+ *
+ * We know if a wrapaound should occur if the new BdPtr is greater than
+ * the high address in the ring OR if the new BdPtr crosses over the
+ * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
+ * allow a BD space to span this boundary.
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ *        final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ ****************************************************************************/
+#define XDMAV3_RING_SEEKAHEAD(Ring, BdPtr, NumBd)                       \
+    {                                                                   \
+        u32 Addr = (u32)BdPtr;                                  \
+                                                                        \
+        Addr += (Ring->Separation * NumBd);                             \
+        if ((Addr > Ring->HighAddr) || ((u32)BdPtr > Addr))         \
+        {                                                               \
+            Addr -= Ring->Length;                                       \
+        }                                                               \
+                                                                        \
+        BdPtr = (XDmaBdV3*)Addr;                                        \
+    }
+
+/****************************************************************************
+ * Move the BdPtr argument backwards an arbitrary number of BDs wrapping
+ * around to the end of the ring if needed.
+ *
+ * We know if a wrapaound should occur if the new BdPtr is less than
+ * the base address in the ring OR if the new BdPtr crosses over the
+ * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
+ * allow a BD space to span this boundary.
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ *        final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ ****************************************************************************/
+#define XDMAV3_RING_SEEKBACK(Ring, BdPtr, NumBd)                        \
+    {                                                                   \
+        u32 Addr = (u32)BdPtr;                                  \
+                                                                        \
+        Addr -= (Ring->Separation * NumBd);                             \
+        if ((Addr < Ring->BaseAddr) || ((u32)BdPtr < Addr))         \
+        {                                                               \
+            Addr += Ring->Length;                                       \
+        }                                                               \
+                                                                        \
+        BdPtr = (XDmaBdV3*)Addr;                                        \
+    }
+
+
+/************************** Function Prototypes ******************************/
+
+static int IsSgDmaChannel(XDmaV3 * InstancePtr);
+
+
+/************************** Variable Definitions *****************************/
+
+/******************************************************************************/
+/**
+ * Start the SGDMA channel.
+ *
+ * @param InstancePtr is a pointer to the instance to be started.
+ *
+ * @return
+ * - XST_SUCCESS if channel was started.
+ * - XST_DMA_SG_NO_LIST if the channel has no initialized BD ring.
+ *
+ ******************************************************************************/
+int XDmaV3_SgStart(XDmaV3 * InstancePtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+	u32 Swcr;
+
+	/* BD list has yet to be created for this channel */
+	if (Ring->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Do nothing if already started */
+	if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_SUCCESS);
+	}
+
+	/* Note as started */
+	Ring->RunState = XST_DMA_SG_IS_STARTED;
+
+	/* Restore BDA */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_BDA_OFFSET,
+			 Ring->BdaRestart);
+
+	/* If there are unprocessed BDs then we want to channel to begin processing
+	 * right away
+	 */
+	if ((XDmaV3_mReadBd(XDMAV3_PHYS_TO_VIRT(Ring, Ring->BdaRestart),
+			    XDMAV3_BD_DMASR_OFFSET) & XDMAV3_DMASR_DMADONE_MASK)
+	    == 0) {
+		/* DMACR.SGS = 0 */
+		XDMAV3_HW_SGS_CLEAR;
+	}
+
+	/* To start, clear SWCR.DSGAR, and set SWCR.SGE */
+	Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	Swcr &= ~XDMAV3_SWCR_DSGAR_MASK;
+	Swcr |= XDMAV3_SWCR_SGE_MASK;
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Swcr);
+
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Stop the SGDMA or Simple SGDMA channel gracefully. Any DMA operation
+ * currently in progress is allowed to finish.
+ *
+ * An interrupt may be generated as the DMA engine finishes the packet in
+ * process. To prevent this (if desired) then disabled DMA interrupts prior to
+ * invoking this function.
+ *
+ * If after stopping the channel, new BDs are enqueued with XDmaV3_SgBdToHw(),
+ * then those BDs will not be processed until after XDmaV3_SgStart() is called.
+ *
+ * @param InstancePtr is a pointer to the instance to be stopped.
+ *
+ * @note This function will block until the HW indicates that DMA has stopped.
+ *
+ ******************************************************************************/
+void XDmaV3_SgStop(XDmaV3 * InstancePtr)
+{
+	volatile u32 Swcr;
+	u32 Dmasr;
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+	u32 Ier;
+
+	/* Save the contents of the interrupt enable register then disable
+	 * interrupts. This register will be restored at the end of the function
+	 */
+	Ier = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET);
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, 0);
+
+	/* Stopping the HW is a three step process:
+	 *   1. Set SWCR.SGD=1
+	 *   2. Wait for SWCR.SGE=0
+	 *   3. Set SWCR.DSGAR=0 and SWCR.SGE=1
+	 *
+	 * Once we've successfully gone through this process, the HW is fully
+	 * stopped. To restart we must give the HW a new BDA.
+	 */
+	Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+
+	/* If the channel is currently active, stop it by setting SWCR.SGD=1
+	 * and waiting for SWCR.SGE to toggle to 0
+	 */
+	if (Swcr & XDMAV3_SWCR_SGE_MASK) {
+		Swcr |= XDMAV3_SWCR_SGD_MASK;
+		XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+				 Swcr);
+
+		while (Swcr & XDMAV3_SWCR_SGE_MASK) {
+			Swcr = XDmaV3_mReadReg(InstancePtr->RegBase,
+					       XDMAV3_SWCR_OFFSET);
+		}
+	}
+
+	/* Note as stopped */
+	Ring->RunState = XST_DMA_SG_IS_STOPPED;
+
+	/* Save the BDA to restore when channel is restarted */
+	Ring->BdaRestart =
+		(XDmaBdV3 *) XDmaV3_mReadReg(InstancePtr->RegBase,
+					     XDMAV3_BDA_OFFSET);
+
+	/* If this is a receive channel, then the BDA restore may require a more
+	 * complex treatment. If the channel stopped without processing a packet,
+	 * then DMASR.SGDONE will be clear. The BDA we've already read in this case
+	 * is really BDA->BDA so we need to backup one BDA to get the correct
+	 * restart point.
+	 */
+	Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if ((Dmasr & XDMAV3_DMASR_DMACNFG_MASK) ==
+	    XDMAV3_DMASR_DMACNFG_SGDMARX_MASK) {
+		if (!(Dmasr & XDMAV3_DMASR_SGDONE_MASK)) {
+			Ring->BdaRestart =
+				(XDmaBdV3 *) XDMAV3_PHYS_TO_VIRT(Ring,
+								 Ring->
+								 BdaRestart);
+			Ring->BdaRestart =
+				XDmaV3_mSgBdPrev(InstancePtr, Ring->BdaRestart);
+			Ring->BdaRestart =
+				(XDmaBdV3 *) XDMAV3_VIRT_TO_PHYS(Ring,
+								 Ring->
+								 BdaRestart);
+		}
+	}
+
+	Swcr |= XDMAV3_SWCR_DSGAR_MASK;
+	Swcr &= ~XDMAV3_SWCR_SGD_MASK;
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Swcr);
+
+	/* Restore interrupt enables. If an interrupt occurs due to this function
+	 * stopping the channel then it will happen right here
+	 */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, Ier);
+}
+
+
+/******************************************************************************/
+/**
+ * Set the packet threshold for this SGDMA channel. This has the effect of
+ * delaying processor interrupts until the given number of packets (not BDs)
+ * have been processed.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Threshold is the packet threshold to set. If 0 is specified, then
+ *        this feature is disabled. Maximum threshold is 2^12 - 1.
+ *
+ * @return
+ * - XST_SUCCESS if threshold set properly.
+ * - XST_NO_FEATURE if this function was called on a DMA channel that does not
+ *   have interrupt coalescing capabilities.
+ *
+ * @note This function should not be prempted by another XDmaV3 function.
+ *
+ ******************************************************************************/
+int XDmaV3_SgSetPktThreshold(XDmaV3 * InstancePtr, u16 Threshold)
+{
+	u32 Reg;
+
+	/* Is this a SGDMA channel */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (!IsSgDmaChannel(InstancePtr)) {
+		return (XST_NO_FEATURE);
+	}
+
+	/* Replace the pkt threshold field in the SWCR */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	Reg &= ~XDMAV3_SWCR_PCT_MASK;
+	Reg |= ((Threshold << XDMAV3_SWCR_PCT_SHIFT) & XDMAV3_SWCR_PCT_MASK);
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Reg);
+
+	/* Finished */
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Set the packet waitbound timer for this SGDMA channel. See xdmav3.h for more
+ * information on interrupt coalescing and the effects of the waitbound timer.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param TimerVal is the waitbound period to set. If 0 is specified, then
+ *        this feature is disabled. Maximum waitbound is 2^12 - 1. LSB is
+ *        1 millisecond (approx).
+ *
+ * @return
+ * - XST_SUCCESS if waitbound set properly.
+ * - XST_NO_FEATURE if this function was called on a DMA channel that does not
+ *   have interrupt coalescing capabilities.
+ *
+ * @note This function should not be prempted by another XDmaV3 function.
+ *
+ ******************************************************************************/
+int XDmaV3_SgSetPktWaitbound(XDmaV3 * InstancePtr, u16 TimerVal)
+{
+	u32 Reg;
+
+	/* Is this a SGDMA channel */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (!IsSgDmaChannel(InstancePtr)) {
+		return (XST_NO_FEATURE);
+	}
+
+	/* Replace the waitbound field in the SWCR */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	Reg &= ~XDMAV3_SWCR_PWB_MASK;
+	Reg |= ((TimerVal << XDMAV3_SWCR_PWB_SHIFT) & XDMAV3_SWCR_PWB_MASK);
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Reg);
+
+	/* Finished */
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Get the packet threshold for this channel that was set with
+ * XDmaV3_SgSetPktThreshold().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return Current packet threshold as reported by HW. If the channel does not
+ *         include interrupt coalescing, then the return value will always be 0.
+ ******************************************************************************/
+u16 XDmaV3_SgGetPktThreshold(XDmaV3 * InstancePtr)
+{
+	u32 Reg;
+
+	/* Is this a SGDMA channel */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (!IsSgDmaChannel(InstancePtr)) {
+		return (0);
+	}
+
+	/* Get the threshold */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	Reg &= XDMAV3_SWCR_PCT_MASK;
+	Reg >>= XDMAV3_SWCR_PCT_SHIFT;
+	return ((u16) Reg);
+}
+
+
+/******************************************************************************/
+/**
+ * Get the waitbound timer for this channel that was set with
+ * XDmaV3_SgSetPktWaitbound().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return Current waitbound timer as reported by HW. If the channel does not
+ *         include interrupt coalescing, then the return value will always be 0.
+ ******************************************************************************/
+u16 XDmaV3_SgGetPktWaitbound(XDmaV3 * InstancePtr)
+{
+	u32 Reg;
+
+	/* Is this a SGDMA channel */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (!IsSgDmaChannel(InstancePtr)) {
+		return (0);
+	}
+
+	/* Get the threshold */
+	Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	Reg &= XDMAV3_SWCR_PWB_MASK;
+	Reg >>= XDMAV3_SWCR_PWB_SHIFT;
+	return ((u16) Reg);
+}
+
+
+/******************************************************************************/
+/**
+ * Using a memory segment allocated by the caller, create and setup the BD list
+ * for the given SGDMA channel.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param PhysAddr is the physical base address of user memory region.
+ * @param VirtAddr is the virtual base address of the user memory region. If
+ *        address translation is not being utilized, then VirtAddr should be
+ *        equivalent to PhysAddr.
+ * @param Alignment governs the byte alignment of individual BDs. This function
+ *        will enforce a minimum alignment of 4 bytes with no maximum as long as
+ *        it is specified as a power of 2.
+ * @param BdCount is the number of BDs to setup in the user memory region. It is
+ *        assumed the region is large enough to contain the BDs. Refer to the
+ *        "SGDMA List Creation" section  in xdmav3.h for more information on
+ *        list creation.
+ *
+ * @return
+ *
+ * - XST_SUCCESS if initialization was successful
+ * - XST_NO_FEATURE if the provided instance is a non SGDMA type of DMA
+ *   channel.
+ * - XST_INVALID_PARAM under any of the following conditions: 1) PhysAddr and/or
+ *   VirtAddr are not aligned to the given Alignment parameter; 2) Alignment
+ *   parameter does not meet minimum requirements or is not a power of 2 value;
+ *   3) BdCount is 0.
+ * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans
+ *   over address 0x00000000 in virtual address space.
+ *
+ * @note
+ *
+ * Some DMA HW requires 8 or more byte alignments of BDs. Make sure the correct
+ * value is passed into the Alignment parameter to meet individual DMA HW
+ * requirements.
+ *
+ ******************************************************************************/
+int XDmaV3_SgListCreate(XDmaV3 * InstancePtr, u32 PhysAddr, u32 VirtAddr,
+			u32 Alignment, unsigned BdCount)
+{
+	unsigned i;
+	u32 BdV;
+	u32 BdP;
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+	/* In case there is a failure prior to creating list, make sure the following
+	 * attributes are 0 to prevent calls to other SG functions from doing anything
+	 */
+	Ring->AllCnt = 0;
+	Ring->FreeCnt = 0;
+	Ring->HwCnt = 0;
+	Ring->PreCnt = 0;
+	Ring->PostCnt = 0;
+
+	/* Is this a SGDMA channel */
+	if (!IsSgDmaChannel(InstancePtr)) {
+		return (XST_NO_FEATURE);
+	}
+
+	/* Make sure Alignment parameter meets minimum requirements */
+	if (Alignment < XDMABDV3_MINIMUM_ALIGNMENT) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Make sure Alignment is a power of 2 */
+	if ((Alignment - 1) & Alignment) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Make sure PhysAddr and VirtAddr are on same Alignment */
+	if ((PhysAddr % Alignment) || (VirtAddr % Alignment)) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Is BdCount reasonable? */
+	if (BdCount == 0) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Parameters are sane. Stop the HW just to be safe */
+	XDmaV3_SgStop(InstancePtr);
+
+	/* Figure out how many bytes will be between the start of adjacent BDs */
+	Ring->Separation =
+		(sizeof(XDmaBdV3) + (Alignment - 1)) & ~(Alignment - 1);
+
+	/* Must make sure the ring doesn't span address 0x00000000. If it does,
+	 * then the next/prev BD traversal macros will fail.
+	 */
+	if (VirtAddr > (VirtAddr + (Ring->Separation * BdCount) - 1)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Initial ring setup:
+	 *  - Clear the entire space
+	 *  - Setup each BD's BDA field with the physical address of the next BD
+	 *  - Set each BD's DMASR.DMADONE bit
+	 */
+	memset((void *) VirtAddr, 0, (Ring->Separation * BdCount));
+
+	BdV = VirtAddr;
+	BdP = PhysAddr + Ring->Separation;
+	for (i = 1; i < BdCount; i++) {
+		XDmaV3_mWriteBd(BdV, XDMAV3_BD_BDA_OFFSET, BdP);
+		XDmaV3_mWriteBd(BdV, XDMAV3_BD_DMASR_OFFSET,
+				XDMAV3_DMASR_DMADONE_MASK);
+		XDMAV3_CACHE_FLUSH(BdV);
+		BdV += Ring->Separation;
+		BdP += Ring->Separation;
+	}
+
+	/* At the end of the ring, link the last BD back to the top */
+	XDmaV3_mWriteBd(BdV, XDMAV3_BD_BDA_OFFSET, PhysAddr);
+
+	/* Setup and initialize pointers and counters */
+	InstancePtr->BdRing.RunState = XST_DMA_SG_IS_STOPPED;
+	Ring->BaseAddr = VirtAddr;
+	Ring->PhysBaseAddr = PhysAddr;
+	Ring->HighAddr = BdV;
+	Ring->Length = Ring->HighAddr - Ring->BaseAddr + Ring->Separation;
+	Ring->AllCnt = BdCount;
+	Ring->FreeCnt = BdCount;
+	Ring->FreeHead = (XDmaBdV3 *) VirtAddr;
+	Ring->PreHead = (XDmaBdV3 *) VirtAddr;
+	Ring->HwHead = (XDmaBdV3 *) VirtAddr;
+	Ring->HwTail = (XDmaBdV3 *) VirtAddr;
+	Ring->PostHead = (XDmaBdV3 *) VirtAddr;
+	Ring->BdaRestart = (XDmaBdV3 *) PhysAddr;
+
+	/* Make sure the DMACR.SGS is 1 so that no DMA operations proceed until
+	 * the start function is called.
+	 */
+	XDMAV3_HW_SGS_SET;
+
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Clone the given BD into every BD in the list. Except for XDMAV3_BD_BDA_OFFSET,
+ * every field of the source BD is replicated in every BD of the list.
+ *
+ * This function can be called only when all BDs are in the free group such as
+ * they are immediately after initialization with XDmaV3_SgListCreate(). This
+ * prevents modification of BDs while they are in use by HW or the user.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param SrcBdPtr is the source BD template to be cloned into the list. This BD
+ *        will be modified.
+ *
+ * @return
+ *   - XST_SUCCESS if the list was modified.
+ *   - XST_DMA_SG_NO_LIST if a list has not been created.
+ *   - XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under HW
+ *     or user control.
+ *   - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
+ *
+ ******************************************************************************/
+int XDmaV3_SgListClone(XDmaV3 * InstancePtr, XDmaBdV3 * SrcBdPtr)
+{
+	unsigned i;
+	u32 CurBd;
+	u32 Save;
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+	/* Can't do this function if there isn't a ring */
+	if (Ring->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Can't do this function with the channel running */
+	if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Can't do this function with some of the BDs in use */
+	if (Ring->FreeCnt != Ring->AllCnt) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Modify the template by setting DMASR.DMADONE */
+	Save = XDmaV3_mReadBd(SrcBdPtr, XDMAV3_BD_DMASR_OFFSET);
+	Save |= XDMAV3_DMASR_DMADONE_MASK;
+	XDmaV3_mWriteBd(SrcBdPtr, XDMAV3_BD_DMASR_OFFSET, Save);
+
+	/* Starting from the top of the ring, save BD.Next, overwrite the entire BD
+	 * with the template, then restore BD.Next
+	 */
+	for (i = 0, CurBd = Ring->BaseAddr;
+	     i < Ring->AllCnt; i++, CurBd += Ring->Separation) {
+		Save = XDmaV3_mReadBd(CurBd, XDMAV3_BD_BDA_OFFSET);
+		memcpy((void *) CurBd, SrcBdPtr, sizeof(XDmaBdV3));
+		XDmaV3_mWriteBd(CurBd, XDMAV3_BD_BDA_OFFSET, Save);
+		XDMAV3_CACHE_FLUSH(CurBd);
+	}
+
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Reserve locations in the BD list. The set of returned BDs may be modified in
+ * preparation for future DMA transaction(s). Once the BDs are ready to be
+ * submitted to HW, the user must call XDmaV3_SgBdToHw() in the same order which
+ * they were allocated here. Example:
+ *
+ * <pre>
+ *        NumBd = 2;
+ *        Status = XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd, &MyBdSet);
+ *
+ *        if (Status != XST_SUCCESS)
+ *        {
+ *            // Not enough BDs available for the request
+ *        }
+ *
+ *        CurBd = MyBdSet;
+ *        for (i=0; i<NumBd; i++)
+ *        {
+ *            // Prepare CurBd.....
+ *
+ *            // Onto next BD
+ *            CurBd = XDmaV3_mSgBdNext(MyDmaInstPtr, CurBd);
+ *        }
+ *
+ *        // Give list to HW
+ *        Status = XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd, MyBdSet);
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be allocated and given to HW in the correct sequence:
+ * <pre>
+ *        // Legal
+ *        XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ *
+ *        // Legal
+ *        XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd2, &MySet2);
+ *        XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ *        XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd2, MySet2);
+ *
+ *        // Not legal
+ *        XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd2, &MySet2);
+ *        XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd2, MySet2);
+ *        XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * Use the API defined in xdmabdv3.h to modify individual BDs. Traversal of the
+ * BD set can be done using XDmaV3_mSgBdNext() and XDmaV3_mSgBdPrev().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs to allocate
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ *        for modification.
+ *
+ * @return
+ *   - XST_SUCCESS if the requested number of BDs was returned in the BdSetPtr
+ *     parameter.
+ *   - XST_FAILURE if there were not enough free BDs to satisfy the request.
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ * @note Do not modify more BDs than the number requested with the NumBd
+ *       parameter. Doing so will lead to data corruption and system
+ *       instability.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdAlloc(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 ** BdSetPtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+	/* Enough free BDs available for the request? */
+	if (Ring->FreeCnt < NumBd) {
+		return (XST_FAILURE);
+	}
+
+	/* Set the return argument and move FreeHead forward */
+	*BdSetPtr = Ring->FreeHead;
+	XDMAV3_RING_SEEKAHEAD(Ring, Ring->FreeHead, NumBd);
+	Ring->FreeCnt -= NumBd;
+	Ring->PreCnt += NumBd;
+	return (XST_SUCCESS);
+}
+
+/******************************************************************************/
+/**
+ * Fully or partially undo an XDmaV3_SgBdAlloc() operation. Use this function
+ * if all the BDs allocated by XDmaV3_SgBdAlloc() could not be transferred to
+ * HW with XDmaV3_SgBdToHw().
+ *
+ * This function helps out in situations when an unrelated error occurs after
+ * BDs have been allocated but before they have been given to HW. An example of
+ * this type of error would be an OS running out of resources.
+ *
+ * This function is not the same as XDmaV3_SgBdFree(). The Free function returns
+ * BDs to the free list after they have been processed by HW, while UnAlloc
+ * returns them before being processed by HW.
+ *
+ * There are two scenarios where this function can be used. Full UnAlloc or
+ * Partial UnAlloc. A Full UnAlloc means all the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ *    Status = XDmaV3_SgBdAlloc(Inst, 10, &BdPtr);
+ *        .
+ *        .
+ *    if (Error)
+ *    {
+ *        Status = XDmaV3_SgBdUnAlloc(Inst, 10, &BdPtr);
+ *    }
+ * </pre>
+ *
+ * A partial UnAlloc means some of the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ *    Status = XDmaV3_SgBdAlloc(Inst, 10, &BdPtr);
+ *    BdsLeft = 10;
+ *    CurBdPtr = BdPtr;
+ *
+ *    while (BdsLeft)
+ *    {
+ *       if (Error)
+ *       {
+ *          Status = XDmaV3_SgBdUnAlloc(Inst, BdsLeft, CurBdPtr);
+ *       }
+ *
+ *       CurBdPtr = XDmaV3_SgBdNext(Inst, CurBdPtr);
+ *       BdsLeft--;
+ *    }
+ * </pre>
+ *
+ * A partial UnAlloc must include the last BD in the list that was Alloc'd.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs to allocate
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ *        for modification.
+ *
+ * @return
+ *   - XST_SUCCESS if the BDs were unallocated.
+ *   - XST_FAILURE if NumBd parameter was greater that the number of BDs in the
+ *     preprocessing state.
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdUnAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+		       XDmaBdV3 * BdSetPtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+	/* Enough BDs in the free state for the request? */
+	if (Ring->PreCnt < NumBd) {
+		return (XST_FAILURE);
+	}
+
+	/* Set the return argument and move FreeHead backward */
+	XDMAV3_RING_SEEKBACK(Ring, Ring->FreeHead, NumBd);
+	Ring->FreeCnt += NumBd;
+	Ring->PreCnt -= NumBd;
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Enqueue a set of BDs to HW that were previously allocated by
+ * XDmaV3_SgBdAlloc(). Once this function returns, the argument BD set goes
+ * under HW control. Any changes made to these BDs after this point will corrupt
+ * the BD list leading to data corruption and system instability.
+ *
+ * The set will be rejected if the last BD of the set does not mark the end of
+ * a packet (see XDmaBdV3_mSetLast()).
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs in the set.
+ * @param BdSetPtr is the first BD of the set to commit to HW.
+ *
+ * @return
+ *   - XST_SUCCESS if the set of BDs was accepted and enqueued to HW.
+ *   - XST_FAILURE if the set of BDs was rejected because the last BD of the set
+ *     did not have its "last" bit set.
+ *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ *     XDmaV3_SgBdAlloc().
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdToHw(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+	XDmaBdV3 *LastBdPtr;
+	unsigned i;
+	u32 Dmacr;
+	u32 Swcr;
+
+	/* Make sure we are in sync with XDmaV3_SgBdAlloc() */
+	if ((Ring->PreCnt < NumBd) || (Ring->PreHead != BdSetPtr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* For all BDs in this set (except the last one)
+	 *   - Clear DMASR except for DMASR.DMABSY
+	 *   - Clear DMACR.SGS
+	 *
+	 * For the last BD in this set
+	 *   - Clear DMASR except for DMASR.DMABSY
+	 *   - Set DMACR.SGS (marks the end of the new active list)
+	 */
+	LastBdPtr = BdSetPtr;
+	for (i = 1; i < NumBd; i++) {
+		XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMASR_OFFSET,
+				XDMAV3_DMASR_DMABSY_MASK);
+
+		Dmacr = XDmaV3_mReadBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET);
+		XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET,	/* DMACR.SGS = 0 */
+				Dmacr & ~XDMAV3_DMACR_SGS_MASK);
+		XDMAV3_CACHE_FLUSH(LastBdPtr);
+
+		LastBdPtr = XDmaV3_mSgBdNext(InstancePtr, LastBdPtr);
+	}
+
+	/* Last BD */
+	XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMASR_OFFSET,
+			XDMAV3_DMASR_DMABSY_MASK);
+
+	Dmacr = XDmaV3_mReadBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET);
+	XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET,	/* DMACR.SGS = 1 */
+			Dmacr | XDMAV3_DMACR_SGS_MASK);
+	XDMAV3_CACHE_FLUSH(LastBdPtr);
+
+	/* The last BD should have DMACR.LAST set */
+	if (!(Dmacr & XDMAV3_DMACR_LAST_MASK)) {
+		return (XST_FAILURE);
+	}
+
+	/* This set has completed pre-processing, adjust ring pointers & counters */
+	XDMAV3_RING_SEEKAHEAD(Ring, Ring->PreHead, NumBd);
+	Ring->PreCnt -= NumBd;
+
+	/* If it is running, tell the DMA engine to pause */
+	Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+	if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+		Swcr |= XDMAV3_SWCR_SGD_MASK;
+		XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+				 Swcr);
+	}
+
+	/* Transfer control of the BDs to the DMA engine. There are two cases to
+	 * consider:
+	 *
+	 * 1) No currently active list.
+	 *    In this case, just resume the engine.
+	 *
+	 * 2) Active list.
+	 *    In this case, the last BD in the current list should have DMACR.SGS
+	 *    cleared so the engine will never stop there. The new stopping
+	 *    point is at the end of the extended list. Once the SGS bits are
+	 *    changed, resume the engine.
+	 */
+	if (Ring->HwCnt != 0) {
+		/* Handle case 2 */
+		Dmacr = XDmaV3_mReadBd(Ring->HwTail, XDMAV3_BD_DMACR_OFFSET);
+		Dmacr &= ~XDMAV3_DMACR_SGS_MASK;
+		XDmaV3_mWriteBd(Ring->HwTail, XDMAV3_BD_DMACR_OFFSET, Dmacr);
+		XDMAV3_CACHE_FLUSH(Ring->HwTail);
+	}
+
+	/* Adjust Hw pointers and counters. XDMAV3_RING_SEEKAHEAD could be used to
+	 * advance HwTail, but it will always evaluate to LastBdPtr
+	 */
+	Ring->HwTail = LastBdPtr;
+	Ring->HwCnt += NumBd;
+
+	/* If it was enabled, tell the engine to resume */
+	if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+		Swcr &= ~XDMAV3_SWCR_SGD_MASK;
+		Swcr |= XDMAV3_SWCR_SGE_MASK;
+		XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+				 Swcr);
+	}
+
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by HW. The returned BDs may
+ * be examined to determine the outcome of the DMA transaction(s). Once the BDs
+ * have been examined, the user must call XDmaV3_SgBdFree() in the same order
+ * which they were retrieved here. Example:
+ *
+ * <pre>
+ *        MaxBd = 0xFFFFFFFF;   // Ensure we get all that are ready
+ *
+ *        NumBd = XDmaV3_SgBdFromHw(MyDmaInstPtr, MaxBd, &MyBdSet);
+ *
+ *        if (NumBd == 0)
+ *        {
+ *           // HW has nothing ready for us yet
+ *        }
+ *
+ *        CurBd = MyBdSet;
+ *        for (i=0; i<NumBd; i++)
+ *        {
+ *           // Examine CurBd for post processing.....
+ *
+ *           // Onto next BD
+ *           CurBd = XDmaV3_mSgBdNext(MyDmaInstPtr, CurBd);
+ *           }
+ *
+ *           XDmaV3_SgBdFree(MyDmaInstPtr, NumBd, MyBdSet); // Return the list
+ *        }
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be retrieved from HW and freed in the correct sequence:
+ * <pre>
+ *        // Legal
+ *        XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ *
+ *        // Legal
+ *        XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd2, &MySet2);
+ *        XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ *        XDmaV3_SgBdFree(MyDmaInstPtr, NumBd2, MySet2);
+ *
+ *        // Not legal
+ *        XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ *        XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd2, &MySet2);
+ *        XDmaV3_SgBdFree(MyDmaInstPtr, NumBd2, MySet2);
+ *        XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If HW has only partially completed a packet spanning multiple BDs, then none
+ * of the BDs for that packet will be included in the results.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param BdLimit is the maximum number of BDs to return in the set.
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ *        for examination.
+ *
+ * @return
+ *   The number of BDs processed by HW. A value of 0 indicates that no data
+ *   is available. No more than BdLimit BDs will be returned.
+ *
+ * @note Treat BDs returned by this function as read-only.
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+unsigned XDmaV3_SgBdFromHw(XDmaV3 * InstancePtr, unsigned BdLimit,
+			   XDmaBdV3 ** BdSetPtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+	XDmaBdV3 *CurBd;
+	unsigned BdCount;
+	unsigned BdPartialCount;
+	u32 Dmasr;
+
+	CurBd = Ring->HwHead;
+	BdCount = 0;
+	BdPartialCount = 0;
+
+	/* If no BDs in work group, then there's nothing to search */
+	if (Ring->HwCnt == 0) {
+		*BdSetPtr = NULL;
+		return (0);
+	}
+
+	/* Starting at HwHead, keep moving forward in the list until:
+	 *  - A BD is encountered with its DMASR.DMABSY bit set which means HW has
+	 *    not completed processing of that BD.
+	 *  - Ring->HwTail is reached
+	 *  - The number of requested BDs has been processed
+	 */
+	while (BdCount < BdLimit) {
+		/* Read the status */
+		XDMAV3_CACHE_INVALIDATE(CurBd);
+		Dmasr = XDmaV3_mReadBd(CurBd, XDMAV3_BD_DMASR_OFFSET);
+
+		/* If the HW still hasn't processed this BD then we are done */
+		if (Dmasr & XDMAV3_DMASR_DMABSY_MASK) {
+			break;
+		}
+
+		BdCount++;
+
+		/* HW has processed this BD so check the "last" bit. If it is clear,
+		 * then there are more BDs for the current packet. Keep a count of
+		 * these partial packet BDs.
+		 */
+		if (Dmasr & XDMAV3_DMASR_LAST_MASK) {
+			BdPartialCount = 0;
+		}
+		else {
+			BdPartialCount++;
+		}
+
+		/* Reached the end of the work group */
+		if (CurBd == Ring->HwTail) {
+			break;
+		}
+
+		/* Move on to next BD in work group */
+		CurBd = XDmaV3_mSgBdNext(InstancePtr, CurBd);
+	}
+
+	/* Subtract off any partial packet BDs found */
+	BdCount -= BdPartialCount;
+
+	/* If BdCount is non-zero then BDs were found to return. Set return
+	 * parameters, update pointers and counters, return success
+	 */
+	if (BdCount) {
+		*BdSetPtr = Ring->HwHead;
+		Ring->HwCnt -= BdCount;
+		Ring->PostCnt += BdCount;
+		XDMAV3_RING_SEEKAHEAD(Ring, Ring->HwHead, BdCount);
+		return (BdCount);
+	}
+	else {
+		*BdSetPtr = NULL;
+		return (0);
+	}
+}
+
+
+/******************************************************************************/
+/**
+ * Frees a set of BDs that had been previously retrieved with XDmaV3_SgBdFromHw().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs to free.
+ * @param BdSetPtr is the head of a list of BDs returned by XDmaV3_SgBdFromHw().
+ *
+ * @return
+ *   - XST_SUCCESS if the set of BDs was freed.
+ *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ *     XDmaV3_SgBdFromHw().
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdFree(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr)
+{
+	XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+	/* Make sure we are in sync with XDmaV3_SgBdFromHw() */
+	if ((Ring->PostCnt < NumBd) || (Ring->PostHead != BdSetPtr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Update pointers and counters */
+	Ring->FreeCnt += NumBd;
+	Ring->PostCnt -= NumBd;
+	XDMAV3_RING_SEEKAHEAD(Ring, Ring->PostHead, NumBd);
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Check the internal data structures of the BD ring for the provided channel.
+ * The following checks are made:
+ *
+ *   - Is the BD ring linked correctly in physical address space.
+ *   - Do the internal pointers point to BDs in the ring.
+ *   - Do the internal counters add up.
+ *
+ * The channel should be stopped prior to calling this function.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ *   - XST_SUCCESS if the set of BDs was freed.
+ *   - XST_DMA_SG_NO_LIST if the list has not been created.
+ *   - XST_IS_STARTED if the channel is not stopped.
+ *   - XST_DMA_SG_LIST_ERROR if a problem is found with the internal data
+ *     structures. If this value is returned, the channel should be reset to
+ *     avoid data corruption or system instability.
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgCheck(XDmaV3 * InstancePtr)
+{
+	XDmaV3_BdRing *RingPtr = &InstancePtr->BdRing;
+	u32 AddrV, AddrP;
+	unsigned i;
+
+	/* Is the list created */
+	if (RingPtr->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Can't check if channel is running */
+	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_IS_STARTED);
+	}
+
+	/* RunState doesn't make sense */
+	else if (RingPtr->RunState != XST_DMA_SG_IS_STOPPED) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify internal pointers point to correct memory space */
+	AddrV = (u32) RingPtr->FreeHead;
+	if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->PreHead;
+	if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->HwHead;
+	if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->HwTail;
+	if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->PostHead;
+	if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify internal counters add up */
+	if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
+	     RingPtr->PostCnt) != RingPtr->AllCnt) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify BDs are linked correctly */
+	AddrV = RingPtr->BaseAddr;
+	AddrP = RingPtr->PhysBaseAddr + RingPtr->Separation;
+	for (i = 1; i < RingPtr->AllCnt; i++) {
+		/* Check BDA for this BD. It should point to next physical addr */
+		if (XDmaV3_mReadBd(AddrV, XDMAV3_BD_BDA_OFFSET) != AddrP) {
+			return (XST_DMA_SG_LIST_ERROR);
+		}
+
+		/* Move on to next BD */
+		AddrV += RingPtr->Separation;
+		AddrP += RingPtr->Separation;
+	}
+
+	/* Last BD should point back to the beginning of ring */
+	if (XDmaV3_mReadBd(AddrV, XDMAV3_BD_BDA_OFFSET) !=
+	    RingPtr->PhysBaseAddr) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* No problems found */
+	return (XST_SUCCESS);
+}
+
+
+/******************************************************************************
+ * Verify given channel is of the SGDMA variety.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ *   - 1 if channel is of type SGDMA
+ *   - 0 if channel is not of type SGDMA
+ ******************************************************************************/
+static int IsSgDmaChannel(XDmaV3 * InstancePtr)
+{
+	u32 Dmasr;
+
+	Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (Dmasr & (XDMAV3_DMASR_DMACNFG_SGDMARX_MASK |
+		     XDMAV3_DMASR_DMACNFG_SGDMATX_MASK |
+		     XDMAV3_DMASR_DMACNFG_SSGDMA_MASK)) {
+		return (1);
+	}
+	else {
+		return (0);
+	}
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_simple.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xdmav3_simple.c	2014-07-20 22:06:38.939263112 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2006 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_simple.c
+*
+* This file implements Simple DMA related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 3.00a rmm  03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Initiate a simple DMA transfer. The BD argument sets the parameters of the
+* transfer. Since the BD is also used for SG DMA transfers, some fields of the
+* BD will be ignored. The following BD macros will have no effect on the
+* transfer:
+*
+* - XDmaBdV3_mSetLast()
+* - XDmaBdV3_mClearLast()
+* - XDmaBdV3_mSetBdPage()
+*
+* To determine when the transfer has completed, the user can poll the device
+* with XDmaV3_mGetStatus() and test the XDMAV3_DMASR_DMABSY_MASK bit, or wait for
+* an interrupt. When the DMA operation has completed, the outcome of the
+* transfer can be retrieved by calling XDmaV3_mGetStatus() and testing for DMA
+* bus errors bits.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param BdPtr sets the parameters of the transfer.
+*
+* @return
+* - XST_SUCCESS if the transfer was initated
+* - XST_DEVICE_BUSY if a transfer is already in progress
+*
+******************************************************************************/
+int XDmaV3_SimpleTransfer(XDmaV3 * InstancePtr, XDmaBdV3 * BdPtr)
+{
+	u32 Dmasr;
+
+	/* Is the channel busy */
+	Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+	if (Dmasr & (XDMAV3_DMASR_DMABSY_MASK | XDMAV3_DMASR_SGBSY_MASK)) {
+		return (XST_DEVICE_BUSY);
+	}
+
+	/* Copy BdPtr fields into the appropriate HW registers */
+
+	/* DMACR: SGS bit is set always. This is done in case the transfer
+	 * occurs on a SGDMA channel and will prevent the HW from fetching the
+	 * next BD.
+	 */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET,
+			 XDmaV3_mReadBd(BdPtr, XDMAV3_BD_DMACR_OFFSET)
+			 | XDMAV3_DMACR_SGS_MASK);
+
+	/* MSBA */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_MSBA_OFFSET,
+			 XDmaV3_mReadBd(BdPtr, XDMAV3_BD_MSBA_OFFSET));
+
+	/* LSBA */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_LSBA_OFFSET,
+			 XDmaV3_mReadBd(BdPtr, XDMAV3_BD_LSBA_OFFSET));
+
+	/* LENGTH: Writing this register starts HW */
+	XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_LENGTH_OFFSET,
+			 XDmaV3_mReadBd(BdPtr, XDMAV3_BD_LENGTH_OFFSET));
+
+	return (XST_SUCCESS);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xenv.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xenv.h	2014-07-20 22:06:38.947262981 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xenv_linux.h
+*
+* Defines common services specified by xenv.h.
+*
+* @note
+* 	This file is not intended to be included directly by driver code.
+* 	Instead, the generic xenv.h file is intended to be included by driver
+* 	code.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a wgr  02/28/07 Added cache handling macros.
+* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* 1.00a ch   10/24/02 First release
+* 1.10a wgr  03/22/07 Converted to new coding style.
+* </pre>
+*
+*
+******************************************************************************/
+
+#ifndef XENV_LINUX_H
+#define XENV_LINUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+
+
+/******************************************************************************
+ *
+ * MEMCPY / MEMSET related macros.
+ *
+ * Those macros are defined to catch legacy code in Xilinx drivers. The
+ * XENV_MEM_COPY and XENV_MEM_FILL macros were used in early Xilinx driver
+ * code. They are being replaced by memcpy() and memset() function calls. These
+ * macros are defined to catch any remaining occurences of those macros.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * Copies a non-overlapping block of memory.
+ *
+ * @param	DestPtr
+ *		Destination address to copy data to.
+ *
+ * @param	SrcPtr
+ * 		Source address to copy data from.
+ *
+ * @param	Bytes
+ * 		Number of bytes to copy.
+ *
+ * @return	None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \
+		memcpy(DestPtr, SrcPtr, Bytes)
+/*		do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/*****************************************************************************/
+/**
+ *
+ * Fills an area of memory with constant data.
+ *
+ * @param	DestPtr
+ *		Destination address to copy data to.
+ *
+ * @param	Data
+ * 		Value to set.
+ *
+ * @param	Bytes
+ * 		Number of bytes to copy.
+ *
+ * @return	None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_FILL(DestPtr, Data, Bytes) \
+		memset(DestPtr, Data, Bytes)
+/*		do_not_use_XENV_MEM_FILL_use_memset_instead */
+
+
+/******************************************************************************
+ *
+ * TIME related macros
+ *
+ ******************************************************************************/
+/**
+ * A structure that contains a time stamp used by other time stamp macros
+ * defined below. This structure is processor dependent.
+ */
+typedef int XENV_TIME_STAMP;
+
+/*****************************************************************************/
+/**
+ *
+ * Time is derived from the 64 bit PPC timebase register
+ *
+ * @param   StampPtr is the storage for the retrieved time stamp.
+ *
+ * @return  None.
+ *
+ * @note
+ *
+ * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
+ * <br><br>
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_GET(StampPtr)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param   Stamp1Ptr is the first sampled time stamp.
+ * @param   Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return  0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr)     (0)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param   Stamp1Ptr is the first sampled time stamp.
+ * @param   Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return  0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr)     (0)
+
+/*****************************************************************************/
+/**
+ *
+ * Delay the specified number of microseconds.
+ *
+ * @param	delay
+ * 		Number of microseconds to delay.
+ *
+ * @return	None.
+ *
+ * @note	XENV_USLEEP is deprecated. Use udelay() instead.
+ *
+ *****************************************************************************/
+
+#define XENV_USLEEP(delay)	udelay(delay)
+/*		do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/******************************************************************************
+ *
+ * CACHE handling macros / mappings
+ *
+ * The implementation of the cache handling functions can be found in
+ * arch/microblaze.
+ *
+ * These #defines are simple mappings to the Linux API.
+ *
+ * The underlying Linux implementation will take care of taking the right
+ * actions depending on the configuration of the MicroBlaze processor in the
+ * system.
+ *
+ ******************************************************************************/
+
+#define XCACHE_ENABLE_DCACHE()		__enable_dcache()
+#define XCACHE_DISABLE_DCACHE()		__disable_dcache()
+#define XCACHE_ENABLE_ICACHE()		__enable_icache()
+#define XCACHE_DISABLE_ICACHE()		__disable_icache()
+
+#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \
+        invalidate_dcache_range((unsigned long)(Addr), ((unsigned long)(Addr)+(Len)))
+#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len)      \
+        flush_dcache_range((unsigned long)(Addr), ((unsigned long)(Addr)+(Len)))
+
+#define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) "XCACHE_INVALIDATE_ICACHE_RANGE unsupported"
+#define XCACHE_FLUSH_ICACHE_RANGE(Addr, Len)      flush_icache_range(Addr, Len)
+
+#define XCACHE_ENABLE_CACHE()	\
+		{ XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); }
+
+#define XCACHE_DISABLE_CACHE()	\
+		{ XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); }
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif            /* end of protection macro */
+
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_assert.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_assert.c	2014-07-20 22:06:38.958262799 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+*
+* (c) Copyright 2009 Xilinx, Inc. All rights reserved.
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or (at
+*     your option) any later version.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with this program; if not, write to the Free Software
+*     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+*     MA  02110-1301  USA
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xil_assert.c
+*
+* This file contains basic assert related functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 Initial release
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_types.h"
+#include "xil_assert.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+unsigned int Xil_AssertStatus;
+
+/**
+ * This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+int Xil_AssertWait = TRUE;
+
+/* The callback function to be invoked when an assert is taken */
+static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Implement assert. Currently, it calls a user-defined callback function
+* if one has been set.  Then, it potentially enters an infinite loop depending
+* on the value of the Xil_AssertWait variable.
+*
+* @param    file is the name of the filename of the source
+* @param    line is the linenumber within File
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+void Xil_Assert(char *File, int Line)
+{
+	/* if the callback has been set then invoke it */
+	if (Xil_AssertCallbackRoutine != 0) {
+		(*Xil_AssertCallbackRoutine)(File, Line);
+	}
+
+	/* if specified, wait indefinitely such that the assert will show up
+	 * in testing
+	 */
+	while (Xil_AssertWait) {
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Set up a callback function to be invoked when an assert occurs. If there
+* was already a callback installed, then it is replaced.
+*
+* @param    routine is the callback to be invoked when an assert is taken
+*
+* @return   None.
+*
+* @note     This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void Xil_AssertSetCallback(Xil_AssertCallback Routine)
+{
+	Xil_AssertCallbackRoutine = Routine;
+}
+
+
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_assert.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_assert.h	2014-07-20 22:06:38.965262684 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+* (c) Copyright 2009 Xilinx, Inc. All rights reserved.
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or (at
+*     your option) any later version.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with this program; if not, write to the Free Software
+*     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+*     MA  02110-1301  USA
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xil_assert.h
+*
+* This file contains assert related functions.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIL_ASSERT_H	/* prevent circular inclusions */
+#define XIL_ASSERT_H	/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+
+/************************** Constant Definitions *****************************/
+
+#define XIL_ASSERT_NONE     0
+#define XIL_ASSERT_OCCURRED 1
+
+extern unsigned int Xil_AssertStatus;
+extern void Xil_Assert(char *, int);
+
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+typedef void (*Xil_AssertCallback) (char *File, int Line);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+#ifndef NDEBUG
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do not return anything
+* (void). This in conjunction with the Xil_AssertWait boolean can be used to
+* accomodate tests so that asserts which fail allow execution to continue.
+*
+* @param    expression is the expression to evaluate. If it evaluates to
+*           false, the assert occurs.
+*
+* @return   Returns void unless the Xil_AssertWait variable is true, in which
+*           case no return is made and an infinite loop is entered.
+*
+* @note     None.
+*
+******************************************************************************/
+#define Xil_AssertVoid(Expression)                \
+{                                                  \
+    if (Expression) {                              \
+        Xil_AssertStatus = XIL_ASSERT_NONE;       \
+    } else {                                       \
+        Xil_Assert(__FILE__, __LINE__);            \
+        Xil_AssertStatus = XIL_ASSERT_OCCURRED;   \
+        return;                                    \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do return a value. This in
+* conjunction with the Xil_AssertWait boolean can be used to accomodate tests
+* so that asserts which fail allow execution to continue.
+*
+* @param    expression is the expression to evaluate. If it evaluates to false,
+*           the assert occurs.
+*
+* @return   Returns 0 unless the Xil_AssertWait variable is true, in which
+* 	    case no return is made and an infinite loop is entered.
+*
+* @note     None.
+*
+******************************************************************************/
+#define Xil_AssertNonvoid(Expression)             \
+{                                                  \
+    if (Expression) {                              \
+        Xil_AssertStatus = XIL_ASSERT_NONE;       \
+    } else {                                       \
+        Xil_Assert(__FILE__, __LINE__);            \
+        Xil_AssertStatus = XIL_ASSERT_OCCURRED;   \
+        return 0;                                  \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do not
+* return anything (void). Use for instances where an assert should always
+* occur.
+*
+* @return Returns void unless the Xil_AssertWait variable is true, in which
+*	  case no return is made and an infinite loop is entered.
+*
+* @note   None.
+*
+******************************************************************************/
+#define Xil_AssertVoidAlways()                   \
+{                                                  \
+   Xil_Assert(__FILE__, __LINE__);                 \
+   Xil_AssertStatus = XIL_ASSERT_OCCURRED;        \
+   return;                                         \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do return
+* a value. Use for instances where an assert should always occur.
+*
+* @return Returns void unless the Xil_AssertWait variable is true, in which
+*	  case no return is made and an infinite loop is entered.
+*
+* @note   None.
+*
+******************************************************************************/
+#define Xil_AssertNonvoidAlways()                \
+{                                                  \
+   Xil_Assert(__FILE__, __LINE__);                 \
+   Xil_AssertStatus = XIL_ASSERT_OCCURRED;        \
+   return 0;                                       \
+}
+
+
+#else
+
+#define Xil_AssertVoid(Expression)
+#define Xil_AssertVoidAlways()
+#define Xil_AssertNonvoid(Expression)
+#define Xil_AssertNonvoidAlways()
+
+#endif
+
+/************************** Function Prototypes ******************************/
+
+void Xil_AssertSetCallback(Xil_AssertCallback Routine);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xilinx_syms.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xilinx_syms.c	2014-07-20 22:06:38.972262568 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * xilinx_syms.c
+ *
+ * This file EXPORT_SYMBOL_GPL's all of the Xilinx entry points.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+
+#include "xbasic_types.h"
+EXPORT_SYMBOL_GPL(XAssert);
+EXPORT_SYMBOL_GPL(XAssertSetCallback);
+EXPORT_SYMBOL_GPL(XAssertStatus);
+extern u32 XWaitInAssert;
+EXPORT_SYMBOL_GPL(XWaitInAssert);
+
+#include "xdma_channel.h"
+EXPORT_SYMBOL_GPL(XDmaChannel_CommitPuts);
+EXPORT_SYMBOL_GPL(XDmaChannel_CreateSgList);
+EXPORT_SYMBOL_GPL(XDmaChannel_DecrementPktCount);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetControl);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetDescriptor);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetIntrEnable);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetIntrStatus);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetPktCount);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetPktThreshold);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetPktWaitBound);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetStatus);
+EXPORT_SYMBOL_GPL(XDmaChannel_GetVersion);
+EXPORT_SYMBOL_GPL(XDmaChannel_Initialize);
+EXPORT_SYMBOL_GPL(XDmaChannel_IsReady);
+EXPORT_SYMBOL_GPL(XDmaChannel_IsSgListEmpty);
+EXPORT_SYMBOL_GPL(XDmaChannel_PutDescriptor);
+EXPORT_SYMBOL_GPL(XDmaChannel_Reset);
+EXPORT_SYMBOL_GPL(XDmaChannel_SelfTest);
+EXPORT_SYMBOL_GPL(XDmaChannel_SetControl);
+EXPORT_SYMBOL_GPL(XDmaChannel_SetIntrEnable);
+EXPORT_SYMBOL_GPL(XDmaChannel_SetIntrStatus);
+EXPORT_SYMBOL_GPL(XDmaChannel_SetPktThreshold);
+EXPORT_SYMBOL_GPL(XDmaChannel_SetPktWaitBound);
+EXPORT_SYMBOL_GPL(XDmaChannel_SgStart);
+EXPORT_SYMBOL_GPL(XDmaChannel_SgStop);
+EXPORT_SYMBOL_GPL(XDmaChannel_Transfer);
+
+#include "xipif_v1_23_b.h"
+//EXPORT_SYMBOL_GPL(XIpIfV123b_SelfTest);
+
+#include "xpacket_fifo_v2_00_a.h"
+EXPORT_SYMBOL_GPL(XPacketFifoV200a_Initialize);
+EXPORT_SYMBOL_GPL(XPacketFifoV200a_Read);
+EXPORT_SYMBOL_GPL(XPacketFifoV200a_SelfTest);
+EXPORT_SYMBOL_GPL(XPacketFifoV200a_Write);
+
+#include "xio.h"
+EXPORT_SYMBOL_GPL(XIo_Out8);
+EXPORT_SYMBOL_GPL(XIo_In8);
+EXPORT_SYMBOL_GPL(XIo_Out16);
+EXPORT_SYMBOL_GPL(XIo_In16);
+EXPORT_SYMBOL_GPL(XIo_Out32);
+EXPORT_SYMBOL_GPL(XIo_In32);
+
+#include "xversion.h"
+EXPORT_SYMBOL_GPL(XVersion_Copy);
+EXPORT_SYMBOL_GPL(XVersion_FromString);
+EXPORT_SYMBOL_GPL(XVersion_IsEqual);
+EXPORT_SYMBOL_GPL(XVersion_Pack);
+EXPORT_SYMBOL_GPL(XVersion_ToString);
+EXPORT_SYMBOL_GPL(XVersion_UnPack);
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_io.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_io.h	2014-07-20 22:06:38.978262469 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+* (c) Copyright 2009 Xilinx, Inc. All rights reserved.
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or (at
+*     your option) any later version.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with this program; if not, write to the Free Software
+*     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+*     MA  02110-1301  USA
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xil_io.h
+*
+* This file contains IO functions for Xilinx OCP in terms of Linux primitives.
+*
+******************************************************************************/
+#ifndef XIL_IO_H
+#define XIL_IO_H
+
+#include "xil_types.h"
+#include <asm/io.h>
+
+extern inline u8
+Xil_In8(u32 InAddress)
+{
+	return (u8) in_8((volatile unsigned char *) InAddress);
+}
+extern inline u16
+Xil_In16(u32 InAddress)
+{
+	return (u16) in_be16((volatile unsigned short *) InAddress);
+}
+extern inline u32
+Xil_In32(u32 InAddress)
+{
+	return (u32) in_be32((volatile unsigned *) InAddress);
+}
+extern inline void
+Xil_Out8(u32 OutAddress, u8 Value)
+{
+	out_8((volatile unsigned char *) OutAddress, Value);
+}
+extern inline void
+Xil_Out16(u32 OutAddress, u16 Value)
+{
+	out_be16((volatile unsigned short *) OutAddress, Value);
+}
+extern inline void
+Xil_Out32(u32 OutAddress, u32 Value)
+{
+	out_be32((volatile unsigned *) OutAddress, Value);
+}
+extern inline u16
+Xil_In16LE(u32 Addr)
+{
+	u16 Value;
+
+	__asm__ volatile ("eieio; lhbrx %0,0,%1":"=r" (Value):"b" (Addr));
+	return Value;
+}
+extern inline u32
+Xil_In32LE(u32 Addr)
+{
+	u32 Value;
+
+	__asm__ volatile ("eieio; lwbrx %0,0,%1":"=r" (Value):"b" (Addr));
+	return Value;
+}
+extern inline void
+Xil_Out16LE(u32 Addr, u16 Value)
+{
+	__asm__ volatile ("sthbrx %0,0,%1; eieio"::"r" (Value), "b"(Addr));
+}
+extern inline void
+Xil_Out32LE(u32 Addr, u32 Value)
+{
+	__asm__ volatile ("stwbrx %0,0,%1; eieio"::"r" (Value), "b"(Addr));
+}
+
+#endif /* XIL_IO_H */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_types.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xil_types.h	2014-07-20 22:06:38.986262337 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/******************************************************************************
+*
+* (c) Copyright 2009 Xilinx, Inc. All rights reserved.
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or (at
+*     your option) any later version.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with this program; if not, write to the Free Software
+*     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+*     MA  02110-1301  USA
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xil_types.h
+*
+* This file contains basic types for Xilinx software IP.
+
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIL_TYPES_H	/* prevent circular inclusions */
+#define XIL_TYPES_H	/* by using protection macros */
+
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#  define TRUE		1
+#endif
+
+#ifndef FALSE
+#  define FALSE		0
+#endif
+
+#ifndef NULL
+#define NULL		0
+#endif
+
+#define XIL_COMPONENT_IS_READY     0x11111111  /**< component has been initialized */
+#define XIL_COMPONENT_IS_STARTED   0x22222222  /**< component has been started */
+
+/** @name New types
+ * New simple types.
+ * @{
+ */
+#ifndef __KERNEL__
+#ifndef XBASIC_TYPES_H
+/**
+ * guarded against xbasic_types.h.
+ */
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+#endif
+/**
+ * xbasic_types.h does not typedef u64
+ */
+typedef unsigned long long u64;
+#else
+#include <linux/types.h>
+#endif
+
+
+/*@}*/
+
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#define TRUE		1
+#endif
+
+#ifndef FALSE
+#define FALSE		0
+#endif
+
+#ifndef NULL
+#define NULL		0
+#endif
+
+#endif	/* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio.c	2014-07-20 22:06:38.996262172 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xio.c,v 1.5 2007/07/24 22:01:35 xduan Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio.c
+*
+* Contains I/O functions for memory-mapped or non-memory-mapped I/O
+* architectures.  These functions encapsulate PowerPC architecture-specific
+* I/O requirements.
+*
+* @note
+*
+* This file contains architecture-dependent code.
+*
+* The order of the SYNCHRONIZE_IO and the read or write operation is
+* important. For the Read operation, all I/O needs to complete prior
+* to the desired read to insure valid data from the address. The PPC
+* is a weakly ordered I/O model and reads can and will occur prior
+* to writes and the SYNCHRONIZE_IO ensures that any writes occur prior
+* to the read. For the Write operation the SYNCHRONIZE_IO occurs
+* after the desired write to ensure that the address is updated with
+* the new value prior to any subsequent read.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a ecm  10/18/05 initial release
+*                     needs to be updated to replace eieio with mbar when
+*                     compilers support this mnemonic.
+*
+* 1.00a ecm  01/24/07 update for new coding standard.
+* 1.10a xd   07/24/07 Corrected the format in asm functions in __DCC__ mode.
+* </pre>
+******************************************************************************/
+
+
+/***************************** Include Files *********************************/
+#include "xio.h"
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+/*****************************************************************************/
+/**
+*
+* Performs a 16-bit endian converion.
+*
+* @param    Source contains the value to be converted.
+* @param    DestPtr contains a pointer to the location to put the
+*           converted value.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void OutSwap16(u16 Source, u16 *DestPtr)
+{
+    *DestPtr = (u16) (((Source & 0xFF00) >> 8) | ((Source & 0x00FF) << 8));
+}
+
+u16 InSwap16(u16 *DestPtr)
+{
+    u16 Source = *DestPtr;
+   return (u16) (((Source & 0xFF00) >> 8) | ((Source & 0x00FF) << 8));
+}
+/*****************************************************************************/
+/**
+*
+* Performs a 32-bit endian converion.
+*
+* @param    Source contains the value to be converted.
+* @param    DestPtr contains a pointer to the location to put the
+*           converted value.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void OutSwap32(u32 Source, u32 *DestPtr)
+{
+
+    /* get each of the half words from the 32 bit word */
+
+    u16 LoWord = (u16) (Source & 0x0000FFFF);
+    u16 HiWord = (u16) ((Source & 0xFFFF0000) >> 16);
+
+    /* byte swap each of the 16 bit half words */
+
+    LoWord = (((LoWord & 0xFF00) >> 8) | ((LoWord & 0x00FF) << 8));
+    HiWord = (((HiWord & 0xFF00) >> 8) | ((HiWord & 0x00FF) << 8));
+
+    /* swap the half words before returning the value */
+
+    *DestPtr = (u32) ((LoWord << 16) | HiWord);
+}
+
+u32 InSwap32(u32 *DestPtr)
+{
+   /* get each of the half words from the 32 bit word */
+    u32 Source = *DestPtr;
+
+    u16 LoWord = (u16) (Source & 0x0000FFFF);
+    u16 HiWord = (u16) ((Source & 0xFFFF0000) >> 16);
+
+    /* byte swap each of the 16 bit half words */
+
+    LoWord = (((LoWord & 0xFF00) >> 8) | ((LoWord & 0x00FF) << 8));
+    HiWord = (((HiWord & 0xFF00) >> 8) | ((HiWord & 0x00FF) << 8));
+
+    /* swap the half words before returning the value */
+
+    return (u32) ((LoWord << 16) | HiWord);
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for an 8-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param    InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+    u8 XIo_In8(XIo_Address InAddress)
+{
+    /* read the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#if defined CONFIG_PPC
+
+    u8 IoContents;
+    __asm__ volatile ("eieio; lbz %0,0(%1)":"=r" (IoContents):"b"
+              (InAddress));
+    return IoContents;
+
+#else
+
+    SYNCHRONIZE_IO;
+    return *(u8 *) InAddress;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 16-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param    InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XIo_In16(XIo_Address InAddress)
+{
+    /* read the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#if defined CONFIG_PPC
+
+    u16 IoContents;
+    __asm__ volatile ("eieio; lhz %0,0(%1)":"=r" (IoContents):"b"
+              (InAddress));
+    return IoContents;
+
+#else
+
+    SYNCHRONIZE_IO;
+    return *(u16 *) InAddress;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 32-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param    InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XIo_In32(XIo_Address InAddress)
+{
+    /* read the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#ifdef CONFIG_PPC
+
+    u32 IoContents;
+    __asm__ volatile ("eieio; lwz %0,0(%1)":"=r" (IoContents):"b"
+              (InAddress));
+    return IoContents;
+
+#else
+
+    SYNCHRONIZE_IO;
+    return *(u32 *) InAddress;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 16-bit memory location by reading from the
+* specified address and returning the byte-swapped value read from that
+* address.
+*
+* @param    InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The byte-swapped value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XIo_InSwap16(XIo_Address InAddress)
+{
+    /* read the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+#ifdef CONFIG_PPC
+    u16 IoContents;
+
+    __asm__ volatile ("eieio; lhbrx %0,0,%1":"=r" (IoContents):"b"
+              (InAddress));
+    return IoContents;
+#else
+    return InSwap16(InAddress);
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 32-bit memory location by reading from the
+* specified address and returning the byte-swapped value read from that
+* address.
+*
+* @param    InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The byte-swapped value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XIo_InSwap32(XIo_Address InAddress)
+{
+    /* read the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+#ifdef CONFIG_PPC
+    u32 IoContents;
+
+    __asm__ volatile ("eieio; lwbrx %0,0,%1":"=r" (IoContents):"b"
+              (InAddress));
+    return IoContents;
+#else
+    return InSwap32(InAddress);
+#endif
+
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for an 8-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param    OutAddress contains the address to perform the output operation at.
+* @param    Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out8(XIo_Address OutAddress, u8 Value)
+{
+    /* write the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#ifdef CONFIG_PPC
+
+    __asm__ volatile ("stb %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+    *(volatile u8 *) OutAddress = Value;
+    SYNCHRONIZE_IO;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 16-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param    OutAddress contains the address to perform the output operation at.
+* @param    Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out16(XIo_Address OutAddress, u16 Value)
+{
+    /* write the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#ifdef CONFIG_PPC
+
+    __asm__ volatile ("sth %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+    *(volatile u16 *) OutAddress = Value;
+    SYNCHRONIZE_IO;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 32-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param    OutAddress contains the address to perform the output operation at.
+* @param    Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out32(XIo_Address OutAddress, u32 Value)
+{
+    /* write the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+
+#ifdef CONFIG_PPC
+
+    __asm__ volatile ("stw %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+    *(volatile u32 *) OutAddress = Value;
+    SYNCHRONIZE_IO;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 16-bit memory location by writing the
+* specified value to the the specified address. The value is byte-swapped
+* before being written.
+*
+* @param    OutAddress contains the address to perform the output operation at.
+* @param    Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_OutSwap16(XIo_Address OutAddress, u16 Value)
+{
+    /* write the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+#ifdef CONFIG_PPC
+    __asm__ volatile ("sthbrx %0,0,%1; eieio"::"r" (Value),
+              "b"(OutAddress));
+#else
+    OutSwap16(OutAddress, Value);
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 32-bit memory location by writing the
+* specified value to the the specified address. The value is byte-swapped
+* before being written.
+*
+* @param    OutAddress contains the address to perform the output operation at.
+* @param    Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_OutSwap32(XIo_Address OutAddress, u32 Value)
+{
+    /* write the contents of the I/O location and then synchronize the I/O
+     * such that the I/O operation completes before proceeding on
+     */
+#ifdef CONFIG_PPC
+    __asm__ volatile ("stwbrx %0,0,%1; eieio"::"r" (Value),
+              "b"(OutAddress));
+#else
+    OutSwap32(OutAddress, Value);
+#endif
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio_dcr.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio_dcr.c	2014-07-20 22:06:39.008261975 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xio_dcr.c,v 1.9 2007/01/24 17:00:16 meinelte Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio_dcr.c
+*
+* The implementation of the XDcrIo interface. See xio_dcr.h for more
+* information about the component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  11/09/06 Modified from the PPC405 version to use the indirect
+*                     addressing that is available in the PPC440 block in V5.
+*                     Removed the jump table structure in xio_dcr.c also.
+*                     Added functionality from the SEG driver to allow for
+*                     one file pair.
+* 1.00a ecm  01/02/07 Incorporated changes from testing with multiple DCR
+*                     masters, discovered and fixed several concurrency
+*                     issues.
+* 1.00a ecm  01/24/07 update for new coding standard.
+* </pre>
+*
+* @internal
+*
+* The C functions which subsequently call into either the assembly code or into
+* the provided table of functions are required since the registers assigned to
+* the calling and return from functions are strictly defined in the ABI and that
+* definition is used in the low-level functions directly. The use of macros is
+* not recommended since the temporary registers in the ABI are defined but there
+* is no way to force the compiler to use a specific register in a block of code.
+*
+*****************************************************************************/
+
+/***************************** Include Files ********************************/
+
+#include <asm/dcr.h>
+#include <asm/reg.h>
+
+#include "xstatus.h"
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xio_dcr.h"
+
+/************************** Constant Definitions ****************************/
+
+/*
+ * base address defines for each of the four possible DCR base
+ * addresses a processor can have
+ */
+#define XDCR_0_BASEADDR 0x000
+#define XDCR_1_BASEADDR 0x100
+#define XDCR_2_BASEADDR 0x200
+#define XDCR_3_BASEADDR 0x300
+
+
+#define MAX_DCR_REGISTERS           4096
+#define MAX_DCR_REGISTER            MAX_DCR_REGISTERS - 1
+#define MIN_DCR_REGISTER            0
+
+/**************************** Type Definitions ******************************/
+
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+
+
+
+/************************** Function Prototypes *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Outputs value provided to specified register defined in the header file.
+*
+* @param    DcrRegister is the intended destination DCR register
+* @param    Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+void XIo_DcrOut(u32 DcrRegister, u32 Data)
+{
+    /*
+     * Assert validates the register number
+     */
+    XASSERT_VOID(DcrRegister < MAX_DCR_REGISTERS);
+
+    /*
+     * pass the call on to the proper function
+     */
+    XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister, Data);
+}
+
+/*****************************************************************************/
+/**
+*
+* Reads value from specified register.
+*
+* @param    DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+u32 XIo_DcrIn(u32 DcrRegister)
+{
+    /*
+     * Assert validates the register number
+     */
+    XASSERT_NONVOID(DcrRegister < MAX_DCR_REGISTERS);
+
+    /*
+     * pass the call on to the proper function
+     */
+    return (XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR, DcrRegister));
+}
+
+/*****************************************************************************/
+/**
+*
+* Reads the value of the specified register using the indirect access method.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended destination DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrReadReg(u32 DcrBase, u32 DcrRegister)
+{
+    switch (DcrBase) {
+    case 0x000:
+        return XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+                           DcrRegister);
+    case 0x100:
+        return XIo_mDcrIndirectAddrReadReg(XDCR_1_BASEADDR,
+                           DcrRegister);
+    case 0x200:
+        return XIo_mDcrIndirectAddrReadReg(XDCR_2_BASEADDR,
+                           DcrRegister);
+    case 0x300:
+        return XIo_mDcrIndirectAddrReadReg(XDCR_3_BASEADDR,
+                           DcrRegister);
+    default:
+        return XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+                           DcrRegister);
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Writes the value to the specified register using the indirect access method.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended destination DCR register
+* @param    Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data)
+{
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+                         Data);
+        return;
+    case 0x100:
+        XIo_mDcrIndirectAddrWriteReg(XDCR_1_BASEADDR, DcrRegister,
+                         Data);
+        return;
+    case 0x200:
+        XIo_mDcrIndirectAddrWriteReg(XDCR_2_BASEADDR, DcrRegister,
+                         Data);
+        return;
+    case 0x300:
+        XIo_mDcrIndirectAddrWriteReg(XDCR_3_BASEADDR, DcrRegister,
+                         Data);
+        return;
+    default:
+        XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+                         Data);
+        return;
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Explicitly acquires and release DCR lock--Auto-Lock is disabled.
+* Reads the value of the specified register using the indirect access method.
+* This function is provided because the most common usecase is to enable
+* Auto-Lock. Checking for Auto-Lock in every indirect access would defeat the
+* purpose of having Auto-Lock.
+* Auto-Lock can only be enable/disabled in hardware.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended destination DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrLockAndReadReg(u32 DcrBase, u32 DcrRegister)
+{
+    unsigned int rVal;
+
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        rVal = XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+                           DcrRegister);
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+    case 0x100:
+        XIo_mDcrLock(XDCR_1_BASEADDR);
+        rVal = XIo_mDcrIndirectAddrReadReg(XDCR_1_BASEADDR,
+                           DcrRegister);
+        XIo_mDcrUnlock(XDCR_1_BASEADDR);
+    case 0x200:
+        XIo_mDcrLock(XDCR_2_BASEADDR);
+        rVal = XIo_mDcrIndirectAddrReadReg(XDCR_2_BASEADDR,
+                           DcrRegister);
+        XIo_mDcrUnlock(XDCR_2_BASEADDR);
+    case 0x300:
+        XIo_mDcrLock(XDCR_3_BASEADDR);
+        rVal = XIo_mDcrIndirectAddrReadReg(XDCR_3_BASEADDR,
+                           DcrRegister);
+        XIo_mDcrUnlock(XDCR_3_BASEADDR);
+    default:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        rVal = XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+                           DcrRegister);
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+    }
+    return rVal;
+}
+
+/*****************************************************************************/
+/**
+*
+* Explicitly acquires and release DCR lock--Auto-Lock is disabled.
+* Writes the value to the specified register using the indirect access method.
+* This function is provided because the most common usecase is to enable
+* Auto-Lock. Checking for Auto-Lock in every indirect access would defeat the
+* purpose of having Auto-Lock.
+* Auto-Lock can only be enable/disabled in hardware.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended destination DCR register
+* @param    Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrLockAndWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data)
+{
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+                         Data);
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+        return;
+    case 0x100:
+        XIo_mDcrLock(XDCR_1_BASEADDR);
+        XIo_mDcrIndirectAddrWriteReg(XDCR_1_BASEADDR, DcrRegister,
+                         Data);
+        XIo_mDcrUnlock(XDCR_1_BASEADDR);
+        return;
+    case 0x200:
+        XIo_mDcrLock(XDCR_2_BASEADDR);
+        XIo_mDcrIndirectAddrWriteReg(XDCR_2_BASEADDR, DcrRegister,
+                         Data);
+        XIo_mDcrUnlock(XDCR_2_BASEADDR);
+        return;
+    case 0x300:
+        XIo_mDcrLock(XDCR_3_BASEADDR);
+        XIo_mDcrIndirectAddrWriteReg(XDCR_3_BASEADDR, DcrRegister,
+                         Data);
+        XIo_mDcrUnlock(XDCR_3_BASEADDR);
+        return;
+    default:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+                         Data);
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+        return;
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Read APU UDI DCR via indirect addressing.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the desired APU UDI register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrReadAPUUDIReg(u32 DcrBase, short UDInum)
+{
+    switch (DcrBase) {
+    case 0x000:
+        return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_0_BASEADDR,
+                             UDInum);
+    case 0x100:
+        return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_1_BASEADDR,
+                             UDInum);
+    case 0x200:
+        return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_2_BASEADDR,
+                             UDInum);
+    case 0x300:
+        return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_3_BASEADDR,
+                             UDInum);
+    default:
+        return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_0_BASEADDR,
+                             UDInum);
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Writes the value to the APU UDI DCR using the indirect access method.
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the intended destination APU register
+* @param    Data is the value to be placed into the specified APU register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrWriteAPUUDIReg(u32 DcrBase, short UDInum, u32 Data)
+{
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_0_BASEADDR, UDInum,
+                           Data);
+        return;
+    case 0x100:
+        XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_1_BASEADDR, UDInum,
+                           Data);
+        return;
+    case 0x200:
+        XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_2_BASEADDR, UDInum,
+                           Data);
+        return;
+    case 0x300:
+        XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_3_BASEADDR, UDInum,
+                           Data);
+        return;
+    default:
+        XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_0_BASEADDR, UDInum,
+                           Data);
+        return;
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Locks DCR bus via the Global Status/Control register.
+*
+* @param    DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared. The internal PPC440 can clear both timeout bits but an
+* external DCR master can only clear the external DCR master's timeout bit.
+*
+* Only available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrLock(u32 DcrBase)
+{
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        return;
+    case 0x100:
+        XIo_mDcrLock(XDCR_1_BASEADDR);
+        return;
+    case 0x200:
+        XIo_mDcrLock(XDCR_2_BASEADDR);
+        return;
+    case 0x300:
+        XIo_mDcrLock(XDCR_3_BASEADDR);
+        return;
+    default:
+        XIo_mDcrLock(XDCR_0_BASEADDR);
+        return;
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Unlocks DCR bus via the Global Status/Control register.
+*
+* @param    DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared. The internal PPC440 can clear both timeout bits but an
+* external DCR master can only clear the external DCR master's timeout bit.
+*
+* Only available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrUnlock(u32 DcrBase)
+{
+    switch (DcrBase) {
+    case 0x000:
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+        return;
+    case 0x100:
+        XIo_mDcrUnlock(XDCR_1_BASEADDR);
+        return;
+    case 0x200:
+        XIo_mDcrUnlock(XDCR_2_BASEADDR);
+        return;
+    case 0x300:
+        XIo_mDcrUnlock(XDCR_3_BASEADDR);
+        return;
+    default:
+        XIo_mDcrUnlock(XDCR_0_BASEADDR);
+        return;
+    }
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio_dcr.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio_dcr.h	2014-07-20 22:06:39.021261760 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xio_dcr.h,v 1.8 2007/01/24 17:00:16 meinelte Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio_dcr.h
+*
+* The DCR I/O access functions.
+*
+* @note
+*
+* These access functions are specific to the PPC440 CPU. Changes might be
+* necessary for other members of the IBM PPC Family.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  10/18/05 First release
+*                     Need to verify opcodes for mt/mfdcr remain the same.
+* 1.00a ecm  11/09/06 Modified from the PPC405 version to use the indirect
+*                     addressing that is available in the PPC440 block in V5.
+*                     Removed the jump table structure in xio_dcr.c also.
+*                     Added functionality from the SEG driver to allow for
+*                     one file pair.
+* 1.00a ecm  01/02/07 Incorporated changes from testing with multiple DCR
+*                     masters, discovered and fixed several concurrency
+*                     issues.
+* 1.00a ecm  01/24/07 update for new coding standard.
+* </pre>
+*
+* @internal
+*
+* This code WILL NOT FUNCTION on the PPC405 based architectures, V2P and V4.
+*
+******************************************************************************/
+
+#ifndef XDCRIO_H        /* prevent circular inclusions */
+#define XDCRIO_H        /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+/*
+ *   256 internal DCR registers
+ *   Base address: 2 most signifcant bits of 10-bit addr taken from
+ *                 the C_DCRBASEADDR parameter of the processor block.
+ *   Offset: 8 least significant bits
+ */
+/* register base addresses */
+
+#define XDCR_APU_BASE   0x04
+#define XDCR_MIB_BASE   0x10
+#define XDCR_XB_BASE    0x20
+#define XDCR_PLBS0_BASE 0x34
+#define XDCR_PLBS1_BASE 0x44
+#define XDCR_PLBM_BASE  0x54
+#define XDCR_DMA0_BASE  0x80
+#define XDCR_DMA1_BASE  0x98
+#define XDCR_DMA2_BASE  0xB0
+#define XDCR_DMA3_BASE  0xC8
+
+/* register offsets */
+/* global registers 0x00-0x02 */
+
+#define XDCR_IDA_ADDR     0x00
+#define XDCR_IDA_ACC      0x01
+#define XDCR_CTRLCFGSTAT  0x02
+
+/* Auxiliary Processor Unit Controller (APU) 0x04-0x05 */
+
+#define XDCR_APU_UDI  (XDCR_APU_BASE+0x00)
+#define XDCR_APU_CTRL (XDCR_APU_BASE+0x01)
+
+/* Memory Interface Bridge (MIB) 0x10-0x13 */
+
+#define XDCR_MIB_CTRL (XDCR_MIB_BASE+0x00)
+#define XDCR_MIB_RCON (XDCR_MIB_BASE+0x01)
+#define XDCR_MIB_BCON (XDCR_MIB_BASE+0x02)
+
+/* Crossbar (XB) 0x20-0x33 */
+
+#define XDCR_XB_IST      (XDCR_XB_BASE+0x00)
+#define XDCR_XB_IMASK    (XDCR_XB_BASE+0x01)
+#define XDCR_XB_ARBCFGX  (XDCR_XB_BASE+0x03)
+#define XDCR_XB_FIFOSTX  (XDCR_XB_BASE+0x04)
+#define XDCR_XB_SMSTX    (XDCR_XB_BASE+0x05)
+#define XDCR_XB_MISCX    (XDCR_XB_BASE+0x06)
+#define XDCR_XB_ARBCFGM  (XDCR_XB_BASE+0x08)
+#define XDCR_XB_FIFOSTM  (XDCR_XB_BASE+0x09)
+#define XDCR_XB_SMSTM    (XDCR_XB_BASE+0x0A)
+#define XDCR_XB_MISCM    (XDCR_XB_BASE+0x0B)
+#define XDCR_XB_TMPL0MAP (XDCR_XB_BASE+0x0D)
+#define XDCR_XB_TMPL1MAP (XDCR_XB_BASE+0x0E)
+#define XDCR_XB_TMPL2MAP (XDCR_XB_BASE+0x0F)
+#define XDCR_XB_TMPL3MAP (XDCR_XB_BASE+0x10)
+#define XDCR_XB_TMPLSEL  (XDCR_XB_BASE+0x11)
+
+/* PLB Slave DCR offsets only */
+
+#define XDCR_PLBS_CFG        0x00
+#define XDCR_PLBS_SEARU      0x02
+#define XDCR_PLBS_SEARL      0x03
+#define XDCR_PLBS_SESR       0x04
+#define XDCR_PLBS_MISCST     0x05
+#define XDCR_PLBS_PLBERRST   0x06
+#define XDCR_PLBS_SMST       0x07
+#define XDCR_PLBS_MISC       0x08
+#define XDCR_PLBS_CMDSNIFF   0x09
+#define XDCR_PLBS_CMDSNIFFA  0x0A
+#define XDCR_PLBS_TMPL0MAP   0x0C
+#define XDCR_PLBS_TMPL1MAP   0x0D
+#define XDCR_PLBS_TMPL2MAP   0x0E
+#define XDCR_PLBS_TMPL3MAP   0x0F
+
+/* PLB Slave 0 (PLBS0) 0x34-0x43 */
+
+#define XDCR_PLBS0_CFG       (XDCR_PLBS0_BASE+0x00)
+#define XDCR_PLBS0_CNT       (XDCR_PLBS0_BASE+0x01)
+#define XDCR_PLBS0_SEARU     (XDCR_PLBS0_BASE+0x02)
+#define XDCR_PLBS0_SEARL     (XDCR_PLBS0_BASE+0x03)
+#define XDCR_PLBS0_SESR      (XDCR_PLBS0_BASE+0x04)
+#define XDCR_PLBS0_MISCST    (XDCR_PLBS0_BASE+0x05)
+#define XDCR_PLBS0_PLBERRST  (XDCR_PLBS0_BASE+0x06)
+#define XDCR_PLBS0_SMST      (XDCR_PLBS0_BASE+0x07)
+#define XDCR_PLBS0_MISC      (XDCR_PLBS0_BASE+0x08)
+#define XDCR_PLBS0_CMDSNIFF  (XDCR_PLBS0_BASE+0x09)
+#define XDCR_PLBS0_CMDSNIFFA (XDCR_PLBS0_BASE+0x0A)
+#define XDCR_PLBS0_TMPL0MAP  (XDCR_PLBS0_BASE+0x0C)
+#define XDCR_PLBS0_TMPL1MAP  (XDCR_PLBS0_BASE+0x0D)
+#define XDCR_PLBS0_TMPL2MAP  (XDCR_PLBS0_BASE+0x0E)
+#define XDCR_PLBS0_TMPL3MAP  (XDCR_PLBS0_BASE+0x0F)
+
+/* PLB Slave 1 (PLBS1) 0x44-0x53 */
+
+#define XDCR_PLBS1_CFG       (XDCR_PLBS1_BASE+0x00)
+#define XDCR_PLBS1_CNT       (XDCR_PLBS1_BASE+0x01)
+#define XDCR_PLBS1_SEARU     (XDCR_PLBS1_BASE+0x02)
+#define XDCR_PLBS1_SEARL     (XDCR_PLBS1_BASE+0x03)
+#define XDCR_PLBS1_SESR      (XDCR_PLBS1_BASE+0x04)
+#define XDCR_PLBS1_MISCST    (XDCR_PLBS1_BASE+0x05)
+#define XDCR_PLBS1_PLBERRST  (XDCR_PLBS1_BASE+0x06)
+#define XDCR_PLBS1_SMST      (XDCR_PLBS1_BASE+0x07)
+#define XDCR_PLBS1_MISC      (XDCR_PLBS1_BASE+0x08)
+#define XDCR_PLBS1_CMDSNIFF  (XDCR_PLBS1_BASE+0x09)
+#define XDCR_PLBS1_CMDSNIFFA (XDCR_PLBS1_BASE+0x0A)
+#define XDCR_PLBS1_TMPL0MAP  (XDCR_PLBS1_BASE+0x0C)
+#define XDCR_PLBS1_TMPL1MAP  (XDCR_PLBS1_BASE+0x0D)
+#define XDCR_PLBS1_TMPL2MAP  (XDCR_PLBS1_BASE+0x0E)
+#define XDCR_PLBS1_TMPL3MAP  (XDCR_PLBS1_BASE+0x0F)
+
+/* PLB Master (PLBM) 0x54-0x5F */
+
+#define XDCR_PLBM_CFG       (XDCR_PLBM_BASE+0x00)
+#define XDCR_PLBM_CNT       (XDCR_PLBM_BASE+0x01)
+#define XDCR_PLBM_FSEARU    (XDCR_PLBM_BASE+0x02)
+#define XDCR_PLBM_FSEARL    (XDCR_PLBM_BASE+0x03)
+#define XDCR_PLBM_FSESR     (XDCR_PLBM_BASE+0x04)
+#define XDCR_PLBM_MISCST    (XDCR_PLBM_BASE+0x05)
+#define XDCR_PLBM_PLBERRST  (XDCR_PLBM_BASE+0x06)
+#define XDCR_PLBM_SMST      (XDCR_PLBM_BASE+0x07)
+#define XDCR_PLBM_MISC      (XDCR_PLBM_BASE+0x08)
+#define XDCR_PLBM_CMDSNIFF  (XDCR_PLBM_BASE+0x09)
+#define XDCR_PLBM_CMDSNIFFA (XDCR_PLBM_BASE+0x0A)
+
+/* DMA Controller DCR offsets only */
+#define XDCR_DMA_TXNXTDESCPTR   0x00
+#define XDCR_DMA_TXCURBUFADDR   0x01
+#define XDCR_DMA_TXCURBUFLEN    0x02
+#define XDCR_DMA_TXCURDESCPTR   0x03
+#define XDCR_DMA_TXTAILDESCPTR  0x04
+#define XDCR_DMA_TXCHANNELCTRL  0x05
+#define XDCR_DMA_TXIRQ          0x06
+#define XDCR_DMA_TXSTATUS       0x07
+#define XDCR_DMA_RXNXTDESCPTR   0x08
+#define XDCR_DMA_RXCURBUFADDR   0x09
+#define XDCR_DMA_RXCURBUFLEN    0x0A
+#define XDCR_DMA_RXCURDESCPTR   0x0B
+#define XDCR_DMA_RXTAILDESCPTR  0x0C
+#define XDCR_DMA_RXCHANNELCTRL  0x0D
+#define XDCR_DMA_RXIRQ          0x0E
+#define XDCR_DMA_RXSTATUS       0x0F
+#define XDCR_DMA_CTRL           0x10
+
+/* DMA Controller 0 (DMA0) 0x80-0x90 */
+
+#define XDCR_DMA0_TXNXTDESCPTR  (XDCR_DMA0_BASE+0x00)
+#define XDCR_DMA0_TXCURBUFADDR  (XDCR_DMA0_BASE+0x01)
+#define XDCR_DMA0_TXCURBUFLEN   (XDCR_DMA0_BASE+0x02)
+#define XDCR_DMA0_TXCURDESCPTR  (XDCR_DMA0_BASE+0x03)
+#define XDCR_DMA0_TXTAILDESCPTR (XDCR_DMA0_BASE+0x04)
+#define XDCR_DMA0_TXCHANNELCTRL (XDCR_DMA0_BASE+0x05)
+#define XDCR_DMA0_TXIRQ         (XDCR_DMA0_BASE+0x06)
+#define XDCR_DMA0_TXSTATUS      (XDCR_DMA0_BASE+0x07)
+#define XDCR_DMA0_RXNXTDESCPTR  (XDCR_DMA0_BASE+0x08)
+#define XDCR_DMA0_RXCURBUFADDR  (XDCR_DMA0_BASE+0x09)
+#define XDCR_DMA0_RXCURBUFLEN   (XDCR_DMA0_BASE+0x0A)
+#define XDCR_DMA0_RXCURDESCPTR  (XDCR_DMA0_BASE+0x0B)
+#define XDCR_DMA0_RXTAILDESCPTR (XDCR_DMA0_BASE+0x0C)
+#define XDCR_DMA0_RXCHANNELCTRL (XDCR_DMA0_BASE+0x0D)
+#define XDCR_DMA0_RXIRQ         (XDCR_DMA0_BASE+0x0E)
+#define XDCR_DMA0_RXSTATUS      (XDCR_DMA0_BASE+0x0F)
+#define XDCR_DMA0_CTRL          (XDCR_DMA0_BASE+0x10)
+
+/* DMA Controller 1 (DMA1) 0x98-0xA8 */
+
+#define XDCR_DMA1_TXNXTDESCPTR  (XDCR_DMA1_BASE+0x00)
+#define XDCR_DMA1_TXCURBUFADDR  (XDCR_DMA1_BASE+0x01)
+#define XDCR_DMA1_TXCURBUFLEN   (XDCR_DMA1_BASE+0x02)
+#define XDCR_DMA1_TXCURDESCPTR  (XDCR_DMA1_BASE+0x03)
+#define XDCR_DMA1_TXTAILDESCPTR (XDCR_DMA1_BASE+0x04)
+#define XDCR_DMA1_TXCHANNELCTRL (XDCR_DMA1_BASE+0x05)
+#define XDCR_DMA1_TXIRQ         (XDCR_DMA1_BASE+0x06)
+#define XDCR_DMA1_TXSTATUS      (XDCR_DMA1_BASE+0x07)
+#define XDCR_DMA1_RXNXTDESCPTR  (XDCR_DMA1_BASE+0x08)
+#define XDCR_DMA1_RXCURBUFADDR  (XDCR_DMA1_BASE+0x09)
+#define XDCR_DMA1_RXCURBUFLEN   (XDCR_DMA1_BASE+0x0A)
+#define XDCR_DMA1_RXCURDESCPTR  (XDCR_DMA1_BASE+0x0B)
+#define XDCR_DMA1_RXTAILDESCPTR (XDCR_DMA1_BASE+0x0C)
+#define XDCR_DMA1_RXCHANNELCTRL (XDCR_DMA1_BASE+0x0D)
+#define XDCR_DMA1_RXIRQ         (XDCR_DMA1_BASE+0x0E)
+#define XDCR_DMA1_RXSTATUS      (XDCR_DMA1_BASE+0x0F)
+#define XDCR_DMA1_CTRL          (XDCR_DMA1_BASE+0x10)
+
+/* DMA Controller 2 (DMA2) 0xB0-0xC0 */
+
+#define XDCR_DMA2_TXNXTDESCPTR  (XDCR_DMA2_BASE+0x00)
+#define XDCR_DMA2_TXCURBUFADDR  (XDCR_DMA2_BASE+0x01)
+#define XDCR_DMA2_TXCURBUFLEN   (XDCR_DMA2_BASE+0x02)
+#define XDCR_DMA2_TXCURDESCPTR  (XDCR_DMA2_BASE+0x03)
+#define XDCR_DMA2_TXTAILDESCPTR (XDCR_DMA2_BASE+0x04)
+#define XDCR_DMA2_TXCHANNELCTRL (XDCR_DMA2_BASE+0x05)
+#define XDCR_DMA2_TXIRQ         (XDCR_DMA2_BASE+0x06)
+#define XDCR_DMA2_TXSTATUS      (XDCR_DMA2_BASE+0x07)
+#define XDCR_DMA2_RXNXTDESCPTR  (XDCR_DMA2_BASE+0x08)
+#define XDCR_DMA2_RXCURBUFADDR  (XDCR_DMA2_BASE+0x09)
+#define XDCR_DMA2_RXCURBUFLEN   (XDCR_DMA2_BASE+0x0A)
+#define XDCR_DMA2_RXCURDESCPTR  (XDCR_DMA2_BASE+0x0B)
+#define XDCR_DMA2_RXTAILDESCPTR (XDCR_DMA2_BASE+0x0C)
+#define XDCR_DMA2_RXCHANNELCTRL (XDCR_DMA2_BASE+0x0D)
+#define XDCR_DMA2_RXIRQ         (XDCR_DMA2_BASE+0x0E)
+#define XDCR_DMA2_RXSTATUS      (XDCR_DMA2_BASE+0x0F)
+#define XDCR_DMA2_CTRL          (XDCR_DMA2_BASE+0x10)
+
+/* DMA Controller 3 (DMA3) 0xC8-0xD8 */
+
+#define XDCR_DMA3_TXNXTDESCPTR  (XDCR_DMA3_BASE+0x00)
+#define XDCR_DMA3_TXCURBUFADDR  (XDCR_DMA3_BASE+0x01)
+#define XDCR_DMA3_TXCURBUFLEN   (XDCR_DMA3_BASE+0x02)
+#define XDCR_DMA3_TXCURDESCPTR  (XDCR_DMA3_BASE+0x03)
+#define XDCR_DMA3_TXTAILDESCPTR (XDCR_DMA3_BASE+0x04)
+#define XDCR_DMA3_TXCHANNELCTRL (XDCR_DMA3_BASE+0x05)
+#define XDCR_DMA3_TXIRQ         (XDCR_DMA3_BASE+0x06)
+#define XDCR_DMA3_TXSTATUS      (XDCR_DMA3_BASE+0x07)
+#define XDCR_DMA3_RXNXTDESCPTR  (XDCR_DMA3_BASE+0x08)
+#define XDCR_DMA3_RXCURBUFADDR  (XDCR_DMA3_BASE+0x09)
+#define XDCR_DMA3_RXCURBUFLEN   (XDCR_DMA3_BASE+0x0A)
+#define XDCR_DMA3_RXCURDESCPTR  (XDCR_DMA3_BASE+0x0B)
+#define XDCR_DMA3_RXTAILDESCPTR (XDCR_DMA3_BASE+0x0C)
+#define XDCR_DMA3_RXCHANNELCTRL (XDCR_DMA3_BASE+0x0D)
+#define XDCR_DMA3_RXIRQ         (XDCR_DMA3_BASE+0x0E)
+#define XDCR_DMA3_RXSTATUS      (XDCR_DMA3_BASE+0x0F)
+#define XDCR_DMA3_CTRL          (XDCR_DMA3_BASE+0x10)
+
+
+/**
+ * <pre
+ * These are the bit defines for the Control, Configuration, and Status
+ * register (XDCR_CTRLCFGSTAT)
+ * @{
+ */
+#define XDCR_INT_MSTR_LOCK_MASK        0x80000000   /* Internal Master Bus Lock */
+#define XDCR_INT_MSTR_AUTO_LOCK_MASK   0x40000000   /* Internal Master Bus Auto Lock, RO */
+#define XDCR_EXT_MSTR_LOCK_MASK        0x20000000   /* External Master Bus Master Lock */
+#define XDCR_EXT_MSTR_AUTO_LOCK_MASK   0x10000000   /* External Master Bus Auto Lock, RO */
+#define XDCR_ENB_DCR_AUTO_LOCK_MASK    0x08000000   /* Enable Auto Bus Lock */
+#define XDCR_ENB_MSTR_ASYNC_MASK       0x04000000   /* External Master in Async Mode */
+#define XDCR_ENB_SLV_ASYNC_MASK        0x02000000   /* External Slave in Async Mode */
+#define XDCR_ENB_DCR_TIMEOUT_SUPP_MASK 0x01000000   /* Enable Timeout Support */
+#define XDCR_INT_MSTR_TIMEOUT_BIT      0x00000002   /* Internal Master Bus Timeout Occurred */
+#define XDCR_EXT_MSTR_TIMEOUT_BIT      0x00000001   /* External Master Bus Timeout Occurred */
+
+/*
+ * Mask to disable exceptions in PPC440 MSR
+ * Bit 14: Critical Interrupt Enable            0x00020000
+ * Bit 16: External Interrupt Enable            0x00008000
+ * Bit 20: Floating-point Exceptions Mode 0     0x00000800
+ * Bit 23: Floating-point Exceptions Mode 1     0x00000100
+ */
+#define XDCR_DISABLE_EXCEPTIONS 0xFFFD76FF
+#define XDCR_ALL_LOCK           (XDCR_INT_MSTR_LOCK_MASK | XDCR_EXT_MSTR_LOCK_MASK)
+#define XDCR_ALL_TIMEOUT        (XDCR_INT_MSTR_TIMEOUT_BIT | XDCR_EXT_MSTR_TIMEOUT_BIT)
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************/
+/**
+* Reads the register at the specified DCR address.
+*
+*
+* @param    DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* C-style signature:
+*    void XIo_mDcrReadReg(u32 DcrRegister)
+*
+*******************************************************************************/
+#define XIo_mDcrReadReg(DcrRegister) ({ mfdcr((DcrRegister)); })
+
+/******************************************************************************/
+/**
+* Writes the register at specified DCR address.
+*
+*
+* @param    DcrRegister is the intended destination DCR register
+* @param    Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*    void XIo_mDcrWriteReg(u32 DcrRegister, u32 Data)
+*
+*******************************************************************************/
+#define XIo_mDcrWriteReg(DcrRegister, Data) ({ mtdcr((DcrRegister), (Data)); })
+
+/******************************************************************************/
+/**
+* Explicitly locks the DCR bus
+*
+* @param    DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrLock(u32 DcrBase)
+*
+*   Sets either Lock bit. Since a master cannot edit another master's Lock bit,
+*   the macro can be simplified.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrLock(DcrBase) \
+({ \
+ u32 temp;	\
+ temp = mfdcr((DcrBase) + XDCR_CTRLCFGSTAT);		\
+ temp = (temp | XDCR_ALL_LOCK) & ~XDCR_ALL_TIMEOUT;	\
+ mtdcr(((DcrBase) + XDCR_CTRLCFGSTAT), temp); \
+})
+
+/******************************************************************************/
+/**
+* Explicitly locks the DCR bus
+*
+* @param    DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrUnlock(u32 DcrBase)
+*
+*   Unsets either Lock bit. Since a master cannot edit another master's Lock bit,
+*   the macro can be simplified.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrUnlock(DcrBase) \
+({ \
+ u32 temp;						\
+ temp = mfdcr((DcrBase) + XDCR_CTRLCFGSTAT);		\
+ temp = temp & ~(XDCR_ALL_LOCK | XDCR_ALL_TIMEOUT);	\
+ mtdcr(((DcrBase) + XDCR_CTRLCFGSTAT), temp);		\
+})
+
+/******************************************************************************/
+/**
+* Reads the APU UDI register at the specified APU address.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the intended source APU register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* C-style signature:
+*    u32 XIo_mDcrReadAPUUDIReg(u32 DcrRegister, u32 UDInum)
+*
+*   Since reading an APU UDI DCR requires a dummy write to the same DCR,
+*   the target UDI number is required. In order to make this operation atomic,
+*   interrupts are disabled before and enabled after the DCR accesses.
+*   Because an APU UDI access involves two DCR accesses, the DCR bus must be
+*   locked to ensure that another master doesn't access the APU UDI register
+*   at the same time.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*   Steps:
+*   - save old MSR
+*   - disable interrupts by writing mask to MSR
+*   - acquire lock; since the PPC440 supports timeout wait, it will wait until
+*     it successfully acquires the DCR bus lock
+*   - shift and mask the UDI number to its bit position of [22:25]
+*   - add the DCR base address to the UDI number and perform the read
+*   - release DCR bus lock
+*   - restore MSR
+*   - return value read
+*
+*******************************************************************************/
+#define XIo_mDcrReadAPUUDIReg(DcrBase, UDInum) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (((UDInum) << 6) & 0x000003c0) | 0x00000030); \
+ rVal = mfdcr((DcrBase) | XDCR_APU_UDI); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the data to the APU UDI register at the specified APU address.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the intended source APU register
+* @param    Data is the value to be placed into the specified APU register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrWriteAPUUDIReg(u32 DcrRegister, u32 UDInum, u32 Data)
+*
+*   Since writing an APU UDI DCR requires a dummy write to the same DCR,
+*   the target UDI number is required. In order to make this operation atomic,
+*   interrupts are disabled before and enabled after the DCR accesses.
+*   Because an APU UDI access involves two DCR accesses, the DCR bus must be
+*   locked to ensure that another master doesn't access the APU UDI register
+*   at the same time.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*   Steps:
+*   - save old MSR
+*   - disable interrupts by writing mask to MSR
+*   - acquire lock, since the PPC440 supports timeout wait, it will wait until
+*     it successfully acquires the DCR bus lock
+*   - shift and mask the UDI number to its bit position of [22:25]
+*   - add DCR base address to UDI number offset and perform the write
+*   - release DCR bus lock
+*   - restore MSR
+*
+*******************************************************************************/
+#define XIo_mDcrWriteAPUUDIReg(DcrBase, UDInum, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (((UDInum) << 6) & 0x000003c0) | 0x00000030); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (Data)); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+})
+
+/******************************************************************************/
+/**
+* Reads the register at the specified DCR address using the indirect addressing
+* method.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrIndirectAddrReadReg(u32 DcrBase, u32 DcrRegister)
+*
+*   Assumes auto-buslocking feature is ON.
+*   In order to make this operation atomic, interrupts are disabled before
+*   and enabled after the DCR accesses.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrReadReg(DcrBase, DcrRegister) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | DcrRegister); \
+ rVal = XIo_mDcrReadReg((DcrBase) | XDCR_IDA_ACC); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the register at specified DCR address using the indirect addressing
+* method.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    DcrRegister is the intended destination DCR register
+* @param    Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrIndirectAddrWriteReg(u32 DcrBase, u32 DcrRegister,
+*                                  u32 Data)
+*
+*   Assumes auto-buslocking feature is ON.
+*   In order to make this operation atomic, interrupts are disabled before
+*   and enabled after the DCR accesses.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrWriteReg(DcrBase, DcrRegister, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | DcrRegister); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, Data); \
+ mtmsr(oldMSR); \
+})
+
+/******************************************************************************/
+/**
+* Reads the APU UDI register at the specified DCR address using the indirect
+* addressing method.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrIndirectAddrReadAPUUDIReg(u32 DcrBase, u32 UDInum)
+*
+*   An indirect APU UDI read requires three DCR accesses:
+*     1) Indirect address reg write
+*     2) Indirect access reg write to specify the UDI number
+*     3) Indirect access reg read of the actual data
+*   Since (2) unlocks the DCR bus, the DCR bus must be explicitly locked
+*   instead of relying on the auto-lock feature.
+*   In order to make this operation atomic, interrupts are disabled before
+*   and enabled after the DCR accesses.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrReadAPUUDIReg(DcrBase, UDInum) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | XDCR_APU_UDI); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, ((UDInum << 6) & 0x000003c0) | 0x00000030); \
+ rVal = XIo_mDcrReadReg((DcrBase) | XDCR_IDA_ACC); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the APU UDI register at specified DCR address using the indirect
+* addressing method.
+*
+*
+* @param    DcrBase is the base of the block of DCR registers
+* @param    UDInum is the intended source DCR register
+* @param    Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+*   void XIo_mDcrIndirectAddrWriteReg(u32 DcrBase, u32 UDInum, u32 Data)
+*
+*   An indirect APU UDI write requires three DCR accesses:
+*     1) Indirect address reg write
+*     2) Indirect access reg write to specify the UDI number
+*     3) Indirect access reg write of the actual data
+*   Since (2) unlocks the DCR bus, the DCR bus must be explicitly locked
+*   instead of relying on the auto-lock feature.
+*   In order to make this operation atomic, interrupts are disabled before
+*   and enabled after the DCR accesses.
+*   Care must be taken to not write a '1' to either timeout bit because
+*   it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrWriteAPUUDIReg(DcrBase, UDInum, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | XDCR_APU_UDI); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, ((UDInum << 6) & 0x000003c0) | 0x00000030); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, Data);\
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+})
+
+/************************** Function Prototypes ******************************/
+void XIo_DcrOut(u32 DcrRegister, u32 Data);
+u32 XIo_DcrIn(u32 DcrRegister);
+
+u32 XIo_DcrReadReg(u32 DcrBase, u32 DcrRegister);
+void XIo_DcrWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data);
+u32 XIo_DcrLockAndReadReg(u32 DcrBase, u32 DcrRegister);
+void XIo_DcrLockAndWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data);
+
+void XIo_DcrWriteAPUUDIReg(u32 DcrBase, short UDInum, u32 Data);
+u32 XIo_DcrReadAPUUDIReg(u32 DcrBase, short UDInum);
+
+void XIo_DcrLock(u32 DcrBase);
+void XIo_DcrUnlock(u32 DcrBase);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xio.h	2014-07-20 22:06:39.031261595 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xio.h,v 1.4 2007/07/24 22:01:35 xduan Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio.h
+*
+* This file contains the interface for the XIo component, which encapsulates
+* the Input/Output functions for the PowerPC architecture.
+* This header file needs to be updated to replace eieio with mbar when
+* compilers support the mbar mnemonic.
+*
+* @note
+*
+* This file contains architecture-dependent items (memory mapped or non memory
+* mapped I/O).
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a ecm  10/18/05 initial release
+*                     needs to be updated to replace eieio with mbar when
+*                     compilers support this mnemonic.
+*
+* 1.00a ecm  01/24/07 update for new coding standard.
+* 1.10a xd   07/24/07 Corrected the format in asm functions in __DCC__ mode.
+* </pre>
+******************************************************************************/
+
+#ifndef XIO_H           /* prevent circular inclusions */
+#define XIO_H           /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * Typedef for an I/O address.  Typically correlates to the width of the
+ * address bus.
+ */
+typedef u32 XIo_Address;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* The following macro is specific to the GNU compiler and PowerPC family. It
+ * performs an EIEIO instruction such that I/O operations are synced correctly.
+ * This macro is not necessarily portable across compilers since it uses
+ * inline assembly.
+ */
+#ifdef CONFIG_PPC
+#  define SYNCHRONIZE_IO __asm__ volatile ("eieio") /* should be 'mbar' ultimately */
+#else
+#  define SYNCHRONIZE_IO
+#endif
+
+/* The following macros allow the software to be transportable across
+ * processors which use big or little endian memory models.
+ *
+ * Defined first are processor-specific endian conversion macros specific to
+ * the GNU compiler and the PowerPC family, as well as a no-op endian conversion
+ * macro. These macros are not to be used directly by software. Instead, the
+ * XIo_To/FromLittleEndianXX and XIo_To/FromBigEndianXX macros below are to be
+ * used to allow the endian conversion to only be performed when necessary
+ */
+
+#define XIo_EndianNoop(Source, DestPtr)    (*DestPtr = Source)
+
+#ifdef CONFIG_PPC
+
+#define XIo_EndianSwap16(Source, DestPtr)  __asm__ __volatile__(\
+                                           "sthbrx %0,0,%1\n"\
+                                           : : "r" (Source), "r" (DestPtr)\
+                                           )
+
+#define XIo_EndianSwap32(Source, DestPtr)  __asm__ __volatile__(\
+                                           "stwbrx %0,0,%1\n"\
+                                           : : "r" (Source), "r" (DestPtr)\
+                                           )
+#else
+
+#define XIo_EndianSwap16(Source, DestPtr) \
+{\
+   u16 src = (Source); \
+   u16 *destptr = (DestPtr); \
+   *destptr = src >> 8; \
+   *destptr |= (src << 8); \
+}
+
+#define XIo_EndianSwap32(Source, DestPtr) \
+{\
+   u32 src = (Source); \
+   u32 *destptr = (DestPtr); \
+   *destptr = src >> 24; \
+   *destptr |= ((src >> 8)  & 0x0000FF00); \
+   *destptr |= ((src << 8)  & 0x00FF0000); \
+   *destptr |= ((src << 24) & 0xFF000000); \
+}
+
+#endif
+
+// #ifdef XLITTLE_ENDIAN
+// /* little-endian processor */
+
+// #define XIo_ToLittleEndian16                XIo_EndianNoop
+// #define XIo_ToLittleEndian32                XIo_EndianNoop
+// #define XIo_FromLittleEndian16              XIo_EndianNoop
+// #define XIo_FromLittleEndian32              XIo_EndianNoop
+
+// #define XIo_ToBigEndian16(Source, DestPtr)  XIo_EndianSwap16(Source, DestPtr)
+// #define XIo_ToBigEndian32(Source, DestPtr)  XIo_EndianSwap32(Source, DestPtr)
+// #define XIo_FromBigEndian16                 XIo_ToBigEndian16
+// #define XIo_FromBigEndian32                 XIo_ToBigEndian32
+
+// #else
+/* big-endian processor */ // ppc or microblaze
+
+#define XIo_ToLittleEndian16(Source, DestPtr) XIo_EndianSwap16(Source, DestPtr)
+#define XIo_ToLittleEndian32(Source, DestPtr) XIo_EndianSwap32(Source, DestPtr)
+#define XIo_FromLittleEndian16                XIo_ToLittleEndian16
+#define XIo_FromLittleEndian32                XIo_ToLittleEndian32
+
+#define XIo_ToBigEndian16                     XIo_EndianNoop
+#define XIo_ToBigEndian32                     XIo_EndianNoop
+#define XIo_FromBigEndian16                   XIo_EndianNoop
+#define XIo_FromBigEndian32                   XIo_EndianNoop
+
+// #endif
+
+
+/************************** Function Prototypes ******************************/
+
+/* The following macros allow optimized I/O operations for memory mapped I/O
+ * Note that the SYNCHRONIZE_IO may be moved by the compiler during
+ * optimization.
+ */
+
+u8 XIo_In8(XIo_Address InAddress);
+u16 XIo_In16(XIo_Address InAddress);
+u32 XIo_In32(XIo_Address InAddress);
+
+void XIo_Out8(XIo_Address OutAddress, u8 Value);
+void XIo_Out16(XIo_Address OutAddress, u16 Value);
+void XIo_Out32(XIo_Address OutAddress, u32 Value);
+
+
+/*
+#define XIo_In8(InputPtr)  (*(volatile u8  *)(InputPtr)); SYNCHRONIZE_IO;
+#define XIo_In16(InputPtr) (*(volatile u16 *)(InputPtr)); SYNCHRONIZE_IO;
+#define XIo_In32(InputPtr) (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO;
+
+#define XIo_Out8(OutputPtr, Value)  \
+    { (*(volatile u8  *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
+#define XIo_Out16(OutputPtr, Value) \
+    { (*(volatile u16 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
+#define XIo_Out32(OutputPtr, Value) \
+    { (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
+ */
+
+/* The following functions handle IO addresses where data must be swapped
+ * They cannot be implemented as macros
+ */
+u16 XIo_InSwap16(XIo_Address InAddress);
+u32 XIo_InSwap32(XIo_Address InAddress);
+void XIo_OutSwap16(XIo_Address OutAddress, u16 Value);
+void XIo_OutSwap32(XIo_Address OutAddress, u32 Value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xipif_v1_23_b.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xipif_v1_23_b.c	2014-07-20 22:06:39.041261430 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xipif_v1_23_b.c,v 1.3 2004/11/15 20:31:35 xduan Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2004 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xipif_v1_23_b.c
+*
+* This file contains the implementation of the XIpIf component. The
+* XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.  This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.  Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.  The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.  The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* The interrupt registers of the IPIF are parameterizable such that the only
+* the number of bits necessary for the device are implemented. The functions
+* of this component do not attempt to validate that the passed in arguments are
+* valid based upon the number of implemented bits.  This is necessary to
+* maintain the level of performance required for the common components.  Bits
+* of the registers are assigned starting at the least significant bit of the
+* registers.
+*
+* <b>Critical Sections</b>
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* <b>Mutual Exclusion</b>
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to reduce size
+* 1.23b rpm  08/17/04 Doxygenated for inclusion in API documentation
+* 1.23b xd   10/27/04 Improve Doxygen format
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xipif_v1_23_b.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constant is used to generate bit masks for register testing
+ * in the self test functions, it defines the starting bit mask that is to be
+ * shifted from the LSB to MSB in creating a register test mask
+ */
+#define XIIF_V123B_FIRST_BIT_MASK     1UL
+
+
+/* the following constant defines the maximum number of bits which may be
+ * used in the registers at the device and IP levels, this is based upon the
+ * number of bits available in the registers
+ */
+#define XIIF_V123B_MAX_REG_BIT_COUNT 32
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/************************** Function Prototypes ******************************/
+
+static int IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
+
+/*****************************************************************************/
+/**
+*
+* This function performs a self test on the specified IPIF component.  Many
+* of the registers in the IPIF are tested to ensure proper operation.  This
+* function is destructive because the IPIF is reset at the start of the test
+* and at the end of the test to ensure predictable results.  The IPIF reset
+* also resets the entire device that uses the IPIF.  This function exits with
+* all interrupts for the device disabled.
+*
+* @param RegBaseAddress is the base address of the device's IPIF registers
+*
+* @param IpRegistersWidth contains the number of bits in the IP interrupt
+*        registers of the device.  The hardware is parameterizable such that
+*        only the number of bits necessary to support a device are implemented.
+*        This value must be between 0 and 32 with 0 indicating there are no IP
+*        interrupt registers used.
+*
+* @return
+*
+* A value of XST_SUCCESS indicates the test was successful with no errors.
+* Any one of the following error values may also be returned.
+*                                       <br><br>
+*   - XST_IPIF_RESET_REGISTER_ERROR     The value of a register at reset was
+*                                       not valid
+*                                       <br><br>
+*   - XST_IPIF_IP_STATUS_ERROR          A write to the IP interrupt status
+*                                       register did not read back correctly
+*                                       <br><br>
+*   - XST_IPIF_IP_ACK_ERROR             One or more bits in the IP interrupt
+*                                       status register did not reset when acked
+*                                       <br><br>
+*   - XST_IPIF_IP_ENABLE_ERROR          The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
+{
+	int Status;
+
+	/* assert to verify arguments are valid */
+
+	XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
+
+	/* reset the IPIF such that it's in a known state before the test
+	 * and interrupts are globally disabled
+	 */
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* perform the self test on the IP interrupt registers, if
+	 * it is not successful exit with the status
+	 */
+	Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	/* reset the IPIF such that it's in a known state before exiting test */
+
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* reaching this point means there were no errors, return success */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Perform a self test on the IP interrupt registers of the IPIF. This
+* function modifies registers of the IPIF such that they are not guaranteed
+* to be in the same state when it returns.  Any bits in the IP interrupt
+* status register which are set are assumed to be set by default after a reset
+* and are not tested in the test.
+*
+* @param RegBaseAddress is the base address of the device's IPIF registers
+*
+* @param IpRegistersWidth contains the number of bits in the IP interrupt
+*        registers of the device.  The hardware is parameterizable such that
+*        only the number of bits necessary to support a device are implemented.
+*        This value must be between 0 and 32 with 0 indicating there are no IP
+*        interrupt registers used.
+*
+* @return
+*
+* A status indicating XST_SUCCESS if the test was successful.  Otherwise, one
+* of the following values is returned.
+*   - XST_IPIF_RESET_REGISTER_ERROR     The value of a register at reset was
+*                                       not valid
+*                                       <br><br>
+*   - XST_IPIF_IP_STATUS_ERROR          A write to the IP interrupt status
+*                                       register did not read back correctly
+*                                       <br><br>
+*   - XST_IPIF_IP_ACK_ERROR             One or more bits in the IP status
+*                                       register did not reset when acked
+*                                       <br><br>
+*   - XST_IPIF_IP_ENABLE_ERROR          The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+* @note
+*
+* None.
+*
+******************************************************************************/
+static int IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
+{
+	/* ensure that the IP interrupt enable register is  zero
+	 * as it should be at reset, the interrupt status is dependent upon the
+	 * IP such that it's reset value is not known
+	 */
+	if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+		return XST_IPIF_RESET_REGISTER_ERROR;
+	}
+
+	/* if there are any used IP interrupts, then test all of the interrupt
+	 * bits in all testable registers
+	 */
+	if (IpRegistersWidth > 0) {
+		u32 BitCount;
+		u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
+		u32 Mask = XIIF_V123B_FIRST_BIT_MASK;	/* bits assigned MSB to LSB */
+		u32 InterruptStatus;
+
+		/* generate the register masks to be used for IP register tests, the
+		 * number of bits supported by the hardware is parameterizable such
+		 * that only that number of bits are implemented in the registers, the
+		 * bits are allocated starting at the MSB of the registers
+		 */
+		for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
+			Mask = Mask << 1;
+			IpInterruptMask |= Mask;
+		}
+
+		/* get the current IP interrupt status register contents, any bits
+		 * already set must default to 1 at reset in the device and these
+		 * bits can't be tested in the following test, remove these bits from
+		 * the mask that was generated for the test
+		 */
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		IpInterruptMask &= ~InterruptStatus;
+
+		/* set the bits in the device status register and verify them by reading
+		 * the register again, all bits of the register are latched
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
+		{
+			return XST_IPIF_IP_STATUS_ERROR;
+		}
+
+		/* test to ensure that the bits set in the IP interrupt status register
+		 * can be cleared by acknowledging them in the IP interrupt status
+		 * register then read it again and verify it was cleared
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != 0) {
+			return XST_IPIF_IP_ACK_ERROR;
+		}
+
+		/* set the IP interrupt enable set register and then read the IP
+		 * interrupt enable register and verify the interrupts were enabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+
+		/* clear the IP interrupt enable register and then read the
+		 * IP interrupt enable register and verify the interrupts were disabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+	}
+	return XST_SUCCESS;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xipif_v1_23_b.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xipif_v1_23_b.h	2014-07-20 22:06:39.055261199 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xipif_v1_23_b.h,v 1.5 2005/09/26 16:04:52 trujillo Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2004 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xipif_v1_23_b.h
+*
+* The XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.  This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.  Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.  The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.  The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* <b>Critical Sections</b>
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* <b>Mutual Exclusion</b>
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to minimize size
+* 1.23b rpm  07/16/04 Changed ifdef for circular inclusion to be more qualified
+* 1.23b rpm  08/17/04 Doxygenated for inclusion of API documentation
+* 1.23b xd   10/27/04 Improve Doxygen format
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIPIF_V123B_H		/* prevent circular inclusions */
+#define XIPIF_V123B_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/** @name Register Offsets
+ *
+ * The following constants define the register offsets for the registers of the
+ * IPIF, there are some holes in the memory map for reserved addresses to allow
+ * other registers to be added and still match the memory map of the interrupt
+ * controller registers
+ * @{
+ */
+#define XIIF_V123B_DISR_OFFSET     0UL	/**< device interrupt status register */
+#define XIIF_V123B_DIPR_OFFSET     4UL	/**< device interrupt pending register */
+#define XIIF_V123B_DIER_OFFSET     8UL	/**< device interrupt enable register */
+#define XIIF_V123B_DIIR_OFFSET     24UL	/**< device interrupt ID register */
+#define XIIF_V123B_DGIER_OFFSET    28UL	/**< device global interrupt enable register */
+#define XIIF_V123B_IISR_OFFSET     32UL	/**< IP interrupt status register */
+#define XIIF_V123B_IIER_OFFSET     40UL	/**< IP interrupt enable register */
+#define XIIF_V123B_RESETR_OFFSET   64UL	/**< reset register */
+/* @} */
+
+/**
+ * The value used for the reset register to reset the IPIF
+ */
+#define XIIF_V123B_RESET_MASK             0xAUL
+
+/**
+ * The following constant is used for the device global interrupt enable
+ * register, to enable all interrupts for the device, this is the only bit
+ * in the register
+ */
+#define XIIF_V123B_GINTR_ENABLE_MASK      0x80000000UL
+
+/**
+ * The mask to identify each internal IPIF error condition in the device
+ * registers of the IPIF. Interrupts are assigned in the register from LSB
+ * to the MSB
+ */
+#define XIIF_V123B_ERROR_MASK             1UL	  /**< LSB of the register */
+
+/** @name Interrupt IDs
+ *
+ * The interrupt IDs which identify each internal IPIF condition, this value
+ * must correlate with the mask constant for the error
+ * @{
+ */
+#define XIIF_V123B_ERROR_INTERRUPT_ID     0    /**< interrupt bit #, (LSB = 0) */
+#define XIIF_V123B_NO_INTERRUPT_ID        128  /**< no interrupts are pending */
+/* @} */
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/*****************************************************************************/
+/**
+*
+* Reset the IPIF component and hardware.  This is a destructive operation that
+* could cause the loss of data since resetting the IPIF of a device also
+* resets the device using the IPIF and any blocks, such as FIFOs or DMA
+* channels, within the IPIF.  All registers of the IPIF will contain their
+* reset value when this function returns.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return   None
+*
+* @note     None
+*
+******************************************************************************/
+#define XIIF_V123B_RESET(RegBaseAddress) \
+    XIo_Out32(RegBaseAddress + XIIF_V123B_RESETR_OFFSET, XIIF_V123B_RESET_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This macro sets the device interrupt status register to the value.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level rather
+* than a more detailed level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.  Writing any of
+* the non-latched bits of the register will have no effect on the register.
+*
+* For the latched bits of this register only, setting a bit which is zero
+* within this register causes an interrupt to generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.  This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes the specified value to the register such that
+* some bits may be set and others cleared.  It is the caller's responsibility
+* to get the value of the register prior to setting the value to prevent a
+* destructive behavior.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @param Status contains the value to be written to the interrupt status
+*        register of the device.  The only bits which can be written are
+*        the latched bits which contain the internal IPIF conditions.  The
+*        following values may be used to set the status register or clear an
+*        interrupt condition.
+*        - XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET, (Status))
+
+/*****************************************************************************/
+/**
+*
+* This macro gets the device interrupt status register contents.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.
+*
+* For only the latched bits of this register, the interrupt may be cleared by
+* writing to these bits in the status register.
+*
+* @param    RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* A status which contains the value read from the interrupt status register of
+* the device. The bit definitions are specific to the device with
+* the exception of the latched internal IPIF condition bits. The following
+* values may be used to detect internal IPIF conditions in the status.
+* <br><br>
+* - XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET)
+
+/*****************************************************************************/
+/**
+*
+* This function sets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device are allowed to
+* generate an interrupt.  The device global interrupt enable register must also
+* be set appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt.  Clearing a bit in this register
+* disables interrupt generation for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupts source may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* An interrupt source may not be enabled to generate an interrupt, but can
+* still be polled in the interrupt status register.
+*
+* @param    RegBaseAddress contains the base address of the IPIF registers.
+*
+* @param
+*
+* Enable contains the value to be written to the interrupt enable register
+* of the device.  The bit definitions are specific to the device with
+* the exception of the internal IPIF conditions. The following
+* values may be used to enable the internal IPIF conditions interrupts.
+*   - XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: u32 XIIF_V123B_WRITE_DIER(u32 RegBaseAddress,
+*                                          u32 Enable)
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET, (Enable))
+
+/*****************************************************************************/
+/**
+*
+* This function gets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device
+* are allowed to generate an interrupt.  The device global interrupt enable
+* register and the device interrupt enable register must also be set
+* appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt if the global enable is set
+* appropriately.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source regardless of the global interrupt enable.
+*
+* @param    RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* The value read from the interrupt enable register of the device.  The bit
+* definitions are specific to the device with the exception of the internal
+* IPIF conditions. The following values may be used to determine from the
+* value if the internal IPIF conditions interrupts are enabled.
+* <br><br>
+* - XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET)
+
+/*****************************************************************************/
+/**
+*
+* This function gets the device interrupt pending register contents.
+* This register indicates the pending interrupt sources, those that are waiting
+* to be serviced by the software, for a device which contains the IPIF.
+* An interrupt must be enabled in the interrupt enable register of the IPIF to
+* be pending.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* the device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched since the condition
+* is latched in the IP interrupt status register, by an internal block of the
+* IPIF such as a FIFO or DMA channel, or by the IP of the device.  This register
+* is read only and is not latched, but it is necessary to acknowledge (clear)
+* the interrupt condition by performing the appropriate processing for the IP
+* or block within the IPIF.
+*
+* This register can be thought of as the contents of the interrupt status
+* register ANDed with the contents of the interrupt enable register.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* The value read from the interrupt pending register of the device.  The bit
+* definitions are specific to the device with the exception of the latched
+* internal IPIF condition bits. The following values may be used to detect
+* internal IPIF conditions in the value.
+* <br><br>
+* - XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIPR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIPR_OFFSET)
+
+/*****************************************************************************/
+/**
+*
+* This macro gets the device interrupt ID for the highest priority interrupt
+* which is pending from the interrupt ID register. This function provides
+* priority resolution such that faster interrupt processing is possible.
+* Without priority resolution, it is necessary for the software to read the
+* interrupt pending register and then check each interrupt source to determine
+* if an interrupt is pending.  Priority resolution becomes more important as the
+* number of interrupt sources becomes larger.
+*
+* Interrupt priorities are based upon the bit position of the interrupt in the
+* interrupt pending register with bit 0 being the highest priority. The
+* interrupt ID is the priority of the interrupt, 0 - 31, with 0 being the
+* highest priority. The interrupt ID register is live rather than latched such
+* that multiple calls to this function may not yield the same results.  A
+* special value, outside of the interrupt priority range of 0 - 31, is
+* contained in the register which indicates that no interrupt is pending.  This
+* may be useful for allowing software to continue processing interrupts in a
+* loop until there are no longer any interrupts pending.
+*
+* The interrupt ID is designed to allow a function pointer table to be used
+* in the software such that the interrupt ID is used as an index into that
+* table.  The function pointer table could contain an instance pointer, such
+* as to DMA channel, and a function pointer to the function which handles
+* that interrupt.  This design requires the interrupt processing of the device
+* driver to be partitioned into smaller more granular pieces based upon
+* hardware used by the device, such as DMA channels and FIFOs.
+*
+* It is not mandatory that this function be used by the device driver software.
+* It may choose to read the pending register and resolve the pending interrupt
+* priorities on it's own.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* An interrupt ID, 0 - 31, which identifies the highest priority interrupt
+* which is pending.  A value of XIIF_NO_INTERRUPT_ID indicates that there is
+* no interrupt pending. The following values may be used to identify the
+* interrupt ID for the internal IPIF interrupts.
+* <br><br>
+* - XIIF_V123B_ERROR_INTERRUPT_ID     Indicates a device error in the IPIF
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIIR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIIR_OFFSET)
+
+/*****************************************************************************/
+/**
+*
+* This function disables all interrupts for the device by writing to the global
+* interrupt enable register.  This register provides the ability to disable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  The corresponding function, XIpIf_GlobalIntrEnable, is provided to
+* restore the interrupts to the previous enabled state.  This function is
+* designed to be used in critical sections of device drivers such that it is
+* not necessary to disable other device interrupts.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_DISABLE(RegBaseAddress) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, 0)
+
+/*****************************************************************************/
+/**
+*
+* This function writes to the global interrupt enable register to enable
+* interrupts from the device.  This register provides the ability to enable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  This function does not enable individual interrupts as the interrupt
+* enable register must be set appropriately.  This function is designed to be
+* used in critical sections of device drivers such that it is not necessary to
+* disable other device interrupts.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_ENABLE(RegBaseAddress)           \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, \
+               XIIF_V123B_GINTR_ENABLE_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function determines if interrupts are enabled at the global level by
+* reading the global interrupt register. This register provides the ability to
+* disable interrupts without any modifications to the interrupt enable register
+* such that it is minimal effort to restore the interrupts to the previous
+* enabled state.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_IS_GINTR_ENABLED(RegBaseAddress)             \
+    (XIo_In32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET) ==    \
+              XIIF_V123B_GINTR_ENABLE_MASK)
+
+/*****************************************************************************/
+/**
+*
+* This function sets the IP interrupt status register to the specified value.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF.  The status is independent of whether interrupts are enabled such that
+* the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  All bits of this register are latched. Setting a bit which is zero
+* within this register causes an interrupt to be generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.  This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes only the specified value to the register such that
+* some status bits may be set and others cleared.  It is the caller's
+* responsibility to get the value of the register prior to setting the value
+* to prevent an destructive behavior.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @param Status contains the value to be written to the IP interrupt status
+*        register.  The bit definitions are specific to the device IP.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET, (Status))
+
+/*****************************************************************************/
+/**
+*
+* This macro gets the contents of the IP interrupt status register.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF. The status is independent of whether interrupts are enabled such
+* that the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device.  All bits of this register are latched.  Writing a 1 to a bit within
+* this register causes an interrupt to be generated if enabled in the interrupt
+* enable register and the global interrupt enable is set.  Since the status is
+* latched, each status bit must be acknowledged in order for the bit in the
+* status register to be updated.  Each bit can be acknowledged by writing a
+* 0 to the bit in the status register.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* A status which contains the value read from the IP interrupt status register.
+* The bit definitions are specific to the device IP.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET)
+
+/*****************************************************************************/
+/**
+*
+* This macro sets the IP interrupt enable register contents.  This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupt sources may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @param Enable contains the value to be written to the IP interrupt enable
+*        register. The bit definitions are specific to the device IP.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET, (Enable))
+
+/*****************************************************************************/
+/**
+*
+* This macro gets the IP interrupt enable register contents.  This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* @param RegBaseAddress contains the base address of the IPIF registers.
+*
+* @return
+*
+* The contents read from the IP interrupt enable register.  The bit definitions
+* are specific to the device IP.
+*
+* @note
+*
+* Signature: u32 XIIF_V123B_READ_IIER(u32 RegBaseAddress)
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET)
+
+/************************** Function Prototypes ******************************/
+
+/**
+ * Initialization Functions
+ */
+int XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bd.h	2014-07-20 22:06:39.065261034 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlldma_bd.h
+ *
+ * This header provides operations to manage buffer descriptors (BD) in support
+ * of Local-Link scatter-gather DMA (see xlldma.h).
+ *
+ * The API exported by this header defines abstracted macros that allow the
+ * application to read/write specific BD fields.
+ *
+ * <b>Buffer Descriptors</b>
+ *
+ * A buffer descriptor defines a DMA transaction (see "Transaction"
+ * section in xlldma.h). The macros defined by this header file allow access
+ * to most fields within a BD to tailor a DMA transaction according to
+ * application and hardware requirements.  See the hardware IP DMA spec for
+ * more information on BD fields and how they affect transfers.
+ *
+ * The XLlDma_Bd structure defines a BD. The organization of this structure is
+ * driven mainly by the hardware for use in scatter-gather DMA transfers.
+ *
+ * <b>Accessor Macros</b>
+ *
+ * Most of the BD attributes can be accessed through macro functions defined
+ * here in this API. Words such as XLLDMA_BD_USR1_OFFSET (see xlldma_hw.h)
+ * should be accessed using XLlDma_mBdRead() and XLlDma_mBdWrite() as defined
+ * in xlldma_hw.h. The USR words are implementation dependent. For example,
+ * they may implement checksum offloading fields for Ethernet devices. Accessor
+ * macros may be defined in the device specific API to get at this data.
+ *
+ * <b>Performance</b>
+ *
+ * BDs are typically in a non-cached memory space. Limiting I/O to BDs can
+ * improve overall performance of the DMA channel.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a xd   12/21/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+
+#ifndef XLLDMA_BD_H		/* prevent circular inclusions */
+#define XLLDMA_BD_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xenv.h"
+#include "xlldma_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The XLlDma_Bd is the type for buffer descriptors (BDs).
+ */
+typedef u32 XLlDma_Bd[XLLDMA_BD_NUM_WORDS];
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* Read the given Buffer Descriptor word.
+*
+* @param    BaseAddress is the base address of the BD to read
+* @param    Offset is the word offset to be read
+*
+* @return   The 32-bit value of the field
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRead(u32 BaseAddress, u32 Offset)
+*
+******************************************************************************/
+#define XLlDma_mBdRead(BaseAddress, Offset)				\
+	(*(u32*)((u32)(BaseAddress) + (u32)(Offset)))
+
+
+/*****************************************************************************/
+/**
+*
+* Write the given Buffer Descriptor word.
+*
+* @param    BaseAddress is the base address of the BD to write
+* @param    Offset is the word offset to be written
+* @param    Data is the 32-bit value to write to the field
+*
+* @return   None.
+*
+* @note
+* C-style signature:
+*    void XLlDma_mBdWrite(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+******************************************************************************/
+#define XLlDma_mBdWrite(BaseAddress, Offset, Data)			\
+	(*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
+
+
+/*****************************************************************************/
+/**
+ * Zero out all BD fields
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Nothing
+ *
+ * @note
+ * C-style signature:
+ *    void XLlDma_mBdClear(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdClear(BdPtr)                    \
+	memset((BdPtr), 0, sizeof(XLlDma_Bd))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's STS/CTRL field. The word containing STS/CTRL also contains the
+ * USR0 field. USR0 will not be modified. This operation requires a read-
+ * modify-write operation. If it is wished to set both STS/CTRL and USR0 with
+ * a single write operation, then use XLlDma_mBdWrite(BdPtr,
+ * XLLDMA_BD_STSCTRL_USR0_OFFSET, Data).
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Data is the value to write to STS/CTRL. Or 0 or more
+ *         XLLDMA_BD_STSCTRL_*** values defined in xlldma_hw.h to create a
+ *         valid value for this parameter
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlDma_mBdSetStsCtrl(XLlDma_Bd* BdPtr, u32 Data)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetStsCtrl(BdPtr, Data)                                   \
+	XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET,             \
+		(XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)     \
+		& XLLDMA_BD_STSCTRL_USR0_MASK) |			    \
+		((Data) & XLLDMA_BD_STSCTRL_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the word containing the BD's STS/CTRL field. This word also
+ * contains the USR0 field.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Word at offset XLLDMA_BD_DMASR_OFFSET. Use XLLDMA_BD_STSCTRL_***
+ *         values defined in xlldma_hw.h to interpret this returned value
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlDma_mBdGetStsCtrl(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetStsCtrl(BdPtr)              \
+	XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Set transfer length in bytes for the given BD. The length must be set each
+ * time a BD is submitted to hardware.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ *    void XLlDma_mBdSetLength(XLlDma_Bd* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetLength(BdPtr, LenBytes)                            \
+	XLlDma_mBdWrite((BdPtr), XLLDMA_BD_BUFL_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length field.
+ *
+ * For TX channels, the returned value is the same as that written with
+ * XLlDma_mBdSetLength().
+ *
+ * For RX channels, the returned value is what was written by the DMA engine
+ * after processing the BD. This value represents the number of bytes
+ * processed.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @return Bytes processed by hardware or set by XLlDma_mBdSetLength().
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlDma_mBdGetLength(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetLength(BdPtr)                      \
+	XLlDma_mBdRead((BdPtr), XLLDMA_BD_BUFL_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Set the ID field of the given BD. The ID is an arbitrary piece of data the
+ * application can associate with a specific BD.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Id is a 32 bit quantity to set in the BD
+ *
+ * @note
+ * C-style signature:
+ *    void XLlDma_mBdSetId(XLlDma_Bd* BdPtr, void Id)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetId(BdPtr, Id)                                      \
+	(XLlDma_mBdWrite((BdPtr), XLLDMA_BD_ID_OFFSET, (u32)(Id)))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the ID field of the given BD previously set with XLlDma_mBdSetId.
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlDma_mBdGetId(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetId(BdPtr) (XLlDma_mBdRead((BdPtr), XLLDMA_BD_ID_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's buffer address.
+ *
+ * @param  BdPtr is the BD to operate on
+ * @param  Addr is the address to set
+ *
+ * @note
+ * C-style signature:
+ *    void XLlDma_mBdSetBufAddr(XLlDma_Bd* BdPtr, u32 Addr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetBufAddr(BdPtr, Addr)                               \
+	(XLlDma_mBdWrite((BdPtr), XLLDMA_BD_BUFA_OFFSET, (u32)(Addr)))
+
+
+/*****************************************************************************/
+/**
+ * Get the BD's buffer address
+ *
+ * @param  BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ *    u32 XLlDma_mBdGetBufAddrLow(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetBufAddr(BdPtr)                     \
+	(XLlDma_mBdRead((BdPtr), XLLDMA_BD_BUFA_OFFSET))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bdring.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bdring.c	2014-07-20 22:06:39.082260754 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_bdring.c
+*
+* This file implements buffer descriptor ring related functions. For more
+* information on this driver, see xlldma.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   12/21/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xlldma.h"
+#include "xenv.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************
+ * Define methods to flush and invalidate cache for BDs should they be
+ * located in cached memory. These macros may NOPs if the underlying
+ * XCACHE_FLUSH_DCACHE_RANGE and XCACHE_INVALIDATE_DCACHE_RANGE macros are not
+ * implemented or they do nothing.
+ *****************************************************************************/
+#ifdef XCACHE_FLUSH_DCACHE_RANGE
+#  define XLLDMA_CACHE_FLUSH(BdPtr)               \
+	XCACHE_FLUSH_DCACHE_RANGE((BdPtr), XLLDMA_BD_HW_NUM_BYTES)
+#else
+#  define XLLDMA_CACHE_FLUSH(BdPtr)
+#endif
+
+#ifdef XCACHE_INVALIDATE_DCACHE_RANGE
+#  define XLLDMA_CACHE_INVALIDATE(BdPtr)          \
+	XCACHE_INVALIDATE_DCACHE_RANGE((BdPtr), XLLDMA_BD_HW_NUM_BYTES)
+#else
+#  define XLLDMA_CACHE_INVALIDATE(BdPtr)
+#endif
+
+/******************************************************************************
+ * Compute the virtual address of a descriptor from its physical address
+ *
+ * @param BdPtr is the physical address of the BD
+ *
+ * @returns Virtual address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ * @note RingPtr is an implicit parameter
+ *****************************************************************************/
+#define XLLDMA_PHYS_TO_VIRT(BdPtr) \
+	((u32)(BdPtr) + (RingPtr->FirstBdAddr - RingPtr->FirstBdPhysAddr))
+
+/******************************************************************************
+ * Compute the physical address of a descriptor from its virtual address
+ *
+ * @param BdPtr is the virtual address of the BD
+ *
+ * @returns Physical address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ * @note RingPtr is an implicit parameter
+ *****************************************************************************/
+#define XLLDMA_VIRT_TO_PHYS(BdPtr) \
+	((u32)(BdPtr) - (RingPtr->FirstBdAddr - RingPtr->FirstBdPhysAddr))
+
+/******************************************************************************
+ * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around
+ * to the beginning of the ring if needed.
+ *
+ * We know if a wraparound should occur if the new BdPtr is greater than
+ * the high address in the ring OR if the new BdPtr crosses the 0xFFFFFFFF
+ * to 0 boundary.
+ *
+ * @param RingPtr is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ *        final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ *****************************************************************************/
+#define XLLDMA_RING_SEEKAHEAD(RingPtr, BdPtr, NumBd)			    \
+	{								    \
+		u32 Addr = (u32)(BdPtr);				    \
+									    \
+		Addr += ((RingPtr)->Separation * (NumBd));		    \
+		if ((Addr > (RingPtr)->LastBdAddr) || ((u32)(BdPtr) > Addr))\
+		{							    \
+			Addr -= (RingPtr)->Length;			    \
+		}							    \
+									    \
+		(BdPtr) = (XLlDma_Bd*)Addr;				    \
+	}
+
+/******************************************************************************
+ * Move the BdPtr argument backwards an arbitrary number of BDs wrapping
+ * around to the end of the ring if needed.
+ *
+ * We know if a wraparound should occur if the new BdPtr is less than
+ * the base address in the ring OR if the new BdPtr crosses the 0xFFFFFFFF
+ * to 0 boundary.
+ *
+ * @param RingPtr is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ *        final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ *****************************************************************************/
+#define XLLDMA_RING_SEEKBACK(RingPtr, BdPtr, NumBd)			      \
+	{                                                                     \
+		u32 Addr = (u32)(BdPtr);				      \
+									      \
+		Addr -= ((RingPtr)->Separation * (NumBd));		      \
+		if ((Addr < (RingPtr)->FirstBdAddr) || ((u32)(BdPtr) < Addr)) \
+		{							      \
+			Addr += (RingPtr)->Length;			      \
+		}							      \
+									      \
+		(BdPtr) = (XLlDma_Bd*)Addr;				      \
+	}
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * Using a memory segment allocated by the caller, create and setup the BD list
+ * for the given SGDMA ring.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param PhysAddr is the physical base address of application memory region.
+ * @param VirtAddr is the virtual base address of the application memory
+ *        region.If address translation is not being utilized, then VirtAddr
+ *        should be equivalent to PhysAddr.
+ * @param Alignment governs the byte alignment of individual BDs. This function
+ *        will enforce a minimum alignment of XLLDMA_BD_MINIMUM_ALIGNMENT bytes
+ *        with no maximum as long as it is specified as a power of 2.
+ * @param BdCount is the number of BDs to setup in the application memory
+ *        region. It is assumed the region is large enough to contain the BDs.
+ *        Refer to the "SGDMA Ring Creation" section  in xlldma.h for more
+ *        information. The minimum valid value for this parameter is 1.
+ *
+ * @return
+ *
+ * - XST_SUCCESS if initialization was successful
+ * - XST_NO_FEATURE if the provided instance is a non SGDMA type of DMA
+ *   channel.
+ * - XST_INVALID_PARAM under any of the following conditions: 1) PhysAddr
+ *   and/or VirtAddr are not aligned to the given Alignment parameter;
+ *   2) Alignment parameter does not meet minimum requirements or is not a
+ *   power of 2 value; 3) BdCount is 0.
+ * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans
+ *   over address 0x00000000 in virtual address space.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingCreate(XLlDma_BdRing * RingPtr, u32 PhysAddr,
+			u32 VirtAddr, u32 Alignment, unsigned BdCount)
+{
+	unsigned i;
+	u32 BdVirtAddr;
+	u32 BdPhysAddr;
+
+	/* In case there is a failure prior to creating list, make sure the
+	 * following attributes are 0 to prevent calls to other SG functions
+	 * from doing anything
+	 */
+	RingPtr->AllCnt = 0;
+	RingPtr->FreeCnt = 0;
+	RingPtr->HwCnt = 0;
+	RingPtr->PreCnt = 0;
+	RingPtr->PostCnt = 0;
+
+	/* Make sure Alignment parameter meets minimum requirements */
+	if (Alignment < XLLDMA_BD_MINIMUM_ALIGNMENT) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Make sure Alignment is a power of 2 */
+	if ((Alignment - 1) & Alignment) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Make sure PhysAddr and VirtAddr are on same Alignment */
+	if ((PhysAddr % Alignment) || (VirtAddr % Alignment)) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Is BdCount reasonable? */
+	if (BdCount == 0) {
+		return (XST_INVALID_PARAM);
+	}
+
+	/* Compute how many bytes will be between the start of adjacent BDs */
+	RingPtr->Separation =
+		(sizeof(XLlDma_Bd) + (Alignment - 1)) & ~(Alignment - 1);
+
+	/* Must make sure the ring doesn't span address 0x00000000. If it does,
+	 * then the next/prev BD traversal macros will fail.
+	 */
+	if (VirtAddr > (VirtAddr + (RingPtr->Separation * BdCount) - 1)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Initial ring setup:
+	 *  - Clear the entire space
+	 *  - Setup each BD's next pointer with the physical address of the
+	 *    next BD
+	 *  - Set each BD's DMA complete status bit
+	 */
+	memset((void *) VirtAddr, 0, (RingPtr->Separation * BdCount));
+
+	BdVirtAddr = VirtAddr;
+	BdPhysAddr = PhysAddr + RingPtr->Separation;
+	for (i = 1; i < BdCount; i++) {
+		XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_NDESC_OFFSET, BdPhysAddr);
+		XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_STSCTRL_USR0_OFFSET,
+				XLLDMA_BD_STSCTRL_COMPLETED_MASK);
+		XLLDMA_CACHE_FLUSH(BdVirtAddr);
+		BdVirtAddr += RingPtr->Separation;
+		BdPhysAddr += RingPtr->Separation;
+	}
+
+	/* At the end of the ring, link the last BD back to the top */
+	XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_NDESC_OFFSET, PhysAddr);
+	XLLDMA_CACHE_FLUSH(BdVirtAddr);
+
+	/* Setup and initialize pointers and counters */
+	RingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+	RingPtr->FirstBdAddr = VirtAddr;
+	RingPtr->FirstBdPhysAddr = PhysAddr;
+	RingPtr->LastBdAddr = BdVirtAddr;
+	RingPtr->Length = RingPtr->LastBdAddr - RingPtr->FirstBdAddr +
+		RingPtr->Separation;
+	RingPtr->AllCnt = BdCount;
+	RingPtr->FreeCnt = BdCount;
+	RingPtr->FreeHead = (XLlDma_Bd *) VirtAddr;
+	RingPtr->PreHead = (XLlDma_Bd *) VirtAddr;
+	RingPtr->HwHead = (XLlDma_Bd *) VirtAddr;
+	RingPtr->HwTail = (XLlDma_Bd *) VirtAddr;
+	RingPtr->PostHead = (XLlDma_Bd *) VirtAddr;
+	RingPtr->BdaRestart = (XLlDma_Bd *) PhysAddr;
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Clone the given BD into every BD in the ring. Except for
+ * XLLDMA_BD_NDESC_OFFSET, every field of the source BD is replicated in every
+ * BD in the ring.
+ *
+ * This function can be called only when all BDs are in the free group such as
+ * they are immediately after creation of the ring. This prevents modification
+ * of BDs while they are in use by hardware or the application.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param SrcBdPtr is the source BD template to be cloned into the list.
+ *
+ * @return
+ *   - XST_SUCCESS if the list was modified.
+ *   - XST_DMA_SG_NO_LIST if a list has not been created.
+ *   - XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under
+ *     hardware or application control.
+ *   - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingClone(XLlDma_BdRing * RingPtr, XLlDma_Bd * SrcBdPtr)
+{
+	unsigned i;
+	u32 CurBd;
+	u32 Save;
+	XLlDma_Bd TmpBd;
+
+	/* Can't do this function if there isn't a ring */
+	if (RingPtr->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Can't do this function with the channel running */
+	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_DEVICE_IS_STARTED);
+	}
+
+	/* Can't do this function with some of the BDs in use */
+	if (RingPtr->FreeCnt != RingPtr->AllCnt) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+
+	/* Make a copy of the template then modify it by setting complete bit
+	 * in status/control field
+	 */
+	memcpy(&TmpBd, SrcBdPtr, sizeof(XLlDma_Bd));
+	Save = XLlDma_mBdRead(&TmpBd, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+	Save |= XLLDMA_BD_STSCTRL_COMPLETED_MASK;
+	XLlDma_mBdWrite(&TmpBd, XLLDMA_BD_STSCTRL_USR0_OFFSET, Save);
+
+	/* Starting from the top of the ring, save BD.Next, overwrite the
+	 * entire BD with the template, then restore BD.Next
+	 */
+	for (i = 0, CurBd = RingPtr->FirstBdAddr;
+	     i < RingPtr->AllCnt; i++, CurBd += RingPtr->Separation) {
+		Save = XLlDma_mBdRead(CurBd, XLLDMA_BD_NDESC_OFFSET);
+		memcpy((void *) CurBd, (void *) &TmpBd, sizeof(XLlDma_Bd));
+		XLlDma_mBdWrite(CurBd, XLLDMA_BD_NDESC_OFFSET, Save);
+		XLLDMA_CACHE_FLUSH(CurBd);
+	}
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Allow DMA transactions to commence on the given channels if descriptors are
+ * ready to be processed.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ *
+ * @return
+ * - XST_SUCCESS if the channel) were started.
+ * - XST_DMA_SG_NO_LIST if the channel) have no initialized BD ring.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingStart(XLlDma_BdRing * RingPtr)
+{
+	/* BD list has yet to be created for this channel */
+	if (RingPtr->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Do nothing if already started */
+	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_SUCCESS);
+	}
+
+	/* Sync hardware and driver with the last unprocessed BD or the 1st BD
+	 * in the ring if this is the first time starting the channel
+	 */
+	XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_CDESC_OFFSET,
+			 (u32) RingPtr->BdaRestart);
+
+	/* Note as started */
+	RingPtr->RunState = XST_DMA_SG_IS_STARTED;
+
+	/* If there are unprocessed BDs then we want to channel to begin
+	 * processing right away
+	 */
+	if (RingPtr->HwCnt > 0) {
+		XLLDMA_CACHE_INVALIDATE(RingPtr->HwTail);
+
+		if ((XLlDma_mBdRead(RingPtr->HwTail,
+				    XLLDMA_BD_STSCTRL_USR0_OFFSET) &
+		     XLLDMA_BD_STSCTRL_COMPLETED_MASK) == 0) {
+			XLlDma_mWriteReg(RingPtr->ChanBase,
+					 XLLDMA_TDESC_OFFSET,
+					 XLLDMA_VIRT_TO_PHYS(RingPtr->HwTail));
+		}
+	}
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Set interrupt coalescing parameters for the given descriptor ring channel.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param Counter sets the packet counter on the channel. Valid range is
+ *        1..255, or XLLDMA_NO_CHANGE to leave this setting unchanged.
+ * @param Timer sets the waitbound timer on the channel. Valid range is
+ *        1..255, or XLLDMA_NO_CHANGE to leave this setting unchanged. LSB is
+ *        in units of 1 / (local link clock).
+ *
+ * @return
+ *        - XST_SUCCESS if interrupt coalescing settings updated
+ *        - XST_FAILURE if Counter or Timer parameters are out of range
+ *****************************************************************************/
+int XLlDma_BdRingSetCoalesce(XLlDma_BdRing * RingPtr, u32 Counter, u32 Timer)
+{
+	u32 Cr = XLlDma_mReadReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET);
+
+	if (Counter != XLLDMA_NO_CHANGE) {
+		if ((Counter == 0) || (Counter > 0xFF)) {
+			return (XST_FAILURE);
+		}
+
+		Cr = (Cr & ~XLLDMA_CR_IRQ_COUNT_MASK) |
+			(Counter << XLLDMA_CR_IRQ_COUNT_SHIFT);
+		Cr |= XLLDMA_CR_LD_IRQ_CNT_MASK;
+	}
+
+	if (Timer != XLLDMA_NO_CHANGE) {
+		if ((Timer == 0) || (Timer > 0xFF)) {
+			return (XST_FAILURE);
+		}
+
+		Cr = (Cr & ~XLLDMA_CR_IRQ_TIMEOUT_MASK) |
+			(Timer << XLLDMA_CR_IRQ_TIMEOUT_SHIFT);
+		Cr |= XLLDMA_CR_LD_IRQ_CNT_MASK;
+	}
+
+	XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET, Cr);
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Retrieve current interrupt coalescing parameters from the given descriptor
+ * ring channel.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param CounterPtr points to a memory location where the current packet
+ *        counter will be written.
+ * @param TimerPtr points to a memory location where the current waitbound
+ *        timer will be written.
+ *****************************************************************************/
+void XLlDma_BdRingGetCoalesce(XLlDma_BdRing * RingPtr,
+			      u32 *CounterPtr, u32 *TimerPtr)
+{
+	u32 Cr = XLlDma_mReadReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET);
+
+	*CounterPtr =
+		((Cr & XLLDMA_CR_IRQ_COUNT_MASK) >> XLLDMA_CR_IRQ_COUNT_SHIFT);
+	*TimerPtr =
+		((Cr & XLLDMA_CR_IRQ_TIMEOUT_MASK) >>
+		 XLLDMA_CR_IRQ_TIMEOUT_SHIFT);
+}
+
+
+/*****************************************************************************/
+/**
+ * Reserve locations in the BD ring. The set of returned BDs may be modified in
+ * preparation for future DMA transactions). Once the BDs are ready to be
+ * submitted to hardware, the application must call XLlDma_BdRingToHw() in the
+ * same order which they were allocated here. Example:
+ *
+ * <pre>
+ *        NumBd = 2;
+ *        Status = XDsma_RingBdAlloc(MyRingPtr, NumBd, &MyBdSet);
+ *
+ *        if (Status != XST_SUCCESS)
+ *        {
+ *            // Not enough BDs available for the request
+ *        }
+ *
+ *        CurBd = MyBdSet;
+ *        for (i=0; i<NumBd; i++)
+ *        {
+ *            // Prepare CurBd.....
+ *
+ *            // Onto next BD
+ *            CurBd = XLlDma_mBdRingNext(MyRingPtr, CurBd);
+ *        }
+ *
+ *        // Give list to hardware
+ *        Status = XLlDma_BdRingToHw(MyRingPtr, NumBd, MyBdSet);
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be allocated and given to hardware in the correct sequence:
+ * <pre>
+ *        // Legal
+ *        XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ *
+ *        // Legal
+ *        XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ *        XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ *        XLlDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ *
+ *        // Not legal
+ *        XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ *        XLlDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ *        XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * Use the API defined in xlldmabd.h to modify individual BDs. Traversal of the
+ * BD set can be done using XLlDma_mBdRingNext() and XLlDma_mBdRingPrev().
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param NumBd is the number of BDs to allocate
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ *        for modification.
+ *
+ * @return
+ *   - XST_SUCCESS if the requested number of BDs was returned in the BdSetPtr
+ *     parameter.
+ *   - XST_FAILURE if there were not enough free BDs to satisfy the request.
+ *
+ * @note This function should not be preempted by another XLlDma_BdRing
+ *       function call that modifies the BD space. It is the caller's
+ *       responsibility to provide a mutual exclusion mechanism.
+ *
+ * @note Do not modify more BDs than the number requested with the NumBd
+ *       parameter. Doing so will lead to data corruption and system
+ *       instability.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		       XLlDma_Bd ** BdSetPtr)
+{
+	/* Enough free BDs available for the request? */
+	if (RingPtr->FreeCnt < NumBd) {
+		return (XST_FAILURE);
+	}
+
+	/* Set the return argument and move FreeHead forward */
+	*BdSetPtr = RingPtr->FreeHead;
+	XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->FreeHead, NumBd);
+	RingPtr->FreeCnt -= NumBd;
+	RingPtr->PreCnt += NumBd;
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Fully or partially undo an XLlDma_BdRingAlloc() operation. Use this function
+ * if all the BDs allocated by XLlDma_BdRingAlloc() could not be transferred to
+ * hardware with XLlDma_BdRingToHw().
+ *
+ * This function helps out in situations when an unrelated error occurs after
+ * BDs have been allocated but before they have been given to hardware.
+ *
+ * This function is not the same as XLlDma_BdRingFree(). The Free function
+ * returns BDs to the free list after they have been processed by hardware,
+ * while UnAlloc returns them before being processed by hardware.
+ *
+ * There are two scenarios where this function can be used. Full UnAlloc or
+ * Partial UnAlloc. A Full UnAlloc means all the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ *    Status = XLlDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ *        .
+ *        .
+ *    if (Error)
+ *    {
+ *        Status = XLlDma_BdRingUnAlloc(MyRingPtr, 10, &BdPtr);
+ *    }
+ * </pre>
+ *
+ * A partial UnAlloc means some of the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ *    Status = XLlDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ *    BdsLeft = 10;
+ *    CurBdPtr = BdPtr;
+ *
+ *    while (BdsLeft)
+ *    {
+ *       if (Error)
+ *       {
+ *          Status = XLlDma_BdRingUnAlloc(MyRingPtr, BdsLeft, CurBdPtr);
+ *       }
+ *
+ *       CurBdPtr = XLlDma_mBdRingNext(MyRingPtr, CurBdPtr);
+ *       BdsLeft--;
+ *    }
+ * </pre>
+ *
+ * A partial UnAlloc must include the last BD in the list that was Alloc'd.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param NumBd is the number of BDs to unallocate
+ * @param BdSetPtr points to the first of the BDs to be returned.
+ *
+ * @return
+ *   - XST_SUCCESS if the BDs were unallocated.
+ *   - XST_FAILURE if NumBd parameter was greater that the number of BDs in the
+ *     preprocessing state.
+ *
+ * @note This function should not be preempted by another XLlDma ring function
+ *       call that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingUnAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+			 XLlDma_Bd * BdSetPtr)
+{
+	/* Enough BDs in the free state for the request? */
+	if (RingPtr->PreCnt < NumBd) {
+		return (XST_FAILURE);
+	}
+
+	/* Set the return argument and move FreeHead backward */
+	XLLDMA_RING_SEEKBACK(RingPtr, RingPtr->FreeHead, NumBd);
+	RingPtr->FreeCnt += NumBd;
+	RingPtr->PreCnt -= NumBd;
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Enqueue a set of BDs to hardware that were previously allocated by
+ * XLlDma_BdRingAlloc(). Once this function returns, the argument BD set goes
+ * under hardware control. Any changes made to these BDs after this point will
+ * corrupt the BD list leading to data corruption and system instability.
+ *
+ * The set will be rejected if the last BD of the set does not mark the end of
+ * a packet.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param NumBd is the number of BDs in the set.
+ * @param BdSetPtr is the first BD of the set to commit to hardware.
+ *
+ * @return
+ *   - XST_SUCCESS if the set of BDs was accepted and enqueued to hardware
+ *   - XST_FAILURE if the set of BDs was rejected because the first BD
+ *     did not have its start-of-packet bit set, the last BD did not have
+ *     its end-of-packet bit set, or any one of the BD set has 0 as length
+ *     value
+ *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ *     XLlDma_BdRingAlloc()
+ *
+ * @note This function should not be preempted by another XLlDma ring function
+ *       call that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingToHw(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		      XLlDma_Bd * BdSetPtr)
+{
+	XLlDma_Bd *CurBdPtr;
+	unsigned i;
+	u32 BdStsCr;
+
+	/* If the commit set is empty, do nothing */
+	if (NumBd == 0) {
+		return (XST_SUCCESS);
+	}
+
+	/* Make sure we are in sync with XLlDma_BdRingAlloc() */
+	if ((RingPtr->PreCnt < NumBd) || (RingPtr->PreHead != BdSetPtr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	CurBdPtr = BdSetPtr;
+	BdStsCr = XLlDma_mBdRead(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+
+	/* The first BD should have been marked as start-of-packet */
+	if (!(BdStsCr & XLLDMA_BD_STSCTRL_SOP_MASK)) {
+		return (XST_FAILURE);
+	}
+
+	/* For each BD being submitted except the last one, clear the completed
+	 * bit and stop_on_end bit in the status word
+	 */
+	for (i = 0; i < NumBd - 1; i++) {
+
+		/* Make sure the length value in the BD is non-zero. */
+		if (XLlDma_mBdGetLength(CurBdPtr) == 0) {
+			return (XST_FAILURE);
+		}
+
+		BdStsCr &=
+			~(XLLDMA_BD_STSCTRL_COMPLETED_MASK |
+			  XLLDMA_BD_STSCTRL_SOE_MASK);
+		XLlDma_mBdWrite(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET,
+				BdStsCr);
+
+		/* In RX channel case, the current BD should have the
+		 * XLLDMA_USERIP_APPWORD_OFFSET initialized to
+		 * XLLDMA_USERIP_APPWORD_INITVALUE
+		 */
+		if (RingPtr->IsRxChannel) {
+			XLlDma_mBdWrite(CurBdPtr, XLLDMA_USERIP_APPWORD_OFFSET,
+					XLLDMA_USERIP_APPWORD_INITVALUE);
+		}
+
+		/* Flush the current BD so DMA core could see the updates */
+		XLLDMA_CACHE_FLUSH(CurBdPtr);
+
+		CurBdPtr = XLlDma_mBdRingNext(RingPtr, CurBdPtr);
+		BdStsCr =
+			XLlDma_mBdRead(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+	}
+
+	/* The last BD should have end-of-packet bit set */
+	if (!(BdStsCr & XLLDMA_BD_STSCTRL_EOP_MASK)) {
+		return (XST_FAILURE);
+	}
+
+	/* Make sure the length value in the last BD is non-zero. */
+	if (XLlDma_mBdGetLength(CurBdPtr) == 0) {
+		return (XST_FAILURE);
+	}
+
+	/* The last BD should also have the completed and stop-on-end bits
+	 * cleared
+	 */
+	BdStsCr &=
+		~(XLLDMA_BD_STSCTRL_COMPLETED_MASK |
+		  XLLDMA_BD_STSCTRL_SOE_MASK);
+	XLlDma_mBdWrite(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET, BdStsCr);
+
+	/* In RX channel case, the last BD should have the
+	 * XLLDMA_USERIP_APPWORD_OFFSET initialized to
+	 * XLLDMA_USERIP_APPWORD_INITVALUE
+	 */
+	if (RingPtr->IsRxChannel) {
+		XLlDma_mBdWrite(CurBdPtr, XLLDMA_USERIP_APPWORD_OFFSET,
+				XLLDMA_USERIP_APPWORD_INITVALUE);
+	}
+
+	/* Flush the last BD so DMA core could see the updates */
+	XLLDMA_CACHE_FLUSH(CurBdPtr);
+
+	/* This set has completed pre-processing, adjust ring pointers and
+	 * counters
+	 */
+	XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->PreHead, NumBd);
+	RingPtr->PreCnt -= NumBd;
+	RingPtr->HwTail = CurBdPtr;
+	RingPtr->HwCnt += NumBd;
+
+	/* If it was enabled, tell the engine to begin processing */
+	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+		XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_TDESC_OFFSET,
+				 XLLDMA_VIRT_TO_PHYS(RingPtr->HwTail));
+	}
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by hardware. The returned
+ * BDs may be examined by the application to determine the outcome of the DMA
+ * transactions). Once the BDs have been examined, the application must call
+ * XLlDma_BdRingFree() in the same order which they were retrieved here.
+ *
+ * Example:
+ *
+ * <pre>
+ *        NumBd = XLlDma_BdRingFromHw(MyRingPtr, XLLDMA_ALL_BDS, &MyBdSet);
+ *
+ *        if (NumBd == 0)
+ *        {
+ *           // hardware has nothing ready for us yet
+ *        }
+ *
+ *        CurBd = MyBdSet;
+ *        for (i=0; i<NumBd; i++)
+ *        {
+ *           // Examine CurBd for post processing.....
+ *
+ *           // Onto next BD
+ *           CurBd = XLlDma_mBdRingNext(MyRingPtr, CurBd);
+ *        }
+ *
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd, MyBdSet); // Return the list
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be retrieved from hardware and freed in the correct sequence:
+ * <pre>
+ *        // Legal
+ *        XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ *
+ *        // Legal
+ *        XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ *
+ *        // Not legal
+ *        XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ *        XLlDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ *        XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If hardware has partially completed a packet spanning multiple BDs, then
+ * none of the BDs for that packet will be included in the results.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param BdLimit is the maximum number of BDs to return in the set. Use
+ *        XLLDMA_ALL_BDS to return all BDs that have been processed.
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ *        for examination.
+ *
+ * @return
+ *   The number of BDs processed by hardware. A value of 0 indicates that no
+ *   data is available. No more than BdLimit BDs will be returned.
+ *
+ * @note Treat BDs returned by this function as read-only.
+ *
+ * @note This function should not be preempted by another XLlDma ring function
+ *       call that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+unsigned XLlDma_BdRingFromHw(XLlDma_BdRing * RingPtr, unsigned BdLimit,
+			     XLlDma_Bd ** BdSetPtr)
+{
+	XLlDma_Bd *CurBdPtr;
+	unsigned BdCount;
+	unsigned BdPartialCount;
+	u32 BdStsCr;
+	u32 UserIpAppWord;
+
+	CurBdPtr = RingPtr->HwHead;
+	BdCount = 0;
+	BdPartialCount = 0;
+
+	/* If no BDs in work group, then there's nothing to search */
+	if (RingPtr->HwCnt == 0) {
+		*BdSetPtr = NULL;
+		return (0);
+	}
+
+	/* Starting at HwHead, keep moving forward in the list until:
+	 *  - A BD is encountered with its completed bit clear in the status
+	 *    word which means hardware has not completed processing of that
+	 *    BD.
+	 *  - A BD is encountered with its XLLDMA_USERIP_APPWORD_OFFSET field
+	 *    with value XLLDMA_USERIP_APPWORD_INITVALUE which means hardware
+	 *    has not completed updating the BD structure.
+	 *  - RingPtr->HwTail is reached
+	 *  - The number of requested BDs has been processed
+	 */
+	while (BdCount < BdLimit) {
+		/* Read the status */
+		XLLDMA_CACHE_INVALIDATE(CurBdPtr);
+		BdStsCr = XLlDma_mBdRead(CurBdPtr,
+					 XLLDMA_BD_STSCTRL_USR0_OFFSET);
+
+		/* If the hardware still hasn't processed this BD then we are
+		 * done
+		 */
+		if (!(BdStsCr & XLLDMA_BD_STSCTRL_COMPLETED_MASK)) {
+			break;
+		}
+
+		/* In RX channel case, check if XLLDMA_USERIP_APPWORD_OFFSET
+		 * field of the BD has been updated. If not, RX channel has
+		 * not completed updating the BD structure and we delay
+		 * the processing of this BD to next time
+		 */
+		if (RingPtr->IsRxChannel) {
+			UserIpAppWord = XLlDma_mBdRead(CurBdPtr,
+						       XLLDMA_USERIP_APPWORD_OFFSET);
+			if (UserIpAppWord == XLLDMA_USERIP_APPWORD_INITVALUE) {
+				break;
+			}
+		}
+
+
+		BdCount++;
+
+		/* Hardware has processed this BD so check the "last" bit. If
+		 * it is clear, then there are more BDs for the current packet.
+		 * Keep a count of these partial packet BDs.
+		 */
+		if (BdStsCr & XLLDMA_BD_STSCTRL_EOP_MASK) {
+			BdPartialCount = 0;
+		}
+		else {
+			BdPartialCount++;
+		}
+
+		/* Reached the end of the work group */
+		if (CurBdPtr == RingPtr->HwTail) {
+			break;
+		}
+
+		/* Move on to next BD in work group */
+		CurBdPtr = XLlDma_mBdRingNext(RingPtr, CurBdPtr);
+	}
+
+	/* Subtract off any partial packet BDs found */
+	BdCount -= BdPartialCount;
+
+	/* If BdCount is non-zero then BDs were found to return. Set return
+	 * parameters, update pointers and counters, return success
+	 */
+	if (BdCount) {
+		*BdSetPtr = RingPtr->HwHead;
+		RingPtr->HwCnt -= BdCount;
+		RingPtr->PostCnt += BdCount;
+		XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
+		return (BdCount);
+	}
+	else {
+		*BdSetPtr = NULL;
+		return (0);
+	}
+}
+
+
+/*****************************************************************************/
+/**
+ * Frees a set of BDs that had been previously retrieved with
+ * XLlDma_BdRingFromHw().
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param NumBd is the number of BDs to free.
+ * @param BdSetPtr is the head of a list of BDs returned by
+ *        XLlDma_BdRingFromHw().
+ *
+ * @return
+ *   - XST_SUCCESS if the set of BDs was freed.
+ *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ *     XLlDma_BdRingFromHw().
+ *
+ * @note This function should not be preempted by another XLlDma function call
+ *       that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ * @internal
+ *          This Interrupt handler provided by application MUST clear pending
+ *          interrupts before handling them by calling the call back. Otherwise
+ *          the following corner case could raise some issue:
+ *
+ *           - A packet was transmitted and asserted an TX interrupt, and if
+ *             this interrupt handler calls the call back before clears the
+ *             interrupt, another packet could get transmitted (and assert the
+ *             interrupt) between when the call back function returned and when
+ *             the interrupt clearing operation begins, and the interrupt
+ *             clearing operation will clear the interrupt raised by the second
+ *             packet and won't never process its according buffer descriptors
+ *             until a new interrupt occurs.
+ *
+ *           Changing the sequence to "Clear interrupts, then handle" solve this
+ *           issue. If the interrupt raised by the second packet is before the
+ *           the interrupt clearing operation, the descriptors associated with
+ *           the second packet must have been finished by hardware and ready for
+ *           the handling by the call back; otherwise, the interrupt raised by
+ *           the second packet is after the interrupt clearing operation,
+ *           the packet's buffer descriptors will be handled by the call back in
+ *           current pass, if the descriptors are finished before the call back
+ *           is invoked, or next pass otherwise.
+ *
+ *           Please note that if the second packet is handled by the call back
+ *           in current pass, the next pass could find no buffer descriptor
+ *           finished by the hardware. (i.e., XLlDma_BdRingFromHw() returns 0).
+ *           As XLlDma_BdRingFromHw() and XLlDma_BdRingFree() are used in pair,
+ *           XLlDma_BdRingFree() covers this situation by checking if the BD
+ *           list to free is empty
+ *****************************************************************************/
+int XLlDma_BdRingFree(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		      XLlDma_Bd * BdSetPtr)
+{
+	/* If the BD Set to free is empty, return immediately with value
+	 * XST_SUCCESS. See the @internal comment block above for detailed
+	 * information
+	 */
+	if (NumBd == 0) {
+		return XST_SUCCESS;
+	}
+
+	/* Make sure we are in sync with XLlDma_BdRingFromHw() */
+	if ((RingPtr->PostCnt < NumBd) || (RingPtr->PostHead != BdSetPtr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Update pointers and counters */
+	RingPtr->FreeCnt += NumBd;
+	RingPtr->PostCnt -= NumBd;
+	XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->PostHead, NumBd);
+
+	return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Check the internal data structures of the BD ring for the provided channel.
+ * The following checks are made:
+ *
+ *   - Is the BD ring linked correctly in physical address space.
+ *   - Do the internal pointers point to BDs in the ring.
+ *   - Do the internal counters add up.
+ *
+ * The channel should be stopped prior to calling this function.
+ *
+ * @param RingPtr is a pointer to the descriptor ring to be worked on.
+ *
+ * @return
+ *   - XST_SUCCESS if no errors were found.
+ *   - XST_DMA_SG_NO_LIST if the ring has not been created.
+ *   - XST_IS_STARTED if the channel is not stopped.
+ *   - XST_DMA_SG_LIST_ERROR if a problem is found with the internal data
+ *     structures. If this value is returned, the channel should be reset to
+ *     avoid data corruption or system instability.
+ *
+ * @note This function should not be preempted by another XLlDma ring function
+ *       call that modifies the BD space. It is the caller's responsibility to
+ *       provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingCheck(XLlDma_BdRing * RingPtr)
+{
+	u32 AddrV, AddrP;
+	unsigned i;
+
+	/* Is the list created */
+	if (RingPtr->AllCnt == 0) {
+		return (XST_DMA_SG_NO_LIST);
+	}
+
+	/* Can't check if channel is running */
+	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+		return (XST_IS_STARTED);
+	}
+
+	/* RunState doesn't make sense */
+	else if (RingPtr->RunState != XST_DMA_SG_IS_STOPPED) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify internal pointers point to correct memory space */
+	AddrV = (u32) RingPtr->FreeHead;
+	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->PreHead;
+	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->HwHead;
+	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->HwTail;
+	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	AddrV = (u32) RingPtr->PostHead;
+	if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify internal counters add up */
+	if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
+	     RingPtr->PostCnt) != RingPtr->AllCnt) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* Verify BDs are linked correctly */
+	AddrV = RingPtr->FirstBdAddr;
+	AddrP = RingPtr->FirstBdPhysAddr + RingPtr->Separation;
+	for (i = 1; i < RingPtr->AllCnt; i++) {
+		XLLDMA_CACHE_INVALIDATE(AddrV);
+		/* Check next pointer for this BD. It should equal to the
+		 * physical address of next BD
+		 */
+		if (XLlDma_mBdRead(AddrV, XLLDMA_BD_NDESC_OFFSET) != AddrP) {
+			return (XST_DMA_SG_LIST_ERROR);
+		}
+
+		/* Move on to next BD */
+		AddrV += RingPtr->Separation;
+		AddrP += RingPtr->Separation;
+	}
+
+	XLLDMA_CACHE_INVALIDATE(AddrV);
+	/* Last BD should point back to the beginning of ring */
+	if (XLlDma_mBdRead(AddrV, XLLDMA_BD_NDESC_OFFSET) !=
+	    RingPtr->FirstBdPhysAddr) {
+		return (XST_DMA_SG_LIST_ERROR);
+	}
+
+	/* No problems found */
+	return (XST_SUCCESS);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bdring.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_bdring.h	2014-07-20 22:06:39.097260507 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_bdring.h
+*
+* This file contains DMA channel related structure and constant definition
+* as well as function prototypes. Each DMA channel is managed by a Buffer
+* Descriptor ring, and so XLlDma_BdRing is chosen as the symbol prefix used in
+* this file. See xlldma.h for more information.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_BDRING_H		/* prevent circular inclusions */
+#define XLLDMA_BDRING_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xlldma_hw.h"
+#include "xlldma_bd.h"
+
+/** Container structure for descriptor storage control. If address translation
+ * is enabled, then all addresses and pointers excluding FirstBdPhysAddr are
+ * expressed in terms of the virtual address.
+ */
+typedef struct {
+	u32 ChanBase;	       /**< Virtual base address of channel registers
+                                       */
+	u32 IsRxChannel;       /**< Is this a receive channel ? */
+	u32 FirstBdPhysAddr;   /**< Physical address of 1st BD in list */
+	u32 FirstBdAddr;       /**< Virtual address of 1st BD in list */
+	u32 LastBdAddr;	       /**< Virtual address of last BD in the list */
+	u32 Length;	       /**< Total size of ring in bytes */
+	u32 RunState;	       /**< Flag to indicate channel is started */
+	u32 Separation;	       /**< Number of bytes between the starting
+	                            address of adjacent BDs */
+	XLlDma_Bd *FreeHead;   /**< First BD in the free group */
+	XLlDma_Bd *PreHead;    /**< First BD in the pre-work group */
+	XLlDma_Bd *HwHead;     /**< First BD in the work group */
+	XLlDma_Bd *HwTail;     /**< Last BD in the work group */
+	XLlDma_Bd *PostHead;   /**< First BD in the post-work group */
+	XLlDma_Bd *BdaRestart; /**< BD to load when channel is started */
+	u32 FreeCnt;	       /**< Number of allocatable BDs in free group */
+	u32 PreCnt;	       /**< Number of BDs in pre-work group */
+	u32 HwCnt;	       /**< Number of BDs in work group */
+	u32 PostCnt;	       /**< Number of BDs in post-work group */
+	u32 AllCnt;	       /**< Total Number of BDs for channel */
+} XLlDma_BdRing;
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many BDs will fit
+* within the given memory constraints.
+*
+* The results of this macro can be provided to XLlDma_BdRingCreate().
+*
+* @param Alignment specifies what byte alignment the BDs must fall on and
+*        must be a power of 2 to get an accurate calculation (32, 64, 126,...)
+* @param Bytes is the number of bytes to be used to store BDs.
+*
+* @return Number of BDs that can fit in the given memory area
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingCntCalc(u32 Alignment, u32 Bytes)
+*
+******************************************************************************/
+#define XLlDma_mBdRingCntCalc(Alignment, Bytes)                           \
+	(u32)((Bytes)/((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
+
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many bytes of memory
+* are required to contain a given number of BDs at a given alignment.
+*
+* @param Alignment specifies what byte alignment the BDs must fall on. This
+*        parameter must be a power of 2 to get an accurate calculation (32, 64,
+*        128,...)
+* @param NumBd is the number of BDs to calculate memory size requirements for
+*
+* @return The number of bytes of memory required to create a BD list with the
+*         given memory constraints.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingMemCalc(u32 Alignment, u32 NumBd)
+*
+******************************************************************************/
+#define XLlDma_mBdRingMemCalc(Alignment, NumBd)			\
+	(u32)((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1))*(NumBd)
+
+
+/****************************************************************************/
+/**
+* Return the total number of BDs allocated by this channel with
+* XLlDma_BdRingCreate().
+*
+* @param  RingPtr is the BD ring to operate on.
+*
+* @return The total number of BDs allocated for this channel.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingGetCnt(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
+
+
+/****************************************************************************/
+/**
+* Return the number of BDs allocatable with XLlDma_BdRingAlloc() for pre-
+* processing.
+*
+* @param  RingPtr is the BD ring to operate on.
+*
+* @return The number of BDs currently allocatable.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingGetFreeCnt(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetFreeCnt(RingPtr)  ((RingPtr)->FreeCnt)
+
+
+/****************************************************************************/
+/**
+* Snap shot the latest BD a BD ring is processing.
+*
+* @param  RingPtr is the BD ring to operate on.
+*
+* @return None
+*
+* @note
+* C-style signature:
+*    void XLlDma_mBdRingSnapShotCurrBd(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingSnapShotCurrBd(RingPtr)				  \
+	{								  \
+		(RingPtr)->BdaRestart = 				  \
+			(XLlDma_Bd *)XLlDma_mReadReg((RingPtr)->ChanBase, \
+					XLLDMA_CDESC_OFFSET);		  \
+	}
+
+
+/****************************************************************************/
+/**
+* Return the next BD in the ring.
+*
+* @param  RingPtr is the BD ring to operate on.
+* @param  BdPtr is the current BD.
+*
+* @return The next BD in the ring relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+*    XLlDma_Bd *XLlDma_mBdRingNext(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingNext(RingPtr, BdPtr)			\
+		(((u32)(BdPtr) >= (RingPtr)->LastBdAddr) ?	\
+			(XLlDma_Bd*)(RingPtr)->FirstBdAddr :	\
+			(XLlDma_Bd*)((u32)(BdPtr) + (RingPtr)->Separation))
+
+
+/****************************************************************************/
+/**
+* Return the previous BD in the ring.
+*
+* @param  InstancePtr is the DMA channel to operate on.
+* @param  BdPtr is the current BD.
+*
+* @return The previous BD in the ring relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+*    XLlDma_Bd *XLlDma_mBdRingPrev(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingPrev(RingPtr, BdPtr)				\
+		(((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ?		\
+			(XLlDma_Bd*)(RingPtr)->LastBdAddr :		\
+			(XLlDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel status register XLLDMA_SR_OFFSET
+*
+* @param  RingPtr is the channel instance to operate on.
+*
+* @return Current contents of SR_OFFSET
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingGetSr(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetSr(RingPtr)				\
+		XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel control register XLLDMA_CR_OFFSET
+*
+* @param  RingPtr is the channel instance to operate on.
+*
+* @return Current contents of CR_OFFSET
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingGetCr(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetCr(RingPtr)				\
+		XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Set the contents of the channel control register XLLDMA_CR_OFFSET. This
+* register does not affect the other DMA channel.
+*
+* @param  RingPtr is the channel instance to operate on.
+* @param  Data is the data to write to CR_OFFSET
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingSetCr(XLlDma_BdRing* RingPtr, u32 Data)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingSetCr(RingPtr, Data)				\
+		XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, (Data))
+
+
+/****************************************************************************/
+/**
+* Check if the current DMA channel is busy with a DMA operation.
+*
+* @param  RingPtr is the channel instance to operate on.
+*
+* @return TRUE if the DMA is busy. FALSE otherwise
+*
+* @note
+* C-style signature:
+*    XBoolean XLlDma_mBdRingBusy(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingBusy(RingPtr)					 \
+		((XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET) \
+			& XLLDMA_SR_ENGINE_BUSY_MASK) ? TRUE : FALSE)
+
+
+/****************************************************************************/
+/**
+* Set interrupt enable bits for a channel. This operation will modify the
+* XLLDMA_CR_OFFSET register.
+*
+* @param  RingPtr is the channel instance to operate on.
+* @param  Mask consists of the interrupt signals to enable. They are formed by
+*         OR'ing one or more of the following bitmasks together:
+*         XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
+*         XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
+*         XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
+*         affected.
+*
+* @note
+* C-style signature:
+*    void XLlDma_mBdRingIntEnable(XLlDma_BdRing* RingPtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntEnable(RingPtr, Mask)			\
+	{							\
+		u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase,	\
+				XLLDMA_CR_OFFSET);		\
+		Reg |= ((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK);	\
+		XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
+	}
+
+
+/****************************************************************************/
+/**
+* Clear interrupt enable bits for a channel. This operation will modify the
+* XLLDMA_CR_OFFSET register.
+*
+* @param  RingPtr is the channel instance to operate on.
+* @param  Mask consists of the interrupt signals to disable. They are formed
+*         by OR'ing one or more of the following bitmasks together:
+*         XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
+*         XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
+*         XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
+*         affected.
+*
+* @note
+* C-style signature:
+*    void XLlDma_mBdRingIntDisable(XLlDma_BdRing* RingPtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntDisable(RingPtr, Mask)				\
+	{								\
+		u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase,		\
+				XLLDMA_CR_OFFSET);			\
+		Reg &= ~((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK);		\
+		XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
+	}
+
+
+/****************************************************************************/
+/**
+* Get enabled interrupts of a channel.
+*
+* @param  RingPtr is the channel instance to operate on.
+* @return Enabled interrupts of a channel. Use XLLDMA_CR_IRQ_* defined in
+*         xlldma_hw.h to interpret this returned value.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingIntGetEnabled(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntGetEnabled(RingPtr)				\
+		(XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET) \
+			& XLLDMA_CR_IRQ_ALL_EN_MASK)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel's IRQ register XDMACR_IRQ_OFFSET. This
+* operation can be used to see which interrupts are pending.
+*
+* @param  RingPtr is the channel instance to operate on.
+*
+* @return Current contents of the IRQ_OFFSET register. Use XLLDMA_IRQ_***
+*         values defined in xlldma_hw.h to interpret the returned value.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingGetIrq(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetIrq(RingPtr)				\
+		XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Acknowledge asserted interrupts.
+*
+* @param  RingPtr is the channel instance to operate on.
+* @param  Mask are the interrupt signals to acknowledge and are made by Or'ing
+*         one or more of the following bits: XLLDMA_IRQ_ERROR_MASK,
+*         XLLDMA_IRQ_DELAY_MASK, XLLDMA_IRQ_COALESCE_MASK, XLLDMA_IRQ_ALL_MASK.
+*         Any mask bit set for an unasserted interrupt has no effect.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mBdRingAckIrq(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingAckIrq(RingPtr, Mask)				\
+		XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET,\
+			(Mask) & XLLDMA_IRQ_ALL_MASK)
+
+/************************* Function Prototypes ******************************/
+
+/*
+ * Descriptor ring functions xlldma_bdring.c
+ */
+int XLlDma_BdRingCreate(XLlDma_BdRing * RingPtr, u32 PhysAddr,
+			u32 VirtAddr, u32 Alignment, unsigned BdCount);
+int XLlDma_BdRingCheck(XLlDma_BdRing * RingPtr);
+int XLlDma_BdRingClone(XLlDma_BdRing * RingPtr, XLlDma_Bd * SrcBdPtr);
+int XLlDma_BdRingAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		       XLlDma_Bd ** BdSetPtr);
+int XLlDma_BdRingUnAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+			 XLlDma_Bd * BdSetPtr);
+int XLlDma_BdRingToHw(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		      XLlDma_Bd * BdSetPtr);
+unsigned XLlDma_BdRingFromHw(XLlDma_BdRing * RingPtr, unsigned BdLimit,
+			     XLlDma_Bd ** BdSetPtr);
+int XLlDma_BdRingFree(XLlDma_BdRing * RingPtr, unsigned NumBd,
+		      XLlDma_Bd * BdSetPtr);
+int XLlDma_BdRingStart(XLlDma_BdRing * RingPtr);
+int XLlDma_BdRingSetCoalesce(XLlDma_BdRing * RingPtr, u32 Counter, u32 Timer);
+void XLlDma_BdRingGetCoalesce(XLlDma_BdRing * RingPtr,
+			      u32 *CounterPtr, u32 *TimerPtr);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma.c	2014-07-20 22:06:39.105260375 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma.c
+*
+* This file implements initialization and control related functions. For more
+* information on this driver, see xlldma.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   12/21/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xlldma.h"
+#include "xenv.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * This function initializes a DMA engine.  This function must be called
+ * prior to using a DMA engine. Initialization of a engine includes setting
+ * up the register base address, setting up the instance data, and ensuring the
+ * hardware is in a quiescent state.
+ *
+ * @param  InstancePtr is a pointer to the DMA engine instance to be worked on.
+ * @param  BaseAddress is where the registers for this engine can be found.
+ *         If address translation is being used, then this parameter must
+ *         reflect the virtual base address.
+ * @return None.
+ *
+ *****************************************************************************/
+void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress)
+{
+	/* Setup the instance */
+	memset(InstancePtr, 0, sizeof(XLlDma));
+	InstancePtr->RegBase = BaseAddress;
+
+	/* Initialize the ring structures */
+	InstancePtr->TxBdRing.RunState = XST_DMA_SG_IS_STOPPED;
+	InstancePtr->TxBdRing.ChanBase = BaseAddress + XLLDMA_TX_OFFSET;
+	InstancePtr->TxBdRing.IsRxChannel = 0;
+	InstancePtr->RxBdRing.RunState = XST_DMA_SG_IS_STOPPED;
+	InstancePtr->RxBdRing.ChanBase = BaseAddress + XLLDMA_RX_OFFSET;
+	InstancePtr->RxBdRing.IsRxChannel = 1;
+
+	/* Reset the device and return */
+	XLlDma_Reset(InstancePtr);
+}
+
+/*****************************************************************************/
+/**
+* Reset both TX and RX channels of a DMA engine.
+*
+* Any DMA transaction in progress aborts immediately. The DMA engine is in
+* stop state after the reset.
+*
+* @param  InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+* @note
+*         - If the hardware is not working properly, this function will enter
+*           infinite loop and never return.
+*         - After the reset, the Normal mode is enabled, and the overflow error
+*           for both TX/RX channels are disabled.
+*         - After the reset, the DMA engine is no longer in pausing state, if
+*           the DMA engine is paused before the reset operation.
+*         - After the reset, the coalescing count value and the delay timeout
+*           value are both set to 1 for TX and RX channels.
+*         - After the reset, all interrupts are disabled.
+*
+******************************************************************************/
+void XLlDma_Reset(XLlDma * InstancePtr)
+{
+	u32 IrqStatus;
+	XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+	TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+	RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+	/* Save the locations of current BDs both rings are working on
+	 * before the reset so later we can resume the rings smoothly.
+	 */
+	XLlDma_mBdRingSnapShotCurrBd(TxRingPtr);
+	XLlDma_mBdRingSnapShotCurrBd(RxRingPtr);
+
+	/* Start reset process then wait for completion */
+	XLlDma_mSetCr(InstancePtr, XLLDMA_DMACR_SW_RESET_MASK);
+
+	/* Loop until the reset is done */
+	while ((XLlDma_mGetCr(InstancePtr) & XLLDMA_DMACR_SW_RESET_MASK)) {
+	}
+
+	/* Disable all interrupts after issue software reset */
+	XLlDma_mBdRingIntDisable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
+	XLlDma_mBdRingIntDisable(RxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
+
+	/* Clear Interrupt registers of both channels, as the software reset
+	 * does not clear any register values. Not doing so will cause
+	 * interrupts asserted after the software reset if there is any
+	 * interrupt left over before.
+	 */
+	IrqStatus = XLlDma_mBdRingGetIrq(TxRingPtr);
+	XLlDma_mBdRingAckIrq(TxRingPtr, IrqStatus);
+	IrqStatus = XLlDma_mBdRingGetIrq(RxRingPtr);
+	XLlDma_mBdRingAckIrq(RxRingPtr, IrqStatus);
+
+	/* Enable Normal mode, and disable overflow errors for both channels */
+	XLlDma_mSetCr(InstancePtr, XLLDMA_DMACR_TAIL_PTR_EN_MASK |
+		      XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK |
+		      XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK);
+
+	/* Set TX/RX Channel coalescing setting */
+	XLlDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
+	XLlDma_BdRingSetCoalesce(RxRingPtr, 1, 1);
+
+	TxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+	RxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+}
+
+/*****************************************************************************/
+/**
+* Pause DMA transactions on both channels. The DMA enters the pausing state
+* immediately. So if a DMA transaction is in progress, it will be left
+* unfinished and will be continued once the DMA engine is resumed
+* (see XLlDma_Resume()).
+*
+* @param  InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+* @note
+*       - If the hardware is not working properly, this function will enter
+*         infinite loop and never return.
+*       - After the DMA is paused, DMA channels still could accept more BDs
+*         from software (see XLlDma_BdRingToHw()), but new BDs will not be
+*         processed until the DMA is resumed (see XLlDma_Resume()).
+*
+*****************************************************************************/
+void XLlDma_Pause(XLlDma * InstancePtr)
+{
+	u32 RegValue;
+	XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+	TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+	RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+	/* Do nothing if both channels already stopped */
+	if ((TxRingPtr->RunState == XST_DMA_SG_IS_STOPPED) &&
+	    (RxRingPtr->RunState == XST_DMA_SG_IS_STOPPED)) {
+		return;
+	}
+
+	/* Enable pause bits for both TX/ RX channels */
+	RegValue = XLlDma_mGetCr(InstancePtr);
+	XLlDma_mSetCr(InstancePtr, RegValue | XLLDMA_DMACR_TX_PAUSE_MASK |
+		      XLLDMA_DMACR_RX_PAUSE_MASK);
+
+	/* Loop until Write Command Queue of RX channel is empty, which
+	 * indicates that all the write data associated with the pending
+	 * commands has been flushed.*/
+	while (!(XLlDma_mBdRingGetIrq(RxRingPtr) | XLLDMA_IRQ_WRQ_EMPTY_MASK));
+
+	TxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+	RxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+}
+
+/*****************************************************************************/
+/**
+* Resume DMA transactions on both channels. Any interrupted DMA transaction
+* caused by DMA pause operation (see XLlDma_Pause()) and all committed
+* transactions after DMA is paused will be continued upon the return of this
+* function.
+*
+* @param  InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+*****************************************************************************/
+void XLlDma_Resume(XLlDma * InstancePtr)
+{
+	u32 RegValue;
+	XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+	TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+	RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+	/* Do nothing if both channels already started */
+	if ((TxRingPtr->RunState == XST_DMA_SG_IS_STARTED) &&
+	    (RxRingPtr->RunState == XST_DMA_SG_IS_STARTED)) {
+		return;
+	}
+
+	/* Clear pause bits for both TX/ RX channels */
+	RegValue = XLlDma_mGetCr(InstancePtr);
+	XLlDma_mSetCr(InstancePtr, RegValue & ~(XLLDMA_DMACR_TX_PAUSE_MASK |
+						XLLDMA_DMACR_RX_PAUSE_MASK));
+
+	TxRingPtr->RunState = XST_DMA_SG_IS_STARTED;
+	RxRingPtr->RunState = XST_DMA_SG_IS_STARTED;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma.h	2014-07-20 22:06:39.119260144 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma.h
+*
+* The Xilinx Local-Link Scatter Gather DMA driver. This driver supports Soft
+* DMA (SDMA) engines. Each SDMA engine contains two separate DMA channels (TX
+* and RX).
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* For a full description of DMA features, please see the hardware spec. This
+* driver supports the following features:
+*
+*   - Scatter-Gather DMA (SGDMA)
+*   - Interrupts
+*   - Programmable interrupt coalescing for SGDMA
+*   - Capable of using 32 bit addressing for buffer. (Hardware spec states
+*     36 Bit bus addressing, which includes Msb 4-bits of DMA address
+*     configurable on each channel through the Channel Control Registers)
+*   - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA
+*     engine
+*   - Virtual memory support
+*
+* <b>Transactions</b>
+*
+* To describe a DMA transaction in its simplest form, you need source address,
+* destination address, and the number of bytes to transfer. When using a DMA
+* receive channel, the source address is within some piece of IP Hardware and
+* doesn't require the application explicitly set it. Likewise with a transmit
+* channel and the destination address. So this leaves a application buffer
+* address and the number bytes to transfer as the primary transaction
+* attributes. Other attributes include:
+*
+*   - If the transaction occurs on a bus wider than 32 bits, what are the
+*     highest order address bits.
+*   - Does this transaction represent the start of a packet, or end of a
+*     packet.
+*
+* The object used to describe a transaction is referred to as a Buffer
+* Descriptor (BD). The format of a BD closely matches that of the DMA hardware.
+* Many fields within the BD correspond directly with the same fields within the
+* hardware registers. See xlldmabd.h for a detailed description of and the API
+* for manipulation of these objects.
+*
+* <b>Scatter-Gather DMA</b>
+*
+* SGDMA allows the application to define a list of transactions in memory which
+* the hardware will process without further application intervention. During
+* this time, the application is free to continue adding more work to keep the
+* Hardware busy.
+*
+* Notification of completed transactions can be done either by polling the
+* hardware, or using interrupts that signal a transaction has completed or a
+* series of transactions have been completed.
+*
+* SGDMA processes whole packets. A packet is defined as a series of
+* data bytes that represent a message. SGDMA allows a packet of data to be
+* broken up into one or more transactions. For example, take an Ethernet IP
+* packet which consists of a 14 byte header followed by a 1 or more byte
+* payload. With SGDMA, the application may point a BD to the header and another
+* BD to the payload, then transfer them as a single message. This strategy can
+* make a TCP/IP stack more efficient by allowing it to keep packet headers and
+* data in different memory regions instead of assembling packets into
+* contiguous blocks of memory.
+*
+* <b>SGDMA Ring Management</b>
+*
+* The hardware expects BDs to be setup as a singly linked list. As a BD is
+* completed, the DMA engine will dereference BD.Next and load the next BD to
+* process. This driver uses a fixed buffer ring where all BDs are linked to the
+* next BD in adjacent memory. The last BD in the ring is linked to the first.
+*
+* Within the ring, the driver maintains four groups of BDs. Each group consists
+* of 0 or more adjacent BDs:
+*
+*   - Free: Those BDs that can be allocated by the application with
+*     XLlDma_BdRingAlloc(). These BDs are under driver control and may not be
+*     modified by the application
+*
+*   - Pre-process: Those BDs that have been allocated with
+*     XLlDma_BdRingAlloc(). These BDs are under application control. The
+*     application modifies these BDs in preparation for future DMA
+*     transactions.
+*
+*   - Hardware: Those BDs that have been enqueued to hardware with
+*     XLlDma_BdRingToHw(). These BDs are under hardware control and may be in a
+*     state of awaiting hardware processing, in process, or processed by
+*     hardware. It is considered an error for the application to change BDs
+*     while they are in this group. Doing so can cause data corruption and lead
+*     to system instability.
+*
+*   - Post-process: Those BDs that have been processed by hardware and have
+*     been extracted from the work group with XLlDma_BdRingFromHw(). These BDs
+*     are under application control. The application may access these BDs to
+*     determine the result of DMA transactions. When the application is
+*     finished, XLlDma_BdRingFree() should be called to place them back into
+*     the Free group.
+*
+*
+* Normally BDs are moved in the following way:
+* <pre>
+*
+*         XLlDma_BdRingAlloc()                   XLlDma_BdRingToHw()
+*   Free ------------------------> Pre-process ----------------------> Hardware
+*                                                                      |
+*    /|\                                                               |
+*     |   XLlDma_BdRingFree()                    XLlDma_BdRingFromHw() |
+*     +--------------------------- Post-process <----------------------+
+*
+* </pre>
+*
+* The only exception to the flow above is that after BDs are moved from Free
+* group to Pre-process group, the application decide for whatever reason these
+* BDs are not ready and could not be given to hardware. In this case these BDs
+* could be moved back to Free group using XLlDma_BdRingUnAlloc() function to
+* help keep the BD ring in great shape and recover the error. See comments of
+* the function for details
+*
+* <pre>
+*
+*         XLlDma_BdRingUnAlloc()
+*   Free <----------------------- Pre-process
+*
+* </pre>
+*
+* The API provides macros that allow BD list traversal. These macros should be
+* used with care as they do not understand where one group ends and another
+* begins.
+*
+* The driver does not cache or keep copies of any BD. When the application
+* modifies BDs returned by XLlDma_BdRingAlloc() or XLlDma_BdRingFromHw(), they
+* are modifying the same BD that hardware accesses.
+*
+* Certain pairs of list modification functions have usage restrictions. See
+* the function headers for XLlDma_BdRingAlloc() and XLlDma_BdRingFromHw() for
+* more information.
+*
+* <b>SGDMA Descriptor Ring Creation</b>
+*
+* During initialization, the function XLlDma_BdRingCreate() is used to setup
+* a application supplied memory block to contain all BDs for the DMA channel.
+* This function takes as an argument the number of BDs to place in the list. To
+* arrive at this number, the application is given two methods of calculating
+* it.
+*
+* The first method assumes the application has a block of memory and they just
+* want to fit as many BDs as possible into it. The application must calculate
+* the number of BDs that will fit with XLlDma_mBdRingCntCalc(), then supply
+* that number into the list creation function.
+*
+* The second method allows the application to just supply the number directly.
+* The driver assumes the memory block is large enough to contain them all. To
+* double-check, the application should invoke XLlDma_mBdRingMemCalc() to verify
+* the memory block size is adequate.
+*
+* Once the list has been created, it can be used right away to perform DMA
+* transactions. However, there are optional steps that can be done to increase
+* throughput and decrease application code complexity by the use of
+* XLlDma_BdRingClone().
+*
+* BDs have several application accessible attributes that affect how DMA
+* transactions are carried out. Some of these attributes will probably be
+* constant at run-time. The cloning function can be used to copy a template BD
+* to every BD in the ring relieving the application of having to setup
+* transactions from scratch every time a BD is submitted to hardware.
+*
+* Ideally, the only transaction parameters that need to be set by application
+* should be: buffer address, bytes to transfer, and whether the BD is the
+* Start and/or End of a packet.
+*
+* <b>Interrupt Coalescing</b>
+*
+* SGDMA provides control over the frequency of interrupts. On a high speed link
+* significant processor overhead may be used servicing interrupts. Interrupt
+* coalescing provides two mechanisms that help control interrupt frequency:
+*
+* - The packet threshold counter will hold off interrupting the CPU until a
+*   programmable number of packets have been processed by the engine.
+* - The packet waitbound timer is used to interrupt the CPU if after a
+*   programmable amount of time after processing the last packet, no new
+*   packets were processed.
+*
+* <b>Interrupt Service </b>
+*
+* This driver does not service interrupts. This is done typically by a
+* interrupt handler within a higher level driver/application that uses DMA.
+* This driver does provide an API to enable or disable specific interrupts.
+*
+* This interrupt handler provided by the higher level driver/application
+* !!!MUST!!! clear pending interrupts before handling the BDs processed by the
+* DMA. Otherwise the following corner case could raise some issue:
+*
+* - A packet is transmitted(/received) and asserts a TX(/RX) interrupt, and if
+*   this interrupt handler deals with the BDs finished by the DMA before clears
+*   the interrupt, another packet could get transmitted(/received) and assert
+*   the interrupt between when the BDs are taken care  and when the interrupt
+*   clearing operation begins, and the interrupt clearing operation will clear
+*   the interrupt raised by the second packet and will never process its
+*   according BDs until a new interrupt occurs.
+*
+* Changing the sequence to "Clear interrupts before handle BDs" solves this
+* issue:
+*
+* - If the interrupt raised by the second packet is before the interrupt
+*   clearing operation, the descriptors associated with the second packet must
+*   have been finished by hardware and ready for the handler to deal with,
+*   and those descriptors will processed with those BDs of the first packet
+*   during the handling of the interrupt asserted by the first packet.
+*
+* - if the interrupt of the second packet is asserted after the interrupt
+*   clearing operation but its BDs are finished before the handler starts to
+*   deal with BDs, the packet's buffer descriptors will be handled with
+*   those of the first packet during the handling of the interrupt asserted
+*   by the first packet.
+*
+* - Otherwise, the BDs of the second packet is not ready when the interrupt
+*   handler starts to deal with the BDs of the first packet. Those BDs will
+*   be handled next time the interrupt handled gets invoked as the interrupt
+*   of the second packet is not cleared in current pass and thereby will
+*   cause the handler to get invoked again
+*
+* Please note if the second case above occurs, the handler will find
+* NO buffer descriptor is finished by the hardware (i.e.,
+* XLlDma_BdRingFromHw() returns 0) during the handling of the interrupt
+* asserted by the second packet. This is valid and the application should NOT
+* consider this is a hardware error and have no need to reset the hardware.
+*
+* <b> Software Initialization </b>
+*
+* The application needs to do following steps in order for preparing DMA engine
+* to be ready to process DMA transactions:
+*
+* - DMA Initialization using XLlDma_Initialize() function. This step
+*   initializes a driver instance for the given DMA engine and resets the
+*   engine.
+* - BD Ring creation. A BD ring is needed per channel and can be built by
+*   calling XLlDma_BdRingCreate(). A parameter passed to this function is the
+*   number of BD fit in a given memory range, and XLlDma_mBdRingCntCalc() helps
+*   calculate the value.
+* - (Optional) BD setup using a template. Once a BD ring is created, the
+*   application could populate a template BD and then invoke
+*   XLlDma_BdRingClone() to set the same attributes on all BDs on the BD ring.
+*   This saves the application some effort to populate all fixed attributes of
+*   each BD before passing it to the hardware.
+* - (RX channel only) Prepare BDs with attached data buffers and give them to
+*   RX channel. First allocate BDs using XLlDma_BdRingAlloc(), then populate
+*   data buffer address, data buffer size and the control word fields of each
+*   allocated BD with valid values. Last call XLlDma_BdRingToHw() to give the
+*   BDs to the channel.
+* - Enable interrupts if interrupt mode is chosen. The application is
+*   responsible for setting up the interrupt system, which includes providing
+*   and connecting interrupt handlers and call back functions, before
+*   the interrupts are enabled.
+* - Start DMA channels: Call XLlDma_BdRingStart() to start a channel
+*
+* <b> How to start DMA transactions </b>
+*
+* RX channel is ready to start RX transactions once the initialization (see
+* Initialization section above) is finished. The DMA transactions are triggered
+* by the user IP (like Local Link TEMAC).
+*
+* Starting TX transactions needs some work. The application calls
+* XLlDma_BdRingAlloc() to allocate a BD list, then populates necessary
+* attributes of each allocated BD including data buffer address, data size,
+* and control word, and last passes those BDs to the TX channel
+* (see XLlDma_BdRingToHw()). The added BDs will be processed as soon as the
+* TX channel reaches them.
+*
+* For both channels, If the DMA engine is currently paused (see
+* XLlDma_Pause()), the newly added BDs will be accepted but not processed
+* until the DMA engine is resumed (see XLlDma_Resume()).
+*
+* <b> Software Post-Processing on completed DMA transactions </b>
+*
+* Some software post-processing is needed after DMA transactions are finished.
+*
+* if interrupt system are set up and enabled, DMA channels notify the software
+* the finishing of DMA transactions using interrupts,  Otherwise the
+* application could poll the channels (see XLlDma_BdRingFromHw()).
+*
+* - Once BDs are finished by a channel, the application first needs to fetch
+*   them from the channel (see XLlDma_BdRingFromHw()).
+* - On TX side, the application now could free the data buffers attached to
+*   those BDs as the data in the buffers has been transmitted.
+* - On RX side, the application now could use the received data in the buffers
+*   attached to those BDs
+* - For both channels, those BDs need to be freed back to the Free group (see
+*   XLlDma_BdRingFree()) so they are allocatable for future transactions.
+* - On RX side, it is the application's responsibility for having BDs ready
+*   to receive data at any time. Otherwise the RX channel will refuse to
+*   accept any data once it runs out of RX BDs. As we just freed those hardware
+*   completed BDs in the previous step, it is good timing to allocate them
+*   back (see XLlDma_BdRingAlloc()), prepare them, and feed them to the RX
+*   channel again (see XLlDma_BdRingToHw())
+*
+* <b> Examples </b>
+*
+* Two examples are provided with this driver to demonstrate the driver usage:
+* One for interrupt mode and one for polling mode.
+*
+* <b>Address Translation</b>
+*
+* When the BD list is setup with XLlDma_BdRingCreate(), a physical and
+* virtual address is supplied for the segment of memory containing the
+* descriptors. The driver will handle any translations internally. Subsequent
+* access of descriptors by the application is done in terms of their virtual
+* address.
+*
+* Any application data buffer address attached to a BD must be physical
+* address. The application is responsible for calculating the physical address
+* before assigns it to the buffer address field in the BD.
+*
+* <b>Cache Coherency</b>
+*
+* This driver expects all application buffers attached to BDs to be in cache
+* coherent memory. Buffers for transmit MUST be flushed from the cache before
+* passing the associated BD to this driver. Buffers for receive MUST be
+* invalidated before passing the associated BD to this driver.
+*
+* <b>Alignment</b>
+*
+* For BDs:
+*
+* Minimum alignment is defined by the constant XLLDMA_BD_MINIMUM_ALIGNMENT.
+* This is the smallest alignment allowed by both hardware and software for them
+* to properly work. Other than XLLDMA_BD_MINIMUM_ALIGNMENT, multiples of the
+* constant are the only valid alignments for BDs.
+*
+* If the descriptor ring is to be placed in cached memory, alignment also MUST
+* be at least the processor's cache-line size. If this requirement is not met
+* then system instability will result. This is also true if the length of a BD
+* is longer than one cache-line, in which case multiple cache-lines are needed
+* to accommodate each BD.
+*
+* Aside from the initial creation of the descriptor ring (see
+* XLlDma_BdRingCreate()), there are no other run-time checks for proper
+* alignment.
+*
+* For application data buffers:
+*
+* Application data buffers may reside on any alignment.
+*
+* <b>Reset After Stopping</b>
+*
+* This driver is designed to allow for stop-reset-start cycles of the DMA
+* hardware while keeping the BD list intact. When restarted after a reset, this
+* driver will point the DMA engine to where it left off after stopping it.
+*
+* <b>Limitations</b>
+*
+* This driver only supports Normal mode (i.e., Tail Descriptor Pointer mode).
+* In this mode write of a Tail Descriptor Pointer register (which is done in
+* XLlDma_BdRingStart() and XLlDma_BdRingToHw()) starts DMA transactions.
+*
+* Legacy mode is NOT supported by this driver.
+*
+* This driver does not have any mechanism for mutual exclusion. It is up to the
+* application to provide this protection.
+*
+* <b>Hardware Defaults & Exclusive Use</b>
+*
+* During initialization, this driver will override the following hardware
+* default settings. If desired, the application may change these settings back
+* to their hardware defaults:
+*
+*   - Normal mode (Tail Descriptor Pointer mode) will be enabled.
+*   - Interrupt coalescing timer and counter overflow errors will be disabled
+*     (XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK and TX_OVERFLOW_ERR_DIS_MASK will
+*     be set to 1). These two items control interrupt "overflow" behavior.
+*     When enabled, the hardware may signal an error if interrupts are not
+*     processed fast enough even though packets were correctly processed. This
+*     error is triggered when certain internal counters overflow. The driver
+*     disables this feature so no such error will be reported.
+*
+* The driver requires exclusive use of the following hardware features. If any
+* are changed by the application then the driver will not operate properly:
+*
+*   - XLLDMA_DMACR_TAIL_PTR_ENABLE_MASK. The driver controls this bit
+*     in the DMACR register.
+*   - XLLDMA_BD_STSCTRL_COMPLETED_MASK. The driver controls this bit in each BD
+*   - XLLDMA_NDESC_OFFSET. The driver controls this register
+*   - XLLDMA_DMACR_SW_RESET_MASK. The driver controls this bit in the DMACR
+*     register
+*
+* <b>BUS Interface</b>
+*
+* The constant CONFIG_XILINX_LLDMA_USE_DCR (see xlldma_hw.h) is used
+* to inform the driver the type of the BUS the DMA device is on. If
+* the DMA device is on DCR BUS, CONFIG_XILINX_LLDMA_USE_DCR must be
+* defined as a compiler option used in the Makefile BEFORE this driver
+* is compiled; Otherwise, the constant must NOT be defined.
+*
+* <b>User-IP Specific Definition</b>
+*
+* This driver relies on two User-IP (like Local-Link TEMAC) specific constants
+* (see xlldma_userip.h) to work properly:
+*
+*   - XLLDMA_USR_APPWORD_OFFSET defines a user word the User-IP always updates
+*     in the RX Buffer Descriptors (BD) during <b>ALL</b> Receive transactions.
+*     This driver uses XLLDMA_BD_USR4_OFFSET as the default value of this
+*     constant.
+*
+*   - XLLDMA_USR_APPWORD_INITVALUE defines the value the DMA driver uses to
+*     populate the XLLDMA_USR_APPWORD_OFFSET field in any RX BD before giving
+*     the BD to the RX channel for receive transaction. It must be ensured
+*     that the User-IP will always populates a different value into the
+*     XLLDMA_USR_APPWORD_OFFSET field during any receive transaction. Failing
+*     to do so will cause the DMA driver to work improperly. This driver uses
+*     0xFFFFFFFF as the default value of this constant.
+*
+* If the User-IP uses different setting, the correct setting must be defined as
+* compiler options used in the Makefile BEFORE this driver is compiled. In
+* either case the default definition of the constants in this driver will be
+* discarded.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_H		/* prevent circular inclusions */
+#define XLLDMA_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xlldma_bd.h"
+#include "xlldma_bdring.h"
+#include "xlldma_userip.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XLLDMA_NO_CHANGE            0xFFFF	/* Used as API argument */
+#define XLLDMA_ALL_BDS              0xFFFFFFFF	/* Used as API argument */
+
+/**************************** Type Definitions *******************************/
+
+
+/**
+ * The XLlDma driver instance data. An instance must be allocated for each DMA
+ * engine in use. Each DMA engine includes a TX channel and a RX channel.
+ */
+typedef struct XLlDma {
+	u32 RegBase;		/**< Virtual base address of DMA engine */
+	XLlDma_BdRing TxBdRing;	/**< BD container management for TX channel */
+	XLlDma_BdRing RxBdRing;	/**< BD container management for RX channel */
+
+} XLlDma;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/****************************************************************************/
+/**
+* Retrieve the TX ring object. This object can be used in the various Ring
+* API functions.
+*
+* @param  InstancePtr is the DMA engine to operate on.
+*
+* @return TxBdRing object
+*
+* @note
+* C-style signature:
+*    XLlDma_BdRing XLlDma_mGetTxRing(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetTxRing(InstancePtr) ((InstancePtr)->TxBdRing)
+
+
+/****************************************************************************/
+/**
+* Retrieve the RX ring object. This object can be used in the various Ring
+* API functions.
+*
+* @param  InstancePtr is the DMA engine to operate on.
+*
+* @return RxBdRing object
+*
+* @note
+* C-style signature:
+*    XLlDma_BdRing XLlDma_mGetRxRing(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetRxRing(InstancePtr) ((InstancePtr)->RxBdRing)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the DMA engine control register
+* (XLLDMA_DMACR_OFFSET).
+*
+* @param  InstancePtr is the DMA engine instance to operate on.
+*
+* @return Current contents of the DMA engine control register.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mGetCr(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetCr(InstancePtr)                                      \
+	XLlDma_mReadReg((InstancePtr)->RegBase, XLLDMA_DMACR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Set the contents of the DMA engine control register (XLLDMA_DMACR_OFFSET).
+* This control register affects both DMA channels.
+*
+* @param  InstancePtr is the DMA engine instance to operate on.
+* @param  Data is the data to write to the DMA engine control register.
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mSetCr(XLlDma* InstancePtr, u32 Data)
+*
+*****************************************************************************/
+#define XLlDma_mSetCr(InstancePtr, Data)                                \
+	XLlDma_mWriteReg((InstancePtr)->RegBase, XLLDMA_DMACR_OFFSET, (Data))
+
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization and control functions in xlldma.c
+ */
+void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress);
+void XLlDma_Reset(XLlDma * InstancePtr);
+void XLlDma_Pause(XLlDma * InstancePtr);
+void XLlDma_Resume(XLlDma * InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_hw.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_hw.h	2014-07-20 22:06:39.131259946 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xlldma_hw.h
+*
+* This header file contains identifiers and register-level driver functions (or
+* macros) that can be used to access the Local-Link Scatter-gather Direct
+* Memory Access Gather (LLDMA) device.
+*
+* For more information about the operation of this device, see the hardware
+* specification and documentation in the higher level driver xlldma.h source
+* code file.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_HW_H		/* prevent circular inclusions */
+#define XLLDMA_HW_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/** @name Device Bus Type definition The constant
+ * CONFIG_XILINX_LLDMA_USE_DCR is used to inform this driver the type
+ * of the BUS the DMA device is on. If the DMA core is on DCR BUS
+ * using indirect addressing, which currently only happens on V5FX,
+ * then this option must be set.  On other architectures where dma
+ * ports are accessed through memory mapped io, this must not be set.
+ *@{
+ */
+#ifdef CONFIG_XILINX_LLDMA_USE_DCR
+#include "xio_dcr.h"
+#else
+#include "xio.h"
+#endif
+/*@}*/
+
+/************************** Constant Definitions *****************************/
+
+/** @name Buffer Descriptor Alignment
+ *  @{
+ */
+#define XLLDMA_BD_MINIMUM_ALIGNMENT 0x40  /**< Minimum byte alignment
+                                               requirement for descriptors to
+                                               satisfy both hardware/software
+                                               needs */
+/*@}*/
+
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+#ifdef CONFIG_XILINX_LLDMA_USE_DCR
+
+/* DMA core is on DCR BUS */
+
+/** @name Device registers for DCR based systems.
+ *  Offsets defined in DCR address space. TX and RX channels consist of
+ *  identical registers
+ *  @{
+ */
+#define XLLDMA_TX_OFFSET    0x00000000	/**< TX channel registers base
+                                             offset [0..7] */
+#define XLLDMA_RX_OFFSET    0x00000008	/**< RX channel registers base
+                                             offset [8..F] */
+#define XLLDMA_DMACR_OFFSET 0x00000010	/**< DMA control register */
+
+/* This set of registers are applicable for both channels. Add
+ * XLLDMA_TX_OFFSET to get to TX channel, and XLLDMA_RX_OFFSET to get to RX
+ * channel
+ */
+#define XLLDMA_NDESC_OFFSET 0x00000000	/**< Next descriptor pointer */
+#define XLLDMA_BUFA_OFFSET  0x00000001	/**< Current buffer address */
+#define XLLDMA_BUFL_OFFSET  0x00000002	/**< Current buffer length */
+#define XLLDMA_CDESC_OFFSET 0x00000003	/**< Current descriptor pointer */
+#define XLLDMA_TDESC_OFFSET 0x00000004	/**< Tail descriptor pointer */
+#define XLLDMA_CR_OFFSET    0x00000005	/**< Channel control */
+#define XLLDMA_IRQ_OFFSET   0x00000006	/**< Interrupt register */
+#define XLLDMA_SR_OFFSET    0x00000007	/**< Status */
+/*@}*/
+
+#else /* Non-DCR interface is used */
+
+/** @name Device registers for Non-DCR based systems.
+ *  Offsets defined in Non-DCR address space. TX and RX channels consist of
+ *  identical registers
+ *  @{
+ */
+#define XLLDMA_TX_OFFSET    0x00000000	/**< TX channel registers base
+                                             offset */
+#define XLLDMA_RX_OFFSET    0x00000020	/**< RX channel registers base
+                                             offset */
+#define XLLDMA_DMACR_OFFSET 0x00000040	/**< DMA control register */
+
+/* This set of registers are applicable for both channels. Add
+ * XLLDMA_TX_OFFSET to get to TX channel, and XLLDMA_RX_OFFSET to get to RX
+ * channel
+ */
+#define XLLDMA_NDESC_OFFSET 0x00000000	/**< Next descriptor pointer */
+#define XLLDMA_BUFA_OFFSET  0x00000004	/**< Current buffer address */
+#define XLLDMA_BUFL_OFFSET  0x00000008	/**< Current buffer length */
+#define XLLDMA_CDESC_OFFSET 0x0000000C	/**< Current descriptor pointer */
+#define XLLDMA_TDESC_OFFSET 0x00000010	/**< Tail descriptor pointer */
+#define XLLDMA_CR_OFFSET    0x00000014	/**< Channel control */
+#define XLLDMA_IRQ_OFFSET   0x00000018	/**< Interrupt register */
+#define XLLDMA_SR_OFFSET    0x0000001C	/**< Status */
+
+/*@}*/
+
+#endif /* #ifdef CONFIG_XILINX_LLDMA_USE_DCR */
+
+/** @name Buffer Descriptor register offsets
+ *  USR fields are defined by higher level IP. For example, checksum offload
+ *  setup for EMAC type devices. The 1st 8 words are utilized by hardware. Any
+ *  words after the 8th are for software use only.
+ *  @{
+ */
+#define XLLDMA_BD_NDESC_OFFSET        0x00  /**< Next descriptor pointer */
+#define XLLDMA_BD_BUFA_OFFSET         0x04  /**< Buffer address */
+#define XLLDMA_BD_BUFL_OFFSET         0x08  /**< Buffer length */
+#define XLLDMA_BD_STSCTRL_USR0_OFFSET 0x0C  /**< Status and Control and
+                                                 hardware implementation
+                                                 specific */
+#define XLLDMA_BD_USR1_OFFSET         0x10  /**< Hardware implementation
+                                                 specific */
+#define XLLDMA_BD_USR2_OFFSET         0x14  /**< Hardware implementation
+                                                 specific */
+#define XLLDMA_BD_USR3_OFFSET         0x18  /**< Hardware implementation
+                                                 specific */
+#define XLLDMA_BD_USR4_OFFSET         0x1C  /**< Hardware implementation
+                                                 specific */
+#define XLLDMA_BD_ID_OFFSET           0x20  /**< Software application use */
+
+#define XLLDMA_BD_NUM_WORDS              9  /**< Number of 32-bit words that
+                                                 make up a full BD */
+#define XLLDMA_BD_HW_NUM_WORDS           8  /**< Number of 32-bit words that
+                                                 make up the hardware
+                                                 accessible portion of a BD */
+#define XLLDMA_BD_HW_NUM_BYTES          32  /**< Number of bytes that make up
+                                                 the hardware accessible
+                                                 portion of a BD */
+/*@}*/
+
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the hardware
+ * spec.
+ */
+
+
+/** @name Bitmasks of XLLDMA_TX_CR_OFFSET and XLLDMA_RX_CR_OFFSET registers
+ * @{
+ */
+#define XLLDMA_CR_IRQ_TIMEOUT_MASK      0xFF000000 /**< Interrupt coalesce
+                                                        waitbound timeout */
+#define XLLDMA_CR_IRQ_COUNT_MASK        0x00FF0000 /**< Interrupt coalesce
+                                                        count threshold */
+#define XLLDMA_CR_MSB_ADDR_MASK         0x0000F000 /**< MSB address of DMA
+                                                        buffers and descriptors
+                                                        for 36 bit
+                                                        addressing */
+#define XLLDMA_CR_APP_EN_MASK           0x00000800 /**< Application data mask
+                                                        enable */
+#define XLLDMA_CR_USE_1_BIT_CNT_MASK    0x00000400 /**< Turn 4 and 2 bit
+                                                        interrupt counters into
+                                                        1 bit counters */
+#define XLLDMA_CR_USE_INT_ON_END_MASK   0x00000200 /**< Use interrupt-on-end */
+#define XLLDMA_CR_LD_IRQ_CNT_MASK       0x00000100 /**< Load IRQ_COUNT */
+#define XLLDMA_CR_IRQ_EN_MASK           0x00000080 /**< Master interrupt
+                                                        enable */
+#define XLLDMA_CR_IRQ_ERROR_EN_MASK     0x00000004 /**< Enable error
+                                                        interrupt */
+#define XLLDMA_CR_IRQ_DELAY_EN_MASK     0x00000002 /**< Enable coalesce delay
+                                                        interrupt */
+#define XLLDMA_CR_IRQ_COALESCE_EN_MASK  0x00000001 /**< Enable coalesce count
+                                                        interrupt */
+#define XLLDMA_CR_IRQ_ALL_EN_MASK       0x00000087 /**< All interrupt enable
+                                                        bits */
+
+/* Shift constants for selected masks */
+#define XLLDMA_CR_IRQ_TIMEOUT_SHIFT     24
+#define XLLDMA_CR_IRQ_COUNT_SHIFT       16
+#define XLLDMA_CR_MSB_ADDR_SHIFT        12
+
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_TX_IRQ_OFFSET & XLLDMA_RX_IRQ_OFFSET registers
+ * @{
+ */
+#define XLLDMA_IRQ_WRQ_EMPTY_MASK        0x00004000 /**< Write Command Queue
+                                                         Empty -- RX channel
+                                                         Only */
+#define XLLDMA_IRQ_COALESCE_COUNTER_MASK 0x00003C00 /**< Coalesce IRQ 4 bit
+                                                         counter */
+#define XLLDMA_IRQ_DELAY_COUNTER_MASK    0x00000300 /**< Coalesce delay IRQ 2
+                                                         bit counter */
+#define XLLDMA_IRQ_PLB_RD_ERROR_MASK     0x00000010 /**< PLB Read Error IRQ */
+#define XLLDMA_IRQ_PLB_WR_ERROR_MASK     0x00000008 /**< PLB Write Error IRQ */
+#define XLLDMA_IRQ_ERROR_MASK            0x00000004 /**< Error IRQ */
+#define XLLDMA_IRQ_DELAY_MASK            0x00000002 /**< Coalesce delay IRQ */
+#define XLLDMA_IRQ_COALESCE_MASK         0x00000001 /**< Coalesce threshold
+                                                         IRQ */
+#define XLLDMA_IRQ_ALL_ERR_MASK          0x0000001C /**< All error interrupt */
+#define XLLDMA_IRQ_ALL_MASK              0x0000001F /**< All interrupt bits */
+
+/* Shift constants for selected masks */
+#define XLLDMA_IRQ_COALESCE_COUNTER_SHIFT 10
+#define XLLDMA_IRQ_DELAY_COUNTER_SHIFT     8
+
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_TX_SR_OFFSET and XLLDMA_RX_SR_OFFSET registers
+ * @{
+ */
+#define XLLDMA_SR_IRQ_ON_END_MASK   0x00000040 /**< IRQ on end has occurred */
+#define XLLDMA_SR_STOP_ON_END_MASK  0x00000020 /**< Stop on end has occurred */
+#define XLLDMA_SR_COMPLETED_MASK    0x00000010 /**< BD completed */
+#define XLLDMA_SR_SOP_MASK          0x00000008 /**< Current BD has SOP set */
+#define XLLDMA_SR_EOP_MASK          0x00000004 /**< Current BD has EOP set */
+#define XLLDMA_SR_ENGINE_BUSY_MASK  0x00000002 /**< Channel is busy */
+/*@}*/
+
+
+/** @name Bitmasks associated with XLLDMA_DMACR_OFFSET register
+ * @{
+ */
+#define XLLDMA_DMACR_TX_PAUSE_MASK             0x20000000 /**< Pause TX channel
+                                                                  */
+#define XLLDMA_DMACR_RX_PAUSE_MASK             0x10000000 /**< Pause RX channel
+                                                                  */
+#define XLLDMA_DMACR_PLB_ERR_DIS_MASK          0x00000020 /**< Disable PLB
+                                                               error detection
+                                                                  */
+#define XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK  0x00000010 /**< Disable error
+                                                               when 2 or 4 bit
+                                                               coalesce counter
+                                                               overflows */
+#define XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK  0x00000008 /**< Disable error
+                                                               when 2 or 4 bit
+                                                               coalesce counter
+                                                               overflows */
+#define XLLDMA_DMACR_TAIL_PTR_EN_MASK          0x00000004 /**< Enable use of
+                                                               tail pointer
+                                                               register */
+#define XLLDMA_DMACR_EN_ARB_HOLD_MASK          0x00000002 /**< Enable
+                                                               arbitration
+                                                               hold */
+#define XLLDMA_DMACR_SW_RESET_MASK             0x00000001 /**< Assert Software
+                                                               reset for both
+                                                               channels */
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_BD_STSCTRL_USR0_OFFSET descriptor word
+ *  @{
+ */
+#define XLLDMA_BD_STSCTRL_ERROR_MASK      0x80000000  /**< DMA error */
+#define XLLDMA_BD_STSCTRL_IOE_MASK        0x40000000  /**< Interrupt on end */
+#define XLLDMA_BD_STSCTRL_SOE_MASK        0x20000000  /**< Stop on end */
+#define XLLDMA_BD_STSCTRL_COMPLETED_MASK  0x10000000  /**< DMA completed */
+#define XLLDMA_BD_STSCTRL_SOP_MASK        0x08000000  /**< Start of packet */
+#define XLLDMA_BD_STSCTRL_EOP_MASK        0x04000000  /**< End of packet */
+#define XLLDMA_BD_STSCTRL_BUSY_MASK       0x02000000  /**< DMA channel busy */
+
+#define XLLDMA_BD_STSCTRL_MASK            0xFF000000  /**< Status/Control field
+                                                               */
+#define XLLDMA_BD_STSCTRL_USR0_MASK       0x00FFFFFF  /**< User field #0 */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+#ifdef CONFIG_XILINX_LLDMA_USE_DCR
+
+/* DCR interface is used */
+
+#define XLlDma_In32  XIo_DcrIn
+#define XLlDma_Out32 XIo_DcrOut
+
+#else
+
+/* Non-DCR interface is used */
+
+#define XLlDma_In32  XIo_In32
+#define XLlDma_Out32 XIo_Out32
+
+#endif
+
+/*****************************************************************************/
+/**
+*
+* Read the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be read
+*
+* @return   The 32-bit value of the register
+*
+* @note
+* C-style signature:
+*    u32 XLlDma_mReadReg(u32 BaseAddress, u32 RegOffset)
+*
+******************************************************************************/
+#define XLlDma_mReadReg(BaseAddress, RegOffset)             \
+    XLlDma_In32((BaseAddress) + (RegOffset))
+
+/*****************************************************************************/
+/**
+*
+* Write the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be written
+* @param    Data is the 32-bit value to write to the register
+*
+* @return   None.
+*
+* @note
+* C-style signature:
+*    void XLlDma_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+******************************************************************************/
+#define XLlDma_mWriteReg(BaseAddress, RegOffset, Data)          \
+    XLlDma_Out32((BaseAddress) + (RegOffset), (Data))
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_userip.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xlldma_userip.h	2014-07-20 22:06:39.138259830 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2007 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_userip.h
+*
+* This file is for the User-IP core (like Local-Link TEMAC) to define constants
+* that are the User-IP core specific. DMA driver requires the constants to work
+* correctly. Two constants must be defined in this file:
+*
+*   - XLLDMA_USR_APPWORD_OFFSET:
+*
+*     This constant defines a user word the User-IP always updates in the RX
+*     Buffer Descriptors (BD) during any Receive transaction.
+*
+*     The DMA driver initializes this chosen user word of any RX BD to the
+*     pre-defined value (see XLLDMA_USR_APPWORD_INITVALUE below) before
+*     giving it to the RX channel. The DMA relies on its updation (by the
+*     User-IP) to ensure the BD has been completed by the RX channel besides
+*     checking the COMPLETE bit in XLLDMA_BD_STSCTRL_USR0_OFFSET field (see
+*     xlldma_hw.h).
+*
+*     The only valid options for this constant are XLLDMA_BD_USR1_OFFSET,
+*     XLLDMA_BD_USR2_OFFSET, XLLDMA_BD_USR3_OFFSET and XLLDMA_BD_USR4_OFFSET.
+*
+*     If the User-IP does not update any of the option fields above, the DMA
+*     driver will not work properly.
+*
+*   - XLLDMA_USR_APPWORD_INITVALUE:
+*
+*     This constant defines the value the DMA driver uses to populate the
+*     XLLDMA_USR_APPWORD_OFFSET field (see above) in any RX BD before giving
+*     the BD to the RX channel for receive transaction.
+*
+*     It must be ensured that the User-IP will always populates a different
+*     value from this constant into the XLLDMA_USR_APPWORD_OFFSET field at
+*     the end of any receive transaction. Failing to do so will cause the
+*     DMA driver to work improperly.
+*
+* If the User-IP uses different setting, the correct setting must be defined as
+* a compiler options used in the Makefile. In either case the default
+* definition of the constants in this file will be discarded.
+*
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   02/21/07 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_USERIP_H		/* prevent circular inclusions */
+#define XLLDMA_USERIP_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xlldma_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+#ifndef XLLDMA_USERIP_APPWORD_OFFSET
+#define XLLDMA_USERIP_APPWORD_OFFSET    XLLDMA_BD_USR4_OFFSET
+#endif
+
+#ifndef XLLDMA_USERIP_APPWORD_INITVALUE
+#define XLLDMA_USERIP_APPWORD_INITVALUE 0xFFFFFFFF
+#endif
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo.c	2014-07-20 22:06:39.148259665 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file llfifo.c
+ *
+ * The Xilinx local link FIFO driver component. This driver supports the
+ * Xilinx xps_ll_fifo core.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  10/13/06 First release
+ * </pre>
+ ******************************************************************************/
+
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xllfifo_hw.h"
+#include "xllfifo.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+#define FIFO_WIDTH_BYTES 4
+
+/*
+ * Implementation Notes:
+ *
+ * This Fifo driver makes use of a byte streamer driver (xstreamer.h). The code
+ * is structured like so:
+ *
+ * +--------------------+
+ * |     llfifo         |
+ * |   +----------------+
+ * |   | +--------------+
+ * |   | |  xstreamer   |
+ * |   | +--------------+
+ * |   +----------------+
+ * |                    |
+ * +--------------------+
+ *
+ * Initialization
+ * At initialization time this driver (llfifo) sets up the streamer objects to
+ * use routines in this driver (llfifo) to perform the actual I/O to the H/W
+ * FIFO core.
+ *
+ * Operation
+ * Once the streamer objects are set up, the API routines in this driver, just
+ * call through to the streamer driver to perform the read/write operations.
+ * The streamer driver will eventually make calls back into the routines (which
+ * reside in this driver) given at initialization to peform the actual I/O.
+ *
+ * Interrupts
+ * Interrupts are handled in the OS/Application layer above this driver.
+ */
+
+xdbg_stmnt(u32 _xllfifo_rr_value;)
+xdbg_stmnt(u32 _xllfifo_ipie_value;)
+xdbg_stmnt(u32 _xllfifo_ipis_value;)
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_RxGetWord reads one 32 bit word from the FIFO specified by
+* <i>InstancePtr</i>.
+*
+* XLlFifo_RxGetLen or XLlFifo_iRxGetLen must be called before calling
+* XLlFifo_RxGetWord. Otherwise, the hardware will raise an <i>Over Read
+* Exception</i>.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_RxGetWord returns the 32 bit word read from the FIFO.
+*
+* @note
+* C-style signature:
+*    u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_RxGetWord(InstancePtr) \
+	XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDFD_OFFSET)
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_TxPutWord writes the 32 bit word, <i>Word</i> to the FIFO specified by
+* <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word)
+*
+*****************************************************************************/
+#define XLlFifo_TxPutWord(InstancePtr, Word) \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFD_OFFSET, \
+			(Word))
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRxOccupancy returns the number of 32-bit words available (occupancy)
+* to be read from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_iRxOccupancy returns the occupancy count in 32-bit words for
+*           the specified FIFO.
+*
+******************************************************************************/
+static u32 XLlFifo_iRxOccupancy(XLlFifo *InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr);
+
+	return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+			XLLF_RDFO_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRxGetLen notifies the hardware that the program is ready to receive the
+* next frame from the receive channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* Note that the program must first call XLlFifo_iRxGetLen before pulling data
+* out of the receive channel of the FIFO with XLlFifo_Read.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_iRxGetLen returns the number of bytes available in the next
+*           frame.
+*
+******************************************************************************/
+static u32 XLlFifo_iRxGetLen(XLlFifo *InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr);
+
+	return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+		XLLF_RLF_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRead_Aligned reads, <i>WordCount</i>, words from the FIFO referenced by
+* <i>InstancePtr</i> to the block of memory, referenced by <i>BufPtr</i>.
+*
+* XLlFifo_iRead_Aligned assumes that <i>BufPtr</i> is already aligned according
+* to the following hardware limitations:
+*    ppc        - aligned on 32 bit boundaries to avoid performance penalties
+*                 from unaligned exception handling.
+*    microblaze - aligned on 32 bit boundaries as microblaze does not handle
+*                 unaligned transfers.
+*
+* Care must be taken to ensure that the number of words read with one or more
+* calls to XLlFifo_Read() does not exceed the number of bytes (rounded up to
+* the nearest whole 32 bit word) available given from the last call to
+* XLlFifo_RxGetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address to place the data read.
+*
+* @param    WordCount specifies the number of 32 bit words to read.
+*
+* @return   XLlFifo_iRead_Aligned always returns XST_SUCCESS. Error handling is
+*           otherwise handled through hardware exceptions and interrupts.
+*
+* @note
+*
+* C Signature: int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr,
+*                      void *BufPtr, unsigned WordCount);
+*
+******************************************************************************/
+/* static */ int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr, void *BufPtr,
+			     unsigned WordCount)
+{
+	unsigned WordsRemaining = WordCount;
+	u32 *BufPtrIdx = BufPtr;
+
+	xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: start\n");
+	XASSERT_NONVOID(InstancePtr);
+	XASSERT_NONVOID(BufPtr);
+	/* assert bufer is 32 bit aligned */
+	XASSERT_NONVOID(((unsigned)BufPtr & 0x3) == 0x0);
+	xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: after asserts\n");
+
+	while (WordsRemaining) {
+/*		xdbg_printf(XDBG_DEBUG_FIFO_RX,
+			    "XLlFifo_iRead_Aligned: WordsRemaining: %d\n",
+			    WordsRemaining);
+*/
+		*BufPtrIdx = XLlFifo_RxGetWord(InstancePtr);
+		BufPtrIdx++;
+		WordsRemaining--;
+	}
+	xdbg_printf(XDBG_DEBUG_FIFO_RX,
+		    "XLlFifo_iRead_Aligned: returning SUCCESS\n");
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_iTxVacancy returns the number of unused 32 bit words available
+* (vacancy) in the send channel of the FIFO, specified by <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_iTxVacancy returns the vacancy count in 32-bit words for
+*           the specified FIFO.
+*
+*****************************************************************************/
+static u32 XLlFifo_iTxVacancy(XLlFifo *InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr);
+
+	return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+			XLLF_TDFV_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iTxSetLen begins a hardware transfer of data out of the transmit
+* channel of the FIFO, specified by <i>InstancePtr</i>. <i>Bytes</i> specifies the number
+* of bytes in the frame to transmit.
+*
+* Note that <i>Bytes</i> (rounded up to the nearest whole 32 bit word) must be same
+* number of words just written using one or more calls to
+* XLlFifo_iWrite_Aligned()
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    Bytes specifies the number of bytes to transmit.
+*
+* @return   N/A
+*
+******************************************************************************/
+static void XLlFifo_iTxSetLen(XLlFifo *InstancePtr, u32 Bytes)
+{
+	XASSERT_VOID(InstancePtr);
+
+	XLlFifo_WriteReg(InstancePtr->BaseAddress, XLLF_TLF_OFFSET,
+			Bytes);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iWrite_Aligned writes, <i>WordCount</i>, words to the FIFO referenced by
+* <i>InstancePtr</i> from the block of memory, referenced by <i>BufPtr</i>.
+*
+* XLlFifo_iWrite_Aligned assumes that <i>BufPtr</i> is already aligned according
+* to the following hardware limitations:
+*    ppc        - aligned on 32 bit boundaries to avoid performance penalties
+*                 from unaligned exception handling.
+*    microblaze - aligned on 32 bit boundaries as microblaze does not handle
+*                 unaligned transfers.
+*
+* Care must be taken to ensure that the number of words written with one or
+* more calls to XLlFifo_iWrite_Aligned() matches the number of bytes (rounded up
+* to the nearest whole 32 bit word) given in the next call to
+* XLlFifo_iTxSetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address to place the data read.
+*
+* @param    WordCount specifies the number of 32 bit words to read.
+*
+* @return   XLlFifo_iWrite_Aligned always returns XST_SUCCESS. Error handling is
+*           otherwise handled through hardware exceptions and interrupts.
+*
+* @note
+*
+* C Signature: int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr,
+*                      void *BufPtr, unsigned WordCount);
+*
+******************************************************************************/
+/* static */ int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr, void *BufPtr,
+			      unsigned WordCount)
+{
+	unsigned WordsRemaining = WordCount;
+	u32 *BufPtrIdx = BufPtr;
+
+	xdbg_printf(XDBG_DEBUG_FIFO_TX,
+		    "XLlFifo_iWrite_Aligned: Inst: %p; Buff: %p; Count: %d\n",
+		    InstancePtr, BufPtr, WordCount);
+	XASSERT_NONVOID(InstancePtr);
+	XASSERT_NONVOID(BufPtr);
+	/* assert bufer is 32 bit aligned */
+	XASSERT_NONVOID(((unsigned)BufPtr & 0x3) == 0x0);
+
+	xdbg_printf(XDBG_DEBUG_FIFO_TX,
+		    "XLlFifo_iWrite_Aligned: WordsRemaining: %d\n",
+		    WordsRemaining);
+	while (WordsRemaining) {
+		XLlFifo_TxPutWord(InstancePtr, *BufPtrIdx);
+		BufPtrIdx++;
+		WordsRemaining--;
+	}
+
+	xdbg_printf(XDBG_DEBUG_FIFO_TX,
+		    "XLlFifo_iWrite_Aligned: returning SUCCESS\n");
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Initialize initializes an XPS_ll_Fifo device along with the
+* <i>InstancePtr</i> that references it.
+*
+* @param    InstancePtr references the memory instance to be associated with
+*           the FIFO device upon initialization.
+*
+* @param    BaseAddress is the processor address used to access the
+*           base address of the Fifo device.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress)
+{
+	XASSERT_VOID(InstancePtr);
+	XASSERT_VOID(BaseAddress);
+
+	/* Clear instance memory */
+	memset(InstancePtr, 0, sizeof(XLlFifo));
+
+	/*
+	 * We don't care about the physical base address, just copy the
+	 * processor address over it.
+	 */
+	InstancePtr->BaseAddress = BaseAddress;
+
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	XLlFifo_TxReset(InstancePtr);
+	XLlFifo_RxReset(InstancePtr);
+
+	XStrm_RxInitialize(&(InstancePtr->RxStreamer), FIFO_WIDTH_BYTES,
+			(void *)InstancePtr,
+                        (XStrm_XferFnType)XLlFifo_iRead_Aligned,
+                        (XStrm_GetLenFnType)XLlFifo_iRxGetLen,
+                        (XStrm_GetOccupancyFnType)XLlFifo_iRxOccupancy);
+
+	XStrm_TxInitialize(&(InstancePtr->TxStreamer), FIFO_WIDTH_BYTES,
+			(void *)InstancePtr,
+                        (XStrm_XferFnType)XLlFifo_iWrite_Aligned,
+                        (XStrm_SetLenFnType)XLlFifo_iTxSetLen,
+                        (XStrm_GetVacancyFnType)XLlFifo_iTxVacancy);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo.h	2014-07-20 22:06:39.160259467 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file llfifo.h
+ *
+ * The Xilinx Dual Channel Fifo driver component. This driver supports the
+ * Virtex-5(TM) and Virtex-4(TM) XPS_ll_Fifo.
+ *
+ * For a full description of the bridge features, please see the HW spec. This driver
+ * supports the following features:
+ *   - Memory mapped access to host interface registers
+ *   - API for polled frame transfers
+ *   - API for interrupt driven frame transfers
+ *   - Virtual memory support
+ *   - Full duplex operation
+ *
+ * <h2>Driver Description</h2>
+ *
+ * This driver enables higher layer software to access the XPS_llFifo core
+ * using any alignment in the data buffers.
+ *
+ * This driver supports send and receive channels in the same instance
+ * structure in the same fashion as the hardware core.
+ *
+ * <h2>Initialization</h2>
+ *
+ * An instance of this driver is initialized using a call to Initialize().
+ *
+ * <h2>Usage</h2>
+ *
+ * It is fairly simple to use the API provided by this FIFO driver. The
+ * only somewhat tricky part is that the calling code must correctly call
+ * a couple routines in the right sequence for receive and transmit.
+ *
+ * This sequence is described here. Check the routine functional
+ * descriptions for information on how to use a specific API routine.
+ *
+ * <h3>Receive</h3>
+ *
+ * A frame is received by using the following sequence:<br>
+ * 1) call XLlFifo_RxGetLen() to get the length of the next incoming frame<br>
+ * 2) call XLlFifo_Read() one or more times to read the number of bytes
+ *    reported by XLlFifo_RxGetLen().<br>
+ *
+ * For example:
+ * <pre>
+ * 	frame_len = XLlFifo_RxGetLen(&RxInstance);
+ * 	while (frame_len) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_len);
+ * 		XLlFifo_Read(&RxInstance, buffer, bytes);
+ * 		// ********
+ * 		// do something with buffer here
+ * 		// ********
+ * 		frame_len -= bytes;
+ * 	}
+ * </pre>
+ *
+ * This FIFO hardware core does <b>not</b> support a sequence where the
+ * calling code calls RxGetLen() twice in a row and then receive the data
+ * for two frames. Each frame must be read in by calling RxGetLen() just
+ * prior to reading the data.
+ *
+ * <h3>Transmit</h3>
+ * A frame is transmittted by using the following sequence:<br>
+ * 1) call XLlFifo_Write() one or more times to write all the of bytes in
+ *    the next frame.<br>
+ * 2) call XLlFifo_TxSetLen() to begin the transmission of frame just
+ *    written.<br>
+ *
+ * For example:
+ * <pre>
+ * 	frame_left = frame_len;
+ * 	while (frame_left) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_left);
+ * 		XLlFifo_Write(&TxInstance, buffer, bytes);
+ * 		// ********
+ * 		// do something here to refill buffer
+ * 		// ********
+ * 	}
+ * 	XLlFifo_TxSetLen(&RxInstance, frame_len);
+ * </pre>
+ *
+ * This FIFO hardware core does <b>not</b> support a sequence where the
+ * calling code writes the data for two frames and then calls TxSetLen()
+ * twice in a row. Each frame must be written by writting the data for one
+ * frame and then calling TxSetLen().
+ *
+ * <h2>Interrupts</h2>
+ * This driver does not handle interrupts from the FIFO hardware. The
+ * software layer above may make use of the interrupts by setting up its
+ * own handlers for the interrupts.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  10/12/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+#ifndef XLLFIFO_H		/* prevent circular inclusions */
+#define XLLFIFO_H		/* by using preprocessor symbols */
+
+/* force C linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xllfifo_hw.h"
+#include "xstreamer.h"
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * This typedef defines a run-time instance of an XLlFifo device.
+ */
+typedef struct XLlFifo {
+	u32 BaseAddress;  /**< BaseAddress is the physical base address of the
+	                   *   device's registers
+	                   */
+
+	u32 IsReady;           /**< IsReady is non-zero if the driver instance
+	                        *   has been initialized.
+	                        */
+	XStrm_RxFifoStreamer RxStreamer; /**< RxStreamer is the byte streamer
+	                                  *   instance for the receive channel.
+	                                  */
+	XStrm_TxFifoStreamer TxStreamer; /**< TxStreamer is the byte streamer
+	                                  *   instance for the transmit channel.
+	                                  */
+} XLlFifo;
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_Reset resets both the Tx and Rx channels and the local link interface
+* the FIFO specified by <i>InstancePtr</i>. XLlFifo_TxReset resets also sends a
+* reset pulse to the downstream device (e.g. TEMAC). XLlFifo_Reset drops any
+* bytes in the FIFO not yet retrieved. XLlFifo_Reset drops any bytes in the FIFO
+* not yet transmitted.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_Reset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_Reset(InstancePtr) \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, \
+			XLLF_LLR_RESET_MASK)
+
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_Status returns a bit mask of the interrupt status register (ISR)
+* for the FIFO specified by <i>InstancePtr</i>. XLlFifo_Status can be used
+* to query the status of the FIFO without having to have interrupts enabled.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_IntStatus returns a bit mask of the status conditions.
+*           The mask will be a set of bitwise or'd values from the
+*           <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    u32 XLlFifo_IntStatus(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_Status(InstancePtr) \
+	 XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntEnable enables the interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding interrupt for each bit
+* set to 1 in <i>Mask</i>, will be enabled.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    Mask contains a bit mask of the interrupts to enable. The mask
+*           can be formed using a set of bitwise or'd values from the
+*           <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_IntEnable(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntEnable(InstancePtr, Mask) \
+{ \
+	u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+			XLLF_IER_OFFSET); \
+	Reg |= ((Mask) & XLLF_INT_ALL_MASK);                    \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \
+			Reg); \
+}
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntDisable disables the interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding interrupt for each bit
+* set to 1 in <i>Mask</i>, will be disabled. In other words, XLlFifo_IntDisable
+* uses the "set a bit to clear it" scheme.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    Mask contains a bit mask of the interrupts to disable. The mask
+*           can be formed using a set of bitwise or'd values from the
+*           <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_IntDisable(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntDisable(InstancePtr, Mask) \
+{ \
+	u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+			XLLF_IER_OFFSET); \
+	Reg &= ~((Mask) & XLLF_INT_ALL_MASK);  \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \
+			Reg); \
+}
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntPending returns a bit mask of the pending interrupts for the
+* FIFO specified by <i>InstancePtr</i>. Each bit set to 1 in the return value
+* represents a pending interrupt.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_IntPending returns a bit mask of the interrupts that are
+*           pending. The mask will be a set of bitwise or'd values from the
+*           <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    u32 XLlFifo_IntPending(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#ifdef DEBUG
+extern u32 _xllfifo_ipie_value;
+extern u32 _xllfifo_ipis_value;
+#define XLlFifo_IntPending(InstancePtr) \
+	(_xllfifo_ipie_value = XLlFifo_ReadReg( \
+		(InstancePtr)->BaseAddress, XLLF_IER_OFFSET),  \
+	_xllfifo_ipis_value = XLlFifo_ReadReg( \
+		(InstancePtr)->BaseAddress, XLLF_ISR_OFFSET),  \
+	(_xllfifo_ipie_value & _xllfifo_ipis_value))
+#else
+#define XLlFifo_IntPending(InstancePtr) \
+	(XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET) &  \
+	 XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET))
+#endif
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntClear clears pending interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding pending interrupt for
+* each bit set to 1 in <i>Mask</i>, will be cleared. In other words,
+* XLlFifo_IntClear uses the "set a bit to clear it" scheme.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    Mask contains a bit mask of the pending interrupts to clear. The
+*           mask can be formed using a set of bitwise or'd values from the
+*           <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+*    void XLlFifo_IntClear(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntClear(InstancePtr, Mask) \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET, \
+			((Mask) & XLLF_INT_ALL_MASK))
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_RxReset resets the receive channel of the FIFO specified by
+* <i>InstancePtr</i>. XLlFifo_RxReset drops any bytes in the FIFO not yet
+* retrieved.
+*
+* The calling software may want to test for the completion of the reset by
+* reading the interrupt status (IS) register and testing for the Rx Reset
+* complete (RRC) bit.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_RxReset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_RxReset(InstancePtr) \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_RDFR_OFFSET, \
+			XLLF_RDFR_RESET_MASK)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IsRxEmpty returns true if the receive channel of the FIFO, specified
+* by <i>InstancePtr</i>, is empty.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_IsRxEmpty returns TRUE when the receive channel of the
+*           FIFO is empty. Otherwise, XLlFifo_IsRxEmpty returns FALSE.
+*
+* @note
+* C-style signature:
+*    int XLlFifo_IsRxEmpty(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_IsRxEmpty(InstancePtr) \
+	((XStrm_IsRxInternalEmpty(&((InstancePtr)->RxStreamer)) && \
+	((XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+			XLLF_RDFO_OFFSET) == 0))) \
+			? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_RxOccupancy returns the number of 32-bit words available (occupancy) to
+* be read from the receive channel of the FIFO, specified by <i>InstancePtr</i>.
+*
+* The xps_ll_fifo core uses the same fifo to store data values and frame length
+* values. Upon initialization, the XLlFifo_RxOccupancy will give the value of
+* 1, which means one length value (a reserved fifo location) and no data
+* values.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_RxOccupancy returns the occupancy count for the specified
+*           packet FIFO.
+*
+* @note
+*
+* C Signature: u32 XLlFifo_RxOccupancy(XLlFifo *InstancePtr)
+*
+******************************************************************************/
+#define XLlFifo_RxOccupancy(InstancePtr) \
+	XStrm_RxOccupancy(&((InstancePtr)->RxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_RxGetLen notifies the hardware that the program is ready to receive
+* the next frame from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* Note that the program must first call XLlFifo_RxGetLen before pulling data
+* out of the receive channel of the FIFO with XLlFifo_Read.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_RxGetLen returns the number of bytes available in the next
+*           frame.
+*
+* @note
+*
+* C Signature: u32 XLlFifo_RxGetLen(XLlFifo *InstancePtr)
+*
+******************************************************************************/
+#define XLlFifo_RxGetLen(InstancePtr) \
+	XStrm_RxGetLen(&((InstancePtr)->RxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Read reads <i>Bytes</i> bytes from the receive channel of the FIFO
+* referenced by <i>InstancePtr</i> to the block of memory, referenced by
+* <i>BufPtr</i>.
+*
+* Care must be taken to ensure that the number of bytes read with one or more
+* calls to XLlFifo_Read() does not exceed the number of bytes available given
+* from the last call to XLlFifo_RxGetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address to place the data read.
+*
+* @param    Bytes specifies the number of bytes to read.
+*
+* @return   N/A
+*
+* @note
+* Error handling is handled through hardware exceptions and interrupts.
+*
+* C Signature: void XLlFifo_Read(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes)
+*
+******************************************************************************/
+#define XLlFifo_Read(InstancePtr, BufPtr, Bytes) \
+	XStrm_Read(&((InstancePtr)->RxStreamer), (BufPtr), (Bytes))
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_TxReset resets the transmit channel of the FIFO specified by
+* <i>InstancePtr</i>. XLlFifo_TxReset drops any bytes in the FIFO not yet
+* transmitted.
+*
+* The calling software may want to test for the completion of the reset by
+* reading the interrupt status (IS) register and testing for the Tx Reset
+* complete (TRC) bit.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_TxReset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_TxReset(InstancePtr) \
+	XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFR_OFFSET, \
+			XLLF_TDFR_RESET_MASK)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IsTxDone returns true if the transmission in the transmit channel
+* of the FIFO, specified by <i>InstancePtr</i>, is complete. XLlFifo_IsTxDone
+* works only if the TC bit in the IS register is cleared before sending a
+* frame.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_IsTxDone returns TRUE when the transmit channel of the
+*           FIFO is complete. Otherwise, XLlFifo_IsTxDone returns FALSE.
+*
+* @note
+* C-style signature:
+*    int XLlFifo_IsTxDone(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_IsTxDone(InstancePtr) \
+	((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \
+		XLLF_INT_TC_MASK) \
+		? TRUE : FALSE)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_TxVacancy returns the number of unused 32 bit words available
+* (vacancy) in the send channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* The xps_ll_fifo core uses tXLLF_he same fifo to store data values and frame length
+* values. Upon initialization, the XLlFifo_TxVacancy will give the value of
+* FIFO_WIDTH - 1, which means one length value used (a reserved fifo location)
+* and no data values yet present.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XLlFifo_TxVacancy returns the vacancy count in 32-bit words for
+*           the specified FIFO.
+*
+* @note
+* C-style signature:
+*    u32 XLlFifo_TxVacancy(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_TxVacancy(InstancePtr) \
+	XStrm_TxVacancy(&((InstancePtr)->TxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_TxSetLen begins a hardware transfer of <i>Bytes</i> bytes out of the
+* transmit channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    Bytes specifies the frame length in bytes.
+*
+* @return   N/A
+*
+* @note
+*
+* C Signature: void XLlFifo_TxSetLen(XLlFifo *InstancePtr, u32 Bytes)
+*
+******************************************************************************/
+#define XLlFifo_TxSetLen(InstancePtr, Bytes) \
+	XStrm_TxSetLen(&((InstancePtr)->TxStreamer), (Bytes))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Write writes <i>Bytes</i> bytes of the block of memory, referenced by
+* <i>BufPtr</i>, to the transmit channel of the FIFO referenced by
+* <i>InstancePtr</i>.
+*
+* Care must be taken to ensure that the number of bytes written with one or
+* more calls to XLlFifo_Write() matches the number of bytes given in the next
+* call to XLlFifo_TxSetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address of data to write.
+*
+* @param    Bytes specifies the number of bytes to write.
+*
+* @return   N/A
+*
+* @note
+* Error handling is handled through hardware exceptions and interrupts.
+*
+* C Signature: void XLlFifo_Write(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes)
+*
+******************************************************************************/
+#define XLlFifo_Write(InstancePtr, BufPtr, Bytes) \
+	XStrm_Write(&((InstancePtr)->TxStreamer), (BufPtr), (Bytes))
+
+
+/************************** Function Prototypes ******************************/
+/*
+ * Initialization functions in xtemac_sinit.c
+ */
+void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress);
+
+#ifdef __cplusplus
+}
+#endif
+#endif				/* XLLFIFO_H  end of preprocessor protection symbols */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo_hw.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xllfifo_hw.h	2014-07-20 22:06:39.169259319 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2004-2006 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file llfifo_hw.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the xps_ll_fifo core.
+* High-level driver functions are defined in xpfifo.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a jvb  10/16/06 First release.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLFIFO_HW_H		/* prevent circular inclusions */
+#define XLLFIFO_HW_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xdebug.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name Registers
+ *  @{
+ */
+#define XLLF_ISR_OFFSET  0x00000000  /**< Interrupt Status */
+#define XLLF_IER_OFFSET  0x00000004 /**< Interrupt Enable */
+
+#define XLLF_TDFR_OFFSET 0x00000008  /**< Transmit Reset */
+#define XLLF_TDFV_OFFSET 0x0000000c  /**< Transmit Vacancy */
+#define XLLF_TDFD_OFFSET 0x00000010  /**< Transmit Data */
+#define XLLF_TLF_OFFSET  0x00000014  /**< Transmit Length */
+
+#define XLLF_RDFR_OFFSET 0x00000018  /**< Receive Reset */
+#define XLLF_RDFO_OFFSET 0x0000001c  /**< Receive Occupancy */
+#define XLLF_RDFD_OFFSET 0x00000020  /**< Receive Data */
+#define XLLF_RLF_OFFSET  0x00000024  /**< Receive Length */
+#define XLLF_LLR_OFFSET  0x00000028  /**< Local Link Reset */
+
+/*@}*/
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+/** @name Interrupt bits
+ *  These bits are associated with the XLLF_IER_OFFSET and XLLF_ISR_OFFSET
+ *  registers.
+ * @{
+ */
+#define XLLF_INT_RPURE_MASK       0x80000000 /**< Receive under-read */
+#define XLLF_INT_RPORE_MASK       0x40000000 /**< Receive over-read */
+#define XLLF_INT_RPUE_MASK        0x20000000 /**< Receive underrun (empty) */
+#define XLLF_INT_TPOE_MASK        0x10000000 /**< Transmit overrun */
+#define XLLF_INT_TC_MASK          0x08000000 /**< Transmit complete */
+#define XLLF_INT_RC_MASK          0x04000000 /**< Receive complete */
+#define XLLF_INT_TSE_MASK         0x02000000 /**< Transmit length mismatch */
+#define XLLF_INT_TRC_MASK         0x01000000 /**< Transmit reset complete */
+#define XLLF_INT_RRC_MASK         0x00800000 /**< Receive reset complete */
+#define XLLF_INT_ALL_MASK         0xff800000 /**< All the ints */
+#define XLLF_INT_ERROR_MASK       0xf2000000 /**< Error status ints */
+#define XLLF_INT_RXERROR_MASK     0xe0000000 /**< Receive Error status ints */
+#define XLLF_INT_TXERROR_MASK     0x12000000 /**< Transmit Error status ints */
+/*@}*/
+
+/** @name Reset register values
+ *  These bits are associated with the XLLF_TDFR_OFFSET and XLLF_RDFR_OFFSET
+ *  reset registers.
+ * @{
+ */
+#define XLLF_RDFR_RESET_MASK        0x000000a5 /**< receive reset value */
+#define XLLF_TDFR_RESET_MASK        0x000000a5 /**< Transmit reset value */
+#define XLLF_LLR_RESET_MASK        0x000000a5 /**< Local Link reset value */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/**** debug macros ****/
+#define XLlFifo_reg_name(RegOffset) \
+	(((RegOffset) == XLLF_ISR_OFFSET) ? "ISR": \
+	((RegOffset) == XLLF_IER_OFFSET) ? "IER": \
+	((RegOffset) == XLLF_TDFR_OFFSET) ? "TDFR {tx reset}": \
+	((RegOffset) == XLLF_TDFV_OFFSET) ? "TDFV {tx vacancy}": \
+	((RegOffset) == XLLF_TDFD_OFFSET) ? "TDFD {tx data}": \
+	((RegOffset) == XLLF_TLF_OFFSET) ? "TLF {tx length}": \
+	((RegOffset) == XLLF_RDFR_OFFSET) ? "RDFR {rx reset}": \
+	((RegOffset) == XLLF_RDFO_OFFSET) ? "RDFO {rx occupancy}": \
+	((RegOffset) == XLLF_RDFD_OFFSET) ? "RDFD {rx data}": \
+	((RegOffset) == XLLF_RLF_OFFSET) ? "RLF {rx length}": \
+	"unknown")
+
+#define XLlFifo_print_reg_o(BaseAddress, RegOffset, Value) \
+	 xdbg_printf(XDBG_DEBUG_FIFO_REG, "0x%08x -> %s(0x%08x)\n", (Value), \
+			  XLlFifo_reg_name(RegOffset), \
+			 (RegOffset) + (BaseAddress))
+
+#define XLlFifo_print_reg_i(BaseAddress, RegOffset, Value) \
+	xdbg_printf(XDBG_DEBUG_FIFO_REG, "%s(0x%08x) -> 0x%08x\n", \
+			 XLlFifo_reg_name(RegOffset), \
+			(RegOffset) + (BaseAddress), (Value))
+/**** end debug macros ****/
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_ReadReg returns the value of the register at the offet,
+* <i>RegOffset</i>, from the memory mapped base address, <i>BaseAddress</i>.
+*
+* @param    BaseAddress specifies the base address of the device.
+*
+* @param    RegOffset specifies the offset from BaseAddress.
+*
+* @return   XLlFifo_ReadReg returns the value of the specified register.
+*
+* @note
+* C-style signature:
+*    u32 XLlFifo_ReadReg(u32 BaseAddress, u32 RegOffset)
+*
+*****************************************************************************/
+#ifdef DEBUG
+extern u32 _xllfifo_rr_value;
+#define XLlFifo_ReadReg(BaseAddress, RegOffset) \
+	((((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \
+		"XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \
+		(RegOffset)) : 0), \
+	_xllfifo_rr_value = XIo_In32((BaseAddress) + (RegOffset)), \
+	XLlFifo_print_reg_i((BaseAddress), (RegOffset), _xllfifo_rr_value), \
+	_xllfifo_rr_value)
+#else
+#define XLlFifo_ReadReg(BaseAddress, RegOffset) \
+	(XIo_In32((BaseAddress) + (RegOffset)))
+#endif
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_WriteReg writes the value, <i>Value</i>, to the register at the
+* offet, <i>RegOffset</i>, from the memory mapped base address,
+* <i>BaseAddress</i>.
+*
+* @param    BaseAddress specifies the base address of the device.
+*
+* @param    RegOffset specifies the offset from BaseAddress.
+*
+* @param    Value is value to write to the register.
+*
+* @return   N/A
+*
+* @note
+* C-style signature:
+*    void XLlFifo_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Value)
+*
+*****************************************************************************/
+#ifdef DEBUG
+#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \
+	(((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \
+		"XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \
+		(RegOffset)) : 0), \
+	XLlFifo_print_reg_o((BaseAddress), (RegOffset), (Value)), \
+	(XIo_Out32((BaseAddress) + (RegOffset), (Value)))
+#else
+#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \
+	((XIo_Out32((BaseAddress) + (RegOffset), (Value))))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif				/* XLLFIFO_HW_H  end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c	2014-07-20 22:06:39.184259072 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xpacket_fifo_l_v2_00_a.c,v 1.1 2006/12/13 14:22:53 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2003-2004 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xpacket_fifo_l_v2_00_a.c
+*
+* Contains low-level (Level 0) functions for the XPacketFifoV200a driver.
+* See xpacket_fifo_v2_00_a.h for information about the high-level (Level 1)
+* driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 2.00a rpm  10/22/03  First release. Moved most of Level 1 driver functions
+*                      into this layer.
+* 2.00a rmm  02/24/04  Added L0WriteDRE function.
+* 2.00a xd   10/27/04  Changed comments to support doxygen for API
+*                      documentation.
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xpacket_fifo_l_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************* Variable Definitions ******************************/
+
+
+/************************** Function Prototypes ******************************/
+
+static int Write32(u32 RegBaseAddress, u32 DataBaseAddress,
+		   u8 *BufferPtr, u32 ByteCount);
+
+static int Write64(u32 RegBaseAddress, u32 DataBaseAddress,
+		   u8 *BufferPtr, u32 ByteCount);
+
+static int Read32(u32 RegBaseAddress, u32 DataBaseAddress,
+		  u8 *BufferPtr, u32 ByteCount);
+
+static int Read64(u32 RegBaseAddress, u32 DataBaseAddress,
+		  u8 *BufferPtr, u32 ByteCount);
+
+
+/*****************************************************************************/
+/**
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
+* currently 32 or 64 bits wide such that an input buffer which is a series of
+* bytes is filled from the FIFO a word at a time. If the requested byte count
+* is not a multiple of 32/64 bit words, it is necessary for this function to
+* format the remaining 32/64 bit word from the FIFO into a series of bytes in
+* the buffer. There may be up to 3/7 extra bytes which must be extracted from
+* the last word of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+*
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+* <br><br>
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 32/64 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 3/7 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 32/64 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+int XPacketFifoV200a_L0Read(u32 RegBaseAddress, u32 DataBaseAddress,
+			    u8 *BufferPtr, u32 ByteCount)
+{
+	u32 Width;
+	int Result = XST_FIFO_ERROR;
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_FIFO_WIDTH_MASK;
+
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		Result = Read32(RegBaseAddress, DataBaseAddress, BufferPtr,
+				ByteCount);
+	}
+	else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		Result = Read64(RegBaseAddress, DataBaseAddress, BufferPtr,
+				ByteCount);
+	}
+
+	return Result;
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data into a packet FIFO. The packet FIFO is currently 32 or 64 bits
+* wide such that an input buffer which is a series of bytes must be written
+* into the FIFO a word at a time. If the buffer is not a multiple of 32 bit
+* words, it is necessary for this function to format the remaining bytes into
+* a single 32 bit word to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+*
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+int XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+			     u32 DataBaseAddress, u8 *BufferPtr, u32 ByteCount)
+{
+	u32 Width;
+	int Result = XST_FIFO_ERROR;
+
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_FIFO_WIDTH_MASK;
+
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		Result = Write32(RegBaseAddress, DataBaseAddress, BufferPtr,
+				 ByteCount);
+	}
+	else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		Result = Write64(RegBaseAddress, DataBaseAddress, BufferPtr,
+				 ByteCount);
+	}
+
+	return Result;
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data into a packet FIFO configured for the Data Realignment Engine
+* (DRE). A packet FIFO channel configured in this way will accept any
+* combination of byte, half-word, or word writes. The DRE will shift the data
+* into the correct byte lane.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. There are no alignment
+*        restrictions.
+*
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+int XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+				u32 DataBaseAddress,
+				u8 *BufferPtr, u32 ByteCount)
+{
+	u32 FifoRoomLeft;
+	u32 BytesLeft;
+	u32 Width;
+
+	/* calculate how many slots are left in the FIFO
+	 */
+	FifoRoomLeft =
+		XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET)
+		& XPF_V200A_COUNT_MASK;
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_FIFO_WIDTH_MASK;
+
+	/* from the width, determine how many bytes can be written to the FIFO
+	 */
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		FifoRoomLeft *= 4;
+	}
+	else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		FifoRoomLeft *= 8;
+	}
+
+	/* Make sure there's enough room in the FIFO */
+	if (FifoRoomLeft < ByteCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* Determine the number of bytes to write until 32 bit alignment is
+	 * reached, then write those bytes to the FIFO one byte at a time
+	 */
+	BytesLeft = (unsigned) BufferPtr % sizeof(u32);
+	ByteCount -= BytesLeft;
+	while (BytesLeft--) {
+		XIo_Out8(DataBaseAddress, *BufferPtr++);
+	}
+
+	/* Write as many 32 bit words as we can */
+	BytesLeft = ByteCount;
+	while (BytesLeft >= sizeof(u32)) {
+		XIo_Out32(DataBaseAddress, *(u32 *) BufferPtr);
+		BufferPtr += sizeof(u32);
+		BytesLeft -= sizeof(u32);
+	}
+
+	/* Write remaining bytes */
+	while (BytesLeft--) {
+		XIo_Out8(DataBaseAddress, *BufferPtr++);
+	}
+
+	return XST_SUCCESS;
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO
+* is 32 bits wide such that an input buffer which is a series of bytes is
+* filled from the FIFO a word at a time. If the requested byte count is not
+* a multiple of 32 bit words, it is necessary for this function to format the
+* remaining 32 bit word from the FIFO into a series of bytes in the buffer.
+* There may be up to 3 extra bytes which must be extracted from the last word
+* of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+*
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+* <br><br>
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 32 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 3 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 32 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+static int Read32(u32 RegBaseAddress, u32 DataBaseAddress,
+		  u8 *BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many 32 bit words are in the FIFO, if there
+	 * aren't enough words to satisfy the request, return an error
+	 */
+
+	FifoCount =
+		XIo_In32(RegBaseAddress +
+			 XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_COUNT_MASK;
+
+	if ((FifoCount * XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+		return XST_PFIFO_LACK_OF_DATA;
+	}
+
+	/* calculate the number of words to read from the FIFO before the word
+	 * containing the extra bytes, and calculate the number of extra bytes
+	 * the extra bytes are defined as those at the end of the buffer when
+	 * the buffer does not end on a 32 bit boundary
+	 */
+	WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* Read the 32 bit words from the FIFO for all the buffer except the
+	 * last word which contains the extra bytes, the following code assumes
+	 * that the buffer is 32 bit aligned, otherwise an alignment exception
+	 * could be generated
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		WordBuffer[FifoCount] = XIo_In32(DataBaseAddress);
+	}
+
+	/* if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* get the last word from the FIFO for the extra bytes */
+
+		LastWord = XIo_In32(DataBaseAddress);
+
+		/* one extra byte in the last word, put the byte into the next
+		 * location of the buffer, bytes in a word of the FIFO are ordered
+		 * from most significant byte to least
+		 */
+		WordPtr = (u8 *) &LastWord;
+		if (ExtraByteCount == 1) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+		}
+
+		/* two extra bytes in the last word, put each byte into the next
+		 * two locations of the buffer
+		 */
+		else if (ExtraByteCount == 2) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+			ExtraBytesBuffer[1] = WordPtr[1];
+		}
+		/* three extra bytes in the last word, put each byte into the next
+		 * three locations of the buffer
+		 */
+		else if (ExtraByteCount == 3) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+			ExtraBytesBuffer[1] = WordPtr[1];
+			ExtraBytesBuffer[2] = WordPtr[2];
+		}
+	}
+
+	return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO
+* is 64 bits wide such that an input buffer which is a series of bytes is
+* filled from the FIFO a word at a time. If the requested byte count is not
+* a multiple of 64 bit words, it is necessary for this function to format the
+* remaining 64 bit word from the FIFO into a series of bytes in the buffer.
+* There may be up to 7 extra bytes which must be extracted from the last word
+* of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+*
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+* <br><br>
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 64 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 7 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 64 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+static int Read64(u32 RegBaseAddress, u32 DataBaseAddress,
+		  u8 *BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many 64 bit words are in the FIFO, if there
+	 * aren't enough words to satisfy the request, return an error
+	 */
+
+	FifoCount =
+		XIo_In32(RegBaseAddress +
+			 XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_COUNT_MASK;
+
+	if ((FifoCount * XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+		return XST_PFIFO_LACK_OF_DATA;
+	}
+
+	/* calculate the number of words to read from the FIFO before the word
+	 * containing the extra bytes, and calculate the number of extra bytes
+	 * the extra bytes are defined as those at the end of the buffer when
+	 * the buffer does not end on a 32 bit boundary
+	 */
+	WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* Read the 64 bit words from the FIFO for all the buffer except the
+	 * last word which contains the extra bytes, the following code assumes
+	 * that the buffer is 32 bit aligned, otherwise an alignment exception
+	 * could be generated. The MSWord must be read first followed by the
+	 * LSWord
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		WordBuffer[(FifoCount * 2)] = XIo_In32(DataBaseAddress);
+		WordBuffer[(FifoCount * 2) + 1] = XIo_In32(DataBaseAddress + 4);
+	}
+
+	/* if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (ExtraByteCount > 0) {
+		u32 MSLastWord;
+		u32 LSLastWord;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+		u8 Index = 0;
+
+		/* get the last word from the FIFO for the extra bytes */
+
+		MSLastWord = XIo_In32(DataBaseAddress);
+		LSLastWord = XIo_In32(DataBaseAddress + 4);
+
+		/* four or more extra bytes in the last word, put the byte into
+		 * the next location of the buffer, bytes in a word of the FIFO
+		 * are ordered from most significant byte to least
+		 */
+		WordPtr = (u8 *) &MSLastWord;
+		if (ExtraByteCount >= 4) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+			ExtraBytesBuffer[Index + 2] = WordPtr[2];
+			ExtraBytesBuffer[Index + 3] = WordPtr[3];
+			ExtraByteCount = ExtraByteCount - 4;
+			MSLastWord = LSLastWord;
+			Index = 4;
+		}
+
+		/* one extra byte in the last word, put the byte into the next
+		 * location of the buffer, bytes in a word of the FIFO are
+		 * ordered from most significant byte to least
+		 */
+		if (ExtraByteCount == 1) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+		}
+
+		/* two extra bytes in the last word, put each byte into the next
+		 * two locations of the buffer
+		 */
+		else if (ExtraByteCount == 2) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+		}
+		/* three extra bytes in the last word, put each byte into the next
+		 * three locations of the buffer
+		 */
+		else if (ExtraByteCount == 3) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+			ExtraBytesBuffer[Index + 2] = WordPtr[2];
+		}
+	}
+
+	return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Write data into a 32 bit packet FIFO. The packet FIFO is 32 bits wide in this
+* function call such that an input buffer which is a series of bytes must be
+* written into the FIFO a word at a time. If the buffer is not a multiple of
+* 32 bit words, it is necessary for this function to format the remaining bytes
+* into a single 32 bit word to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+static int Write32(u32 RegBaseAddress, u32 DataBaseAddress,
+		   u8 *BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many words may be inserted into the FIFO */
+
+	FifoCount =
+		XIo_In32(RegBaseAddress +
+			 XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_COUNT_MASK;
+
+	/* Calculate the number of 32 bit words required to insert the
+	 * specified number of bytes in the FIFO and determine the number
+	 * of extra bytes if the buffer length is not a multiple of 32 bit
+	 * words
+	 */
+
+	WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* take into account the extra bytes in the total word count */
+
+	if (ExtraByteCount > 0) {
+		WordCount++;
+	}
+
+	/* if there's not enough room in the FIFO to hold the specified
+	 * number of bytes, then indicate an error,
+	 */
+	if (FifoCount < WordCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* readjust the word count to not take into account the extra bytes */
+
+	if (ExtraByteCount > 0) {
+		WordCount--;
+	}
+
+	/* Write all the bytes of the buffer which can be written as 32 bit
+	 * words into the FIFO, waiting to handle the extra bytes separately
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		XIo_Out32(DataBaseAddress, WordBuffer[FifoCount]);
+	}
+
+	/* if there are extra bytes to handle, extract them from the buffer
+	 * and create a 32 bit word and write it to the FIFO
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord = 0;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* one extra byte in the buffer, put the byte into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		WordPtr = (u8 *) &LastWord;
+		if (ExtraByteCount == 1) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+		}
+
+		/* two extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 2) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+			WordPtr[1] = ExtraBytesBuffer[1];
+		}
+
+		/* three extra bytes in the buffer, put each byte into the last
+		 * word to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 3) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+			WordPtr[1] = ExtraBytesBuffer[1];
+			WordPtr[2] = ExtraBytesBuffer[2];
+		}
+
+		/* write the last 32 bit word to the FIFO and return with
+		 * no errors
+		 */
+
+		XIo_Out32(DataBaseAddress, LastWord);
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data into a 64 bit packet FIFO. The packet FIFO is 64 bits wide in this
+* function call such that an input buffer which is a series of bytes must be
+* written into the FIFO a word at a time. If the buffer is not a multiple of
+* 64 bit words, it is necessary for this function to format the remaining bytes
+* into two 32 bit words to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+*
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+*
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+static int Write64(u32 RegBaseAddress, u32 DataBaseAddress,
+		   u8 *BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many words may be inserted into the FIFO */
+
+	FifoCount =
+		XIo_In32(RegBaseAddress +
+			 XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+		XPF_V200A_COUNT_MASK;
+
+	/* Calculate the number of 64 bit words required to insert the
+	 * specified number of bytes in the FIFO and determine the number
+	 * of extra bytes if the buffer length is not a multiple of 64 bit
+	 * words
+	 */
+
+	WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* take into account the extra bytes in the total word count */
+
+	if (ExtraByteCount > 0) {
+		WordCount++;
+	}
+
+	/* if there's not enough room in the FIFO to hold the specified
+	 * number of bytes, then indicate an error,
+	 */
+	if (FifoCount < WordCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* readjust the word count to not take into account the extra bytes */
+
+	if (ExtraByteCount > 0) {
+		WordCount--;
+	}
+
+	/* Write all the bytes of the buffer which can be written as 32 bit
+	 * words into the FIFO, waiting to handle the extra bytes separately
+	 * The MSWord must be written first followed by the LSWord
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		XIo_Out32(DataBaseAddress, WordBuffer[(FifoCount * 2)]);
+		XIo_Out32(DataBaseAddress + 4, WordBuffer[(FifoCount * 2) + 1]);
+	}
+
+	/* if there are extra bytes to handle, extract them from the buffer
+	 * and create two 32 bit words and write to the FIFO
+	 */
+	if (ExtraByteCount > 0) {
+
+		u32 MSLastWord = 0;
+		u32 LSLastWord = 0;
+		u8 Index = 0;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+
+		/* four extra bytes in the buffer, put the bytes into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		WordPtr = (u8 *) &MSLastWord;
+
+		if (ExtraByteCount >= 4) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+			WordPtr[2] = ExtraBytesBuffer[Index + 2];
+			WordPtr[3] = ExtraBytesBuffer[Index + 3];
+			ExtraByteCount = ExtraByteCount - 4;
+			WordPtr = (u8 *) &LSLastWord;
+			Index = 4;
+		}
+
+		/* one extra byte in the buffer, put the byte into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		if (ExtraByteCount == 1) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+		}
+
+		/* two extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 2) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+		}
+
+		/* three extra bytes in the buffer, put each byte into the last
+		 * word to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 3) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+			WordPtr[2] = ExtraBytesBuffer[Index + 2];
+		}
+
+		/* write the last 64 bit word to the FIFO and return with no errors
+		 * The MSWord must be written first followed by the LSWord
+		 */
+		XIo_Out32(DataBaseAddress, MSLastWord);
+		XIo_Out32(DataBaseAddress + 4, LSLastWord);
+	}
+
+	return XST_SUCCESS;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h	2014-07-20 22:06:39.191258956 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xpacket_fifo_l_v2_00_a.h,v 1.1 2006/12/13 14:23:01 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2003-2004 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xpacket_fifo_l_v2_00_a.h
+*
+* This header file contains identifiers and low-level (Level 0) driver
+* functions (or macros) that can be used to access the FIFO.  High-level driver
+* (Level 1) functions are defined in xpacket_fifo_v2_00_a.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 2.00a rpm  10/22/03  First release. Moved most of Level 1 driver functions
+*                      into this layer.
+* 2.00a rmm  02/24/04  Added L0WriteDre function.
+* 2.00a xd   10/27/04  Changed comments to support doxygen for API
+*                      documentation.
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_L_V200A_H	/* prevent circular inclusions */
+#define XPACKET_FIFO_L_V200A_H	/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/** @name FIFO types
+ *
+ * These constants specify the FIFO type and are mutually exclusive
+ * @{
+ */
+#define XPF_V200A_READ_FIFO_TYPE      0	    /**< a read FIFO */
+#define XPF_V200A_WRITE_FIFO_TYPE     1	    /**< a write FIFO */
+/* @} */
+
+/** @name Register offsets
+ *
+ * These constants define the offsets to each of the registers from the
+ * register base address, each of the constants are a number of bytes
+ * @{
+ */
+#define XPF_V200A_RESET_REG_OFFSET            0UL /**< Reset register */
+#define XPF_V200A_MODULE_INFO_REG_OFFSET      0UL /**< MIR register */
+#define XPF_V200A_COUNT_STATUS_REG_OFFSET     4UL /**< Count/Status register */
+/* @} */
+
+/**
+ * This constant is used with the Reset Register
+ */
+#define XPF_V200A_RESET_FIFO_MASK             0x0000000A
+
+/** @name Occupancy/Vacancy Count Register constants
+ * @{
+ */
+/** Constant used with the Occupancy/Vacancy Count Register. This
+ *  register also contains FIFO status
+ */
+#define XPF_V200A_COUNT_MASK                  0x00FFFFFF
+#define XPF_V200A_DEADLOCK_MASK               0x20000000
+#define XPF_V200A_ALMOST_EMPTY_FULL_MASK      0x40000000
+#define XPF_V200A_EMPTY_FULL_MASK             0x80000000
+#define XPF_V200A_VACANCY_SCALED_MASK         0x10000000
+/* @} */
+
+/**
+ * This constant is used to mask the Width field
+ */
+#define XPF_V200A_FIFO_WIDTH_MASK             0x0E000000
+
+/** @name Width field
+ * @{
+ */
+/** Constant used with the Width field */
+#define XPF_V200A_FIFO_WIDTH_LEGACY_TYPE      0x00000000
+#define XPF_V200A_FIFO_WIDTH_8BITS_TYPE       0x02000000
+#define XPF_V200A_FIFO_WIDTH_16BITS_TYPE      0x04000000
+#define XPF_V200A_FIFO_WIDTH_32BITS_TYPE      0x06000000
+#define XPF_V200A_FIFO_WIDTH_64BITS_TYPE      0x08000000
+#define XPF_V200A_FIFO_WIDTH_128BITS_TYPE     0x0A000000
+#define XPF_V200A_FIFO_WIDTH_256BITS_TYPE     0x0C000000
+#define XPF_V200A_FIFO_WIDTH_512BITS_TYPE     0x0E000000
+/* @} */
+
+/** @name FIFO word width
+ * @{
+ */
+/** Width of a FIFO word */
+#define XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT       4
+#define XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT       8
+/* @} */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+int XPacketFifoV200a_L0Read(u32 RegBaseAddress,
+			    u32 DataBaseAddress,
+			    u8 *ReadBufferPtr, u32 ByteCount);
+
+int XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+			     u32 DataBaseAddress,
+			     u8 *WriteBufferPtr, u32 ByteCount);
+
+int XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+				u32 DataBaseAddress,
+				u8 *BufferPtr, u32 ByteCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_v2_00_a.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_v2_00_a.c	2014-07-20 22:06:39.200258808 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xpacket_fifo_v2_00_a.c,v 1.1 2006/12/13 14:23:11 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2003 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xpacket_fifo_v2_00_a.c
+*
+* Contains functions for the XPacketFifoV200a component. See
+* xpacket_fifo_v2_00_a.h for more information about the component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.00a ecm 12/30/02  First release
+* 2.00a rmm 05/14/03  Fixed diab compiler warnings
+* 2.00a rpm 10/22/03  Created and made use of Level 0 driver
+* 2.00a rmm 02/24/04  Added WriteDRE function.
+* 2.00a xd  10/27/04  Changed comments to support doxygen for API
+*                     documentation.
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xstatus.h"
+#include "xpacket_fifo_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************* Variable Definitions ******************************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/*****************************************************************************/
+/**
+*
+* This function initializes a packet FIFO.  Initialization resets the
+* FIFO such that it's empty and ready to use.
+*
+* @param    InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @param    RegBaseAddress contains the base address of the registers for
+*           the packet FIFO.
+*
+* @param    DataBaseAddress contains the base address of the data for
+*           the packet FIFO.
+*
+* @return   Always returns XST_SUCCESS.
+*
+* @note     None.
+*
+******************************************************************************/
+int XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+				u32 RegBaseAddress, u32 DataBaseAddress)
+{
+	/* assert to verify input argument are valid */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* initialize the component variables to the specified state */
+
+	InstancePtr->RegBaseAddress = RegBaseAddress;
+	InstancePtr->DataBaseAddress = DataBaseAddress;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* reset the FIFO such that it's empty and ready to use and indicate the
+	 * initialization was successful, note that the is ready variable must be
+	 * set prior to calling the reset function to prevent an assert
+	 */
+	XPF_V200A_RESET(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function performs a self-test on the specified packet FIFO.  The self
+* test resets the FIFO and reads a register to determine if it is the correct
+* reset value.  This test is destructive in that any data in the FIFO will
+* be lost.
+*
+* @param InstancePtr is a pointer to the packet FIFO to be operated on.
+*
+* @param FifoType specifies the type of FIFO, read or write, for the self test.
+*        The FIFO type is specified by the values XPF_V200A_READ_FIFO_TYPE or
+*        XPF_V200A_WRITE_FIFO_TYPE.
+*
+* @return
+*
+* XST_SUCCESS is returned if the selftest is successful, or
+* XST_PFIFO_BAD_REG_VALUE indicating that the value read back from the
+* occupancy/vacancy count register after a reset does not match the
+* specified reset value.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType)
+{
+	u32 Register;
+
+	/* assert to verify valid input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID((FifoType == XPF_V200A_READ_FIFO_TYPE) ||
+			(FifoType == XPF_V200A_WRITE_FIFO_TYPE));
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the FIFO and then check to make sure the occupancy/vacancy
+	 * register contents are correct for a reset condition
+	 */
+	XPF_V200A_RESET(InstancePtr);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress +
+			    XPF_V200A_COUNT_STATUS_REG_OFFSET);
+
+	/* check the value of the register to ensure that it's correct for the
+	 * specified FIFO type since both FIFO types reset to empty, but a bit
+	 * in the register changes definition based upon FIFO type
+	 */
+
+	if (FifoType == XPF_V200A_READ_FIFO_TYPE) {
+		/* check the register value for a read FIFO which should be empty */
+
+		if ((Register & ~(XPF_V200A_FIFO_WIDTH_MASK)) !=
+		    XPF_V200A_EMPTY_FULL_MASK) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	}
+	else {
+		/* check the register value for a write FIFO which should not be full
+		 * on reset
+		 */
+		if (((Register & ~(XPF_V200A_FIFO_WIDTH_MASK) &
+		      XPF_V200A_EMPTY_FULL_MASK)) != 0) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	}
+
+	/* check the register value for the proper FIFO width */
+
+	Register &= ~XPF_V200A_EMPTY_FULL_MASK;
+
+	if (((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) &&
+	    ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_32BITS_TYPE) &&
+	    ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_64BITS_TYPE)) {
+		return XST_PFIFO_BAD_REG_VALUE;
+	}
+
+	/* the test was successful */
+
+	return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Read data from a FIFO and puts it into a specified buffer. This function
+* invokes the Level 0 driver function to read the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+*
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+* - XST_SUCCESS if the operation was successful
+*   <br><br>
+* - XST_PFIFO_LACK_OF_DATA if the number of bytes specified by the byte count
+*   is not present in the FIFO.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+			  u8 *BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments including 32 bit alignment of
+	 * the buffer pointer
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferPtr &
+			 (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return XPacketFifoV200a_L0Read(InstancePtr->RegBaseAddress,
+				       InstancePtr->DataBaseAddress,
+				       BufferPtr, ByteCount);
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data into a packet FIFO. This function invokes the Level 0 driver
+* function to read the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+*
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+* - XST_SUCCESS is returned if the operation succeeded.
+*   <br><br>
+* - XST_PFIFO_NO_ROOM is returned if there is not enough room in the FIFO to
+*   hold the specified bytes.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+			   u8 *BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments including 32 bit alignment of
+	 * the buffer pointer
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferPtr &
+			 (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+
+	return XPacketFifoV200a_L0Write(InstancePtr->RegBaseAddress,
+					InstancePtr->DataBaseAddress,
+					BufferPtr, ByteCount);
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Write data into a packet FIFO configured with the Data Realignment engine
+* (DRE). There are no alignment restrictions. The FIFO can be written on any
+* byte boundary. The FIFO must be at least 32 bits wide.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent.
+*
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+int XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+			      u8 *BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return XPacketFifoV200a_L0WriteDre(InstancePtr->RegBaseAddress,
+					   InstancePtr->DataBaseAddress,
+					   BufferPtr, ByteCount);
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_v2_00_a.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xpacket_fifo_v2_00_a.h	2014-07-20 22:06:39.208258675 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xpacket_fifo_v2_00_a.h,v 1.1 2006/12/13 14:23:19 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2004 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xpacket_fifo_v2_00_a.h
+*
+* This component is a common component because it's primary purpose is to
+* prevent code duplication in drivers. A driver which must handle a packet
+* FIFO uses this component rather than directly manipulating a packet FIFO.
+*
+* A FIFO is a device which has dual port memory such that one user may be
+* inserting data into the FIFO while another is consuming data from the FIFO.
+* A packet FIFO is designed for use with packet protocols such as Ethernet and
+* ATM.  It is typically only used with devices when DMA and/or Scatter Gather
+* is used.  It differs from a nonpacket FIFO in that it does not provide any
+* interrupts for thresholds of the FIFO such that it is less useful without
+* DMA.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This component provides the ability to
+* determine if that interrupt is active, a deadlock condition, and the ability
+* to reset the FIFO to clear the condition. In this condition, the device which
+* is using the FIFO should also be reset to prevent other problems. This error
+* condition could occur as a normal part of operation if the size of the FIFO
+* is not setup correctly.  See the hardware IP specification for more details.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.00a ecm 12/30/02  First release
+* 2.00a rpm 10/22/03  Created and made use of Level 0 driver
+* 2.00a rmm 02/24/04  Added WriteDre function.
+* 2.00a xd  10/27/04  Changed comments to support doxygen for API
+*                     documentation.
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_V200A_H	/* prevent circular inclusions */
+#define XPACKET_FIFO_V200A_H	/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xpacket_fifo_l_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+/* See the low-level header file for constant definitions */
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The XPacketFifo driver instance data. The driver is required to allocate a
+ * variable of this type for every packet FIFO in the device.
+ */
+typedef struct {
+	u32 RegBaseAddress; /**< Base address of registers */
+	u32 IsReady;	    /**< Device is initialized and ready */
+	u32 DataBaseAddress;/**< Base address of data for FIFOs */
+} XPacketFifoV200a;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* Reset the specified packet FIFO.  Resetting a FIFO will cause any data
+* contained in the FIFO to be lost.
+*
+* @param    InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return   None.
+*
+* @note     C Signature: void XPF_V200A_RESET(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_RESET(InstancePtr) \
+    XIo_Out32((InstancePtr)->RegBaseAddress + XPF_V200A_RESET_REG_OFFSET, XPF_V200A_RESET_FIFO_MASK);
+
+
+/*****************************************************************************/
+/**
+*
+* Get the occupancy count for a read packet FIFO and the vacancy count for a
+* write packet FIFO. These counts indicate the number of 32-bit words
+* contained (occupancy) in the FIFO or the number of 32-bit words available
+* to write (vacancy) in the FIFO.
+*
+* @param    InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return   The occupancy or vacancy count for the specified packet FIFO.
+*
+* @note
+*
+* C Signature: u32 XPF_V200A_GET_COUNT(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_GET_COUNT(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_COUNT_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Determine if the specified packet FIFO is almost empty. Almost empty is
+* defined for a read FIFO when there is only one data word in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost empty, FALSE otherwise.
+*
+* @note
+*
+* C Signature: u32 XPF_V200A_IS_ALMOST_EMPTY(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_ALMOST_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_ALMOST_EMPTY_FULL_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Determine if the specified packet FIFO is almost full. Almost full is
+* defined for a write FIFO when there is only one available data word in the
+* FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost full, FALSE otherwise.
+*
+* @note
+*
+* C Signature: u32 XPF_V200A_IS_ALMOST_FULL(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_ALMOST_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_ALMOST_EMPTY_FULL_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Determine if the specified packet FIFO is empty. This applies only to a
+* read FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is empty, FALSE otherwise.
+*
+* @note
+*
+* C Signature: u32 XPF_V200A_IS_EMPTY(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_EMPTY_FULL_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Determine if the specified packet FIFO is full. This applies only to a
+* write FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is full, FALSE otherwise.
+*
+* @note
+*
+* C Signature: u32 XPF_V200A_IS_FULL(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_EMPTY_FULL_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Determine if the specified packet FIFO is deadlocked.  This condition occurs
+* when the FIFO is full and empty at the same time and is caused by a packet
+* being written to the FIFO which exceeds the total data capacity of the FIFO.
+* It occurs because of the mark/restore features of the packet FIFO which allow
+* retransmission of a packet. The software should reset the FIFO and any devices
+* using the FIFO when this condition occurs.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This function provides the ability to
+* determine if a deadlock condition, and the ability to reset the FIFO to
+* clear the condition.
+* <br><br>
+* In this condition, the device which is using the FIFO should also be reset
+* to prevent other problems. This error condition could occur as a normal part
+* of operation if the size of the FIFO is not setup correctly.
+* <br><br>
+* C Signature: u32 XPF_V200A_IS_DEADLOCKED(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_DEADLOCKED(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_DEADLOCK_MASK)
+
+
+/************************** Function Prototypes ******************************/
+
+/**
+ * Standard functions
+ */
+int XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+				u32 RegBaseAddress, u32 DataBaseAddress);
+int XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType);
+
+/**
+ * Data functions
+ */
+int XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+			  u8 *ReadBufferPtr, u32 ByteCount);
+int XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+			   u8 *WriteBufferPtr, u32 ByteCount);
+int XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+			      u8 *WriteBufferPtr, u32 ByteCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstatus.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstatus.h	2014-07-20 22:06:39.220258478 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xstatus.h,v 1.1 2006/12/13 14:23:26 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xstatus.h
+*
+* This file contains Xilinx software status codes.  Status codes have their
+* own data type called int.  These codes are used throughout the Xilinx
+* device drivers.
+*
+******************************************************************************/
+
+#ifndef XSTATUS_H		/* prevent circular inclusions */
+#define XSTATUS_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+/************************** Constant Definitions *****************************/
+
+/*********************** Common statuses 0 - 500 *****************************/
+
+#define XST_SUCCESS                     0L
+#define XST_FAILURE                     1L
+#define XST_DEVICE_NOT_FOUND            2L
+#define XST_DEVICE_BLOCK_NOT_FOUND      3L
+#define XST_INVALID_VERSION             4L
+#define XST_DEVICE_IS_STARTED           5L
+#define XST_DEVICE_IS_STOPPED           6L
+#define XST_FIFO_ERROR                  7L	/* an error occurred during an
+						   operation with a FIFO such as
+						   an underrun or overrun, this
+						   error requires the device to
+						   be reset */
+#define XST_RESET_ERROR                 8L	/* an error occurred which requires
+						   the device to be reset */
+#define XST_DMA_ERROR                   9L	/* a DMA error occurred, this error
+						   typically requires the device
+						   using the DMA to be reset */
+#define XST_NOT_POLLED                  10L	/* the device is not configured for
+						   polled mode operation */
+#define XST_FIFO_NO_ROOM                11L	/* a FIFO did not have room to put
+						   the specified data into */
+#define XST_BUFFER_TOO_SMALL            12L	/* the buffer is not large enough
+						   to hold the expected data */
+#define XST_NO_DATA                     13L	/* there was no data available */
+#define XST_REGISTER_ERROR              14L	/* a register did not contain the
+						   expected value */
+#define XST_INVALID_PARAM               15L	/* an invalid parameter was passed
+						   into the function */
+#define XST_NOT_SGDMA                   16L	/* the device is not configured for
+						   scatter-gather DMA operation */
+#define XST_LOOPBACK_ERROR              17L	/* a loopback test failed */
+#define XST_NO_CALLBACK                 18L	/* a callback has not yet been
+						   registered */
+#define XST_NO_FEATURE                  19L	/* device is not configured with
+						   the requested feature */
+#define XST_NOT_INTERRUPT               20L	/* device is not configured for
+						   interrupt mode operation */
+#define XST_DEVICE_BUSY                 21L	/* device is busy */
+#define XST_ERROR_COUNT_MAX             22L	/* the error counters of a device
+						   have maxed out */
+#define XST_IS_STARTED                  23L	/* used when part of device is
+						   already started i.e.
+						   sub channel */
+#define XST_IS_STOPPED                  24L	/* used when part of device is
+						   already stopped i.e.
+						   sub channel */
+#define XST_DATA_LOST                   26L	/* driver defined error */
+#define XST_RECV_ERROR                  27L	/* generic receive error */
+#define XST_SEND_ERROR                  28L	/* generic transmit error */
+#define XST_NOT_ENABLED                 29L	/* a requested service is not
+						   available because it has not
+						   been enabled */
+
+/***************** Utility Component statuses 401 - 500  *********************/
+
+#define XST_MEMTEST_FAILED              401L	/* memory test failed */
+
+
+/***************** Common Components statuses 501 - 1000 *********************/
+
+/********************* Packet Fifo statuses 501 - 510 ************************/
+
+#define XST_PFIFO_LACK_OF_DATA          501L	/* not enough data in FIFO   */
+#define XST_PFIFO_NO_ROOM               502L	/* not enough room in FIFO   */
+#define XST_PFIFO_BAD_REG_VALUE         503L	/* self test, a register value
+						   was invalid after reset */
+#define XST_PFIFO_ERROR                 504L	/* generic packet FIFO error */
+#define XST_PFIFO_DEADLOCK              505L	/* packet FIFO is reporting
+						 * empty and full simultaneously
+						 */
+
+/************************** DMA statuses 511 - 530 ***************************/
+
+#define XST_DMA_TRANSFER_ERROR          511L	/* self test, DMA transfer
+						   failed */
+#define XST_DMA_RESET_REGISTER_ERROR    512L	/* self test, a register value
+						   was invalid after reset */
+#define XST_DMA_SG_LIST_EMPTY           513L	/* scatter gather list contains
+						   no buffer descriptors ready
+						   to be processed */
+#define XST_DMA_SG_IS_STARTED           514L	/* scatter gather not stopped */
+#define XST_DMA_SG_IS_STOPPED           515L	/* scatter gather not running */
+#define XST_DMA_SG_LIST_FULL            517L	/* all the buffer desciptors of
+						   the scatter gather list are
+						   being used */
+#define XST_DMA_SG_BD_LOCKED            518L	/* the scatter gather buffer
+						   descriptor which is to be
+						   copied over in the scatter
+						   list is locked */
+#define XST_DMA_SG_NOTHING_TO_COMMIT    519L	/* no buffer descriptors have been
+						   put into the scatter gather
+						   list to be commited */
+#define XST_DMA_SG_COUNT_EXCEEDED       521L	/* the packet count threshold
+						   specified was larger than the
+						   total # of buffer descriptors
+						   in the scatter gather list */
+#define XST_DMA_SG_LIST_EXISTS          522L	/* the scatter gather list has
+						   already been created */
+#define XST_DMA_SG_NO_LIST              523L	/* no scatter gather list has
+						   been created */
+#define XST_DMA_SG_BD_NOT_COMMITTED     524L	/* the buffer descriptor which was
+						   being started was not committed
+						   to the list */
+#define XST_DMA_SG_NO_DATA              525L	/* the buffer descriptor to start
+						   has already been used by the
+						   hardware so it can't be reused
+						 */
+#define XST_DMA_SG_LIST_ERROR           526L	/* general purpose list access
+						   error */
+#define XST_DMA_BD_ERROR                527L	/* general buffer descriptor
+						   error */
+
+/************************** IPIF statuses 531 - 550 ***************************/
+
+#define XST_IPIF_REG_WIDTH_ERROR        531L	/* an invalid register width
+						   was passed into the function */
+#define XST_IPIF_RESET_REGISTER_ERROR   532L	/* the value of a register at
+						   reset was not valid */
+#define XST_IPIF_DEVICE_STATUS_ERROR    533L	/* a write to the device interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_DEVICE_ACK_ERROR       534L	/* the device interrupt status
+						   register did not reset when
+						   acked */
+#define XST_IPIF_DEVICE_ENABLE_ERROR    535L	/* the device interrupt enable
+						   register was not updated when
+						   other registers changed */
+#define XST_IPIF_IP_STATUS_ERROR        536L	/* a write to the IP interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_IP_ACK_ERROR           537L	/* the IP interrupt status register
+						   did not reset when acked */
+#define XST_IPIF_IP_ENABLE_ERROR        538L	/* IP interrupt enable register was
+						   not updated correctly when other
+						   registers changed */
+#define XST_IPIF_DEVICE_PENDING_ERROR   539L	/* The device interrupt pending
+						   register did not indicate the
+						   expected value */
+#define XST_IPIF_DEVICE_ID_ERROR        540L	/* The device interrupt ID register
+						   did not indicate the expected
+						   value */
+#define XST_IPIF_ERROR                  541L	/* generic ipif error */
+
+/****************** Device specific statuses 1001 - 4095 *********************/
+
+/********************* Ethernet statuses 1001 - 1050 *************************/
+
+#define XST_EMAC_MEMORY_SIZE_ERROR  1001L	/* Memory space is not big enough
+						 * to hold the minimum number of
+						 * buffers or descriptors */
+#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L	/* Memory allocation failed */
+#define XST_EMAC_MII_READ_ERROR     1003L	/* MII read error */
+#define XST_EMAC_MII_BUSY           1004L	/* An MII operation is in progress */
+#define XST_EMAC_OUT_OF_BUFFERS     1005L	/* Adapter is out of buffers */
+#define XST_EMAC_PARSE_ERROR        1006L	/* Invalid adapter init string */
+#define XST_EMAC_COLLISION_ERROR    1007L	/* Excess deferral or late
+						 * collision on polled send */
+
+/*********************** UART statuses 1051 - 1075 ***************************/
+#define XST_UART
+
+#define XST_UART_INIT_ERROR         1051L
+#define XST_UART_START_ERROR        1052L
+#define XST_UART_CONFIG_ERROR       1053L
+#define XST_UART_TEST_FAIL          1054L
+#define XST_UART_BAUD_ERROR         1055L
+#define XST_UART_BAUD_RANGE         1056L
+
+
+/************************ IIC statuses 1076 - 1100 ***************************/
+
+#define XST_IIC_SELFTEST_FAILED         1076	/* self test failed            */
+#define XST_IIC_BUS_BUSY                1077	/* bus found busy              */
+#define XST_IIC_GENERAL_CALL_ADDRESS    1078	/* mastersend attempted with   */
+					     /* general call address        */
+#define XST_IIC_STAND_REG_RESET_ERROR   1079	/* A non parameterizable reg   */
+					     /* value after reset not valid */
+#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080	/* Tx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081	/* Rx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_TBA_REG_RESET_ERROR     1082	/* 10 bit addr incl in design  */
+					     /* value after reset not valid */
+#define XST_IIC_CR_READBACK_ERROR       1083	/* Read of the control register */
+					     /* didn't return value written */
+#define XST_IIC_DTR_READBACK_ERROR      1084	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_DRR_READBACK_ERROR      1085	/* Read of the data Receive reg */
+					     /* didn't return value written */
+#define XST_IIC_ADR_READBACK_ERROR      1086	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_TBA_READBACK_ERROR      1087	/* Read of the 10 bit addr reg */
+					     /* didn't return written value */
+#define XST_IIC_NOT_SLAVE               1088	/* The device isn't a slave    */
+
+/*********************** ATMC statuses 1101 - 1125 ***************************/
+
+#define XST_ATMC_ERROR_COUNT_MAX    1101L	/* the error counters in the ATM
+						   controller hit the max value
+						   which requires the statistics
+						   to be cleared */
+
+/*********************** Flash statuses 1126 - 1150 **************************/
+
+#define XST_FLASH_BUSY                1126L	/* Flash is erasing or programming */
+#define XST_FLASH_READY               1127L	/* Flash is ready for commands */
+#define XST_FLASH_ERROR               1128L	/* Flash had detected an internal
+						   error. Use XFlash_DeviceControl
+						   to retrieve device specific codes */
+#define XST_FLASH_ERASE_SUSPENDED     1129L	/* Flash is in suspended erase state */
+#define XST_FLASH_WRITE_SUSPENDED     1130L	/* Flash is in suspended write state */
+#define XST_FLASH_PART_NOT_SUPPORTED  1131L	/* Flash type not supported by
+						   driver */
+#define XST_FLASH_NOT_SUPPORTED       1132L	/* Operation not supported */
+#define XST_FLASH_TOO_MANY_REGIONS    1133L	/* Too many erase regions */
+#define XST_FLASH_TIMEOUT_ERROR       1134L	/* Programming or erase operation
+						   aborted due to a timeout */
+#define XST_FLASH_ADDRESS_ERROR       1135L	/* Accessed flash outside its
+						   addressible range */
+#define XST_FLASH_ALIGNMENT_ERROR     1136L	/* Write alignment error */
+#define XST_FLASH_BLOCKING_CALL_ERROR 1137L	/* Couldn't return immediately from
+						   write/erase function with
+						   XFL_NON_BLOCKING_WRITE/ERASE
+						   option cleared */
+#define XST_FLASH_CFI_QUERY_ERROR     1138L	/* Failed to query the device */
+
+/*********************** SPI statuses 1151 - 1175 ****************************/
+
+#define XST_SPI_MODE_FAULT          1151	/* master was selected as slave */
+#define XST_SPI_TRANSFER_DONE       1152	/* data transfer is complete */
+#define XST_SPI_TRANSMIT_UNDERRUN   1153	/* slave underruns transmit register */
+#define XST_SPI_RECEIVE_OVERRUN     1154	/* device overruns receive register */
+#define XST_SPI_NO_SLAVE            1155	/* no slave has been selected yet */
+#define XST_SPI_TOO_MANY_SLAVES     1156	/* more than one slave is being
+						 * selected */
+#define XST_SPI_NOT_MASTER          1157	/* operation is valid only as master */
+#define XST_SPI_SLAVE_ONLY          1158	/* device is configured as slave-only */
+#define XST_SPI_SLAVE_MODE_FAULT    1159	/* slave was selected while disabled */
+
+/********************** OPB Arbiter statuses 1176 - 1200 *********************/
+
+#define XST_OPBARB_INVALID_PRIORITY  1176	/* the priority registers have either
+						 * one master assigned to two or more
+						 * priorities, or one master not
+						 * assigned to any priority
+						 */
+#define XST_OPBARB_NOT_SUSPENDED     1177	/* an attempt was made to modify the
+						 * priority levels without first
+						 * suspending the use of priority
+						 * levels
+						 */
+#define XST_OPBARB_PARK_NOT_ENABLED  1178	/* bus parking by id was enabled but
+						 * bus parking was not enabled
+						 */
+#define XST_OPBARB_NOT_FIXED_PRIORITY 1179	/* the arbiter must be in fixed
+						 * priority mode to allow the
+						 * priorities to be changed
+						 */
+
+/************************ Intc statuses 1201 - 1225 **************************/
+
+#define XST_INTC_FAIL_SELFTEST      1201	/* self test failed */
+#define XST_INTC_CONNECT_ERROR      1202	/* interrupt already in use */
+
+/********************** TmrCtr statuses 1226 - 1250 **************************/
+
+#define XST_TMRCTR_TIMER_FAILED     1226	/* self test failed */
+
+/********************** WdtTb statuses 1251 - 1275 ***************************/
+
+#define XST_WDTTB_TIMER_FAILED      1251L
+
+/********************** PlbArb statuses 1276 - 1300 **************************/
+
+#define XST_PLBARB_FAIL_SELFTEST    1276L
+
+/********************** Plb2Opb statuses 1301 - 1325 *************************/
+
+#define XST_PLB2OPB_FAIL_SELFTEST   1301L
+
+/********************** Opb2Plb statuses 1326 - 1350 *************************/
+
+#define XST_OPB2PLB_FAIL_SELFTEST   1326L
+
+/********************** SysAce statuses 1351 - 1360 **************************/
+
+#define XST_SYSACE_NO_LOCK          1351L	/* No MPU lock has been granted */
+
+/********************** PCI Bridge statuses 1361 - 1375 **********************/
+
+#define XST_PCI_INVALID_ADDRESS     1361L
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstreamer.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstreamer.c	2014-07-20 22:06:39.231258296 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+* @file xstreamer.c
+*
+* See xtreamer.h for a description on how to use this driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a jvb  10/13/06 First release - based on Robert McGee's streaming packet
+*                     fifo driver.
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xstreamer.h"
+
+/*
+ * Implementation Notes
+ *
+ * --- Receive ---
+ *
+ * The basic algorithm for receiving bytes through this byte streamer copies a
+ * fifo key-hole width chunk from the fifo into a holding buffer and then doles
+ * out the bytes from the holding buffer. In some cases, when the buffer given
+ * happens to already be aligned in memory, this algorithm will bypass the
+ * holding buffer.
+ *
+ * Here is a picture to depict this process:
+ *
+ * Initial state:                 holding buffer
+ *                                +--------------+
+ *                                |   <empty>    |
+ *                                +--------------+
+ *                                               ^
+ *                                               |
+ *                                             index
+ *
+ * during XStrm_Read():
+ * first holding buffer fill:     holding buffer
+ *                                +--------------+
+ *                                |////<full>////|
+ *                                +--------------+
+ *                                ^
+ *                                |
+ *                              index
+ *
+ * first holding buffer read:     holding buffer
+ *                                 read   unread
+ *                                +--------------+
+ *                                |      |///////|
+ *                                +--------------+
+ *                                       ^
+ *                                       |
+ *                                     index
+ *
+ * ...
+ *
+ * last holding buffer read:     holding buffer
+ *                                +--------------+
+ *                                |   <empty>    |
+ *                                +--------------+
+ *                                               ^
+ *                                               |
+ *                                             index
+ *
+ * repeat this process ^^^
+ *
+ *
+ * --- Transmit ---
+ *
+ * The basic algorithm for transmitting bytes through this byte streamer copies
+ * bytes into a holding buffer and then writes the holding buffer into the fifo
+ * when it is full.  In some cases, when the buffer given happens to already be
+ * aligned in memory, this algorithm will bypass the holding buffer.
+ *
+ * Here is a picture to depict this process:
+ *
+ * Initial state:                 holding buffer
+ *                                +--------------+
+ *                                |   <empty>    |
+ *                                +--------------+
+ *                                ^
+ *                                |
+ *                              index
+ *
+ * during XStrm_Write():
+ * first holding buffer write:    holding buffer
+ *                                 writen  empty
+ *                                +--------------+
+ *                                |//////|       |
+ *                                +--------------+
+ *                                       ^
+ *                                       |
+ *                                     index
+ *
+ * ...
+ * last holding buffer write:     holding buffer
+ *                                +--------------+
+ *                                |////<full>////|
+ *                                +--------------+
+ *                                               ^
+ *                                               |
+ *                                             index
+ *
+ * holding buffer flush:          holding buffer
+ *                                +--------------+
+ *                                |   <empty>    |
+ *                                +--------------+
+ *                                ^
+ *                                |
+ *                              index
+ *
+ * repeat this process ^^^
+ */
+
+#ifndef min
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxInitialize initializes the XStrm_RxFifoStreamer object referenced by
+* <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the tx streamer on which to operate.
+*
+* @param    FifoWidth specifies the FIFO keyhole size in bytes.
+*
+* @param    FifoInstance references the FIFO driver instance that this streamer
+*           object should use to transfer data into the the actual fifo.
+*
+* @param    ReadFn specifies a routine to use to read data from the actual
+*           FIFO. It is assumed that this read routine will handle only reads
+*           from an aligned buffer. (Otherwise, why are we using this streamer
+*           driver?)
+*
+* @param    GetLenFn specifies a routine to use to initiate a receive on the
+*           actual FIFO.
+*
+* @param    GetOccupancyFn specifies a routine to use to retrieve the occupancy
+*           in the actual FIFO. The true occupancy value needs to come through
+*           this streamer driver becuase it holds some of the bytes.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XStrm_RxInitialize(XStrm_RxFifoStreamer * InstancePtr,
+			unsigned FifoWidth, void *FifoInstance,
+			XStrm_XferFnType ReadFn,
+			XStrm_GetLenFnType GetLenFn,
+			XStrm_GetOccupancyFnType GetOccupancyFn)
+{
+	/* Verify arguments */
+	XASSERT_VOID(InstancePtr != NULL);
+
+	InstancePtr->HeadIndex = FifoWidth;
+	InstancePtr->FifoWidth = FifoWidth;
+	InstancePtr->FifoInstance = FifoInstance;
+	InstancePtr->ReadFn = ReadFn;
+	InstancePtr->GetLenFn = GetLenFn;
+	InstancePtr->GetOccupancyFn = GetOccupancyFn;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxInitialize initializes the XStrm_TxFifoStreamer object referenced by
+* <i>InstancePtr</i>.
+*
+* @param    InstancePtr references the tx streamer on which to operate.
+*
+* @param    FifoWidth specifies the FIFO keyhole size in bytes.
+*
+* @param    FifoInstance references the FIFO driver instance that this streamer
+*           object should use to transfer data into the the actual fifo.
+*
+* @param    WriteFn specifies a routine to use to write data into the actual
+*           FIFO. It is assumed that this write routine will handle only writes
+*           from an aligned buffer. (Otherwise, why are we using this streamer
+*           driver?)
+*
+* @param    SetLenFn specifies a routine to use to initiate a transmit on the
+*           actual FIFO.
+*
+* @param    GetVacancyFn specifies a routine to use to retrieve the vacancy in
+*           the actual FIFO. The true vacancy value needs to come through this
+*           streamer driver becuase it holds some of the bytes.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XStrm_TxInitialize(XStrm_TxFifoStreamer * InstancePtr, unsigned FifoWidth,
+			void *FifoInstance, XStrm_XferFnType WriteFn,
+			XStrm_SetLenFnType SetLenFn,
+			XStrm_GetVacancyFnType GetVacancyFn)
+{
+	/* Verify arguments */
+	XASSERT_VOID(InstancePtr != NULL);
+
+	InstancePtr->TailIndex = 0;
+	InstancePtr->FifoWidth = FifoWidth;
+	InstancePtr->FifoInstance = FifoInstance;
+	InstancePtr->WriteFn = WriteFn;
+	InstancePtr->SetLenFn = SetLenFn;
+	InstancePtr->GetVacancyFn = GetVacancyFn;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxGetLen notifies the hardware that the program is ready to receive the
+* next frame from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* Note that the program must first call XStrm_RxGetLen before pulling data
+* out of the receive channel of the FIFO with XStrm_Read.
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @return   XStrm_RxGetLen returns the number of bytes available in the next
+*           frame.
+*
+******************************************************************************/
+u32 XStrm_RxGetLen(XStrm_RxFifoStreamer * InstancePtr)
+{
+	u32 len;
+
+	InstancePtr->HeadIndex = InstancePtr->FifoWidth;
+	len = (*InstancePtr->GetLenFn) (InstancePtr->FifoInstance);
+	InstancePtr->FrmByteCnt = len;
+	return len;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_Read reads <i>Bytes</i> bytes from the FIFO specified by
+* <i>InstancePtr</i> to the block of memory, referenced by <i>BufPtr</i>.
+*
+* Care must be taken to ensure that the number of bytes read with one or more
+* calls to XStrm_Read() does not exceed the number of bytes available given
+* from the last call to XStrm_RxGetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address to place the data read.
+*
+* @param    Bytes specifies the number of bytes to read.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XStrm_Read(XStrm_RxFifoStreamer * InstancePtr, void *BufPtr,
+		unsigned Bytes)
+{
+	u8 *DestPtr = (u8 *) BufPtr;
+	unsigned BytesRemaining = Bytes;
+	unsigned FifoWordsToXfer;
+	unsigned PartialBytes;
+	unsigned i;
+
+	while (BytesRemaining) {
+		xdbg_printf(XDBG_DEBUG_FIFO_RX,
+			    "XStrm_Read: BytesRemaining: %d\n", BytesRemaining);
+		/* Case 1: There are bytes in the holding buffer
+		 *
+		 *   1) Read the bytes from the holding buffer to the target buffer.
+		 *   2) Loop back around and handle the rest of the transfer.
+		 */
+		if (InstancePtr->HeadIndex != InstancePtr->FifoWidth) {
+			xdbg_printf(XDBG_DEBUG_FIFO_RX,
+				    "XStrm_Read: Case 1: InstancePtr->HeadIndex [%d] != InstancePtr->FifoWidth [%d]\n",
+				    InstancePtr->HeadIndex,
+				    InstancePtr->FifoWidth);
+			i = InstancePtr->HeadIndex;
+
+			PartialBytes = min(BytesRemaining,
+					   InstancePtr->FifoWidth -
+					   InstancePtr->HeadIndex);
+			InstancePtr->HeadIndex += PartialBytes;
+			BytesRemaining -= PartialBytes;
+			InstancePtr->FrmByteCnt -= PartialBytes;
+			while (PartialBytes--) {
+				*DestPtr = InstancePtr->AlignedBuffer.bytes[i];
+				i++;
+				DestPtr++;
+			}
+		}
+		/* Case 2: There are no more bytes in the holding buffer and
+		 *         the target buffer is 32 bit aligned and
+		 *         the number of bytes remaining to transfer is greater
+		 *         than or equal to the fifo width.
+		 *
+		 *   1) We can go fast by reading a long string of fifo words right out
+		 *      of the fifo into the target buffer.
+		 *   2) Loop back around to transfer the last few bytes.
+		 */
+		else if ((((unsigned) DestPtr & 3) == 0) &&
+			 (BytesRemaining >= InstancePtr->FifoWidth)) {
+			xdbg_printf(XDBG_DEBUG_FIFO_RX,
+				    "XStrm_Read: Case 2: DestPtr: %p, BytesRemaining: %d, InstancePtr->FifoWidth: %d\n",
+				    DestPtr, BytesRemaining,
+				    InstancePtr->FifoWidth);
+			FifoWordsToXfer =
+				BytesRemaining / InstancePtr->FifoWidth;
+
+			(*(InstancePtr->ReadFn)) (InstancePtr->FifoInstance,
+						  DestPtr, FifoWordsToXfer);
+			DestPtr += FifoWordsToXfer * InstancePtr->FifoWidth;
+			BytesRemaining -=
+				FifoWordsToXfer * InstancePtr->FifoWidth;
+			InstancePtr->FrmByteCnt -=
+				FifoWordsToXfer * InstancePtr->FifoWidth;
+		}
+		/* Case 3: There are no more bytes in the holding buffer and
+		 *         the number of bytes remaining to transfer is less than
+		 *         the fifo width or
+		 *         things just don't line up.
+		 *
+		 *   1) Fill the holding buffer.
+		 *   2) Loop back around and handle the rest of the transfer.
+		 */
+		else {
+			xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: Case 3\n");
+			/*
+			 * At the tail end, read one fifo word into the local holding
+			 * buffer and loop back around to take care of the transfer.
+			 */
+			(*InstancePtr->ReadFn) (InstancePtr->FifoInstance,
+						&(InstancePtr->AlignedBuffer.
+						  bytes[0]), 1);
+			InstancePtr->HeadIndex = 0;
+		}
+	}
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxSetLen flushes to the FIFO, specified by <i>InstancePtr</i>, any
+* bytes remaining in internal buffers and begins a hardware transfer of data
+* out of the transmit channel of the FIFO. <i>Bytes</i> specifies the number
+* of bytes in the frame to transmit.
+*
+* @param    InstancePtr references the FIFO Streamer on which to operate.
+*
+* @param    Bytes specifies the frame length in bytes.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XStrm_TxSetLen(XStrm_TxFifoStreamer * InstancePtr, u32 Bytes)
+{
+	/*
+	 * First flush what's in the holding buffer
+	 */
+	if (InstancePtr->TailIndex != 0) {
+		(*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+					 &(InstancePtr->AlignedBuffer.bytes[0]),
+					 1);
+		InstancePtr->TailIndex = 0;
+	}
+
+	/*
+	 * Kick off the hw write
+	 */
+	(*(InstancePtr)->SetLenFn) (InstancePtr->FifoInstance, Bytes);
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_Write writes <i>Bytes</i> bytes of the block of memory, referenced by
+* <i>BufPtr</i>, to the transmit channel of the FIFO referenced by
+* <i>InstancePtr</i>.
+*
+* Care must be taken to ensure that the number of bytes written with one or
+* more calls to XStrm_Write() matches the number of bytes given in the next
+* call to XStrm_TxSetLen().
+*
+* @param    InstancePtr references the FIFO on which to operate.
+*
+* @param    BufPtr specifies the memory address of data to write.
+*
+* @param    Bytes specifies the number of bytes to write.
+*
+* @return   N/A
+*
+******************************************************************************/
+void XStrm_Write(XStrm_TxFifoStreamer * InstancePtr, void *BufPtr,
+		 unsigned Bytes)
+{
+	u8 *SrcPtr = (u8 *) BufPtr;
+	unsigned BytesRemaining = Bytes;
+	unsigned FifoWordsToXfer;
+	unsigned PartialBytes;
+	unsigned i;
+
+	while (BytesRemaining) {
+		xdbg_printf(XDBG_DEBUG_FIFO_TX,
+			    "XStrm_Write: BytesRemaining: %d\n",
+			    BytesRemaining);
+		/* Case 1: The holding buffer is full
+		 *
+		 *   1) Write it to the fifo.
+		 *   2) Fall through to transfer more bytes in this iteration.
+		 */
+		if (InstancePtr->TailIndex == InstancePtr->FifoWidth) {
+			xdbg_printf(XDBG_DEBUG_FIFO_TX,
+				    "XStrm_Write: (case 1) TailIndex: %d; FifoWidth: %d; WriteFn: %p\n",
+				    InstancePtr->TailIndex,
+				    InstancePtr->FifoWidth,
+				    InstancePtr->WriteFn);
+			(*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+						 &(InstancePtr->AlignedBuffer.
+						   bytes[0]), 1);
+			InstancePtr->TailIndex = 0;
+		}
+		/* Case 2: There are no bytes in the holding buffer and
+		 *         the target buffer is 32 bit aligned and
+		 *         the number of bytes remaining to transfer is greater
+		 *         than or equal to the fifo width.
+		 *
+		 *   1) We can go fast by writing a long string of fifo words right out
+		 *      of the source buffer into the fifo.
+		 *   2) Loop back around to transfer the last few bytes.
+		 */
+		if ((InstancePtr->TailIndex == 0) &&
+		    (BytesRemaining >= InstancePtr->FifoWidth) &&
+		    (((unsigned) SrcPtr & 3) == 0)) {
+			FifoWordsToXfer =
+				BytesRemaining / InstancePtr->FifoWidth;
+
+			xdbg_printf(XDBG_DEBUG_FIFO_TX,
+				    "XStrm_Write: (case 2) TailIndex: %d; BytesRemaining: %d; FifoWidth: %d; SrcPtr: %p;\n InstancePtr: %p; WriteFn: %p (XLlFifo_iWrite_Aligned: %p),\nFifoWordsToXfer: %d (BytesRemaining: %d)\n",
+				    InstancePtr->TailIndex, BytesRemaining,
+				    InstancePtr->FifoWidth, SrcPtr, InstancePtr,
+				    InstancePtr->WriteFn,
+				    XLlFifo_iWrite_Aligned, FifoWordsToXfer,
+				    BytesRemaining);
+
+			(*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+						 SrcPtr, FifoWordsToXfer);
+			SrcPtr += FifoWordsToXfer * InstancePtr->FifoWidth;
+			BytesRemaining -=
+				FifoWordsToXfer * InstancePtr->FifoWidth;
+			xdbg_printf(XDBG_DEBUG_FIFO_TX,
+				    "XStrm_Write: (end case 2) TailIndex: %d; BytesRemaining: %d; SrcPtr: %p\n",
+				    InstancePtr->TailIndex, BytesRemaining,
+				    SrcPtr);
+		}
+		/* Case 3: The alignment of the "galaxies" didn't occur in
+		 *         Case 2 above, so we must pump the bytes through the
+		 *         holding buffer.
+		 *
+		 *   1) Write bytes from the source buffer to the holding buffer
+		 *   2) Loop back around and handle the rest of the transfer.
+		 */
+		else {
+			i = InstancePtr->TailIndex;
+
+			PartialBytes =
+				min(BytesRemaining,
+				    InstancePtr->FifoWidth -
+				    InstancePtr->TailIndex);
+			BytesRemaining -= PartialBytes;
+			InstancePtr->TailIndex += PartialBytes;
+			while (PartialBytes--) {
+				xdbg_printf(XDBG_DEBUG_FIFO_TX,
+					    "XStrm_Write: (case 3) PartialBytes: %d\n",
+					    PartialBytes);
+				InstancePtr->AlignedBuffer.bytes[i] = *SrcPtr;
+				i++;
+				SrcPtr++;
+			}
+		}
+	}
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstreamer.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xstreamer.h	2014-07-20 22:06:39.241258131 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2005-2008 Xilinx Inc.
+*       All rights reserved.
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+ *
+ * @file xstreamer.h
+ *
+ * The Xilinx byte streamer for packet FIFOs.
+ *
+ * <h2>Driver Description</h2>
+ *
+ * This driver enables higher layer software to access a hardware FIFO using
+ * any alignment in the data buffers while preserving alignment for the hardware
+ * FIFO access.
+ *
+ * This driver treats send and receive channels separately, using different
+ * types of instance objects for each.
+ *
+ * This driver makes use of another FIFO driver to access the specific FIFO
+ * hardware through use of the routines passed into the Tx/RxInitialize
+ * routines.
+ *
+ * <h2>Initialization</h2>
+ *
+ * Send and receive channels are intialized separately. The receive channel is
+ * initiailzed using XStrm_RxInitialize(). The send channel is initialized
+ * using XStrm_TxInitialize().
+ *
+ *
+ * <h2>Usage</h2>
+ * It is fairly simple to use the API provided by this byte streamer
+ * driver. The only somewhat tricky part is that the calling code must
+ * correctly call a couple routines in the right sequence for receive and
+ * transmit.
+ *
+ * 	This sequence is described here. Check the routine functional
+ * descriptions for information on how to use a specific API routine.
+ *
+ * <h3>Receive</h3>
+ * A frame is received by using the following sequence:<br>
+ * 1) call XStrm_RxGetLen() to get the length of the next incoming frame.<br>
+ * 2) call XStrm_Read() one or more times to read the number of bytes
+ * 	   reported by XStrm_RxGetLen().<br>
+ *
+ * For example:
+ * <pre>
+ * 	frame_len = XStrm_RxGetLen(&RxInstance);
+ * 	while (frame_len) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_len);
+ * 		XStrm_Read(&RxInstance, buffer, bytes);
+ * 		// do something with buffer here
+ * 		frame_len -= bytes;
+ * 	}
+ * </pre>
+ *
+ * Other restrictions on the sequence of API calls may apply depending on
+ * the specific FIFO driver used by this byte streamer driver.
+ *
+ * <h3>Transmit</h3>
+ * A frame is transmittted by using the following sequence:<br>
+ * 1) call XStrm_Write() one or more times to write all the of bytes in
+ *    the next frame.<br>
+ * 2) call XStrm_TxSetLen() to begin the transmission of frame just
+ *    written.<br>
+ *
+ * For example:
+ * <pre>
+ * 	frame_left = frame_len;
+ * 	while (frame_left) {
+ * 		unsigned bytes = min(sizeof(buffer), frame_left);
+ * 		XStrm_Write(&TxInstance, buffer, bytes);
+ * 		// do something here to refill buffer
+ * 	}
+ * 	XStrm_TxSetLen(&RxInstance, frame_len);
+ * </pre>
+ *
+ * Other restrictions on the sequence of API calls may apply depending on
+ * the specific FIFO driver used by this byte streamer driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a jvb  10/12/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+#ifndef XSTREAMER_H		/* prevent circular inclusions */
+#define XSTREAMER_H		/* by using preprocessor symbols */
+
+/* force C linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xdebug.h"
+
+/*
+ * key hole size in 32 bit words
+ */
+#define LARGEST_FIFO_KEYHOLE_SIZE_WORDS 4
+
+/*
+ * This union is used simply to force a 32bit alignment on the
+ * buffer. Only the 'bytes' member is really used.
+ */
+union XStrm_AlignedBufferType {
+	u32 _words[LARGEST_FIFO_KEYHOLE_SIZE_WORDS];
+	char bytes[LARGEST_FIFO_KEYHOLE_SIZE_WORDS * 4];
+};
+
+typedef int(*XStrm_XferFnType) (void *FifoInstance, void *BufPtr,
+                                    unsigned WordCount);
+typedef u32 (*XStrm_GetLenFnType) (void *FifoInstance);
+typedef void (*XStrm_SetLenFnType) (void *FifoInstance,
+                                    u32 ByteCount);
+typedef u32 (*XStrm_GetOccupancyFnType) (void *FifoInstance);
+typedef u32 (*XStrm_GetVacancyFnType) (void *FifoInstance);
+
+/**
+ * This typedef defines a run-time instance of a receive byte-streamer.
+ */
+typedef struct XStrm_RxFifoStreamer {
+	union XStrm_AlignedBufferType AlignedBuffer;
+	unsigned HeadIndex;  /**< HeadIndex is the index to the AlignedBuffer
+	                      *   as bytes.
+                              */
+	unsigned FifoWidth;  /**< FifoWidth is the FIFO key hole width in bytes.
+	                      */
+	unsigned FrmByteCnt; /**< FrmByteCnt is the number of bytes in the next
+			      *   Frame.
+			      */
+	void *FifoInstance;  /**< FifoInstance is the FIFO driver instance to
+	                      *   pass to ReadFn, GetLenFn, and GetOccupancyFn
+	                      *   routines.
+	                      */
+	XStrm_XferFnType ReadFn;     /**< ReadFn is the routine the streamer
+	                              *   uses to receive bytes from the Fifo.
+	                              */
+	XStrm_GetLenFnType GetLenFn; /**< GetLenFn is the routine the streamer
+	                              *   uses to initiate receive operations
+	                              *   on the FIFO.
+                                      */
+	XStrm_GetOccupancyFnType GetOccupancyFn; /**< GetOccupancyFn is the
+	                                          *   routine the streamer uses
+	                                          *   to get the occupancy from
+	                                          *   the FIFO.
+	                                          */
+} XStrm_RxFifoStreamer;
+
+/**
+ * This typedef defines a run-time instance of a transmit byte-streamer.
+ */
+typedef struct XStrm_TxFifoStreamer {
+	union XStrm_AlignedBufferType AlignedBuffer;
+	unsigned TailIndex; /**< TailIndex is the index to the AlignedBuffer
+	                     *   as bytes
+                             */
+	unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes.
+	                     */
+
+	void *FifoInstance; /**< FifoInstance is the FIFO driver instance to
+	                     *   pass to WriteFn, SetLenFn, and GetVacancyFn
+	                     *   routines.
+	                     */
+	XStrm_XferFnType WriteFn; /**< WriteFn is the routine the streamer
+	                           *   uses to transmit bytes to the Fifo.
+	                           */
+	XStrm_SetLenFnType SetLenFn; /**< SetLenFn is the routine the streamer
+	                              *   uses to initiate transmit operations
+	                              *   on the FIFO.
+                                      */
+	XStrm_GetVacancyFnType GetVacancyFn; /**< GetVaccancyFn is the routine
+	                                      *   the streamer uses to get the
+	                                      *   vacancy from the FIFO.
+	                                      */
+} XStrm_TxFifoStreamer;
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxVacancy returns the number of unused 32-bit words available (vacancy)
+* between the streamer, specified by <i>InstancePtr</i>, and the FIFO this
+* streamer is using.
+*
+* @param    InstancePtr references the streamer on which to operate.
+*
+* @return   XStrm_TxVacancy returns the vacancy count in number of 32 bit words.
+*
+* @note
+*
+* C Signature: u32 XStrm_TxVacancy(XStrm_TxFifoStreamer *InstancePtr)
+*
+* The amount of bytes in the holding buffer (rounded up to whole 32-bit words)
+* is subtracted from the vacancy value of FIFO this streamer is using. This is
+* to ensure the caller can write the number words given in the return value and
+* not overflow the FIFO.
+*
+******************************************************************************/
+#define XStrm_TxVacancy(InstancePtr) \
+	(((*(InstancePtr)->GetVacancyFn)((InstancePtr)->FifoInstance)) - \
+			(((InstancePtr)->TailIndex + 3) / 4))
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxOccupancy returns the number of 32-bit words available (occupancy) to
+* be read from the streamer, specified by <i>InstancePtr</i>, and FIFO this
+* steamer is using.
+*
+* @param    InstancePtr references the streamer on which to operate.
+*
+* @return   XStrm_RxOccupancy returns the occupancy count in number of 32 bit
+*           words.
+*
+* @note
+*
+* C Signature: u32 XStrm_RxOccupancy(XStrm_RxFifoStreamer *InstancePtr)
+*
+* The amount of bytes in the holding buffer (rounded up to whole 32-bit words)
+* is added to the occupancy value of FIFO this streamer is using. This is to
+* ensure the caller will get a little more accurate occupancy value.
+*
+******************************************************************************/
+#ifdef DEBUG
+extern u32 _xstrm_ro_value;
+extern u32 _xstrm_buffered;
+#define XStrm_RxOccupancy(InstancePtr) \
+        (_xstrm_ro_value = ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)), \
+	xdbg_printf(XDBG_DEBUG_FIFO_RX, "reg: %d; frmbytecnt: %d\n", \
+		_xstrm_ro_value, (InstancePtr)->FrmByteCnt), \
+	(((InstancePtr)->FrmByteCnt) ? \
+		_xstrm_buffered = ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \
+		0), \
+	xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered_bytes: %d\n", _xstrm_buffered), \
+	xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered (rounded): %d\n", _xstrm_buffered), \
+	(_xstrm_ro_value + _xstrm_buffered))
+#else
+#define XStrm_RxOccupancy(InstancePtr) \
+	( \
+	  ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)) + \
+	  ( \
+	    ((InstancePtr)->FrmByteCnt) ? \
+	      ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \
+	      0 \
+	  ) \
+	)
+#endif
+
+/****************************************************************************/
+/*
+*
+* XStrm_IsRxInternalEmpty returns true if the streamer, specified by
+* <i>InstancePtr</i>, is not holding any bytes in it's  internal buffers. Note
+* that this routine does not reflect information about the state of the
+* FIFO used by this streamer.
+*
+* @param    InstancePtr references the streamer on which to operate.
+*
+* @return   XStrm_IsRxInternalEmpty returns TRUE when the streamer is not
+*           holding any bytes in it's internal buffers. Otherwise,
+*           XStrm_IsRxInternalEmpty returns FALSE.
+*
+* @note
+* C-style signature:
+*    int XStrm_IsRxInternalEmpty(XStrm_RxFifoStreamer *InstancePtr)
+*
+*****************************************************************************/
+#define XStrm_IsRxInternalEmpty(InstancePtr) \
+	(((InstancePtr)->HeadIndex == (InstancePtr)->FifoWidth) ? TRUE : FALSE)
+
+void XStrm_RxInitialize(XStrm_RxFifoStreamer *InstancePtr,
+                        unsigned FifoWidth, void *FifoInstance,
+                        XStrm_XferFnType ReadFn,
+                        XStrm_GetLenFnType GetLenFn,
+                        XStrm_GetOccupancyFnType GetOccupancyFn);
+
+void XStrm_TxInitialize(XStrm_TxFifoStreamer *InstancePtr,
+                        unsigned FifoWidth, void *FifoInstance,
+                        XStrm_XferFnType WriteFn,
+                        XStrm_SetLenFnType SetLenFn,
+                        XStrm_GetVacancyFnType GetVacancyFn);
+
+void XStrm_TxSetLen(XStrm_TxFifoStreamer *InstancePtr, u32 Bytes);
+void XStrm_Write(XStrm_TxFifoStreamer *InstancePtr, void *BufPtr,
+                    unsigned bytes);
+
+u32 XStrm_RxGetLen(XStrm_RxFifoStreamer *InstancePtr);
+void XStrm_Read(XStrm_RxFifoStreamer *InstancePtr, void *BufPtr,
+                   unsigned bytes);
+
+#ifdef __cplusplus
+}
+#endif
+#endif				/* XSTREAMER_H  end of preprocessor protection symbols */
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xversion.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xversion.c	2014-07-20 22:06:39.252257950 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xversion.c,v 1.1 2006/12/13 14:23:34 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xversion.c
+*
+* This file contains the implementation of the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   11/03/04 Improved support for doxygen.
+</pre>
+*
+******************************************************************************/
+
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants define the masks and shift values to allow the
+ * revisions to be packed and unpacked, a packed version is packed into a 16
+ * bit value in the following format, XXXXYYYYYYYZZZZZ, where XXXX is the
+ * major revision, YYYYYYY is the minor revision, and ZZZZZ is the compatability
+ * revision
+ */
+#define XVE_MAJOR_SHIFT_VALUE       12
+#define XVE_MINOR_ONLY_MASK         0x0FE0
+#define XVE_MINOR_SHIFT_VALUE       5
+#define XVE_COMP_ONLY_MASK          0x001F
+
+/* the following constants define the specific characters of a version string
+ * for each character of the revision, a version string is in the following
+ * format, "X.YYZ" where X is the major revision (0 - 9), YY is the minor
+ * revision (00 - 99), and Z is the compatability revision (a - z)
+ */
+#define XVE_MAJOR_CHAR      0	/* major revision 0 - 9 */
+#define XVE_MINOR_TENS_CHAR 2	/* minor revision tens 0 - 9 */
+#define XVE_MINOR_ONES_CHAR 3	/* minor revision ones 0 - 9 */
+#define XVE_COMP_CHAR       4	/* compatability revision a - z */
+#define XVE_END_STRING_CHAR 5
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static u32 IsVersionStringValid(s8 *StringPtr);
+
+/*****************************************************************************/
+/**
+*
+* Unpacks a packed version into the specified version. Versions are packed
+* into the configuration ROM to reduce the amount storage. A packed version
+* is a binary format as oppossed to a non-packed version which is implemented
+* as a string.
+*
+* @param    InstancePtr points to the version to unpack the packed version into.
+* @param    PackedVersion contains the packed version to unpack.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion)
+{
+	/* not implemented yet since CROM related */
+}
+
+/*****************************************************************************/
+/**
+*
+* Packs a version into the specified packed version. Versions are packed into
+* the configuration ROM to reduce the amount storage.
+*
+* @param    InstancePtr points to the version to pack.
+* @param    PackedVersionPtr points to the packed version which will receive
+*           the new packed version.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the packing was accomplished
+* successfully, or an error, XST_INVALID_VERSION, indicating the specified
+* input version was not valid such that the pack did not occur
+* <br><br>
+* The packed version pointed to by PackedVersionPtr is modified with the new
+* packed version if the status indicates success.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XVersion_Pack(XVersion * InstancePtr, u16 *PackedVersionPtr)
+{
+	/* not implemented yet since CROM related */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Determines if two versions are equal.
+*
+* @param    InstancePtr points to the first version to be compared.
+* @param    VersionPtr points to a second version to be compared.
+*
+* @return
+*
+* TRUE if the versions are equal, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Version1 = (u8 *) InstancePtr;
+	u8 *Version2 = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(VersionPtr != NULL);
+
+	/* check each byte of the versions to see if they are the same,
+	 * return at any point a byte differs between them
+	 */
+	for (Index = 0; Index < sizeof(XVersion); Index++) {
+		if (Version1[Index] != Version2[Index]) {
+			return FALSE;
+		}
+	}
+
+	/* No byte was found to be different between the versions, so indicate
+	 * the versions are equal
+	 */
+	return TRUE;
+}
+
+/*****************************************************************************/
+/**
+*
+* Converts a version to a null terminated string.
+*
+* @param    InstancePtr points to the version to convert.
+* @param    StringPtr points to the string which will be the result of the
+*           conversion. This does not need to point to a null terminated
+*           string as an input, but must point to storage which is an adequate
+*           amount to hold the result string.
+*
+* @return
+*
+* The null terminated string is inserted at the location pointed to by
+* StringPtr if the status indicates success.
+*
+* @note
+*
+* It is necessary for the caller to have already allocated the storage to
+* contain the string.  The amount of memory necessary for the string is
+* specified in the version header file.
+*
+******************************************************************************/
+void XVersion_ToString(XVersion * InstancePtr, s8 *StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(StringPtr != NULL);
+
+	/* since version is implemented as a string, just copy the specified
+	 * input into the specified output
+	 */
+	XVersion_Copy(InstancePtr, (XVersion *) StringPtr);
+}
+
+/*****************************************************************************/
+/**
+*
+* Initializes a version from a null terminated string. Since the string may not
+* be a format which is compatible with the version, an error could occur.
+*
+* @param    InstancePtr points to the version which is to be initialized.
+* @param    StringPtr points to a null terminated string which will be
+*           converted to a version.  The format of the string must match the
+*           version string format which is X.YYX where X = 0 - 9, YY = 00 - 99,
+*           Z = a - z.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the conversion was accomplished
+* successfully, or XST_INVALID_VERSION indicating the version string format
+* was not valid.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XVersion_FromString(XVersion * InstancePtr, s8 *StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(StringPtr != NULL);
+
+	/* if the version string specified is not valid, return an error */
+
+	if (!IsVersionStringValid(StringPtr)) {
+		return XST_INVALID_VERSION;
+	}
+
+	/* copy the specified string into the specified version and indicate the
+	 * conversion was successful
+	 */
+	XVersion_Copy((XVersion *) StringPtr, InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Copies the contents of a version to another version.
+*
+* @param    InstancePtr points to the version which is the source of data for
+*           the copy operation.
+* @param    VersionPtr points to another version which is the destination of
+*           the copy operation.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Source = (u8 *) InstancePtr;
+	u8 *Destination = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(VersionPtr != NULL);
+
+	/* copy each byte of the source version to the destination version */
+
+	for (Index = 0; Index < sizeof(XVersion); Index++) {
+		Destination[Index] = Source[Index];
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Determines if the specified version is valid.
+*
+* @param    StringPtr points to the string to be validated.
+*
+* @return
+*
+* TRUE if the version string is a valid format, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static u32 IsVersionStringValid(s8 *StringPtr)
+{
+	/* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
+	 * YY = 00 - 99, and Z = a - z, then indicate it's not valid
+	 */
+	if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
+	    (StringPtr[XVE_MAJOR_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
+	    (StringPtr[XVE_COMP_CHAR] < 'a') ||
+	    (StringPtr[XVE_COMP_CHAR] > 'z')) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
Index: linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xversion.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/drivers/xilinx_common/xversion.h	2014-07-20 22:06:39.258257851 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/* $Id: xversion.h,v 1.1 2006/12/13 14:23:41 imanuilov Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xversion.h
+*
+* This file contains the interface for the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XVERSION_H		/* prevent circular inclusions */
+#define XVERSION_H		/* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+/* the following data type is used to hold a null terminated version string
+ * consisting of the following format, "X.YYX"
+ */
+typedef s8 XVersion[6];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion);
+
+int XVersion_Pack(XVersion * InstancePtr, u16 *PackedVersion);
+
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr);
+
+void XVersion_ToString(XVersion * InstancePtr, s8 *StringPtr);
+
+int XVersion_FromString(XVersion * InstancePtr, s8 *StringPtr);
+
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: linux-3.12.24-rt38-xilinx/include/asm-generic/dma-mapping-common.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/asm-generic/dma-mapping-common.h	2014-07-20 22:05:50.339064921 +0200
+++ linux-3.12.24-rt38-xilinx/include/asm-generic/dma-mapping-common.h	2014-07-20 22:06:39.274257587 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:19 @
 	dma_addr_t addr;
 
 	kmemcheck_mark_initialized(ptr, size);
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	addr = ops->map_page(dev, virt_to_page(ptr),
 			     (unsigned long)ptr & ~PAGE_MASK, size,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:37 @
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
 		ops->unmap_page(dev, addr, size, dir, attrs);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:54 @
 
 	for_each_sg(sg, s, nents, i)
 		kmemcheck_mark_initialized(sg_virt(s), s->length);
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	ents = ops->map_sg(dev, sg, nents, dir, attrs);
 	debug_dma_map_sg(dev, sg, nents, ents, dir);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:68 @
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	debug_dma_unmap_sg(dev, sg, nents, dir);
 	if (ops->unmap_sg)
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:83 @
 	dma_addr_t addr;
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	addr = ops->map_page(dev, page, offset, size, dir, NULL);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:96 @
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
 		ops->unmap_page(dev, addr, size, dir, NULL);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:161 @
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_sg_for_cpu)
 		ops->sync_sg_for_cpu(dev, sg, nelems, dir);
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:174 @
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
+	BUG_ON(!ops);
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_sg_for_device)
 		ops->sync_sg_for_device(dev, sg, nelems, dir);
Index: linux-3.12.24-rt38-xilinx/include/asm-generic/vmlinux.lds.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/asm-generic/vmlinux.lds.h	2014-07-20 22:05:50.340064905 +0200
+++ linux-3.12.24-rt38-xilinx/include/asm-generic/vmlinux.lds.h	2014-07-20 22:06:39.288257356 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:473 @
 	}
 
 #ifdef CONFIG_CONSTRUCTORS
-#define KERNEL_CTORS()	. = ALIGN(8);			   \
-			VMLINUX_SYMBOL(__ctors_start) = .; \
-			*(.ctors)			   \
+#define KERNEL_CTORS()	. = ALIGN(8);					\
+			VMLINUX_SYMBOL(__ctors_start) = .;		\
+			*(CONFIG_CONSTRUCTORS_NAME)			\
 			VMLINUX_SYMBOL(__ctors_end) = .;
 #else
 #define KERNEL_CTORS()
Index: linux-3.12.24-rt38-xilinx/include/drm/drm_edid.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/drm/drm_edid.h	2014-07-20 22:05:50.335064988 +0200
+++ linux-3.12.24-rt38-xilinx/include/drm/drm_edid.h	2014-07-20 22:06:39.303257109 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:277 @
 drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
 					    const struct drm_display_mode *mode);
 
+struct edid *drm_do_get_edid(struct drm_connector *connector,
+	int (*get_edid_block)(void *, unsigned char *buf, int, int),
+	void *data);
+
 #endif /* __DRM_EDID_H__ */
Index: linux-3.12.24-rt38-xilinx/include/drm/i2c/adv7511.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/drm/i2c/adv7511.h	2014-07-20 22:06:39.321256812 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __DRM_I2C_ADV7511_H__
+#define __DRM_I2C_ADV7511_H__
+
+#include <linux/hdmi.h>
+
+#define ADV7511_REG_CHIP_REVISION		0x00
+#define ADV7511_REG_N0				0x01
+#define ADV7511_REG_N1				0x02
+#define ADV7511_REG_N2				0x03
+#define ADV7511_REG_SPDIF_FREQ			0x04
+#define ADV7511_REG_CTS_AUTOMATIC1		0x05
+#define ADV7511_REG_CTS_AUTOMATIC2		0x06
+#define ADV7511_REG_CTS_MANUAL0			0x07
+#define ADV7511_REG_CTS_MANUAL1			0x08
+#define ADV7511_REG_CTS_MANUAL2			0x09
+#define ADV7511_REG_AUDIO_SOURCE		0x0a
+#define ADV7511_REG_AUDIO_CONFIG		0x0b
+#define ADV7511_REG_I2S_CONFIG			0x0c
+#define ADV7511_REG_I2S_WIDTH			0x0d
+#define ADV7511_REG_AUDIO_SUB_SRC0		0x0e
+#define ADV7511_REG_AUDIO_SUB_SRC1		0x0f
+#define ADV7511_REG_AUDIO_SUB_SRC2		0x10
+#define ADV7511_REG_AUDIO_SUB_SRC3		0x11
+#define ADV7511_REG_AUDIO_CFG1			0x12
+#define ADV7511_REG_AUDIO_CFG2			0x13
+#define ADV7511_REG_AUDIO_CFG3			0x14
+#define ADV7511_REG_I2C_FREQ_ID_CFG		0x15
+#define ADV7511_REG_VIDEO_INPUT_CFG1		0x16
+#define ADV7511_REG_CSC_UPPER(x)		(0x18 + (x) * 2)
+#define ADV7511_REG_CSC_LOWER(x)		(0x19 + (x) * 2)
+#define ADV7511_REG_SYNC_DECODER(x)		(0x30 + (x))
+#define ADV7511_REG_DE_GENERATOR		(0x35 + (x))
+#define ADV7511_REG_PIXEL_REPETITION		0x3b
+#define ADV7511_REG_VIC_MANUAL			0x3c
+#define ADV7511_REG_VIC_SEND			0x3d
+#define ADV7511_REG_VIC_DETECTED		0x3e
+#define ADV7511_REG_AUX_VIC_DETECTED		0x3f
+#define ADV7511_REG_PACKET_ENABLE0		0x40
+#define ADV7511_REG_POWER			0x41
+#define ADV7511_REG_STATUS			0x42
+#define ADV7511_REG_EDID_I2C_ADDR		0x43
+#define ADV7511_REG_PACKET_ENABLE1		0x44
+#define ADV7511_REG_PACKET_I2C_ADDR		0x45
+#define ADV7511_REG_DSD_ENABLE			0x46
+#define ADV7511_REG_VIDEO_INPUT_CFG2		0x48
+#define ADV7511_REG_INFOFRAME_UPDATE		0x4a
+#define ADV7511_REG_GC(x)			(0x4b + (x)) /* 0x4b - 0x51 */
+#define ADV7511_REG_AVI_INFOFRAME_VERSION	0x52
+#define ADV7511_REG_AVI_INFOFRAME_LENGTH	0x53
+#define ADV7511_REG_AVI_INFOFRAME_CHECKSUM	0x54
+#define ADV7511_REG_AVI_INFOFRAME(x)		(0x55 + (x)) /* 0x55 - 0x6f */
+#define ADV7511_REG_AUDIO_INFOFRAME_VERSION	0x70
+#define ADV7511_REG_AUDIO_INFOFRAME_LENGTH	0x71
+#define ADV7511_REG_AUDIO_INFOFRAME_CHECKSUM	0x72
+#define ADV7511_REG_AUDIO_INFOFRAME(x)		(0x73 + (x)) /* 0x73 - 0x7c */
+#define ADV7511_REG_INT_ENABLE(x)		(0x94 + (x))
+#define ADV7511_REG_INT(x)			(0x96 + (x))
+#define ADV7511_REG_INPUT_CLK_DIV		0x9d
+#define ADV7511_REG_PLL_STATUS			0x9e
+#define ADV7511_REG_HDMI_POWER			0xa1
+#define ADV7511_REG_HDCP_HDMI_CFG		0xaf
+#define ADV7511_REG_AN(x)			(0xb0 + (x)) /* 0xb0 - 0xb7 */
+#define ADV7511_REG_HDCP_STATUS			0xb8
+#define ADV7511_REG_BCAPS			0xbe
+#define ADV7511_REG_BKSV(x)			(0xc0 + (x)) /* 0xc0 - 0xc3 */
+#define ADV7511_REG_EDID_SEGMENT		0xc4
+#define ADV7511_REG_DDC_STATUS			0xc8
+#define ADV7511_REG_EDID_READ_CTRL		0xc9
+#define ADV7511_REG_BSTATUS(x)			(0xca + (x)) /* 0xca - 0xcb */
+#define ADV7511_REG_TIMING_GEN_SEQ		0xd0
+#define ADV7511_REG_POWER2			0xd6
+#define ADV7511_REG_HSYNC_PLACEMENT_MSB		0xfa
+
+#define ADV7511_REG_SYNC_ADJUSTMENT(x)		(0xd7 + (x)) /* 0xd7 - 0xdc */
+#define ADV7511_REG_TMDS_CLOCK_INV		0xde
+#define ADV7511_REG_ARC_CTRL			0xdf
+#define ADV7511_REG_CEC_I2C_ADDR		0xe1
+#define ADV7511_REG_CEC_CTRL			0xe2
+#define ADV7511_REG_CHIP_ID_HIGH		0xf5
+#define ADV7511_REG_CHIP_ID_LOW			0xf6
+
+#define ADV7511_CSC_ENABLE			BIT(7)
+#define ADV7511_CSC_UPDATE_MODE			BIT(5)
+
+#define ADV7511_INT0_HDP			BIT(7)
+#define ADV7511_INT0_VSYNC			BIT(5)
+#define ADV7511_INT0_AUDIO_FIFO_FULL		BIT(4)
+#define ADV7511_INT0_EDID_READY			BIT(2)
+#define ADV7511_INT0_HDCP_AUTHENTICATED		BIT(1)
+
+#define ADV7511_INT1_DDC_ERROR			BIT(7)
+#define ADV7511_INT1_BKSV			BIT(6)
+#define ADV7511_INT1_CEC_TX_READY		BIT(5)
+#define ADV7511_INT1_CEC_TX_ARBIT_LOST		BIT(4)
+#define ADV7511_INT1_CEC_TX_RETRY_TIMEOUT	BIT(3)
+#define ADV7511_INT1_CEC_RX_READY3		BIT(2)
+#define ADV7511_INT1_CEC_RX_READY2		BIT(1)
+#define ADV7511_INT1_CEC_RX_READY1		BIT(0)
+
+#define ADV7511_ARC_CTRL_POWER_DOWN		BIT(0)
+
+#define ADV7511_CEC_CTRL_POWER_DOWN		BIT(0)
+
+#define ADV7511_POWER_POWER_DOWN		BIT(6)
+
+#define ADV7511_AUDIO_SELECT_I2C		0x0
+#define ADV7511_AUDIO_SELECT_SPDIF		0x1
+#define ADV7511_AUDIO_SELECT_DSD		0x2
+#define ADV7511_AUDIO_SELECT_HBR		0x3
+#define ADV7511_AUDIO_SELECT_DST		0x4
+
+#define ADV7511_I2S_SAMPLE_LEN_16		0x2
+#define ADV7511_I2S_SAMPLE_LEN_20		0x3
+#define ADV7511_I2S_SAMPLE_LEN_18		0x4
+#define ADV7511_I2S_SAMPLE_LEN_22		0x5
+#define ADV7511_I2S_SAMPLE_LEN_19		0x8
+#define ADV7511_I2S_SAMPLE_LEN_23		0x9
+#define ADV7511_I2S_SAMPLE_LEN_24		0xb
+#define ADV7511_I2S_SAMPLE_LEN_17		0xc
+#define ADV7511_I2S_SAMPLE_LEN_21		0xd
+
+#define ADV7511_SAMPLE_FREQ_44100		0x0
+#define ADV7511_SAMPLE_FREQ_48000		0x2
+#define ADV7511_SAMPLE_FREQ_32000		0x3
+#define ADV7511_SAMPLE_FREQ_88200		0x8
+#define ADV7511_SAMPLE_FREQ_96000		0xa
+#define ADV7511_SAMPLE_FREQ_176400		0xc
+#define ADV7511_SAMPLE_FREQ_192000		0xe
+
+#define ADV7511_STATUS_POWER_DOWN_POLARITY	BIT(7)
+#define ADV7511_STATUS_HPD			BIT(6)
+#define ADV7511_STATUS_MONITOR_SENSE		BIT(5)
+#define ADV7511_STATUS_I2S_32BIT_MODE		BIT(3)
+
+#define ADV7511_PACKET_ENABLE_N_CTS		BIT(8+6)
+#define ADV7511_PACKET_ENABLE_AUDIO_SAMPLE	BIT(8+5)
+#define ADV7511_PACKET_ENABLE_AVI_INFOFRAME	BIT(8+4)
+#define ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME	BIT(8+3)
+#define ADV7511_PACKET_ENABLE_GC		BIT(7)
+#define ADV7511_PACKET_ENABLE_SPD		BIT(6)
+#define ADV7511_PACKET_ENABLE_MPEG		BIT(5)
+#define ADV7511_PACKET_ENABLE_ACP		BIT(4)
+#define ADV7511_PACKET_ENABLE_ISRC		BIT(3)
+#define ADV7511_PACKET_ENABLE_GM		BIT(2)
+#define ADV7511_PACKET_ENABLE_SPARE2		BIT(1)
+#define ADV7511_PACKET_ENABLE_SPARE1		BIT(0)
+
+#define ADV7511_REG_POWER2_HDP_SRC_MASK		0xc0
+#define ADV7511_REG_POWER2_HDP_SRC_BOTH		0x00
+#define ADV7511_REG_POWER2_HDP_SRC_HDP		0x40
+#define ADV7511_REG_POWER2_HDP_SRC_CEC		0x80
+#define ADV7511_REG_POWER2_HDP_SRC_NONE		0xc0
+#define ADV7511_REG_POWER2_TDMS_ENABLE		BIT(4)
+#define ADV7511_REG_POWER2_GATE_INPUT_CLK	BIT(0)
+
+#define ADV7511_LOW_REFRESH_RATE_NONE		0x0
+#define ADV7511_LOW_REFRESH_RATE_24HZ		0x1
+#define ADV7511_LOW_REFRESH_RATE_25HZ		0x2
+#define ADV7511_LOW_REFRESH_RATE_30HZ		0x3
+
+#define ADV7511_AUDIO_CFG3_LEN_MASK		0x0f
+#define ADV7511_I2C_FREQ_ID_CFG_RATE_MASK	0xf0
+
+#define ADV7511_AUDIO_SOURCE_I2S		0
+#define ADV7511_AUDIO_SOURCE_SPDIF		1
+
+#define ADV7511_I2S_FORMAT_I2S			0
+#define ADV7511_I2S_FORMAT_RIGHT_J		1
+#define ADV7511_I2S_FORMAT_LEFT_J		2
+
+#define ADV7511_PACKET(p, x)	    ((p) * 0x20 + (x))
+#define ADV7511_PACKET_SDP(x)	    ADV7511_PACKET(0, x)
+#define ADV7511_PACKET_MPEG(x)	    ADV7511_PACKET(1, x)
+#define ADV7511_PACKET_ACP(x)	    ADV7511_PACKET(2, x)
+#define ADV7511_PACKET_ISRC1(x)	    ADV7511_PACKET(3, x)
+#define ADV7511_PACKET_ISRC2(x)	    ADV7511_PACKET(4, x)
+#define ADV7511_PACKET_GM(x)	    ADV7511_PACKET(5, x)
+#define ADV7511_PACKET_SPARE(x)	    ADV7511_PACKET(6, x)
+
+#include <drm/drmP.h>
+
+struct i2c_client;
+struct regmap;
+struct adv7511;
+
+int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet);
+int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet);
+
+int adv7511_audio_init(struct device *dev);
+void adv7511_audio_exit(struct device *dev);
+
+/**
+ * enum adv7511_input_style - Selects the input format style
+ * @ADV7511_INPUT_STYLE1: Use input style 1
+ * @ADV7511_INPUT_STYLE2: Use input style 2
+ * @ADV7511_INPUT_STYLE3: Use input style 3
+ */
+enum adv7511_input_style {
+	ADV7511_INPUT_STYLE1 = 2,
+	ADV7511_INPUT_STYLE2 = 1,
+	ADV7511_INPUT_STYLE3 = 3,
+};
+
+/**
+ * enum adv7511_input_id - Selects the input format id
+ * @ADV7511_INPUT_ID_24BIT_RGB444_YCbCr444: Input pixel format is 24-bit 444 RGB
+ *					    or 444 YCbCR with separate syncs
+ * @ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_SEPARATE_SYNC: FIXME
+ * @ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC: FIXME
+ * @ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_SEPARATE_SYNC: FIXME
+ * @ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_EMBEDDED_SYNC: FIXME
+ * @ADV7511_INPUT_ID_12_15_16BIT_RGB444_YCbCr444: FIXME
+ */
+enum adv7511_input_id {
+	ADV7511_INPUT_ID_24BIT_RGB444_YCbCr444 = 0,
+	ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_SEPARATE_SYNC = 1,
+	ADV7511_INPUT_ID_16_20_24BIT_YCbCr422_EMBEDDED_SYNC = 2,
+	ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_SEPARATE_SYNC = 3,
+	ADV7511_INPUT_ID_8_10_12BIT_YCbCr422_EMBEDDED_SYNC = 4,
+	ADV7511_INPUT_ID_12_15_16BIT_RGB444_YCbCr444 = 5,
+};
+
+/**
+ * enum adv7511_input_bit_justifiction - Selects the input format bit
+ *					 justifiction
+ * @ADV7511_INPUT_BIT_JUSTIFICATION_EVENLY: Input bits are evenly distributed
+ * @ADV7511_INPUT_BIT_JUSTIFICATION_RIGHT: Input bit signals have right
+ *					  justification
+ * @ADV7511_INPUT_BIT_JUSTIFICATION_LEFT: Input bit signals have left
+ *					 justification
+ */
+enum adv7511_input_bit_justifiction {
+	ADV7511_INPUT_BIT_JUSTIFICATION_EVENLY = 0,
+	ADV7511_INPUT_BIT_JUSTIFICATION_RIGHT = 1,
+	ADV7511_INPUT_BIT_JUSTIFICATION_LEFT = 2,
+};
+
+/**
+ * enum adv7511_input_color_depth - Selects the input format color depth
+ * @ADV7511_INPUT_COLOR_DEPTH_8BIT: Input format color depth is 8 bits per
+ *				    channel
+ * @ADV7511_INPUT_COLOR_DEPTH_10BIT: Input format color dpeth is 10 bits per
+ *				     channel
+ * @ADV7511_INPUT_COLOR_DEPTH_12BIT: Input format color depth is 12 bits per
+ *				     channel
+ */
+enum adv7511_input_color_depth {
+	ADV7511_INPUT_COLOR_DEPTH_8BIT = 3,
+	ADV7511_INPUT_COLOR_DEPTH_10BIT = 1,
+	ADV7511_INPUT_COLOR_DEPTH_12BIT = 2,
+};
+
+/**
+ * enum adv7511_input_sync_pulse - Selects the sync pulse
+ * @ADV7511_INPUT_SYNC_PULSE_DE: Use the DE signal as sync pulse
+ * @ADV7511_INPUT_SYNC_PULSE_HSYNC: Use the HSYNC signal as sync pulse
+ * @ADV7511_INPUT_SYNC_PULSE_VSYNC: Use the VSYNC signal as sync pulse
+ * @ADV7511_INPUT_SYNC_PULSE_NONE: No external sync pulse signal
+ */
+enum adv7511_input_sync_pulse {
+	ADV7511_INPUT_SYNC_PULSE_DE = 0,
+	ADV7511_INPUT_SYNC_PULSE_HSYNC = 1,
+	ADV7511_INPUT_SYNC_PULSE_VSYNC = 2,
+	ADV7511_INPUT_SYNC_PULSE_NONE = 3,
+};
+
+/**
+ * enum adv7511_input_clock_delay - Delay for the video data input clock
+ * @ADV7511_INPUT_CLOCK_DELAY_MINUS_1200PS: -1200 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_MINUS_800PS: -800 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_MINUS_400PS: -400 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_NONE: No delay
+ * @ADV7511_INPUT_CLOCK_DELAY_PLUS_400PS: 400 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_PLUS_800PS: 800 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_PLUS_1200PS: 1200 pico seconds delay
+ * @ADV7511_INPUT_CLOCK_DELAY_PLUS_1600PS: 1600 pico seconds delay
+ */
+enum adv7511_input_clock_delay {
+	ADV7511_INPUT_CLOCK_DELAY_MINUS_1200PS = 0,
+	ADV7511_INPUT_CLOCK_DELAY_MINUS_800PS = 1,
+	ADV7511_INPUT_CLOCK_DELAY_MINUS_400PS = 2,
+	ADV7511_INPUT_CLOCK_DELAY_NONE = 3,
+	ADV7511_INPUT_CLOCK_DELAY_PLUS_400PS = 4,
+	ADV7511_INPUT_CLOCK_DELAY_PLUS_800PS = 5,
+	ADV7511_INPUT_CLOCK_DELAY_PLUS_1200PS = 6,
+	ADV7511_INPUT_CLOCK_DELAY_PLUS_1600PS = 7,
+};
+
+/**
+ * enum adv7511_sync_polarity - Polarity for the input sync signals
+ * @ADV7511_SYNC_POLARITY_PASSTHROUGH:  Sync polarity matches that of
+ *				       the currently configured mode.
+ * @ADV7511_SYNC_POLARITY_LOW:	    Sync polarity is low
+ * @ADV7511_SYNC_POLARITY_HIGH:	    Sync polarity is high
+ *
+ * If the polarity is set to either ADV7511_SYNC_POLARITY_LOW or
+ * ADV7511_SYNC_POLARITY_HIGH the ADV7511 will internally invert the signal if
+ * it is required to match the sync polarity setting for the currently selected
+ * mode. If the polarity is set to ADV7511_SYNC_POLARITY_PASSTHROUGH,
+ * the ADV7511 will route the signal unchanged, this is useful if the upstream
+ * graphics core will already generate the sync singals with the correct
+ * polarity.
+ */
+enum adv7511_sync_polarity {
+	ADV7511_SYNC_POLARITY_PASSTHROUGH,
+	ADV7511_SYNC_POLARITY_LOW,
+	ADV7511_SYNC_POLARITY_HIGH,
+};
+
+/**
+ * enum adv7511_timing_gen_seq - Selects the order in which timing adjustments
+ * are performed
+ * @ADV7511_TIMING_GEN_SEQ_SYN_ADJ_FIRST: Sync adjustment first,
+ *					  then DE generation
+ * @ADV7511_TIMING_GEN_SEQ_DE_GEN_FIRST: DE generation first,
+ *					 then sync adjustment
+ *
+ * This setting is only relevant if both DE generation and sync adjustment are
+ * active.
+ */
+enum adv7511_timing_gen_seq {
+	ADV7511_TIMING_GEN_SEQ_SYN_ADJ_FIRST = 0,
+	ADV7511_TIMING_GEN_SEQ_DE_GEN_FIRST = 1,
+};
+
+/**
+ * enum adv7511_up_conversion - Selects the upscaling conversion method
+ * @ADV7511_UP_CONVERSION_ZERO_ORDER: Use zero order up conversion
+ * @ADV7511_UP_CONVERSION_FIRST_ORDER: Use first order up conversion
+ *
+ * This used when converting from a 4:2:2 format to a 4:4:4 format.
+ */
+enum adv7511_up_conversion {
+	ADV7511_UP_CONVERSION_ZERO_ORDER = 0,
+	ADV7511_UP_CONVERSION_FIRST_ORDER = 1,
+};
+
+/**
+ * struct adv7511_link_config - Describes adv7511 hardware configuration
+ * @id:				Video input format id
+ * @input_style:		Video input format style
+ * @sync_pulse:			Select the sync pulse
+ * @clock_delay:		Clock delay for the input clock
+ * @reverse_bitorder:		Reverse video input signal bitorder
+ * @bit_justification:		Video input format bit justification
+ * @up_conversion:		Selects the upscaling conversion method
+ * @input_color_depth:		Input video format color depth
+ * @tmds_clock_inversion:	Whether to invert the TDMS clock
+ * @timing_gen_seq:		Selects the order in which sync DE generation
+ *				and sync adjustment are performt.
+ * @vsync_polarity:		vsync input signal configuration
+ * @hsync_polarity:		hsync input signal configuration
+ * @gpio_pd:			GPIO controlling the PD (powerdown) pin
+ */
+struct adv7511_link_config {
+	enum adv7511_input_id id;
+	enum adv7511_input_style input_style;
+	enum adv7511_input_sync_pulse sync_pulse;
+	enum adv7511_input_clock_delay clock_delay;
+	bool reverse_bitorder;
+	enum adv7511_input_bit_justifiction bit_justification;
+	enum adv7511_up_conversion up_conversion;
+	enum adv7511_input_color_depth input_color_depth;
+	bool tmds_clock_inversion;
+	enum adv7511_timing_gen_seq timing_gen_seq;
+
+	enum adv7511_sync_polarity vsync_polarity;
+	enum adv7511_sync_polarity hsync_polarity;
+
+	int gpio_pd;
+};
+
+/*
+ *	adi,input-style = 1|2|3;
+ *	adi,input-id =
+ *		"24-bit-rgb444-ycbcr444",
+ *		"16-20-24-bit-ycbcr422-separate-sync" |
+ *		"16-20-24-bit-ycbcr422-embedded-sync" |
+ *		"8-10-12-bit-ycbcr422-separate-sync" |
+ *		"8-10-12-bit-ycbcr422-embedded-sync" |
+ *		"12-15-16-bit-rgb444-ycbcr444"
+ *	adi,sync-pulse = "de","vsync","hsync","none"
+ *	adi,clock-delay = -1200|-800|-400|0|400|800|1200|1600
+ *	adi,reverse-bitorder
+ *	adi,bit-justification = "left"|"right"|"evently";
+ *	adi,up-conversion = "zero-order"|"first-order"
+ *	adi,input-color-depth = 8|10|12
+ *	adi,tdms-clock-inversion
+ *	adi,vsync-polarity = "low"|"high"|"passthrough"
+ *	adi,hsync-polarity = "low"|"high"|"passtrhough"
+ *	adi,timing-gen-seq = "sync-adjustment-first"|"de-generation-first"
+ */
+
+/**
+ * enum adv7511_csc_scaling - Scaling factor for the ADV7511 CSC
+ * @ADV7511_CSC_SCALING_1: CSC results are not scaled
+ * @ADV7511_CSC_SCALING_2: CSC results are scaled by a factor of two
+ * @ADV7511_CSC_SCALING_4: CSC results are scalled by a factor of four
+ */
+enum adv7511_csc_scaling {
+	ADV7511_CSC_SCALING_1 = 0,
+	ADV7511_CSC_SCALING_2 = 1,
+	ADV7511_CSC_SCALING_4 = 2,
+};
+
+/**
+ * struct adv7511_video_config - Describes adv7511 hardware configuration
+ * @csc_enable:			Whether to enable color space conversion
+ * @csc_scaling_factor:		Color space conversion scaling factor
+ * @csc_coefficents:		Color space conversion coefficents
+ * @hdmi_mode:			Whether to use HDMI or DVI output mode
+ * @avi_infoframe:		HDMI infoframe
+ */
+struct adv7511_video_config {
+	bool csc_enable;
+	enum adv7511_csc_scaling csc_scaling_factor;
+	const uint16_t *csc_coefficents;
+
+	bool hdmi_mode;
+	struct hdmi_avi_infoframe avi_infoframe;
+};
+
+struct adv7511 {
+	struct i2c_client *i2c_main;
+	struct i2c_client *i2c_edid;
+	struct i2c_client *i2c_packet;
+	struct i2c_client *i2c_cec;
+
+	struct regmap *regmap;
+	struct regmap *packet_memory_regmap;
+	enum drm_connector_status status;
+	int dpms_mode;
+
+	unsigned int f_tmds;
+	unsigned int f_audio;
+
+	unsigned int audio_source;
+
+	unsigned int current_edid_segment;
+	uint8_t edid_buf[256];
+
+	wait_queue_head_t wq;
+	struct drm_encoder *encoder;
+
+	bool embedded_sync;
+	enum adv7511_sync_polarity vsync_polarity;
+	enum adv7511_sync_polarity hsync_polarity;
+
+	struct edid *edid;
+
+	int gpio_pd;
+};
+
+struct edid *adv7511_get_edid(struct drm_encoder *encoder);
+
+#endif /* __DRM_I2C_ADV7511_H__ */
Index: linux-3.12.24-rt38-xilinx/include/linux/amba/bus.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/amba/bus.h	2014-07-20 22:05:50.350064740 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/amba/bus.h	2014-07-20 22:06:39.335256581 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:24 @
 #include <linux/resource.h>
 #include <linux/regulator/consumer.h>
 
-#define AMBA_NR_IRQS	2
+#define AMBA_NR_IRQS	10
 #define AMBA_CID	0xb105f00d
 
 struct clk;
Index: linux-3.12.24-rt38-xilinx/include/linux/amba/xilinx_dma.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/amba/xilinx_dma.h	2014-07-20 22:06:39.344256432 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx DMA Engines support header file
+ *
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  . Axi CDMA engine, it does transfers between memory and memory, it
+ *    only has one channel.
+ *  . Axi DMA engine, it does transfers between memory and device. It can be
+ *    configured to have one channel or two channels. If configured as two
+ *    channels, one is to transmit to device and another is to receive from
+ *    device.
+ *  . Axi VDMA engine, it does transfers between memory and video devices.
+ *    It can be configured to have one channel or two channels. If configured
+ *    as two channels, one is to transmit to the video device and another is
+ *    to receive from the video device.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __DMA_XILINX_DMA_H
+#define __DMA_XILINX_DMA_H
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+
+/* Specific hardware configuration-related constants */
+#define XILINX_DMA_NO_CHANGE	0xFFFF;
+
+/* DMA IP masks */
+#define XILINX_DMA_IP_DMA	0x00100000	/* A DMA IP */
+#define XILINX_DMA_IP_CDMA	0x00200000	/* A Central DMA IP */
+#define XILINX_DMA_IP_VDMA	0x00400000	/* A Video DMA IP */
+#define XILINX_DMA_IP_MASK	0x00700000	/* DMA IP MASK */
+
+/* Device Id in the private structure */
+#define XILINX_DMA_DEVICE_ID_SHIFT	28
+
+/*
+ * Device configuration structure
+ *
+ * If used to start/stop parking mode for Xilinx VDMA, vsize must be -1
+ * If used to set interrupt coalescing and delay counter only for
+ * Xilinx VDMA, hsize must be -1
+ */
+struct xilinx_vdma_config {
+	int reserved;			/* Not used */
+	int vsize;			/* Vertical size */
+	int hsize;			/* Horizontal size */
+	int stride;			/* Stride */
+	int frm_dly;			/* Frame delay */
+	int gen_lock;			/* Whether in gen-lock mode */
+	int master;			/* Master that it syncs to */
+	int frm_cnt_en;			/* Enable frame count enable */
+	int park;			/* Whether wants to park */
+	int park_frm;			/* Frame to park on */
+	int coalesc;			/* Interrupt coalescing threshold */
+	int delay;			/* Delay counter */
+	int reset;			/* Reset Channel */
+	int ext_fsync;			/* External Frame Sync */
+};
+
+/* Device configuration structure for DMA */
+struct xilinx_dma_config {
+	enum dma_transfer_direction direction;
+					/* Channel direction */
+	int coalesc;			/* Interrupt coalescing threshold */
+	int delay;			/* Delay counter */
+	int reset;			/* Reset Channel */
+};
+
+/* Device configuration structure for CDMA */
+struct xilinx_cdma_config {
+	enum dma_transfer_direction direction;
+					/* Channel direction */
+	int coalesc;			/* Interrupt coalescing threshold */
+	int delay;			/* Delay counter */
+	int reset;			/* Reset Channel */
+};
+
+#endif
Index: linux-3.12.24-rt38-xilinx/include/linux/clk/zynq.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/clk/zynq.h	2014-07-20 22:05:50.347064789 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/clk/zynq.h	2014-07-20 22:06:39.358256202 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:25 @
 
 #include <linux/spinlock.h>
 
+extern unsigned int zynq_clk_suspended;
+
+int zynq_clk_suspend_early(void);
+void zynq_clk_resume_late(void);
+void zynq_clk_topswitch_enable(void);
+void zynq_clk_topswitch_disable(void);
 void zynq_clock_init(void __iomem *slcr);
 
 struct clk *clk_register_zynq_pll(const char *name, const char *parent,
Index: linux-3.12.24-rt38-xilinx/include/linux/clk.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/clk.h	2014-07-20 22:05:50.349064756 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/clk.h	2014-07-20 22:06:39.369256020 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:227 @
 
 
 /**
- * clk_round_rate - adjust a rate to the exact rate a clock can provide
+ * clk_round_rate - round a rate to the exact rate a clock can provide not
+ *		    exceeding @rate
  * @clk: clock source
  * @rate: desired clock rate in Hz
  *
- * Returns rounded clock rate in Hz, or negative errno.
+ * Returns rounded clock rate in Hz, or parent rate
  */
 long clk_round_rate(struct clk *clk, unsigned long rate);
 
 /**
+ * clk_round_rate_nearest - round a rate to the exact rate a clock can provide
+ * @clk: the clk for which we are rounding a rate
+ * @rate: the rate which is to be rounded
+ *
+ * Returns rounded clock rate in Hz, or parent rate
+ */
+long clk_round_rate_nearest(struct clk *clk, unsigned long rate);
+
+/**
  * clk_set_rate - set the clock rate for a clock source
  * @clk: clock source
  * @rate: desired clock rate in Hz
Index: linux-3.12.24-rt38-xilinx/include/linux/i2c/si570.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/i2c/si570.h	2014-07-20 22:06:39.382255806 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * si570.h - Configuration for si570 misc driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License only).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_SI570_H
+#define __LINUX_SI570_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+struct si570_platform_data {
+	u64 factory_fout;		/* Factory default output frequency */
+	unsigned long initial_fout;	/* Requested initial frequency */
+};
+
+int get_frequency_si570(struct device *dev, unsigned long *freq);
+int set_frequency_si570(struct device *dev, unsigned long freq);
+int reset_si570(struct device *dev, int id);
+struct i2c_client *get_i2c_client_si570(void);
+
+#endif /* __LINUX_SI570_H */
Index: linux-3.12.24-rt38-xilinx/include/linux/irqchip/arm-gic.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/irqchip/arm-gic.h	2014-07-20 22:05:50.343064855 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/irqchip/arm-gic.h	2014-07-20 22:06:39.394255608 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:70 @
 		    u32 offset, struct device_node *);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_cpu_if_down(void);
+void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+
+void gic_set_cpu(unsigned int cpu, unsigned int irq);
 
 static inline void gic_init(unsigned int nr, int start,
 			    void __iomem *dist , void __iomem *cpu)
Index: linux-3.12.24-rt38-xilinx/include/linux/memory/zynq-smc.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/memory/zynq-smc.h	2014-07-20 22:06:39.406255410 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx Zynq SMC Driver Header
+ *
+ * Copyright (C) 2012 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __LINUX_MEMORY_ZYNQ_SMC_H
+#define __LINUX_MEMORY_ZYNQ_SMC_H
+
+enum xsmcps_ecc_mode {
+	XSMCPS_ECCMODE_BYPASS = 0,
+	XSMCPS_ECCMODE_APB = 1,
+	XSMCPS_ECCMODE_MEM = 2
+};
+
+u32 xsmcps_get_ecc_val(int ecc_reg);
+int xsmcps_ecc_is_busy(void);
+int xsmcps_get_nand_int_status_raw(void);
+void xsmcps_clr_nand_int(void);
+int xsmcps_set_ecc_mode(enum xsmcps_ecc_mode mode);
+int xsmcps_set_ecc_pg_size(unsigned int pg_sz);
+
+#endif
Index: linux-3.12.24-rt38-xilinx/include/linux/remoteproc.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/remoteproc.h	2014-07-20 22:05:50.346064806 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/remoteproc.h	2014-07-20 22:06:39.416255245 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:118 @
 	RSC_DEVMEM	= 1,
 	RSC_TRACE	= 2,
 	RSC_VDEV	= 3,
-	RSC_LAST	= 4,
+	RSC_MMU		= 4,
+	RSC_LAST	= 5,
 };
 
 #define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
Index: linux-3.12.24-rt38-xilinx/include/linux/rpmsg.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/rpmsg.h	2014-07-20 22:05:50.342064872 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/rpmsg.h	2014-07-20 22:06:39.438254882 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:332 @
 	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
 }
 
+int get_virtproc_id(struct virtproc_info *vrp);
+struct rpmsg_channel *rpmsg_create_channel(int vrp_id, const char *name,
+							int src, int dst);
+
 #endif /* _LINUX_RPMSG_H */
Index: linux-3.12.24-rt38-xilinx/include/linux/rpmsg_omx.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/rpmsg_omx.h	2014-07-20 22:06:39.446254750 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * OMX offloading remote processor driver
+ *
+ * Copyright(c) 2011 Texas Instruments. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RPMSG_OMX_H
+#define RPMSG_OMX_H
+
+#include <linux/ioctl.h>
+
+#define OMX_IOC_MAGIC	'X'
+
+#define OMX_IOCCONNECT	_IOW(OMX_IOC_MAGIC, 1, char *)
+
+#define OMX_IOC_MAXNR	(1)
+
+#ifdef __KERNEL__
+
+/**
+ * enum omx_msg_types - various message types currently supported
+ *
+ * @OMX_CONN_REQ: a connection request message type. the message should carry
+ * the name of the OMX service which we try to connect to. An instance of
+ * that service will be created remotely, and its address will be sent as
+ * a reply.
+ *
+ * @OMX_CONN_RSP: a response to a connection request. the message will carry
+ * an error code (success/failure), and if connection established successfully,
+ * the addr field will carry the address of the newly created OMX instance.
+ *
+ * @OMX_DISCONNECT: disconnect remote OMX instance. this message tells
+ * remote processor to release the resources coupled with this connection
+ *
+ * @OMX_RAW_MSG: a message that should be propagated as-is to the user.
+ * this would immediately enable user space development to start.
+ * as we progress, most likely this message won't be needed anymore.
+ */
+enum omx_msg_types {
+	OMX_CONN_REQ = 0,
+	OMX_CONN_RSP = 1,
+	OMX_DISCONNECT = 4,
+	OMX_RAW_MSG = 5,
+	/* todo: do we need a disconnect response ? ION refcounts should allow
+	 * asynchronous release of relevant buffers */
+};
+
+/**
+ * enum omx_error_codes - various error codes that will be used
+ *
+ * @OMX_SUCCESS: success
+ *
+ * @OMX_NOTSUPP: not supported
+ *
+ * @OMX_NOMEM: remote processor is out of memory
+ */
+enum omx_error_codes {
+	OMX_SUCCESS = 0,
+	OMX_NOTSUPP = 1,
+	OMX_NOMEM = 2,
+};
+
+/* keep documenting... */
+enum omx_state {
+	OMX_UNCONNECTED,
+	OMX_CONNECTED,
+	OMX_FAIL,
+};
+
+/**
+ * struct omx_msg_hdr - common header for all OMX messages
+ * @type:	type of message, see enum omx_msg_types
+ * @flags:	currently unused, should be zero
+ * @len:	length of msg payload (in bytes)
+ * @data:	the msg payload (depends on the message type)
+ *
+ * All OMX messages will start with this common header (which will begin
+ * right after the standard rpmsg header ends).
+ */
+struct omx_msg_hdr {
+	u32 type;
+	u32 flags;
+	u32 len;
+	char data[0];
+} __packed;
+
+struct omx_conn_rsp {
+	u32 status;
+	u32 addr;
+} __packed;
+
+struct omx_disc_req {
+	u32 addr;
+} __packed;
+
+
+#endif /* __KERNEL__ */
+
+/* temporarily exposed to user space too */
+struct omx_conn_req {
+	char name[48];
+} __packed;
+
+#endif /* RPMSG_OMX_H */
Index: linux-3.12.24-rt38-xilinx/include/linux/socket.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/socket.h	2014-07-20 22:05:50.344064839 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/socket.h	2014-07-20 22:06:39.455254601 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:183 @
 #define AF_ALG		38	/* Algorithm sockets		*/
 #define AF_NFC		39	/* NFC sockets			*/
 #define AF_VSOCK	40	/* vSockets			*/
-#define AF_MAX		41	/* For now.. */
+#define AF_RPMSG	41	/* Remote-processor messaging   */
+#define AF_MAX		42	/* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC	AF_UNSPEC
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:230 @
 #define PF_NFC		AF_NFC
 #define PF_VSOCK	AF_VSOCK
 #define PF_MAX		AF_MAX
+#define PF_RPMSG	AF_RPMSG
 
 /* Maximum queue length specifiable by listen.  */
 #define SOMAXCONN	128
Index: linux-3.12.24-rt38-xilinx/include/linux/spi/spi.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/spi/spi.h	2014-07-20 22:05:50.341064888 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/spi/spi.h	2014-07-20 22:06:39.592252342 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:333 @
 #define SPI_MASTER_HALF_DUPLEX	BIT(0)		/* can't do full duplex */
 #define SPI_MASTER_NO_RX	BIT(1)		/* can't do buffer read */
 #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
+#define SPI_MASTER_U_PAGE	BIT(3)		/* select upper flash */
+#define SPI_MASTER_QUAD_MODE	BIT(4)		/* support quad mode */
 
 	/* lock and mutex for SPI bus locking */
 	spinlock_t		bus_lock_spinlock;
Index: linux-3.12.24-rt38-xilinx/include/linux/usb/c67x00.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/linux/usb/c67x00.h	2014-07-20 22:05:50.348064773 +0200
+++ linux-3.12.24-rt38-xilinx/include/linux/usb/c67x00.h	2014-07-20 22:06:39.606252111 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:44 @
 #define C67X00_SIE2_PERIPHERAL_B	(C67X00_SIE_PERIPHERAL_B	<< 4)
 
 struct c67x00_platform_data {
-	int sie_config;			/* SIEs config (C67X00_SIEx_*) */
-	unsigned long hpi_regstep;	/* Step between HPI registers  */
+	u32 sie_config;			/* SIEs config (C67X00_SIEx_*) */
+	u32 hpi_regstep;	/* Step between HPI registers  */
 };
 
 #endif /* _LINUX_USB_C67X00_H */
Index: linux-3.12.24-rt38-xilinx/include/linux/usb/xilinx_usbps_otg.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/usb/xilinx_usbps_otg.h	2014-07-20 22:06:39.616251946 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx PS USB OTG Driver Header file.
+ *
+ * Copyright 2011 Xilinx, Inc.
+ *
+ * This file is based on langwell_otg.h file with few minor modifications
+ * to support Xilinx PS USB controller.
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __XILINX_XUSBPS_OTG_H
+#define __XILINX_XUSBPS_OTG_H
+
+#define CI_USBCMD		0x140
+#	define USBCMD_RST		BIT(1)
+#	define USBCMD_RS		BIT(0)
+#define CI_USBSTS		0x144
+#	define USBSTS_SLI		BIT(8)
+#	define USBSTS_URI		BIT(6)
+#	define USBSTS_PCI		BIT(2)
+#define CI_PORTSC1		0x184
+#	define PORTSC_PP		BIT(12)
+#	define PORTSC_LS		(BIT(11) | BIT(10))
+#	define PORTSC_SUSP		BIT(7)
+#	define PORTSC_CCS		BIT(0)
+#define CI_OTGSC		0x1a4
+#	define OTGSC_DPIE		BIT(30)
+#	define OTGSC_1MSE		BIT(29)
+#	define OTGSC_BSEIE		BIT(28)
+#	define OTGSC_BSVIE		BIT(27)
+#	define OTGSC_ASVIE		BIT(26)
+#	define OTGSC_AVVIE		BIT(25)
+#	define OTGSC_IDIE		BIT(24)
+#	define OTGSC_DPIS		BIT(22)
+#	define OTGSC_1MSS		BIT(21)
+#	define OTGSC_BSEIS		BIT(20)
+#	define OTGSC_BSVIS		BIT(19)
+#	define OTGSC_ASVIS		BIT(18)
+#	define OTGSC_AVVIS		BIT(17)
+#	define OTGSC_IDIS		BIT(16)
+#	define OTGSC_DPS		BIT(14)
+#	define OTGSC_1MST		BIT(13)
+#	define OTGSC_BSE		BIT(12)
+#	define OTGSC_BSV		BIT(11)
+#	define OTGSC_ASV		BIT(10)
+#	define OTGSC_AVV		BIT(9)
+#	define OTGSC_ID			BIT(8)
+#	define OTGSC_HABA		BIT(7)
+#	define OTGSC_HADP		BIT(6)
+#	define OTGSC_IDPU		BIT(5)
+#	define OTGSC_DP			BIT(4)
+#	define OTGSC_OT			BIT(3)
+#	define OTGSC_HAAR		BIT(2)
+#	define OTGSC_VC			BIT(1)
+#	define OTGSC_VD			BIT(0)
+#	define OTGSC_INTEN_MASK		(0x7f << 24)
+#	define OTGSC_INT_MASK		(0x5f << 24)
+#	define OTGSC_INTSTS_MASK	(0x7f << 16)
+#define CI_USBMODE		0x1a8
+#	define USBMODE_CM		(BIT(1) | BIT(0))
+#	define USBMODE_IDLE		0
+#	define USBMODE_DEVICE		0x2
+#	define USBMODE_HOST		0x3
+
+#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
+
+enum xusbps_otg_timer_type {
+	TA_WAIT_VRISE_TMR,
+	TA_WAIT_BCON_TMR,
+	TA_AIDL_BDIS_TMR,
+	TB_ASE0_BRST_TMR,
+	TB_SE0_SRP_TMR,
+	TB_SRP_INIT_TMR,
+	TB_SRP_FAIL_TMR,
+	TB_BUS_SUSPEND_TMR
+};
+
+#define TA_WAIT_VRISE	100
+#define TA_WAIT_BCON	30000
+#define TA_AIDL_BDIS	15000
+#define TB_ASE0_BRST	5000
+#define TB_SE0_SRP	2
+#define TB_SRP_INIT	100
+#define TB_SRP_FAIL	5500
+#define TB_BUS_SUSPEND	500
+
+struct xusbps_otg_timer {
+	unsigned long expires;	/* Number of count increase to timeout */
+	unsigned long count;	/* Tick counter */
+	void (*function)(unsigned long);	/* Timeout function */
+	unsigned long data;	/* Data passed to function */
+	struct list_head list;
+};
+
+/* This is a common data structure to
+ * save values of the OTG state machine */
+struct otg_hsm {
+	/* Input */
+	int a_bus_resume;
+	int a_bus_suspend;
+	int a_conn;
+	int a_sess_vld;
+	int a_srp_det;
+	int a_vbus_vld;
+	int b_bus_resume;
+	int b_bus_suspend;
+	int b_conn;
+	int b_se0_srp;
+	int b_ssend_srp;
+	int b_sess_end;
+	int b_sess_vld;
+	int id;
+/* id values */
+#define ID_B		0x05
+#define ID_A		0x04
+#define ID_ACA_C	0x03
+#define ID_ACA_B	0x02
+#define ID_ACA_A	0x01
+	int power_up;
+	int adp_change;
+	int test_device;
+
+	/* Internal variables */
+	int a_set_b_hnp_en;
+	int b_srp_done;
+	int b_hnp_enable;
+	int hnp_poll_enable;
+
+	/* Timeout indicator for timers */
+	int a_wait_vrise_tmout;
+	int a_wait_bcon_tmout;
+	int a_aidl_bdis_tmout;
+	int a_bidl_adis_tmout;
+	int a_bidl_adis_tmr;
+	int a_wait_vfall_tmout;
+	int b_ase0_brst_tmout;
+	int b_bus_suspend_tmout;
+	int b_srp_init_tmout;
+	int b_srp_fail_tmout;
+	int b_srp_fail_tmr;
+	int b_adp_sense_tmout;
+
+	/* Informative variables */
+	int a_bus_drop;
+	int a_bus_req;
+	int a_clr_err;
+	int b_bus_req;
+	int a_suspend_req;
+	int b_bus_suspend_vld;
+
+	/* Output */
+	int drv_vbus;
+	int loc_conn;
+	int loc_sof;
+
+	/* Others */
+	int vbus_srp_up;
+};
+
+struct xusbps_otg {
+	struct usb_phy		otg;
+	struct usb_phy		*ulpi;
+
+	struct otg_hsm		hsm;
+
+	/* base address */
+	void __iomem		*base;
+
+	/* irq */
+	int			irq;
+
+	/* clk */
+	struct clk		*clk;
+	struct notifier_block	clk_rate_change_nb;
+
+	/* atomic notifier for interrupt context */
+	struct atomic_notifier_head	otg_notifier;
+
+	/* start/stop USB Host function */
+	int	(*start_host)(struct usb_phy *otg);
+	int	(*stop_host)(struct usb_phy *otg);
+
+	/* start/stop USB Peripheral function */
+	int	(*start_peripheral)(struct usb_phy *otg);
+	int	(*stop_peripheral)(struct usb_phy *otg);
+
+	struct device			*dev;
+
+	unsigned			region;
+
+	struct work_struct		work;
+	struct workqueue_struct		*qwork;
+	struct timer_list		hsm_timer;
+
+	spinlock_t			lock;
+	spinlock_t			wq_lock;
+
+	struct notifier_block		xotg_notifier;
+};
+
+static inline
+struct xusbps_otg *xceiv_to_xotg(struct usb_phy *otg)
+{
+	return container_of(otg, struct xusbps_otg, otg);
+}
+
+void xusbps_update_transceiver(void);
+
+#endif /* __XILINX_XUSBPS_OTG_H__ */
Index: linux-3.12.24-rt38-xilinx/include/linux/xilinx_devices.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/xilinx_devices.h	2014-07-20 22:06:39.621251863 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * include/linux/xilinx_devices.h
+ *
+ * Definitions for any platform device related flags or structures for
+ * Xilinx EDK IPs
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002-2005 (c) MontaVista Software, Inc.  This file is licensed under the
+ * terms of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#ifdef __KERNEL__
+#ifndef _XILINX_DEVICE_H_
+#define _XILINX_DEVICE_H_
+
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+
+/*- PS USB Controller IP -*/
+enum xusbps_usb2_operating_modes {
+	XUSBPS_USB2_MPH_HOST,
+	XUSBPS_USB2_DR_HOST,
+	XUSBPS_USB2_DR_DEVICE,
+	XUSBPS_USB2_DR_OTG,
+};
+
+enum xusbps_usb2_phy_modes {
+	XUSBPS_USB2_PHY_NONE,
+	XUSBPS_USB2_PHY_ULPI,
+	XUSBPS_USB2_PHY_UTMI,
+	XUSBPS_USB2_PHY_UTMI_WIDE,
+	XUSBPS_USB2_PHY_SERIAL,
+};
+
+struct clk;
+struct platform_device;
+
+struct xusbps_usb2_platform_data {
+	/* board specific information */
+	enum xusbps_usb2_operating_modes	operating_mode;
+	enum xusbps_usb2_phy_modes	phy_mode;
+	unsigned int			port_enables;
+	unsigned int			workaround;
+
+	int		(*init)(struct platform_device *);
+	void		(*exit)(struct platform_device *);
+	void __iomem	*regs;		/* ioremap'd register base */
+	struct usb_phy	*otg;
+	struct usb_phy	*ulpi;
+	int		irq;
+	struct clk	*clk;
+	struct notifier_block clk_rate_change_nb;
+	unsigned	big_endian_mmio:1;
+	unsigned	big_endian_desc:1;
+	unsigned	es:1;		/* need USBMODE:ES */
+	unsigned	le_setup_buf:1;
+	unsigned	have_sysif_regs:1;
+	unsigned	invert_drvvbus:1;
+	unsigned	invert_pwr_fault:1;
+};
+
+#define XUSBPS_USB2_PORT0_ENABLED	0x00000001
+#define XUSBPS_USB2_PORT1_ENABLED	0x00000002
+
+#endif /* _XILINX_DEVICE_H_ */
+#endif /* __KERNEL__ */
Index: linux-3.12.24-rt38-xilinx/include/linux/xylonfb.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/xylonfb.h	2014-07-20 22:06:39.627251765 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver IOCTL parameters
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __XYLON_FB_H__
+#define __XYLON_FB_H__
+
+
+#include <linux/types.h>
+
+
+struct xylonfb_layer_color {
+	__u32 raw_rgb;
+	__u8 use_raw;
+	__u8 r;
+	__u8 g;
+	__u8 b;
+};
+
+struct xylonfb_layer_pos_size {
+	__u16 x;
+	__u16 y;
+	__u16 width;
+	__u16 height;
+};
+
+struct xylonfb_hw_access {
+	__u32 offset;
+	__u32 value;
+};
+
+/* XylonFB events */
+#define XYLONFB_EVENT_FBI_UPDATE 0x01
+
+/* XylonFB IOCTL's */
+#define XYLONFB_IOW(num, dtype)  _IOW('x', num, dtype)
+#define XYLONFB_IOR(num, dtype)  _IOR('x', num, dtype)
+#define XYLONFB_IOWR(num, dtype) _IOWR('x', num, dtype)
+#define XYLONFB_IO(num)          _IO('x', num)
+
+#define XYLONFB_GET_LAYER_IDX           XYLONFB_IOR(30, unsigned int)
+#define XYLONFB_GET_LAYER_ALPHA         XYLONFB_IOR(31, unsigned int)
+#define XYLONFB_SET_LAYER_ALPHA         XYLONFB_IOW(32, unsigned int)
+#define XYLONFB_LAYER_COLOR_TRANSP      XYLONFB_IOW(33, unsigned int)
+#define XYLONFB_GET_LAYER_COLOR_TRANSP \
+	XYLONFB_IOR(34, struct xylonfb_layer_color)
+#define XYLONFB_SET_LAYER_COLOR_TRANSP \
+	XYLONFB_IOW(35, struct xylonfb_layer_color)
+#define XYLONFB_GET_LAYER_SIZE_POS \
+	XYLONFB_IOR(36, struct xylonfb_layer_pos_size)
+#define XYLONFB_SET_LAYER_SIZE_POS \
+	XYLONFB_IOW(37, struct xylonfb_layer_pos_size)
+#define XYLONFB_GET_LAYER_BUFFER        XYLONFB_IOR(38, unsigned int)
+#define XYLONFB_SET_LAYER_BUFFER        XYLONFB_IOW(39, unsigned int)
+#define XYLONFB_GET_LAYER_BUFFER_OFFSET XYLONFB_IOR(40, unsigned int)
+#define XYLONFB_GET_LAYER_BUFFERS_NUM   XYLONFB_IOR(41, unsigned int)
+#define XYLONFB_GET_BACKGROUND_COLOR \
+	XYLONFB_IOR(42, struct xylonfb_layer_color)
+#define XYLONFB_SET_BACKGROUND_COLOR \
+	XYLONFB_IOW(43, struct xylonfb_layer_color)
+#define XYLONFB_LAYER_EXT_BUFF_SWITCH   XYLONFB_IOW(43, unsigned int)
+#define XYLONFB_READ_HW_REG \
+	XYLONFB_IOR(44, struct xylonfb_hw_access)
+#define XYLONFB_WRITE_HW_REG \
+	XYLONFB_IOW(45, struct xylonfb_hw_access)
+#define XYLONFB_WAIT_EDID               XYLONFB_IOW(46, unsigned int)
+#define XYLONFB_GET_EDID                XYLONFB_IOR(47, char)
+
+#endif /* __XYLON_FB_H__ */
Index: linux-3.12.24-rt38-xilinx/include/linux/xylonfb_platform.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/linux/xylonfb_platform.h	2014-07-20 22:06:39.633251666 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xylon logiCVC frame buffer driver platform data structures
+ *
+ * Author: Xylon d.o.o.
+ * e-mail: davor.joja@logicbricks.com
+ *
+ * 2013 Xylon d.o.o.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef	__XYLON_FB_PLATFORM_H__
+#define __XYLON_FB_PLATFORM_H__
+
+
+#include <linux/types.h>
+
+
+/* Framebuffer driver platform layer structure */
+struct xylonfb_platform_layer_params {
+	/* Layer memory offset in lines */
+	unsigned int offset;
+	/* Layer buffer memory offset in lines */
+	unsigned short buffer_offset;
+	/* Layer type */
+	unsigned char type;
+	/* Layer bits per pixel */
+	unsigned char bpp;
+	/* Layer alpha mode */
+	unsigned char alpha_mode;
+	/* Layer control flags */
+	unsigned char ctrl_flags;
+};
+
+/* Framebuffer driver platform data structure */
+struct xylonfb_platform_data {
+	struct xylonfb_platform_layer_params *layer_params;
+	/* logiCVC video mode */
+	char *vmode;
+	/* logiCVC Control Register value */
+	u32 ctrl_reg;
+	/* Physical starting address of the video memory */
+	unsigned long vmem_base_addr;
+	/* Physical ending address of the video memory */
+	unsigned long vmem_high_addr;
+	/* Layer row stride in pixels */
+	unsigned short row_stride;
+	/* ID of driver supported pixel clock generator */
+	unsigned char pixclk_src_id;
+	/* Number of logiCVC layers */
+	unsigned char num_layers;
+	/* logiCVC layer ID for FB console */
+	unsigned char active_layer;
+	/* Background layer bits per pixel */
+	unsigned char bg_layer_bpp;
+	/* Background layer alpha mode */
+	unsigned char bg_layer_alpha_mode;
+	/* Display interface and color space type */
+	/* higher 4 bits: display interface
+	   lower 4 bits: display color space */
+	unsigned char display_interface_type;
+	/* logiCVC specific flags */
+	unsigned short flags;
+};
+
+#endif /* __XYLON_FB_PLATFORM_H__ */
Index: linux-3.12.24-rt38-xilinx/include/media/adv7604.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/media/adv7604.h	2014-07-20 22:05:50.336064971 +0200
+++ linux-3.12.24-rt38-xilinx/include/media/adv7604.h	2014-07-20 22:06:39.645251468 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:81 @
 	ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a,
 };
 
+enum adv7604_int1_config {
+	ADV7604_INT1_CONFIG_OPEN_DRAIN,
+	ADV7604_INT1_CONFIG_ACTIVE_LOW,
+	ADV7604_INT1_CONFIG_ACTIVE_HIGH,
+	ADV7604_INT1_CONFIG_DISABLED,
+};
+
 /* Platform dependent definition */
 struct adv7604_platform_data {
 	/* connector - HDMI or DVI? */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:108 @
 	/* Select output format */
 	enum adv7604_op_format_sel op_format_sel;
 
+	/* Configuration of the INT1 pin */
+	enum adv7604_int1_config int1_config;
+
 	/* IO register 0x02 */
 	unsigned alt_gamma:1;
 	unsigned op_656_range:1;
Index: linux-3.12.24-rt38-xilinx/include/media/v4l2-hdmi.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/media/v4l2-hdmi.h	2014-07-20 22:06:39.656251286 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * v4l2-hdmi.h - HDMI extensions to the V4L2 API
+ *
+ * Copyright 2011 Tandberg Telecom AS.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _V4L2_HDMI_H_
+#define _V4L2_HDMI_H_
+
+#ifdef __KERNEL__
+#include <linux/ioctl.h>
+#include <linux/videodev2.h>
+#else
+#include <sys/ioctl.h>
+/*
+  videodev2.h, including patched version from released os
+ */
+#include "videodev2.h"
+#endif
+
+
+/* data[0] == 0 if format is invalid, == 1 if format is valid. */
+#define V4L2_EVENT_FMT_CHANGED (V4L2_EVENT_PRIVATE_START + 0)
+
+/* data[0] == 0 if EDID was not found, == 1 if EDID was found.
+ * data[1] == EDID segment that was found. */
+#define V4L2_EVENT_EDID        (V4L2_EVENT_PRIVATE_START + 1)
+
+/* data[0] == cec tx status field */
+#define V4L2_EVENT_CEC_TX      (V4L2_EVENT_PRIVATE_START + 2)
+
+/* data[0] == cec rx status field */
+#define V4L2_EVENT_CEC_RX      (V4L2_EVENT_PRIVATE_START + 3)
+
+/* data[0] == hotplug present or not */
+#define V4L2_EVENT_TX_HOTPLUG  (V4L2_EVENT_PRIVATE_START + 4)
+
+struct v4l2_edid {
+	__u32 port;
+	__u32 segment;
+	__u8 edid[256];
+};
+
+struct v4l2_cec_cap {
+	__u32 logicaldevices;
+	__u32 reserved[7];
+};
+
+struct v4l2_cec_cmd {
+	__u32 cmd;
+	__u32 reserved[7];
+	union {
+		struct {
+			__u32 id;
+			__u32 enable;
+			__u32 addr;
+		} conf;
+		struct {
+			__u32 len;
+			__u8  msg[16];
+			__u32 status;
+		} data;
+		__u32 raw[8];
+	};
+};
+
+/* cec commands */
+#define V4L2_CEC_CMD_CONF  (0)
+#define V4L2_CEC_CMD_TX    (1)
+#define V4L2_CEC_CMD_RX    (2)
+
+/* cec status field */
+#define V4L2_CEC_TX_STATUS_OK            (1 << 0)
+#define V4L2_CEC_TX_STATUS_ARB_LOST      (1 << 1)
+#define V4L2_CEC_TX_STATUS_RETRY_TIMEOUT (1 << 2)
+#define V4L2_CEC_RX_STATUS_READY         (1 << 0)
+
+/* ioctls */
+
+/* set a new EDID segment for a receiver */
+#define V4L2_S_EDID		 _IOW('a', 1, struct v4l2_edid)
+/* get the CEC capabilities */
+#define V4L2_CEC_CAP		 _IOR('a', 2, struct v4l2_cec_cap)
+/* issue a CEC command */
+#define V4L2_CEC_CMD		_IOWR('a', 3, struct v4l2_cec_cmd)
+/* request a new EDID segment */
+#define V4L2_REQ_EDID_SEGMENT	 _IOW('a', 4, int)
+/* get a EDID segment */
+#define V4L2_G_EDID		_IOWR('a', 5, struct v4l2_edid)
+
+/* controls */
+#define V4L2_CID_DV_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
+/* hdmi or dvi-d mode */
+#define V4L2_CID_DV_TX_DVI_HDMI_MODE		(V4L2_CID_DV_CID_CUSTOM_BASE + 0)
+/* audio sample frequency */
+#define V4L2_CID_DV_TX_AUDIO_SAMPLE_FREQ	(V4L2_CID_DV_CID_CUSTOM_BASE + 1)
+/* audio word length */
+#define V4L2_CID_DV_TX_AUDIO_WORD_LEN		(V4L2_CID_DV_CID_CUSTOM_BASE + 2)
+/* audio channel count */
+#define V4L2_CID_DV_TX_AUDIO_CH_COUNT		(V4L2_CID_DV_CID_CUSTOM_BASE + 3)
+/* audio i2s format */
+#define V4L2_CID_DV_TX_AUDIO_I2S_FORMAT		(V4L2_CID_DV_CID_CUSTOM_BASE + 4)
+/* to be hooked up to events */
+/* hotplug present or not */
+#define V4L2_CID_DV_TX_HOTPLUG			(V4L2_CID_DV_CID_CUSTOM_BASE + 5)
+/* rx sense */
+#define V4L2_CID_DV_TX_RXSENSE			(V4L2_CID_DV_CID_CUSTOM_BASE + 6)
+/* edid present */
+#define V4L2_CID_DV_TX_EDID_SEGMENT0_PRESENT	(V4L2_CID_DV_CID_CUSTOM_BASE + 7)
+/* audio channel mapping - refer to CEA 861D */
+#define V4L2_CID_DV_TX_AUDIO_CH_MAP		(V4L2_CID_DV_CID_CUSTOM_BASE + 8)
+/* cable detect */
+#define V4L2_CID_DV_CABLE_DETECT		(V4L2_CID_DV_CID_CUSTOM_BASE + 9)
+/* 5v from source detected */
+#define V4L2_CID_DV_RX_TX_POWER			(V4L2_CID_DV_CID_CUSTOM_BASE + 10)
+/* dvi-a sync detection */
+#define V4L2_CID_DV_SYNC_DETECT			(V4L2_CID_DV_CID_CUSTOM_BASE + 11)
+/* analog sampling phase */
+#define V4L2_CID_DV_RX_ANALOG_SAMPLING_PHASE	(V4L2_CID_DV_CID_CUSTOM_BASE + 12)
+/* free run color manual */
+#define V4L2_CID_FREE_RUN_COLOR_MANUAL		(V4L2_CID_DV_CID_CUSTOM_BASE + 13)
+/* free run color */
+#define V4L2_CID_FREE_RUN_COLOR			(V4L2_CID_DV_CID_CUSTOM_BASE + 14)
+/* hdmi/dvi-d RGB limited range */
+#define V4L2_CID_RGB_QUANTIZATION_RANGE		(V4L2_CID_DV_CID_CUSTOM_BASE + 15)
+
+/*
+ *	D V	P R E S E T	V A L U E S
+ */
+#define		V4L2_DV_PRESET_MASK		0xf0000000
+
+/* 0x00000000 - 0x000000ff reserved for CEA 861 formats */
+#define		V4L2_DV_CEA_861_FORMAT		0x00000000
+
+/* 0x10000000 - 0x100000ff reserved for DMT formats */
+#define		V4L2_DV_DMT_FORMAT		0x10000000
+
+#define		V4L2_DV_DMT_640X350P85		(V4L2_DV_DMT_FORMAT + 0x01)
+#define		V4L2_DV_DMT_640X400P85		(V4L2_DV_DMT_FORMAT + 0x02)
+#define		V4L2_DV_DMT_720X400P85		(V4L2_DV_DMT_FORMAT + 0x03)
+#define		V4L2_DV_DMT_640X480P60		(V4L2_DV_DMT_FORMAT + 0x04)
+#define		V4L2_DV_DMT_640X480P72		(V4L2_DV_DMT_FORMAT + 0x05)
+#define		V4L2_DV_DMT_640X480P75		(V4L2_DV_DMT_FORMAT + 0x06)
+#define		V4L2_DV_DMT_640X480P85		(V4L2_DV_DMT_FORMAT + 0x07)
+#define		V4L2_DV_DMT_800X600P56		(V4L2_DV_DMT_FORMAT + 0x08)
+#define		V4L2_DV_DMT_800X600P60		(V4L2_DV_DMT_FORMAT + 0x09)
+#define		V4L2_DV_DMT_800X600P72		(V4L2_DV_DMT_FORMAT + 0x0a)
+#define		V4L2_DV_DMT_800X600P75		(V4L2_DV_DMT_FORMAT + 0x0b)
+#define		V4L2_DV_DMT_800X600P85		(V4L2_DV_DMT_FORMAT + 0x0c)
+#define		V4L2_DV_DMT_800X600P120RB	(V4L2_DV_DMT_FORMAT + 0x0d)
+#define		V4L2_DV_DMT_848X480P60		(V4L2_DV_DMT_FORMAT + 0x0e)
+#define		V4L2_DV_DMT_1024X768I43		(V4L2_DV_DMT_FORMAT + 0x0f)
+#define		V4L2_DV_DMT_1024X768P60		(V4L2_DV_DMT_FORMAT + 0x10)
+#define		V4L2_DV_DMT_1024X768P70		(V4L2_DV_DMT_FORMAT + 0x11)
+#define		V4L2_DV_DMT_1024X768P75		(V4L2_DV_DMT_FORMAT + 0x12)
+#define		V4L2_DV_DMT_1024X768P85		(V4L2_DV_DMT_FORMAT + 0x13)
+#define		V4L2_DV_DMT_1024X768P120RB	(V4L2_DV_DMT_FORMAT + 0x14)
+#define		V4L2_DV_DMT_1152X864P75		(V4L2_DV_DMT_FORMAT + 0x15)
+#define		V4L2_DV_DMT_1280X768P60RB	(V4L2_DV_DMT_FORMAT + 0x16)
+#define		V4L2_DV_DMT_1280X768P60		(V4L2_DV_DMT_FORMAT + 0x17)
+#define		V4L2_DV_DMT_1280X768P75		(V4L2_DV_DMT_FORMAT + 0x18)
+#define		V4L2_DV_DMT_1280X768P85		(V4L2_DV_DMT_FORMAT + 0x19)
+#define		V4L2_DV_DMT_1280X768P120RB	(V4L2_DV_DMT_FORMAT + 0x1a)
+#define		V4L2_DV_DMT_1280X800P60RB	(V4L2_DV_DMT_FORMAT + 0x1b)
+#define		V4L2_DV_DMT_1280X800P60		(V4L2_DV_DMT_FORMAT + 0x1c)
+#define		V4L2_DV_DMT_1280X800P75		(V4L2_DV_DMT_FORMAT + 0x1d)
+#define		V4L2_DV_DMT_1280X800P85		(V4L2_DV_DMT_FORMAT + 0x1e)
+#define		V4L2_DV_DMT_1280X800P120RB	(V4L2_DV_DMT_FORMAT + 0x1f)
+#define		V4L2_DV_DMT_1280X960P60		(V4L2_DV_DMT_FORMAT + 0x20)
+#define		V4L2_DV_DMT_1280X960P85		(V4L2_DV_DMT_FORMAT + 0x21)
+#define		V4L2_DV_DMT_1280X960P120RB	(V4L2_DV_DMT_FORMAT + 0x22)
+#define		V4L2_DV_DMT_1280X1024P60	(V4L2_DV_DMT_FORMAT + 0x23)
+#define		V4L2_DV_DMT_1280X1024P75	(V4L2_DV_DMT_FORMAT + 0x24)
+#define		V4L2_DV_DMT_1280X1024P85	(V4L2_DV_DMT_FORMAT + 0x25)
+#define		V4L2_DV_DMT_1280X1024P120RB	(V4L2_DV_DMT_FORMAT + 0x26)
+#define		V4L2_DV_DMT_1360X768P60		(V4L2_DV_DMT_FORMAT + 0x27)
+#define		V4L2_DV_DMT_1360X768P120RB	(V4L2_DV_DMT_FORMAT + 0x28)
+#define		V4L2_DV_DMT_1400X1050P60RB	(V4L2_DV_DMT_FORMAT + 0x29)
+#define		V4L2_DV_DMT_1400X1050P60	(V4L2_DV_DMT_FORMAT + 0x2a)
+#define		V4L2_DV_DMT_1400X1050P75	(V4L2_DV_DMT_FORMAT + 0x2b)
+#define		V4L2_DV_DMT_1400X1050P85	(V4L2_DV_DMT_FORMAT + 0x2c)
+#define		V4L2_DV_DMT_1400X1050P120RB	(V4L2_DV_DMT_FORMAT + 0x2d)
+#define		V4L2_DV_DMT_1440X900P60RB	(V4L2_DV_DMT_FORMAT + 0x2e)
+#define		V4L2_DV_DMT_1440X900P60		(V4L2_DV_DMT_FORMAT + 0x2f)
+#define		V4L2_DV_DMT_1440X900P75		(V4L2_DV_DMT_FORMAT + 0x30)
+#define		V4L2_DV_DMT_1440X900P85		(V4L2_DV_DMT_FORMAT + 0x31)
+#define		V4L2_DV_DMT_1440X900P120RB	(V4L2_DV_DMT_FORMAT + 0x32)
+#define		V4L2_DV_DMT_1600X1200P60	(V4L2_DV_DMT_FORMAT + 0x33)
+#define		V4L2_DV_DMT_1600X1200P65	(V4L2_DV_DMT_FORMAT + 0x34)
+#define		V4L2_DV_DMT_1600X1200P70	(V4L2_DV_DMT_FORMAT + 0x35)
+#define		V4L2_DV_DMT_1600X1200P75	(V4L2_DV_DMT_FORMAT + 0x36)
+#define		V4L2_DV_DMT_1600X1200P85	(V4L2_DV_DMT_FORMAT + 0x37)
+#define		V4L2_DV_DMT_1600X1200P120RB	(V4L2_DV_DMT_FORMAT + 0x38)
+#define		V4L2_DV_DMT_1680X1050P60RB	(V4L2_DV_DMT_FORMAT + 0x39)
+#define		V4L2_DV_DMT_1680X1050P60	(V4L2_DV_DMT_FORMAT + 0x3a)
+#define		V4L2_DV_DMT_1680X1050P75	(V4L2_DV_DMT_FORMAT + 0x3b)
+#define		V4L2_DV_DMT_1680X1050P85	(V4L2_DV_DMT_FORMAT + 0x3c)
+#define		V4L2_DV_DMT_1680X1050P120RB	(V4L2_DV_DMT_FORMAT + 0x3d)
+#define		V4L2_DV_DMT_1792X1344P60	(V4L2_DV_DMT_FORMAT + 0x3e)
+#define		V4L2_DV_DMT_1792X1344P75	(V4L2_DV_DMT_FORMAT + 0x3f)
+#define		V4L2_DV_DMT_1792X1344P120RB	(V4L2_DV_DMT_FORMAT + 0x40)
+#define		V4L2_DV_DMT_1856X1392P60	(V4L2_DV_DMT_FORMAT + 0x41)
+#define		V4L2_DV_DMT_1856X1392P75	(V4L2_DV_DMT_FORMAT + 0x42)
+#define		V4L2_DV_DMT_1856X1392P120RB	(V4L2_DV_DMT_FORMAT + 0x43)
+#define		V4L2_DV_DMT_1920X1200P60RB	(V4L2_DV_DMT_FORMAT + 0x44)
+#define		V4L2_DV_DMT_1920X1200P60	(V4L2_DV_DMT_FORMAT + 0x45)
+#define		V4L2_DV_DMT_1920X1200P75	(V4L2_DV_DMT_FORMAT + 0x46)
+#define		V4L2_DV_DMT_1920X1200P85	(V4L2_DV_DMT_FORMAT + 0x47)
+#define		V4L2_DV_DMT_1920X1200P120RB	(V4L2_DV_DMT_FORMAT + 0x48)
+#define		V4L2_DV_DMT_1920X1440P60	(V4L2_DV_DMT_FORMAT + 0x49)
+#define		V4L2_DV_DMT_1920X1440P75	(V4L2_DV_DMT_FORMAT + 0x4a)
+#define		V4L2_DV_DMT_1920X1440P120RB	(V4L2_DV_DMT_FORMAT + 0x4b)
+#define		V4L2_DV_DMT_2560X1600P60RB	(V4L2_DV_DMT_FORMAT + 0x4c)
+#define		V4L2_DV_DMT_2560X1600P60	(V4L2_DV_DMT_FORMAT + 0x4d)
+#define		V4L2_DV_DMT_2560X1600P75	(V4L2_DV_DMT_FORMAT + 0x4e)
+#define		V4L2_DV_DMT_2560X1600P85	(V4L2_DV_DMT_FORMAT + 0x4f)
+#define		V4L2_DV_DMT_2560X1600P120RB	(V4L2_DV_DMT_FORMAT + 0x50)
+#define		V4L2_DV_DMT_1366X768P60		(V4L2_DV_DMT_FORMAT + 0x51)
+#define		V4L2_DV_DMT_1920X1080P60	(V4L2_DV_DMT_FORMAT + 0x52)
+
+/* CVT format */
+#define		V4L2_DV_CVT_FORMAT		0x20000000
+/* GTF format */
+#define		V4L2_DV_GTF_FORMAT		0x30000000
+/* Special formats that doesn't follow any standard */
+#define		V4L2_DV_SPECIAL_FORMAT		0xe0000000
+/* Error codes */
+#define		V4L2_DV_UNSUPPORTED_SIGNAL	0xf0000000
+
+#endif
Index: linux-3.12.24-rt38-xilinx/include/media/v4l2-of.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/media/v4l2-of.h	2014-07-20 22:05:50.337064954 +0200
+++ linux-3.12.24-rt38-xilinx/include/media/v4l2-of.h	2014-07-20 22:06:39.664251154 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:56 @
  * @port: identifier (value of reg property) of a port this endpoint belongs to
  * @id: identifier (value of reg property) of this endpoint
  * @local_node: pointer to device_node of this endpoint
- * @remote: phandle to remote endpoint node
  * @bus_type: bus type
  * @bus: bus configuration data structure
  * @head: list head for this structure
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:64 @
 	unsigned int port;
 	unsigned int id;
 	const struct device_node *local_node;
-	const __be32 *remote;
 	enum v4l2_mbus_type bus_type;
 	union {
 		struct v4l2_of_bus_parallel parallel;
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:72 @
 	struct list_head head;
 };
 
+/**
+ * struct v4l2_of_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+ * @remote_node: pointer to device_node of the remote endpoint
+ * @remote_port: identifier of the port the remote endpoint belongs to
+ */
+struct v4l2_of_link {
+	struct device_node *local_node;
+	unsigned int local_port;
+	struct device_node *remote_node;
+	unsigned int remote_port;
+};
+
 #ifdef CONFIG_OF
-void v4l2_of_parse_endpoint(const struct device_node *node,
-				struct v4l2_of_endpoint *link);
+int v4l2_of_parse_endpoint(const struct device_node *node,
+			   struct v4l2_of_endpoint *endpoint);
+int v4l2_of_parse_link(const struct device_node *node,
+		       struct v4l2_of_link *link);
+void v4l2_of_put_link(struct v4l2_of_link *link);
 struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
 					struct device_node *previous);
 struct device_node *v4l2_of_get_remote_port_parent(
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:105 @
 	return -ENOSYS;
 }
 
+static inline int v4l2_of_parse_link(const struct device_node *node,
+				     struct v4l2_of_link *link)
+{
+	return -ENOSYS;
+}
+
+static inline void v4l2_of_put_link(struct v4l2_of_link *link)
+{
+}
+
 static inline struct device_node *v4l2_of_get_next_endpoint(
 					const struct device_node *parent,
 					struct device_node *previous)
Index: linux-3.12.24-rt38-xilinx/include/net/rpmsg.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/include/net/rpmsg.h	2014-07-20 22:06:39.675250973 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Remote processor messaging sockets
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __NET_RPMSG_H
+#define __NET_RPMSG_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/* user space needs this */
+#ifndef AF_RPMSG
+#define AF_RPMSG	41
+#define PF_RPMSG	AF_RPMSG
+#endif
+
+/* Connection and socket states */
+enum {
+	RPMSG_CONNECTED = 1, /* wait_for_packet() wants this... */
+	RPMSG_OPEN,
+	RPMSG_LISTENING,
+	RPMSG_CLOSED,
+};
+
+struct sockaddr_rpmsg {
+	sa_family_t family;
+	__u32 vproc_id;
+	__u32 addr;
+};
+
+#define RPMSG_LOCALHOST ((__u32) ~0UL)
+
+#ifdef __KERNEL__
+
+#include <net/sock.h>
+#include <linux/rpmsg.h>
+
+struct rpmsg_socket {
+	struct sock sk;
+	struct rpmsg_channel *rpdev;
+	bool unregister_rpdev;
+};
+
+#endif /* __KERNEL__ */
+#endif /* __NET_RPMSG_H */
Index: linux-3.12.24-rt38-xilinx/include/sound/soc-dai.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/sound/soc-dai.h	2014-07-20 22:05:50.334065004 +0200
+++ linux-3.12.24-rt38-xilinx/include/sound/soc-dai.h	2014-07-20 22:06:39.687250775 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:36 @
 #define SND_SOC_DAIFMT_DSP_B		5 /* L data MSB during FRM LRC */
 #define SND_SOC_DAIFMT_AC97		6 /* AC97 */
 #define SND_SOC_DAIFMT_PDM		7 /* Pulse density modulation */
+#define SND_SOC_DAIFMT_SPDIF		8 /* SPDIF */
 
 /* left and right justified also known as MSB and LSB respectively */
 #define SND_SOC_DAIFMT_MSB		SND_SOC_DAIFMT_LEFT_J
Index: linux-3.12.24-rt38-xilinx/include/uapi/linux/v4l2-mediabus.h
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/include/uapi/linux/v4l2-mediabus.h	2014-07-20 22:05:50.338064938 +0200
+++ linux-3.12.24-rt38-xilinx/include/uapi/linux/v4l2-mediabus.h	2014-07-20 22:06:39.702250527 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:40 @
 enum v4l2_mbus_pixelcode {
 	V4L2_MBUS_FMT_FIXED = 0x0001,
 
-	/* RGB - next is 0x100e */
+	/* RGB - next is 0x1010 */
 	V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001,
 	V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002,
 	V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:54 @
 	V4L2_MBUS_FMT_RGB888_2X12_BE = 0x100b,
 	V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c,
 	V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d,
+	V4L2_MBUS_FMT_RBG888_1X24 = 0x100e,
+	V4L2_MBUS_FMT_RGB888_1X32_PADHI = 0x100f,
 
-	/* YUV (including grey) - next is 0x2018 */
+	/* YUV (including grey) - next is 0x201a */
 	V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
 	V4L2_MBUS_FMT_UV8_1X8 = 0x2015,
 	V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:81 @
 	V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
 	V4L2_MBUS_FMT_YUV10_1X30 = 0x2016,
 	V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017,
+	V4L2_MBUS_FMT_YUYV10_1X24_PADHI = 0x2018,
+	V4L2_MBUS_FMT_YUYV12_1X24 = 0x2019,
 
 	/* Bayer - next is 0x3019 */
 	V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
Index: linux-3.12.24-rt38-xilinx/init/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/init/Kconfig	2014-07-20 22:05:50.328065103 +0200
+++ linux-3.12.24-rt38-xilinx/init/Kconfig	2014-07-20 22:10:26.384515092 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:23 @
 	bool
 	depends on !UML
 
+config CONSTRUCTORS_NAME
+	string
+	depends on CONSTRUCTORS
+	default ".init_array" if ARM && AEABI
+	default ".ctors"
+
 config IRQ_WORK
 	bool
 
Index: linux-3.12.24-rt38-xilinx/kernel/gcov/Kconfig
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/kernel/gcov/Kconfig	2014-07-20 22:05:50.327065119 +0200
+++ linux-3.12.24-rt38-xilinx/kernel/gcov/Kconfig	2014-07-20 22:06:39.736249967 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:38 @
 config GCOV_PROFILE_ALL
 	bool "Profile entire Kernel"
 	depends on GCOV_KERNEL
-	depends on SUPERH || S390 || X86 || PPC || MICROBLAZE
+	depends on SUPERH || S390 || X86 || PPC || MICROBLAZE || ARM
 	default n
 	---help---
 	This options activates profiling for the entire kernel.
Index: linux-3.12.24-rt38-xilinx/kernel/module.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/kernel/module.c	2014-07-20 22:05:50.326065136 +0200
+++ linux-3.12.24-rt38-xilinx/kernel/module.c	2014-07-20 22:06:39.759249587 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:2769 @
 	mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
 #endif
 #ifdef CONFIG_CONSTRUCTORS
-	mod->ctors = section_objs(info, ".ctors",
+	mod->ctors = section_objs(info, CONFIG_CONSTRUCTORS_NAME,
 				  sizeof(*mod->ctors), &mod->num_ctors);
 #endif
 
Index: linux-3.12.24-rt38-xilinx/MAINTAINERS
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/MAINTAINERS	2014-07-20 22:05:50.266066126 +0200
+++ linux-3.12.24-rt38-xilinx/MAINTAINERS	2014-07-20 22:06:39.808248779 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1360 @
 S:	Supported
 F:	arch/arm/mach-zynq/
 F:	drivers/cpuidle/cpuidle-zynq.c
+N:	[^a-z]zynq
+N:	[^a-z]xilinx
+F:	drivers/clocksource/cadence_ttc_timer.c
 
 ARM SMMU DRIVER
 M:	Will Deacon <will.deacon@arm.com>
Index: linux-3.12.24-rt38-xilinx/net/Makefile
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/net/Makefile	2014-07-20 22:05:50.333065020 +0200
+++ linux-3.12.24-rt38-xilinx/net/Makefile	2014-07-20 22:06:39.914247031 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:73 @
 obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_OPENVSWITCH)	+= openvswitch/
 obj-$(CONFIG_VSOCKETS)	+= vmw_vsock/
+obj-$(CONFIG_RPMSG)		+= rpmsg/
 obj-$(CONFIG_NET_MPLS_GSO)	+= mpls/
Index: linux-3.12.24-rt38-xilinx/net/rpmsg/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/net/rpmsg/Makefile	2014-07-20 22:06:39.925246849 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:1 @
+obj-$(CONFIG_RPMSG)	+= rpmsg_proto.o
Index: linux-3.12.24-rt38-xilinx/net/rpmsg/rpmsg_proto.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/net/rpmsg/rpmsg_proto.c	2014-07-20 22:06:39.935246684 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * AF_RPMSG: Remote processor messaging sockets
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)    "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/rwlock_rt.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/rpmsg.h>
+#include <net/sock.h>
+#include <net/rpmsg.h>
+#include <linux/radix-tree.h>
+
+#define RPMSG_CB(skb)	(*(struct sockaddr_rpmsg *)&((skb)->cb))
+
+/*
+ * A two-level radix-tree-based scheme is used to maintain the rpmsg channels
+ * we're exposing to userland. The first radix tree maps vproc index id
+ * to its channels, and the second radix tree associates each channel
+ * with its destination addresses (so sockaddr_rpmsg lookups are quick).
+ *
+ * Currently only channels with a valid dst address are supported (aka 'client'
+ * channels as opposed to 'server' channels which usually only have a valid
+ * src address).
+ */
+static RADIX_TREE(rpmsg_channels, GFP_KERNEL);
+
+/*
+ * Synchronization of access to the tree is achieved using a mutex,
+ * because we're using non-atomic radix tree allocations.
+ */
+static DEFINE_MUTEX(rpmsg_channels_lock);
+
+static struct proto rpmsg_proto = {
+	.name		= "RPMSG",
+	.owner		= THIS_MODULE,
+	.obj_size = sizeof(struct rpmsg_socket),
+};
+
+static int rpmsg_sock_connect(struct socket *sock, struct sockaddr *addr,
+							int alen, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct rpmsg_socket *rpsk;
+	struct sockaddr_rpmsg *sa;
+	int err = 0;
+	struct radix_tree_root *vrp_channels;
+	struct rpmsg_channel *rpdev;
+
+	pr_debug("sk %p\n", sk);
+
+	if (sk->sk_state != RPMSG_OPEN)
+		return -EBADFD;
+
+	if (sk->sk_type != SOCK_SEQPACKET)
+		return -EINVAL;
+
+	if (!addr || addr->sa_family != AF_RPMSG)
+		return -EINVAL;
+
+	if (alen < sizeof(*sa))
+		return -EINVAL;
+
+	sa = (struct sockaddr_rpmsg *) addr;
+
+	lock_sock(sk);
+
+	rpsk = container_of(sk, struct rpmsg_socket, sk);
+
+	mutex_lock(&rpmsg_channels_lock);
+
+	/* find the set of channels exposed by this remote processor */
+	vrp_channels = radix_tree_lookup(&rpmsg_channels, sa->vproc_id);
+	if (!vrp_channels) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	/* find the specific channel we need to connect with */
+	rpdev = radix_tree_lookup(vrp_channels, sa->addr);
+	if (!rpdev) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	rpsk->rpdev = rpdev;
+
+	/* bind this socket with its rpmsg endpoint */
+	rpdev->ept->priv = sk;
+
+	/* XXX take care of disconnection state too */
+	sk->sk_state = RPMSG_CONNECTED;
+
+out:
+	mutex_unlock(&rpmsg_channels_lock);
+	release_sock(sk);
+	return err;
+}
+
+static int rpmsg_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+					struct msghdr *msg, size_t len)
+{
+	struct sock *sk = sock->sk;
+	struct rpmsg_socket *rpsk;
+	char payload[512];/* todo: sane payload length methodology */
+	int err;
+
+	pr_debug("sk %p len %d\n", sk, len);
+
+	/* XXX check for sock_error as well ? */
+	/* XXX handle noblock ? */
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	/* no payload ? */
+	if (msg->msg_iov->iov_base == NULL)
+		return -EINVAL;
+
+	lock_sock(sk);
+
+	/* we don't support loopback at this point */
+	if (sk->sk_state != RPMSG_CONNECTED) {
+		release_sock(sk);
+		return -ENOTCONN;
+	}
+
+	rpsk = container_of(sk, struct rpmsg_socket, sk);
+
+	/* XXX for now, ignore the peer address. later use it
+	 * with rpmsg_sendto, but only if user is root */
+
+	err = memcpy_fromiovec(payload, msg->msg_iov, len);
+	if (err)
+		goto out;
+
+	/* XXX add length validation */
+	err = rpmsg_send(rpsk->rpdev, payload, len);
+	if (err)
+		pr_err("rpmsg_send failed: %d\n", err);
+
+out:
+	release_sock(sk);
+	return err;
+}
+
+static int rpmsg_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+				struct msghdr *msg, size_t len, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct sockaddr_rpmsg *sa;
+	struct sk_buff *skb;
+	int noblock = flags & MSG_DONTWAIT;
+	int ret;
+
+	pr_debug("sk %p len %d\n", sk, len);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	msg->msg_namelen = 0;
+
+	skb = skb_recv_datagram(sk, flags, noblock, &ret);
+	if (!skb)
+		/* check for shutdown ? */
+		return ret;
+
+	if (msg->msg_name) {
+		msg->msg_namelen = sizeof(*sa);
+		sa = (struct sockaddr_rpmsg *) msg->msg_name;
+		sa->vproc_id = RPMSG_CB(skb).vproc_id;
+		sa->addr = RPMSG_CB(skb).addr;
+		sa->family = AF_RPMSG;
+	}
+
+	if (len > skb->len) {
+		len = skb->len;
+	} else if (len < skb->len) {
+		pr_warn("user buffer is too small\n");
+		/* XXX truncate or error ? */
+		msg->msg_flags |= MSG_TRUNC;
+	}
+
+	ret = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
+	if (ret) {
+		pr_warn("error copying skb data: %d\n", ret);
+		goto out_free;
+	}
+
+	ret = len;
+
+out_free:
+	skb_free_datagram(sk, skb);
+	return ret;
+}
+
+static unsigned int rpmsg_sock_poll(struct file *file, struct socket *sock,
+							poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	unsigned int mask = 0;
+
+	pr_debug("sk %p\n", sk);
+
+	poll_wait(file, sk_sleep(sk), wait);
+
+	/* exceptional events? */
+	if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
+		mask |= POLLERR;
+	if (sk->sk_shutdown & RCV_SHUTDOWN)
+		mask |= POLLRDHUP;
+	if (sk->sk_shutdown == SHUTDOWN_MASK)
+		mask |= POLLHUP;
+
+	/* readable? */
+	if (!skb_queue_empty(&sk->sk_receive_queue) ||
+	    (sk->sk_shutdown & RCV_SHUTDOWN))
+		mask |= POLLIN | POLLRDNORM;
+
+	if (sk->sk_state == RPMSG_CLOSED)
+		mask |= POLLHUP;
+
+	/*
+	 * XXX is writable ?
+	 * this depends on the destination processor.
+	 * if loopback: we're writable unless no memory
+	 * if to remote: we need enabled rpmsg buffer or user supplied bufs
+	 * for now, let's always be writable.
+	 */
+	mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+	return mask;
+}
+EXPORT_SYMBOL(rpmsg_sock_poll);
+
+/*
+ * return bound socket address information, either local or remote
+ * note: len is just an output parameter, doesn't carry any input value
+ */
+static int rpmsg_sock_getname(struct socket *sock, struct sockaddr *addr,
+							int *len, int peer)
+{
+	struct sock *sk = sock->sk;
+	struct rpmsg_socket *rpsk;
+	struct rpmsg_channel *rpdev;
+	struct sockaddr_rpmsg *sa;
+
+	pr_debug("sk %p\n", sk);
+
+	rpsk = container_of(sk, struct rpmsg_socket, sk);
+	rpdev = rpsk->rpdev;
+
+	if (!rpdev)
+		return -ENOTCONN;
+
+	addr->sa_family = AF_RPMSG;
+
+	sa = (struct sockaddr_rpmsg *) addr;
+
+	*len = sizeof(*sa);
+
+	if (peer) {
+		sa->vproc_id = get_virtproc_id(rpdev->vrp);
+		sa->addr = rpdev->dst;
+	} else {
+		sa->vproc_id = RPMSG_LOCALHOST;
+		sa->addr = rpsk->rpdev->src;
+	}
+
+	return 0;
+}
+
+static int rpmsg_sock_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
+
+	pr_debug("sk %p\n", sk);
+
+	if (!sk)
+		return 0;
+
+	if (rpsk->unregister_rpdev)
+		device_unregister(&rpsk->rpdev->dev);
+
+	sock_put(sock->sk);
+
+	return 0;
+}
+
+/*
+ * Notes:
+ * - calling connect after bind isn't currently supported (is it even needed ?).
+ * - userspace arguments to bind aren't intuitive: one needs to provide
+ *   the vproc id of the remote processor he wants the channel to be shared
+ *   with, and the -local- address he wants the channel to be bind with
+ */
+static int
+rpmsg_sock_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+{
+	struct sock *sk = sock->sk;
+	struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
+	struct rpmsg_channel *rpdev;
+	struct sockaddr_rpmsg *sa = (struct sockaddr_rpmsg *)uaddr;
+
+	pr_debug("sk %p\n", sk);
+
+	if (sock->state == SS_CONNECTED)
+		return -EINVAL;
+
+	if (addr_len != sizeof(*sa))
+		return -EINVAL;
+
+	if (sa->family != AF_RPMSG)
+		return -EINVAL;
+
+	if (rpsk->rpdev)
+		return -EBUSY;
+
+	if (sk->sk_state != RPMSG_OPEN)
+		return -EINVAL;
+
+	rpdev = rpmsg_create_channel(sa->vproc_id, "rpmsg-proto", sa->addr,
+							RPMSG_ADDR_ANY);
+	if (!rpdev)
+		return -EINVAL;
+
+	rpsk->rpdev = rpdev;
+	rpsk->unregister_rpdev = true;
+
+	/* bind this socket with its rpmsg endpoint */
+	rpdev->ept->priv = sk;
+
+	sk->sk_state = RPMSG_LISTENING;
+
+	return 0;
+}
+
+static const struct proto_ops rpmsg_sock_ops = {
+	.family		= PF_RPMSG,
+	.owner		= THIS_MODULE,
+
+	.release	= rpmsg_sock_release,
+	.connect	= rpmsg_sock_connect,
+	.getname	= rpmsg_sock_getname,
+	.sendmsg	= rpmsg_sock_sendmsg,
+	.recvmsg	= rpmsg_sock_recvmsg,
+	.poll		= rpmsg_sock_poll,
+	.bind		= rpmsg_sock_bind,
+
+	.listen		= sock_no_listen,
+	.accept		= sock_no_accept,
+	.ioctl		= sock_no_ioctl,
+	.mmap		= sock_no_mmap,
+	.socketpair	= sock_no_socketpair,
+	.shutdown	= sock_no_shutdown,
+	.setsockopt	= sock_no_setsockopt,
+	.getsockopt	= sock_no_getsockopt
+};
+
+static void rpmsg_sock_destruct(struct sock *sk)
+{
+}
+
+static int rpmsg_sock_create(struct net *net, struct socket *sock, int proto,
+				int kern)
+{
+	struct sock *sk;
+
+	if (sock->type != SOCK_SEQPACKET)
+		return -ESOCKTNOSUPPORT;
+	if (proto != 0)
+		return -EPROTONOSUPPORT;
+
+	sk = sk_alloc(net, PF_RPMSG, GFP_KERNEL, &rpmsg_proto);
+	if (!sk)
+		return -ENOMEM;
+
+	pr_debug("sk %p\n", sk);
+
+	sock->state = SS_UNCONNECTED;
+	sock->ops = &rpmsg_sock_ops;
+	sock_init_data(sock, sk);
+
+	sk->sk_destruct = rpmsg_sock_destruct;
+	sk->sk_protocol = proto;
+
+	sk->sk_state = RPMSG_OPEN;
+
+	return 0;
+}
+
+static const struct net_proto_family rpmsg_proto_family = {
+	.family = PF_RPMSG,
+	.create	= rpmsg_sock_create,
+	.owner = THIS_MODULE,
+};
+
+static void __rpmsg_proto_cb(struct device *dev, int from_vproc_id, void *data,
+					int len, struct sock *sk, u32 src)
+{
+	struct rpmsg_socket *rpsk = container_of(sk, struct rpmsg_socket, sk);
+	struct sk_buff *skb;
+	int ret;
+
+	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+		       data, len,  true);
+
+	lock_sock(sk);
+
+	switch (sk->sk_state) {
+	case RPMSG_CONNECTED:
+		if (rpsk->rpdev->dst != src)
+			dev_warn(dev, "unexpected source address: %d\n", src);
+		break;
+	case RPMSG_LISTENING:
+		/* When an inbound message is received while we're listening,
+		 * we implicitly become connected */
+		sk->sk_state = RPMSG_CONNECTED;
+		rpsk->rpdev->dst = src;
+		break;
+	default:
+		dev_warn(dev, "unexpected inbound message (from %d)\n", src);
+		break;
+	}
+
+	skb = sock_alloc_send_skb(sk, len, 1, &ret);
+	if (!skb) {
+		dev_err(dev, "sock_alloc_send_skb failed: %d\n", ret);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	RPMSG_CB(skb).vproc_id = from_vproc_id;
+	RPMSG_CB(skb).addr = src;
+	RPMSG_CB(skb).family = AF_RPMSG;
+
+	memcpy(skb_put(skb, len), data, len);
+
+	ret = sock_queue_rcv_skb(sk, skb);
+	if (ret) {
+		dev_err(dev, "sock_queue_rcv_skb failed: %d\n", ret);
+		kfree_skb(skb);
+	}
+
+out:
+	release_sock(sk);
+}
+
+static void rpmsg_proto_cb(struct rpmsg_channel *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	int id = get_virtproc_id(rpdev->vrp);
+
+	__rpmsg_proto_cb(&rpdev->dev, id, data, len, priv, src);
+}
+
+/* every channel we're probed with is exposed to userland via the Socket API */
+static int rpmsg_proto_probe(struct rpmsg_channel *rpdev)
+{
+	struct device *dev = &rpdev->dev;
+	int ret, dst = rpdev->dst, id;
+	struct radix_tree_root *vrp_channels;
+
+	if (dst == RPMSG_ADDR_ANY)
+		return 0;
+
+	id = get_virtproc_id(rpdev->vrp);
+
+	mutex_lock(&rpmsg_channels_lock);
+
+	/* are we exposing channels for this remote processor yet ? */
+	vrp_channels = radix_tree_lookup(&rpmsg_channels, id);
+	/* not yet ? let's prepare the 2nd radix tree level then */
+	if (!vrp_channels) {
+		vrp_channels = kzalloc(sizeof(*vrp_channels), GFP_KERNEL);
+		INIT_RADIX_TREE(vrp_channels, GFP_KERNEL);
+		/* now let's associate the new channel with its vrp */
+		ret = radix_tree_insert(&rpmsg_channels, id, vrp_channels);
+		if (ret) {
+			dev_err(dev, "radix_tree_insert failed: %d\n", ret);
+			kfree(vrp_channels);
+			return ret;
+		}
+	}
+
+	/* let's associate the new channel with its dst */
+	ret = radix_tree_insert(vrp_channels, dst, rpdev);
+	if (ret)
+		dev_err(dev, "failed to add rpmsg addr %d: %d\n", dst, ret);
+
+	mutex_unlock(&rpmsg_channels_lock);
+
+	return ret;
+}
+
+static void rpmsg_proto_remove(struct rpmsg_channel *rpdev)
+{
+	struct device *dev = &rpdev->dev;
+	int id, dst = rpdev->dst;
+	struct radix_tree_root *vrp_channels;
+
+	if (dst == RPMSG_ADDR_ANY)
+		return;
+
+	id = get_virtproc_id(rpdev->vrp);
+
+	mutex_lock(&rpmsg_channels_lock);
+
+	vrp_channels = radix_tree_lookup(&rpmsg_channels, id);
+	if (!vrp_channels) {
+		dev_err(dev, "can't find channels for this vrp: %d\n", id);
+		goto out;
+	}
+
+	if (!radix_tree_delete(vrp_channels, dst))
+		dev_err(dev, "failed to delete rpmsg %d\n", dst);
+
+out:
+	mutex_unlock(&rpmsg_channels_lock);
+}
+
+static struct rpmsg_device_id rpmsg_proto_id_table[] = {
+	{ .name	= "rpmsg-proto" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_proto_id_table);
+
+static struct rpmsg_driver rpmsg_proto_drv = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_proto_id_table,
+	.probe		= rpmsg_proto_probe,
+	.callback	= rpmsg_proto_cb,
+	.remove		= rpmsg_proto_remove,
+};
+
+int __init rpmsg_proto_init(void)
+{
+	int ret;
+
+	ret = proto_register(&rpmsg_proto, 0);
+	if (ret) {
+		pr_err("proto_register failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = sock_register(&rpmsg_proto_family);
+	if (ret) {
+		pr_err("sock_register failed: %d\n", ret);
+		goto proto_unreg;
+	}
+
+	/* gimme rpmsg channels to expose ! */
+	ret = register_rpmsg_driver(&rpmsg_proto_drv);
+	if (ret) {
+		pr_err("register_rpmsg_driver failed: %d\n", ret);
+		goto sock_unreg;
+	}
+
+	return 0;
+
+sock_unreg:
+	sock_unregister(PF_RPMSG);
+proto_unreg:
+	proto_unregister(&rpmsg_proto);
+	return ret;
+}
+
+void __exit rpmsg_proto_exit(void)
+{
+	unregister_rpmsg_driver(&rpmsg_proto_drv);
+	sock_unregister(PF_RPMSG);
+	proto_unregister(&rpmsg_proto);
+}
+
+module_init(rpmsg_proto_init);
+module_exit(rpmsg_proto_exit);
+
+MODULE_DESCRIPTION("Remote processor messaging protocol");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_NETPROTO(AF_RPMSG);
Index: linux-3.12.24-rt38-xilinx/samples/xilinx_apm/main.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/samples/xilinx_apm/main.c	2014-07-20 22:06:39.946246503 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * Xilinx AXI Performance Monitor Example
+ *
+ * Copyright (c) 2013 Xilinx Inc.
+ *
+ * The code may be used by anyone for any purpose and can serve as a
+ * starting point for developing applications using Xilinx AXI
+ * Performance Monitor.
+ *
+ * This example based on Xilinx AXI Performance Monitor UIO driver shows
+ * sequence to read metrics from Xilinx AXI Performance Monitor IP.
+ * User need to provide the uio device file with option -d:
+ * main -d /dev/uio0, say /dev/uio0 as device file for AXI Performance
+ * Monitor driver. User need not clear Interrupt Status Register after
+ * waiting for interrupt on read since driver clears it.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <sys/msg.h>
+#include <sys/ipc.h>
+#include <stdint.h>
+#include "xaxipmon.h"
+
+#define MAP_SIZE 4096
+
+void usage(void)
+{
+	printf("*argv[0] -d <UIO_DEV_FILE> -i|-o <VALUE>\n");
+	printf(" -d UIO device file. e.g. /dev/uio0");
+	return;
+}
+
+static void start(int fd)
+{
+	u8 slot = 2;
+	int tmp;
+	u32 isr;
+
+	setmetrics(slot, XAPM_METRIC_SET_4, XAPM_METRIC_COUNTER_0);
+	setsampleinterval(0x3FFFFFF);
+
+	loadsic();
+
+	intrenable(XAPM_IXR_SIC_OVERFLOW_MASK);
+
+	intrglobalenable();
+
+	enablemetricscounter();
+
+	enablesic();
+
+	isr = intrgetstatus();
+	/* Wait for SIC overflow interrupt */
+	if (read(fd, &tmp, 4) < 0)
+		perror("Read\n");
+	/* Driver clears the interrupt and occured interrupt status is
+		stored in param->isr */
+	isr = intrgetstatus();
+	if (isr & XAPM_IXR_SIC_OVERFLOW_MASK)
+		disablesic();
+
+	disablemetricscounter();
+
+	intrdisable(XAPM_IXR_SIC_OVERFLOW_MASK);
+
+	intrglobaldisable();
+
+	printf("Required metrics: %u\n",
+		getsampledmetriccounter(XAPM_METRIC_COUNTER_0) *
+		params->scalefactor);
+}
+
+int main(int argc, char *argv[])
+{
+	int c;
+	char *uiod;
+	int fd;
+
+	while ((c = getopt(argc, argv, "d:h")) != -1) {
+		switch (c) {
+		case 'd':
+			uiod = optarg;
+			break;
+		case 'h':
+			usage();
+			return 0;
+		default:
+			printf("invalid option: %c\n", (char)c);
+			usage();
+			return -1;
+		}
+	}
+
+	/* Open the UIO device file */
+	fd = open(uiod, O_RDWR);
+	if (fd < 1) {
+		perror(argv[0]);
+		printf("Invalid UIO device file:%s.\n", uiod);
+		usage();
+		return -1;
+	}
+
+	baseaddr = (u32)mmap(0, MAP_SIZE , PROT_READ|PROT_WRITE,
+				MAP_SHARED , fd, 0);
+	if ((u32 *)baseaddr == MAP_FAILED)
+		perror("mmap failed\n");
+
+	/* mmap the UIO device */
+	params = (struct xapm_param *)mmap(0, MAP_SIZE , PROT_READ|PROT_WRITE,
+				MAP_SHARED , fd, getpagesize());
+	if (params == MAP_FAILED)
+		perror("mmap failed\n");
+
+	if (params->mode == 1)
+		printf("AXI PMON is in Advanced Mode\n");
+	else if (params->mode == 2)
+		printf("AXI PMON is in Profile Mode\n");
+	else
+		printf("AXI PMON is in trace Mode\n");
+
+	start(fd);
+
+	close(fd);
+	munmap((u32 *)baseaddr, MAP_SIZE);
+	munmap(params, MAP_SIZE);
+
+	return 0;
+}
Index: linux-3.12.24-rt38-xilinx/samples/xilinx_apm/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/samples/xilinx_apm/Makefile	2014-07-20 22:06:39.951246420 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#
+# 'make depend' uses makedepend to automatically generate dependencies
+#               (dependencies are added to end of Makefile)
+# 'make'        build executable file 'mycc'
+# 'make clean'  removes all .o and executable files
+#
+
+# define the C compiler to use
+CC = $(CROSS_COMPILE)gcc
+
+# define any compile-time flags
+CFLAGS = -Wall -g
+
+# define any directories containing header files other than /usr/include
+#
+INCLUDES =
+
+# define library paths in addition to /usr/lib
+#   if I wanted to include libraries not in /usr/lib I'd specify
+#   their path using -Lpath, something like:
+LFLAGS =
+
+# define any libraries to link into executable:
+#   if I want to link in libraries (libx.so or libx.a) I use the -llibname
+#   option, something like (this will link in libmylib.so and libm.so:
+LIBS =  -lm
+
+# define the C source files
+SRCS = main.c xaxipmon.c
+
+# define the C object files
+#
+# This uses Suffix Replacement within a macro:
+#   $(name:string1=string2)
+#         For each word in 'name' replace 'string1' with 'string2'
+# Below we are replacing the suffix .c of all words in the macro SRCS
+# with the .o suffix
+#
+OBJS = $(SRCS:.c=.o)
+
+# define the executable file
+MAIN = main
+
+#
+# The following part of the makefile is generic; it can be used to
+# build any executable just by changing the definitions above and by
+# deleting dependencies appended to the file from 'make depend'
+#
+
+.PHONY: depend clean
+
+all:    $(MAIN)
+	@echo  Xilinx AXI Performance Monitor application compiled
+
+$(MAIN): $(OBJS)
+	$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
+
+# this is a suffix replacement rule for building .o's from .c's
+# it uses automatic variables $<: the name of the prerequisite of
+# the rule(a .c file) and $@: the name of the target of the rule (a .o file)
+# (see the gnu make manual section about automatic variables)
+.c.o:
+	$(CC) $(CFLAGS) $(INCLUDES) -c $<  -o $@
+
+clean:
+	$(RM) *.o *~ $(MAIN)
+
+depend: $(SRCS)
+	makedepend $(INCLUDES) $^
+
+# DO NOT DELETE THIS LINE -- make depend needs it
Index: linux-3.12.24-rt38-xilinx/samples/xilinx_apm/xaxipmon.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/samples/xilinx_apm/xaxipmon.c	2014-07-20 22:06:39.966246173 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#include "xaxipmon.h"
+/*****************************************************************************/
+/**
+*
+* This function resets all Metric Counters and Sampled Metric Counters of
+* AXI Performance Monitor.
+*
+* @return	XST_SUCCESS
+*
+*
+* @note		None.
+*
+******************************************************************************/
+int resetmetriccounter(void)
+{
+	u32 regval;
+
+	/*
+	 * Write the reset value to the Control register to reset
+	 * Metric counters
+	 */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+					(regval | XAPM_CR_MCNTR_RESET_MASK));
+	/*
+	 * Release from Reset
+	 */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				(regval & ~(XAPM_CR_MCNTR_RESET_MASK)));
+	return XST_SUCCESS;
+
+}
+
+/*****************************************************************************/
+/**
+*
+* This function resets Global Clock Counter of AXI Performance Monitor
+*
+* @return	None.
+*
+* @note		None.
+*
+******************************************************************************/
+void resetglobalclkcounter(void)
+{
+
+	u32 regval;
+
+	/*
+	 * Write the reset value to the Control register to reset
+	 * Global Clock Counter
+	 */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+					(regval | XAPM_CR_GCC_RESET_MASK));
+
+	/*
+	 * Release from Reset
+	 */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				(regval & ~(XAPM_CR_GCC_RESET_MASK)));
+
+}
+
+/*****************************************************************************/
+/**
+*
+* This function resets Streaming FIFO of AXI Performance Monitor
+*
+* @return	XST_SUCCESS
+*
+* @note		None.
+*
+******************************************************************************/
+int resetfifo(void)
+{
+	u32 regval;
+
+	/* Check Event Logging is enabled in Hardware */
+	if (params->eventlog == 0)
+		/*Event Logging not enabled in Hardware*/
+		return XST_SUCCESS;
+
+	/*
+	 * Write the reset value to the Control register to reset
+	 * FIFO
+	 */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+					(regval | XAPM_CR_FIFO_RESET_MASK));
+	/*
+	 * Release from Reset
+	 */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				(regval & ~(XAPM_CR_FIFO_RESET_MASK)));
+
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Ranges for Incrementers depending on parameters passed.
+*
+* @param	incrementer specifies the Incrementer for which Ranges
+*		need to be set
+* @param	rangehigh specifies the Upper limit in 32 bit Register
+* @param	rangelow specifies the Lower limit in 32 bit Register
+*
+* @return	None.
+*
+* @note		None
+*
+*****************************************************************************/
+void setincrementerrange(u8 incrementer, u16 rangehigh, u16 rangelow)
+{
+	u32 regval;
+
+	/*
+	 * Write to the specified Range register
+	 */
+	regval = rangehigh << 16;
+	regval |= rangelow;
+	writereg(baseaddr,
+		(XAPM_RANGE0_OFFSET + (incrementer * 16)), regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the Ranges of Incrementers Registers.
+*
+* @param	incrementer specifies the Incrementer for which Ranges
+*		need to be returned.
+* @param	rangehigh specifies the user reference variable which returns
+*		the Upper Range Value of the specified Incrementer.
+* @param	rangelow specifies the user reference variable which returns
+*		the Lower Range Value of the specified Incrementer.
+*
+* @return	None.
+*
+* @note		None
+*
+*****************************************************************************/
+void getincrementerrange(u8 incrementer, u16 *rangehigh, u16 *rangelow)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, (XAPM_RANGE0_OFFSET +
+					(incrementer * 16)));
+
+	*rangelow = regval & 0xFFFF;
+	*rangehigh = (regval >> 16) & 0xFFFF;
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets the Sample Interval Register
+*
+* @param	sampleinterval is the Sample Interval
+*
+* @return	None
+*
+* @note		None.
+*
+*****************************************************************************/
+void setsampleinterval(u32 sampleinterval)
+{
+	/*
+	 * Set Sample Interval
+	 */
+	writereg(baseaddr, XAPM_SI_LOW_OFFSET, sampleinterval);
+
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of Sample Interval Register
+*
+* @param	sampleinterval is a pointer where Sample Interval register
+*		contents are returned.
+* @return	None.
+*
+* @note		None.
+*
+******************************************************************************/
+void getsampleinterval(u32 *sampleinterval)
+{
+	/*
+	 * Set Sample Interval Lower
+	 */
+	*sampleinterval = readreg(baseaddr, XAPM_SI_LOW_OFFSET);
+
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets metrics for specified Counter in the corresponding
+* Metric Selector Register.
+*
+* @param	slot is the slot ID for which specified counter has to
+*		be connected.
+* @param	metrics is one of the Metric Sets. User has to use
+*		XAPM_METRIC_SET_* macros in xaxipmon.h for this parameter
+* @param	counter is the Counter Number.
+*		The valid values are 0 to 9.
+*
+* @return	XST_SUCCESS if Success
+*		XST_FAILURE if Failure
+*
+* @note		None.
+*
+*****************************************************************************/
+int setmetrics(u8 slot, u8 metrics, u8 counter)
+{
+	u32 regval;
+	u32 mask;
+
+	/* Find mask value to force zero in counternum byte range */
+	if (counter == 0 || counter == 4 || counter == 8)
+		mask = 0xFFFFFF00;
+	else if (counter == 1 || counter == 5 || counter == 9)
+		mask = 0xFFFF00FF;
+	else if (counter == 2 || counter == 6)
+		mask = 0xFF00FFFF;
+	else
+		mask = 0x00FFFFFF;
+
+	if (counter <= 3) {
+		regval = readreg(baseaddr, XAPM_MSR0_OFFSET);
+		regval = regval & mask;
+		regval = regval | (metrics << (counter * 8));
+		regval = regval | (slot << (counter * 8 + 5));
+		writereg(baseaddr, XAPM_MSR0_OFFSET, regval);
+	} else if ((counter >= 4) && (counter <= 7)) {
+		counter = counter - 4;
+		regval = readreg(baseaddr, XAPM_MSR1_OFFSET);
+		regval = regval & mask;
+		regval = regval | (metrics << (counter * 8));
+		regval = regval | (slot << (counter * 8 + 5));
+		writereg(baseaddr, XAPM_MSR1_OFFSET, regval);
+	} else {
+		counter = counter - 8;
+		regval = readreg(baseaddr, XAPM_MSR2_OFFSET);
+
+		regval = regval & mask;
+		regval = regval | (metrics << (counter * 8));
+		regval = regval | (slot << (counter * 8 + 5));
+		writereg(baseaddr, XAPM_MSR2_OFFSET, regval);
+	}
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns metrics in the specified Counter from the corresponding
+* Metric Selector Register.
+*
+* @param	counter is the Counter Number.
+*		The valid values are 0 to 9.
+* @param	metrics is a reference parameter from application where metrics
+*		of specified counter is filled.
+* @praram	slot is a reference parameter in which slot Id of
+*		specified counter is filled
+* @return	XST_SUCCESS if Success
+*		XST_FAILURE if Failure
+*
+* @note		None.
+*
+*****************************************************************************/
+int getmetrics(u8 counter, u8 *metrics, u8 *slot)
+{
+	u32 regval;
+
+	if (counter <= 3) {
+		regval = readreg(baseaddr, XAPM_MSR0_OFFSET);
+		*metrics = (regval >> (counter * 8)) & 0x1F;
+		*slot	= (regval >> (counter * 8 + 5)) & 0x7;
+	} else if ((counter >= 4) && (counter <= 7)) {
+		counter = counter - 4;
+		regval = readreg(baseaddr, XAPM_MSR1_OFFSET);
+		*metrics = (regval >> (counter * 8)) & 0x1F;
+		*slot	= (regval >> (counter * 8 + 5)) & 0x7;
+	} else {
+		counter = counter - 8;
+		regval = readreg(baseaddr, XAPM_MSR2_OFFSET);
+		*metrics = (regval >> (counter * 8)) & 0x1F;
+		*slot	= (regval >> (counter * 8 + 5)) & 0x7;
+	}
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of the Global Clock Counter Register.
+*
+* @param	cnthigh is the user space pointer with which upper 32 bits
+*		of Global Clock Counter has to be filled
+* @param	cntlow is the user space pointer with which lower 32 bits
+*		of Global Clock Counter has to be filled
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void getglobalclkcounter(u32 *cnthigh, u32 *cntlow)
+{
+	*cnthigh = 0x0;
+	*cntlow  = 0x0;
+
+	/*
+	 * If Counter width is 64 bit then Counter Value has to be
+	 * filled at CntHighValue address also.
+	 */
+	if (params->globalcntwidth == 64) {
+		/* Bits[63:32] exists at XAPM_GCC_HIGH_OFFSET */
+		*cnthigh = readreg(baseaddr, XAPM_GCC_HIGH_OFFSET);
+	}
+	/* Bits[31:0] exists at XAPM_GCC_LOW_OFFSET */
+	*cntlow = readreg(baseaddr, XAPM_GCC_LOW_OFFSET);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of the Metric Counter Register.
+*
+* @param	counter is the number of the Metric Counter to be read.
+*		Use the XAPM_METRIC_COUNTER* defines for the counter number in
+*		xaxipmon.h. The valid values are 0 (XAPM_METRIC_COUNTER_0) to
+*		9 (XAPM_METRIC_COUNTER_9).
+* @return	regval is the content of specified Metric Counter.
+*
+* @note		None.
+*
+*****************************************************************************/
+u32 getmetriccounter(u32 counter)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr,
+				(XAPM_MC0_OFFSET + (counter * 16)));
+	return regval;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of the Sampled Metric Counter Register.
+*
+* @param	counter is the number of the Sampled Metric Counter to read.
+*		Use the XAPM_METRIC_COUNTER* defines for the counter number in
+*		xaxipmon.h. The valid values are 0 (XAPM_METRIC_COUNTER_0) to
+*		9 (XAPM_METRIC_COUNTER_9).
+*
+* @return	regval is the content of specified Sampled Metric Counter.
+*
+* @note		None.
+*
+*****************************************************************************/
+u32 getsampledmetriccounter(u32 counter)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, (XAPM_SMC0_OFFSET +
+						(counter * 16)));
+	return regval;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of the Incrementer Register.
+*
+* @param	incrementer is the number of the Incrementer register to
+*		read.Use the XAPM_INCREMENTER_* defines for the Incrementer
+*		number.The valid values are 0 (XAPM_INCREMENTER_0) to
+*		9 (XAPM_INCREMENTER_9).
+* @param	incrementer is the number of the specified Incrementer
+*		register
+* @return	regval is content of specified Metric Incrementer register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u32 getincrementer(u32 incrementer)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, (XAPM_INC0_OFFSET +
+						(incrementer * 16)));
+	return regval;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the contents of the Sampled Incrementer Register.
+*
+* @param	incrementer is the number of the Sampled Incrementer
+*		register to read.Use the XAPM_INCREMENTER_* defines for the
+*		Incrementer number.The valid values are 0 (XAPM_INCREMENTER_0)
+*		to 9 (XAPM_INCREMENTER_9).
+* @param	incrementer is the number of the specified Sampled
+*		Incrementer register
+* @return	regval is content of specified Sampled Incrementer register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u32 getsampledincrementer(u32 incrementer)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, (XAPM_SINC0_OFFSET +
+					(incrementer * 16)));
+	return regval;
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Software-written Data Register.
+*
+* @param	swdata is the Software written Data.
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void setswdatareg(u32 swdata)
+{
+	/*
+	 * Set Software-written Data Register
+	 */
+	writereg(baseaddr, XAPM_SWD_OFFSET, swdata);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns contents of Software-written Data Register.
+*
+* @return	swdata.
+*
+* @note		None.
+*
+*****************************************************************************/
+u32 getswdatareg(void)
+{
+	u32 swdata;
+
+	/*
+	 * Set Metric Selector Register
+	 */
+	swdata = (u32)readreg(baseaddr, XAPM_SWD_OFFSET);
+	return swdata;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables the following in the AXI Performance Monitor:
+*   - Event logging
+*
+* @param        flagenables is a value to write to the flag enables
+*               register defined by XAPM_FEC_OFFSET. It is recommended
+*               to use the XAPM_FEC_*_MASK mask bits to generate.
+*               A value of 0x0 will disable all events to the event
+*               log streaming FIFO.
+*
+* @return       XST_SUCCESS
+*
+* @note         None
+*
+******************************************************************************/
+int starteventlog(u32 flagenables)
+{
+	u32 regval;
+
+	/* Read current register value */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	/* Now write to flag enables register */
+	writereg(baseaddr, XAPM_FEC_OFFSET, flagenables);
+	/* Write the new value to the Control register to
+	 *	enable event logging */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+			regval | XAPM_CR_EVENTLOG_ENABLE_MASK);
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function disables the following in the AXI Performance Monitor:
+*   - Event logging
+*
+* @return       XST_SUCCESS
+*
+* @note         None
+*
+******************************************************************************/
+int stopeventlog(void)
+{
+	u32 regval;
+
+	/* Read current register value */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	/* Write the new value to the Control register to disable
+	 * event logging */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				regval & ~XAPM_CR_EVENTLOG_ENABLE_MASK);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables the following in the AXI Performance Monitor:
+*   - Global clock counter
+*   - All metric counters
+*   - All sampled metric counters
+*
+* @param    sampleinterval is the sample interval
+* @return   XST_SUCCESS
+*
+* @note	    None
+******************************************************************************/
+int startcounters(u32 sampleinterval)
+{
+	u32 regval;
+
+	/* Read current register value */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	/* Global Clock Counter is present in Advanced Mode only */
+	if (params->mode == 1)
+		regval = regval | XAPM_CR_GCC_ENABLE_MASK;
+	/*
+	 * Write the new value to the Control register to enable
+	 * global clock counter and metric counters
+	 */
+	writereg(baseaddr, XAPM_CTL_OFFSET, regval | XAPM_CR_MCNTR_ENABLE_MASK);
+
+	/* Set, enable, and load sampled counters */
+	setsampleinterval(sampleinterval);
+	loadsic();
+	enablesic();
+
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+* This function disables the following in the AXI Performance Monitor:
+*   - Global clock counter
+*   - All metric counters
+*
+* @return       XST_SUCCESS
+*
+* @note         None
+*
+******************************************************************************/
+int stopcounters(void)
+{
+	u32 regval;
+
+	/* Read current register value */
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	/* Global Clock Counter is present in Advanced Mode only */
+	if (params->mode == 1)
+		regval = regval & ~XAPM_CR_GCC_ENABLE_MASK;
+
+	/*
+	 * Write the new value to the Control register to disable
+	 * global clock counter and metric counters
+	 */
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+			regval & ~XAPM_CR_MCNTR_ENABLE_MASK);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables Metric Counters.
+*
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void enablemetricscounter(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+					regval | XAPM_CR_MCNTR_ENABLE_MASK);
+}
+/****************************************************************************/
+/**
+*
+* This function disables the Metric Counters.
+*
+* @return	None
+*
+* @note		None
+*
+*****************************************************************************/
+void disablemetricscounter(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+					regval & ~(XAPM_CR_MCNTR_ENABLE_MASK));
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets the Upper and Lower Ranges for specified Metric Counter
+* Log Enable Register.Event Logging starts when corresponding Metric Counter
+* value falls in between these ranges
+*
+* @param	counter is the Metric Counter number for which
+*		Ranges are to be assigned.Use the XAPM_METRIC_COUNTER*
+*		defines for the counter number in xaxipmon.h.
+*		The valid values are 0 (XAPM_METRIC_COUNTER_0) to
+*		9 (XAPM_METRIC_COUNTER_9).
+* @param	rangehigh specifies the Upper limit in 32 bit Register
+* @param	rangelow specifies the Lower limit in 32 bit Register
+* @return	None
+*
+* @note		None.
+*
+*****************************************************************************/
+void setlogenableranges(u32 counter, u16 rangehigh, u16 rangelow)
+{
+	u32 regval;
+
+	/*
+	 * Write the specified Ranges to corresponding Metric Counter Log
+	 * Enable Register
+	 */
+	regval = rangehigh << 16;
+	regval |= rangelow;
+	writereg(baseaddr, (XAPM_MC0LOGEN_OFFSET +
+					(counter * 16)), regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns the Ranges of specified Metric Counter Log
+* Enable Register.
+*
+* @param	counter is the Metric Counter number for which
+*		Ranges are to be returned.Use the XAPM_METRIC_COUNTER*
+*		defines for the counter number in xaxipmon.h.
+*		The valid values are 0 (XAPM_METRIC_COUNTER_0) to
+*		9 (XAPM_METRIC_COUNTER_9).
+*
+* @param	rangehigh specifies the user reference variable which returns
+*		the Upper Range Value of the specified Metric Counter
+*		Log Enable Register.
+* @param	rangelow specifies the user reference variable which returns
+*		the Lower Range Value of the specified Metric Counter
+*		Log Enable Register.
+*
+* @note		None.
+*
+*****************************************************************************/
+void getlogenableranges(u32 counter, u16 *rangehigh, u16 *rangelow)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr,
+				(XAPM_MC0LOGEN_OFFSET + (counter * 16)));
+
+	*rangelow = regval & 0xFFFF;
+	*rangehigh = (regval >> 16) & 0xFFFF;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables Event Logging.
+*
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void enableeventlog(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				regval | XAPM_CR_EVENTLOG_ENABLE_MASK);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables External trigger pulse so that Metric Counters can be
+* started on external trigger pulse for a slot.
+*
+*
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void enablemctrigger(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+			regval | XAPM_CR_MCNTR_EXTTRIGGER_MASK);
+}
+
+/****************************************************************************/
+/**
+*
+* This function disables the External trigger pulse used to start Metric
+* Counters on external trigger pulse for a slot.
+*
+* @return	None
+*
+* @note		None
+*
+*****************************************************************************/
+void disablemctrigger(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+			regval & ~(XAPM_CR_MCNTR_EXTTRIGGER_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables External trigger pulse for Event Log
+* so that Event Logging can be started on external trigger pulse for a slot.
+*
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void enableeventlogtrigger(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				regval | XAPM_CR_EVTLOG_EXTTRIGGER_MASK);
+}
+
+/****************************************************************************/
+/**
+*
+* This function disables the External trigger pulse used to start Event
+* Log on external trigger pulse for a slot.
+*
+* @return	None
+*
+* @note		None
+*
+*****************************************************************************/
+void disableeventlogtrigger(void)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+
+	writereg(baseaddr, XAPM_CTL_OFFSET,
+				regval & ~(XAPM_CR_EVTLOG_EXTTRIGGER_MASK));
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns a name for a given Metric.
+*
+* @param        metrics is one of the Metric Sets. User has to use
+*               XAPM_METRIC_SET_* macros in xaxipmon.h for this parameter
+*
+* @return       const char *
+*
+* @note         None
+*
+*****************************************************************************/
+const char *getmetricname(u8 metrics)
+{
+	if (metrics == XAPM_METRIC_SET_0)
+		return "Write Transaction Count";
+	if (metrics == XAPM_METRIC_SET_1)
+		return "Read Transaction Count";
+	if (metrics == XAPM_METRIC_SET_2)
+		return "Write Byte Count";
+	if (metrics == XAPM_METRIC_SET_3)
+		return "Read Byte Count";
+	if (metrics == XAPM_METRIC_SET_4)
+		return "Write Beat Count";
+	if (metrics == XAPM_METRIC_SET_5)
+		return "Total Read Latency";
+	if (metrics == XAPM_METRIC_SET_6)
+		return "Total Write Latency";
+	if (metrics == XAPM_METRIC_SET_7)
+		return "Slv_Wr_Idle_Cnt";
+	if (metrics == XAPM_METRIC_SET_8)
+		return "Mst_Rd_Idle_Cnt";
+	if (metrics == XAPM_METRIC_SET_9)
+		return "Num_BValids";
+	if (metrics == XAPM_METRIC_SET_10)
+		return "Num_WLasts";
+	if (metrics == XAPM_METRIC_SET_11)
+		return "Num_RLasts";
+	if (metrics == XAPM_METRIC_SET_12)
+		return "Minimum Write Latency";
+	if (metrics == XAPM_METRIC_SET_13)
+		return "Maximum Write Latency";
+	if (metrics == XAPM_METRIC_SET_14)
+		return "Minimum Read Latency";
+	if (metrics == XAPM_METRIC_SET_15)
+		return "Maximum Read Latency";
+	if (metrics == XAPM_METRIC_SET_16)
+		return "Transfer Cycle Count";
+	if (metrics == XAPM_METRIC_SET_17)
+		return "Packet Count";
+	if (metrics == XAPM_METRIC_SET_18)
+		return "Data Byte Count";
+	if (metrics == XAPM_METRIC_SET_19)
+		return "Position Byte Count";
+	if (metrics == XAPM_METRIC_SET_20)
+		return "Null Byte Count";
+	if (metrics == XAPM_METRIC_SET_21)
+		return "Slv_Idle_Cnt";
+	if (metrics == XAPM_METRIC_SET_22)
+		return "Mst_Idle_Cnt";
+	if (metrics == XAPM_METRIC_SET_30)
+		return "External event count";
+	return "Unsupported";
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Write ID in Latency ID register to capture Write
+* Latency metrics.
+*
+* @param	writeid is the Write ID to be written in Latency ID register.
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void setwriteid(u16 writeid)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_ID_OFFSET);
+	regval = regval & ~(XAPM_ID_WID_MASK);
+	regval = regval | writeid;
+	writereg(baseaddr, XAPM_ID_OFFSET, regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Read ID in Latency ID register to capture
+* Read Latency metrics.
+*
+* @param	readid is the Read ID to be written in Latency ID register.
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void setreadid(u16 readid)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_ID_OFFSET);
+	regval = regval & ~(XAPM_ID_RID_MASK);
+	regval = regval | (readid << 16);
+	writereg(baseaddr, XAPM_ID_OFFSET, regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns Write ID in Latency ID register.
+*
+* @return	writeid is the required Write ID in Latency ID register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u16 getwriteid(void)
+{
+
+	u16 writeid;
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_ID_OFFSET);
+	writeid = regval & XAPM_ID_WID_MASK;
+
+	return writeid;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns Read ID in Latency ID register.
+*
+* @return	readid is the required Read ID in Latency ID register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u16 getreadid(void)
+{
+
+	u16 readid;
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_ID_OFFSET);
+	regval = regval & XAPM_ID_RID_MASK;
+	readid = regval >> 16;
+
+	return readid;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets Latency Start point to calculate write latency.
+*
+* @param	Param can be 0 - XAPM_LATENCY_ADDR_ISSUE
+*		or 1 - XAPM_LATENCY_ADDR_ACCEPT
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void setwrlatencystart(u8 param)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	if (param == XAPM_LATENCY_ADDR_ACCEPT)
+		writereg(baseaddr, XAPM_CTL_OFFSET, regval |
+				XAPM_CR_WRLATENCY_START_MASK);
+	else
+		writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr,
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_WRLATENCY_START_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets Latency End point to calculate write latency.
+*
+* @param	Param can be 0 - XAPM_LATENCY_LASTWR
+*		or 1 - XAPM_LATENCY_FIRSTWR
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void setwrlatencyend(u8 param)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	if (param == XAPM_LATENCY_FIRSTWR)
+		writereg(baseaddr, XAPM_CTL_OFFSET, regval |
+					XAPM_CR_WRLATENCY_END_MASK);
+	else
+		writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr,
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_WRLATENCY_END_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets Latency Start point to calculate read latency.
+*
+* @param	Param can be 0 - XAPM_LATENCY_ADDR_ISSUE
+*		or 1 - XAPM_LATENCY_ADDR_ACCEPT
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void setrdlatencystart(u8 param)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	if (param == XAPM_LATENCY_ADDR_ACCEPT)
+		writereg(baseaddr, XAPM_CTL_OFFSET, regval |
+					XAPM_CR_RDLATENCY_START_MASK);
+	else
+		writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr,
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_RDLATENCY_START_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets Latency End point to calculate read latency.
+*
+* @param	Param can be 0 - XAPM_LATENCY_LASTRD
+*		or 1 - XAPM_LATENCY_FIRSTRD
+* @return	None
+*
+* @note		None
+*
+******************************************************************************/
+void setrdlatencyend(u8 param)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	if (param == XAPM_LATENCY_FIRSTRD)
+		writereg(baseaddr, XAPM_CTL_OFFSET, regval |
+				XAPM_CR_RDLATENCY_END_MASK);
+	else
+		writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr,
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_RDLATENCY_END_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns Write Latency Start point.
+*
+* @return	Returns 0 - XAPM_LATENCY_ADDR_ISSUE or
+*			1 - XAPM_LATENCY_ADDR_ACCEPT
+*
+* @note		None
+*
+******************************************************************************/
+u8 getwrlatencystart(void)
+{
+	u8 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	regval = regval & XAPM_CR_WRLATENCY_START_MASK;
+	if (regval != XAPM_LATENCY_ADDR_ISSUE)
+		return XAPM_LATENCY_ADDR_ACCEPT;
+	else
+		return XAPM_LATENCY_ADDR_ISSUE;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns Write Latency End point.
+*
+* @return	Returns 0 - XAPM_LATENCY_LASTWR or
+*			1 - XAPM_LATENCY_FIRSTWR.
+*
+* @note		None
+*
+******************************************************************************/
+u8 getwrlatencyend(void)
+{
+	u8 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	regval = regval & XAPM_CR_WRLATENCY_END_MASK;
+	if (regval != XAPM_LATENCY_LASTWR)
+		return XAPM_LATENCY_FIRSTWR;
+	else
+		return XAPM_LATENCY_LASTWR;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns read Latency Start point.
+*
+* @return	Returns 0 - XAPM_LATENCY_ADDR_ISSUE or
+*			1 - XAPM_LATENCY_ADDR_ACCEPT
+*
+* @note		None
+*
+******************************************************************************/
+u8 getrdlatencystart(void)
+{
+	u8 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	regval = regval & XAPM_CR_RDLATENCY_START_MASK;
+
+	if (regval != XAPM_LATENCY_ADDR_ISSUE)
+		return	XAPM_LATENCY_ADDR_ACCEPT;
+	else
+		return XAPM_LATENCY_ADDR_ISSUE;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns Read Latency End point.
+*
+* @return	Returns 0 - XAPM_LATENCY_LASTRD or
+*			1 - XAPM_LATENCY_FIRSTRD.
+*
+* @note		None
+*
+******************************************************************************/
+u8 getrdlatencyend(void)
+{
+	u8 regval;
+
+	regval = readreg(baseaddr, XAPM_CTL_OFFSET);
+	regval = regval & XAPM_CR_RDLATENCY_END_MASK;
+	if (regval != XAPM_LATENCY_LASTRD)
+		return XAPM_LATENCY_FIRSTRD;
+	else
+		return XAPM_LATENCY_LASTRD;
+
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Write ID Mask in ID Mask register.
+*
+* @param	wrmask is the Write ID mask to be written in ID register.
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void setwriteidmask(u16 wrmask)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_IDMASK_OFFSET);
+	regval = regval & ~(XAPM_MASKID_WID_MASK);
+	regval = regval | wrmask;
+	writereg(baseaddr, XAPM_IDMASK_OFFSET, regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function sets Read ID Mask in ID Mask register.
+*
+* @param	rdmask is the Read ID mask to be written in ID Mask register.
+*
+* @return	None.
+*
+* @note		None.
+*
+*****************************************************************************/
+void setreadidmask(u16 rdmask)
+{
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_IDMASK_OFFSET);
+	regval = regval & ~(XAPM_MASKID_RID_MASK);
+	regval = regval | (rdmask << 16);
+	writereg(baseaddr, XAPM_IDMASK_OFFSET, regval);
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns Write ID Mask in ID Mask register.
+*
+* @return	wrmask is the required Write ID Mask in ID Mask register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u16 getwriteidmask(void)
+{
+
+	u16 wrmask;
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_IDMASK_OFFSET);
+	wrmask = regval & XAPM_MASKID_WID_MASK;
+
+	return wrmask;
+}
+
+/****************************************************************************/
+/**
+*
+* This function returns Read ID Mask in ID Mask register.
+*
+* @return	rdmask is the required Read ID Mask in ID Mask register.
+*
+* @note		None.
+*
+*****************************************************************************/
+u16 getreadidmask(void)
+{
+
+	u16 rdmask;
+	u32 regval;
+
+	regval = readreg(baseaddr, XAPM_IDMASK_OFFSET);
+	regval = regval & XAPM_MASKID_RID_MASK;
+	rdmask = regval >> 16;
+
+	return rdmask;
+}
Index: linux-3.12.24-rt38-xilinx/samples/xilinx_apm/xaxipmon.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/samples/xilinx_apm/xaxipmon.h	2014-07-20 22:06:39.981245925 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#ifndef XAXIPMON_H /* Prevent circular inclusions */
+#define XAXIPMON_H /* by using protection macros  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+
+#define XST_SUCCESS	0
+#define XST_FAILURE	1
+
+#ifndef TRUE
+#define TRUE		1
+#endif
+
+#ifndef FALSE
+#define FALSE		0
+#endif
+
+#ifndef NULL
+#define NULL		0
+#endif
+
+#define XAPM_GCC_HIGH_OFFSET		0x0000	/* Global Clock Counter
+							32 to 63 bits  */
+#define XAPM_GCC_LOW_OFFSET		0x0004	/* Global Clock Counter Lower
+							0-31 bits  */
+#define XAPM_SI_HIGH_OFFSET		0x0020	/* Sample Interval MSB */
+#define XAPM_SI_LOW_OFFSET		0x0024	/* Sample Interval LSB */
+#define XAPM_SICR_OFFSET		0x0028	/* Sample Interval Control
+							Register */
+#define XAPM_SR_OFFSET			0x002C	/* Sample Register */
+#define XAPM_GIE_OFFSET			0x0030	/* Global Interrupt Enable
+							Register */
+#define XAPM_IE_OFFSET			0x0034	/* Interrupt Enable Register */
+#define XAPM_IS_OFFSET			0x0038	/* Interrupt Status Register */
+
+#define XAPM_MSR0_OFFSET		0x0044	/* Metric Selector 0 Register*/
+#define XAPM_MSR1_OFFSET		0x0048	/* Metric Selector 1 Register*/
+#define XAPM_MSR2_OFFSET		0x004C	/* Metric Selector 2 Register*/
+
+#define XAPM_MC0_OFFSET			0x0100	/* Metric Counter 0 Register */
+#define XAPM_INC0_OFFSET		0x0104	/* Incrementer 0 Register */
+#define XAPM_RANGE0_OFFSET		0x0108	/* Range 0 Register */
+#define XAPM_MC0LOGEN_OFFSET		0x010C	/* Metric Counter 0
+							Log Enable Register */
+#define XAPM_MC1_OFFSET			0x0110	/* Metric Counter 1 Register */
+#define XAPM_INC1_OFFSET		0x0114	/* Incrementer 1 Register */
+#define XAPM_RANGE1_OFFSET		0x0118	/* Range 1 Register */
+#define XAPM_MC1LOGEN_OFFSET		0x011C	/* Metric Counter 1
+							Log Enable Register */
+#define XAPM_MC2_OFFSET			0x0120	/* Metric Counter 2 Register */
+#define XAPM_INC2_OFFSET		0x0124	/* Incrementer 2 Register */
+#define XAPM_RANGE2_OFFSET		0x0128	/* Range 2 Register */
+#define XAPM_MC2LOGEN_OFFSET		0x012C	/* Metric Counter 2
+							Log Enable Register */
+#define XAPM_MC3_OFFSET			0x0130	/* Metric Counter 3 Register */
+#define XAPM_INC3_OFFSET		0x0134	/* Incrementer 3 Register */
+#define XAPM_RANGE3_OFFSET		0x0138	/* Range 3 Register */
+#define XAPM_MC3LOGEN_OFFSET		0x013C	/* Metric Counter 3
+							Log Enable Register */
+#define XAPM_MC4_OFFSET			0x0140	/* Metric Counter 4 Register */
+#define XAPM_INC4_OFFSET		0x0144	/* Incrementer 4 Register */
+#define XAPM_RANGE4_OFFSET		0x0148	/* Range 4 Register */
+#define XAPM_MC4LOGEN_OFFSET		0x014C	/* Metric Counter 4
+							Log Enable Register */
+#define XAPM_MC5_OFFSET			0x0150	/* Metric Counter 5
+							Register */
+#define XAPM_INC5_OFFSET		0x0154	/* Incrementer 5 Register */
+#define XAPM_RANGE5_OFFSET		0x0158	/* Range 5 Register */
+#define XAPM_MC5LOGEN_OFFSET		0x015C	/* Metric Counter 5
+							Log Enable Register */
+#define XAPM_MC6_OFFSET			0x0160	/* Metric Counter 6
+							Register */
+#define XAPM_INC6_OFFSET		0x0164	/* Incrementer 6 Register */
+#define XAPM_RANGE6_OFFSET		0x0168	/* Range 6 Register */
+#define XAPM_MC6LOGEN_OFFSET		0x016C	/* Metric Counter 6
+							Log Enable Register */
+#define XAPM_MC7_OFFSET			0x0170	/* Metric Counter 7
+							Register */
+#define XAPM_INC7_OFFSET		0x0174	/* Incrementer 7 Register */
+#define XAPM_RANGE7_OFFSET		0x0178	/* Range 7 Register */
+#define XAPM_MC7LOGEN_OFFSET		0x017C	/* Metric Counter 7
+							Log Enable Register */
+#define XAPM_MC8_OFFSET			0x0180	/* Metric Counter 8
+							Register */
+#define XAPM_INC8_OFFSET		0x0184	/* Incrementer 8 Register */
+#define XAPM_RANGE8_OFFSET		0x0188	/* Range 8 Register */
+#define XAPM_MC8LOGEN_OFFSET		0x018C	/* Metric Counter 8
+							Log Enable Register */
+#define XAPM_MC9_OFFSET			0x0190	/* Metric Counter 9
+							Register */
+#define XAPM_INC9_OFFSET		0x0194	/* Incrementer 9 Register */
+#define XAPM_RANGE9_OFFSET		0x0198	/* Range 9 Register */
+#define XAPM_MC9LOGEN_OFFSET		0x019C	/* Metric Counter 9
+							Log Enable Register */
+
+#define XAPM_MC10_OFFSET		0x01A0	/* Metric Counter 10
+							Register */
+#define XAPM_MC11_OFFSET		0x01B0	/* Metric Counter 11
+							Register */
+#define XAPM_MC12_OFFSET		0x0500	/* Metric Counter 12
+							Register */
+#define XAPM_MC13_OFFSET		0x0510	/* Metric Counter 13
+							Register */
+#define XAPM_MC14_OFFSET		0x0520	/* Metric Counter 14
+							Register */
+#define XAPM_MC15_OFFSET		0x0530	/* Metric Counter 15
+							Register */
+#define XAPM_MC16_OFFSET		0x0540	/* Metric Counter 16
+							Register */
+#define XAPM_MC17_OFFSET		0x0550	/* Metric Counter 17
+							Register */
+#define XAPM_MC18_OFFSET		0x0560	/* Metric Counter 18
+							Register */
+#define XAPM_MC19_OFFSET		0x0570	/* Metric Counter 19
+							Register */
+#define XAPM_MC20_OFFSET		0x0580	/* Metric Counter 20
+							Register */
+#define XAPM_MC21_OFFSET		0x0590	/* Metric Counter 21
+							Register */
+#define XAPM_MC22_OFFSET		0x05A0	/* Metric Counter 22
+							Register */
+#define XAPM_MC23_OFFSET		0x05B0	/* Metric Counter 23
+							Register */
+#define XAPM_MC24_OFFSET		0x0700	/* Metric Counter 24
+							Register */
+#define XAPM_MC25_OFFSET		0x0710	/* Metric Counter 25
+							Register */
+#define XAPM_MC26_OFFSET		0x0720	/* Metric Counter 26
+							Register */
+#define XAPM_MC27_OFFSET		0x0730	/* Metric Counter 27
+							Register */
+#define XAPM_MC28_OFFSET		0x0740	/* Metric Counter 28
+							Register */
+#define XAPM_MC29_OFFSET		0x0750	/* Metric Counter 29
+							Register */
+#define XAPM_MC30_OFFSET		0x0760	/* Metric Counter 30
+							Register */
+#define XAPM_MC31_OFFSET		0x0770	/* Metric Counter 31
+							Register */
+#define XAPM_MC32_OFFSET		0x0780	/* Metric Counter 32
+							Register */
+#define XAPM_MC33_OFFSET		0x0790	/* Metric Counter 33
+							Register */
+#define XAPM_MC34_OFFSET		0x07A0	/* Metric Counter 34
+							Register */
+#define XAPM_MC35_OFFSET		0x07B0	/* Metric Counter 35
+							Register */
+#define XAPM_MC36_OFFSET		0x0900	/* Metric Counter 36
+							Register */
+#define XAPM_MC37_OFFSET		0x0910	/* Metric Counter 37
+							Register */
+#define XAPM_MC38_OFFSET		0x0920	/* Metric Counter 38
+							Register */
+#define XAPM_MC39_OFFSET		0x0930	/* Metric Counter 39
+							Register */
+#define XAPM_MC40_OFFSET		0x0940	/* Metric Counter 40
+							Register */
+#define XAPM_MC41_OFFSET		0x0950	/* Metric Counter 41
+							Register */
+#define XAPM_MC42_OFFSET		0x0960	/* Metric Counter 42
+							Register */
+#define XAPM_MC43_OFFSET		0x0970	/* Metric Counter 43
+							Register */
+#define XAPM_MC44_OFFSET		0x0980	/* Metric Counter 44
+							Register */
+#define XAPM_MC45_OFFSET		0x0990	/* Metric Counter 45
+							Register */
+#define XAPM_MC46_OFFSET		0x09A0	/* Metric Counter 46
+							Register */
+#define XAPM_MC47_OFFSET		0x09B0	/* Metric Counter 47
+							Register */
+
+#define XAPM_SMC0_OFFSET		0x0200	/* Sampled Metric Counter
+							0 Register */
+#define XAPM_SINC0_OFFSET		0x0204	/* Sampled Incrementer
+							0 Register */
+#define XAPM_SMC1_OFFSET		0x0210	/* Sampled Metric Counter
+							1 Register */
+#define XAPM_SINC1_OFFSET		0x0214	/* Sampled Incrementer
+							1 Register */
+#define XAPM_SMC2_OFFSET		0x0220	/* Sampled Metric Counter
+							2 Register */
+#define XAPM_SINC2_OFFSET		0x0224	/* Sampled Incrementer
+							2 Register */
+#define XAPM_SMC3_OFFSET		0x0230	/* Sampled Metric Counter
+							3 Register */
+#define XAPM_SINC3_OFFSET		0x0234	/* Sampled Incrementer
+							3 Register */
+#define XAPM_SMC4_OFFSET		0x0240	/* Sampled Metric Counter
+							4 Register */
+#define XAPM_SINC4_OFFSET		0x0244	/* Sampled Incrementer
+							4 Register */
+#define XAPM_SMC5_OFFSET		0x0250	/* Sampled Metric Counter
+							5 Register */
+#define XAPM_SINC5_OFFSET		0x0254	/* Sampled Incrementer
+							5 Register */
+#define XAPM_SMC6_OFFSET		0x0260	/* Sampled Metric Counter
+							6 Register */
+#define XAPM_SINC6_OFFSET		0x0264	/* Sampled Incrementer
+							6 Register */
+#define XAPM_SMC7_OFFSET		0x0270	/* Sampled Metric Counter
+							7 Register */
+#define XAPM_SINC7_OFFSET		0x0274	/* Sampled Incrementer
+							7 Register */
+#define XAPM_SMC8_OFFSET		0x0280	/* Sampled Metric Counter
+							8 Register */
+#define XAPM_SINC8_OFFSET		0x0284	/* Sampled Incrementer
+							8 Register */
+#define XAPM_SMC9_OFFSET		0x0290	/* Sampled Metric Counter
+							9 Register */
+#define XAPM_SINC9_OFFSET		0x0294	/* Sampled Incrementer
+							9 Register */
+#define XAPM_SMC10_OFFSET		0x02A0	/* Sampled Metric Counter
+							10 Register */
+#define XAPM_SMC11_OFFSET		0x02B0	/* Sampled Metric Counter
+							11 Register */
+#define XAPM_SMC12_OFFSET		0x0600	/* Sampled Metric Counter
+							12 Register */
+#define XAPM_SMC13_OFFSET		0x0610	/* Sampled Metric Counter
+							13 Register */
+#define XAPM_SMC14_OFFSET		0x0620	/* Sampled Metric Counter
+							14 Register */
+#define XAPM_SMC15_OFFSET		0x0630	/* Sampled Metric Counter
+							15 Register */
+#define XAPM_SMC16_OFFSET		0x0640	/* Sampled Metric Counter
+							16 Register */
+#define XAPM_SMC17_OFFSET		0x0650	/* Sampled Metric Counter
+							17 Register */
+#define XAPM_SMC18_OFFSET		0x0660	/* Sampled Metric Counter
+							18 Register */
+#define XAPM_SMC19_OFFSET		0x0670	/* Sampled Metric Counter
+							19 Register */
+#define XAPM_SMC20_OFFSET		0x0680	/* Sampled Metric Counter
+							20 Register */
+#define XAPM_SMC21_OFFSET		0x0690	/* Sampled Metric Counter
+							21 Register */
+#define XAPM_SMC22_OFFSET		0x06A0	/* Sampled Metric Counter
+							22 Register */
+#define XAPM_SMC23_OFFSET		0x06B0	/* Sampled Metric Counter
+							23 Register */
+#define XAPM_SMC24_OFFSET		0x0800	/* Sampled Metric Counter
+							24 Register */
+#define XAPM_SMC25_OFFSET		0x0810	/* Sampled Metric Counter
+							25 Register */
+#define XAPM_SMC26_OFFSET		0x0820	/* Sampled Metric Counter
+							26 Register */
+#define XAPM_SMC27_OFFSET		0x0830	/* Sampled Metric Counter
+							27 Register */
+#define XAPM_SMC28_OFFSET		0x0840	/* Sampled Metric Counter
+							28 Register */
+#define XAPM_SMC29_OFFSET		0x0850	/* Sampled Metric Counter
+							29 Register */
+#define XAPM_SMC30_OFFSET		0x0860	/* Sampled Metric Counter
+							30 Register */
+#define XAPM_SMC31_OFFSET		0x0870	/* Sampled Metric Counter
+							31 Register */
+#define XAPM_SMC32_OFFSET		0x0880	/* Sampled Metric Counter
+							32 Register */
+#define XAPM_SMC33_OFFSET		0x0890	/* Sampled Metric Counter
+							33 Register */
+#define XAPM_SMC34_OFFSET		0x08A0	/* Sampled Metric Counter
+							34 Register */
+#define XAPM_SMC35_OFFSET		0x08B0	/* Sampled Metric Counter
+							35 Register */
+#define XAPM_SMC36_OFFSET		0x0A00	/* Sampled Metric Counter
+							36 Register */
+#define XAPM_SMC37_OFFSET		0x0A10	/* Sampled Metric Counter
+							37 Register */
+#define XAPM_SMC38_OFFSET		0x0A20	/* Sampled Metric Counter
+							38 Register */
+#define XAPM_SMC39_OFFSET		0x0A30	/* Sampled Metric Counter
+							39 Register */
+#define XAPM_SMC40_OFFSET		0x0A40	/* Sampled Metric Counter
+							40 Register */
+#define XAPM_SMC41_OFFSET		0x0A50	/* Sampled Metric Counter
+							41 Register */
+#define XAPM_SMC42_OFFSET		0x0A60	/* Sampled Metric Counter
+							42 Register */
+#define XAPM_SMC43_OFFSET		0x0A70	/* Sampled Metric Counter
+							43 Register */
+#define XAPM_SMC44_OFFSET		0x0A80	/* Sampled Metric Counter
+							44 Register */
+#define XAPM_SMC45_OFFSET		0x0A90	/* Sampled Metric Counter
+							45 Register */
+#define XAPM_SMC46_OFFSET		0x0AA0	/* Sampled Metric Counter
+							46 Register */
+#define XAPM_SMC47_OFFSET		0x0AB0	/* Sampled Metric Counter
+							47 Register */
+
+#define XAPM_CTL_OFFSET			0x0300	/* Control Register */
+
+#define XAPM_ID_OFFSET			0x0304	/* Latency ID Register */
+
+#define XAPM_IDMASK_OFFSET		0x0308	/* ID Mask Register */
+
+#define XAPM_FEC_OFFSET			0x0400	/* flag Enable
+							Control Register */
+
+#define XAPM_SWD_OFFSET			0x0404	/* Software-written
+							Data Register */
+
+#define XAPM_SICR_MCNTR_RST_MASK	0x00000100 /* Enable the Metric
+							Counter Reset */
+#define XAPM_SICR_LOAD_MASK		0x00000002 /* Load the Sample Interval
+							Register Value into
+							the counter */
+#define XAPM_SICR_ENABLE_MASK		0x00000001 /* Enable the downcounter */
+
+#define XAPM_IXR_MC9_OVERFLOW_MASK	0x00001000	/**< Metric Counter 9
+							  *  Overflow> */
+#define XAPM_IXR_MC8_OVERFLOW_MASK	0x00000800	/**< Metric Counter 8
+							  *  Overflow> */
+#define XAPM_IXR_MC7_OVERFLOW_MASK	0x00000400	/**< Metric Counter 7
+							  *  Overflow> */
+#define XAPM_IXR_MC6_OVERFLOW_MASK	0x00000200	/**< Metric Counter 6
+							  *  Overflow> */
+#define XAPM_IXR_MC5_OVERFLOW_MASK	0x00000100	/**< Metric Counter 5
+							  *  Overflow> */
+#define XAPM_IXR_MC4_OVERFLOW_MASK	0x00000080	/**< Metric Counter 4
+							  *  Overflow> */
+#define XAPM_IXR_MC3_OVERFLOW_MASK	0x00000040	/**< Metric Counter 3
+							  *  Overflow> */
+#define XAPM_IXR_MC2_OVERFLOW_MASK	0x00000020	/**< Metric Counter 2
+							  *  Overflow> */
+#define XAPM_IXR_MC1_OVERFLOW_MASK	0x00000010	/**< Metric Counter 1
+							  *  Overflow> */
+#define XAPM_IXR_MC0_OVERFLOW_MASK	0x00000008	/**< Metric Counter 0
+							  *  Overflow> */
+#define XAPM_IXR_FIFO_FULL_MASK		0x00000004	/**< Event Log FIFO
+							  *  full> */
+#define XAPM_IXR_SIC_OVERFLOW_MASK	0x00000002	/**< Sample Interval
+							  * Counter Overflow */
+#define XAPM_IXR_GCC_OVERFLOW_MASK	0x00000001	/**< Global Clock
+							Counter Overflow */
+#define XAPM_IXR_ALL_MASK		(XAPM_IXR_SIC_OVERFLOW_MASK | \
+					XAPM_IXR_GCC_OVERFLOW_MASK |  \
+					XAPM_IXR_FIFO_FULL_MASK | \
+					XAPM_IXR_MC0_OVERFLOW_MASK | \
+					XAPM_IXR_MC1_OVERFLOW_MASK | \
+					XAPM_IXR_MC2_OVERFLOW_MASK | \
+					XAPM_IXR_MC3_OVERFLOW_MASK | \
+					XAPM_IXR_MC4_OVERFLOW_MASK | \
+					XAPM_IXR_MC5_OVERFLOW_MASK | \
+					XAPM_IXR_MC6_OVERFLOW_MASK | \
+					XAPM_IXR_MC7_OVERFLOW_MASK | \
+					XAPM_IXR_MC8_OVERFLOW_MASK | \
+					XAPM_IXR_MC9_OVERFLOW_MASK)
+
+#define XAPM_CR_FIFO_RESET_MASK			0x02000000
+						/**< FIFO Reset */
+#define XAPM_CR_MUXSEL_MASK			0x01000000
+						/**< Mux Selector mask */
+#define XAPM_CR_GCC_RESET_MASK			0x00020000
+						/**< Global Clk
+						  Counter Reset */
+#define XAPM_CR_GCC_ENABLE_MASK			0x00010000
+						/**< Global Clk
+						   Counter Enable */
+#define XAPM_CR_EVTLOG_EXTTRIGGER_MASK		0x00000200
+						/**< Enable External trigger
+						to start event Log */
+#define XAPM_CR_EVENTLOG_ENABLE_MASK		0x00000100
+						/**< Event Log Enable */
+#define XAPM_CR_RDLATENCY_END_MASK		0x00000080
+						/**< Write Latency
+							End point */
+#define XAPM_CR_RDLATENCY_START_MASK		0x00000040
+						/**< Read Latency
+							Start point */
+#define XAPM_CR_WRLATENCY_END_MASK		0x00000020
+						/**< Write Latency
+							End point */
+#define XAPM_CR_WRLATENCY_START_MASK		0x00000010
+						/**< Write Latency
+							Start point */
+#define XAPM_CR_IDFILTER_ENABLE_MASK		0x00000008
+						/**< ID Filter Enable */
+#define XAPM_CR_MCNTR_EXTTRIGGER_MASK		0x00000004
+						/**< Enable External
+						   trigger to start
+						   Metric Counters  */
+#define XAPM_CR_MCNTR_RESET_MASK		0x00000002
+						/**< Metrics Counter
+						   Reset */
+#define XAPM_CR_MCNTR_ENABLE_MASK		0x00000001
+						/**< Metrics Counter
+							Enable */
+
+#define XAPM_ID_RID_MASK			0xFFFF0000 /**< Read ID */
+
+#define XAPM_ID_WID_MASK			0x0000FFFF /**< Write ID */
+
+#define XAPM_MASKID_RID_MASK			0xFFFF0000 /**< Read ID Mask */
+
+#define XAPM_MASKID_WID_MASK			0x0000FFFF /**< Write ID Mask*/
+
+
+#define XAPM_MAX_COUNTERS		10 /**< Maximum number of Counters */
+#define XAPM_MAX_COUNTERS_PROFILE	48 /**< Maximum number of Counters in
+						profile mode */
+
+#define XAPM_METRIC_COUNTER_0	0 /**< Metric Counter 0 Register Index */
+#define XAPM_METRIC_COUNTER_1	1 /**< Metric Counter 1 Register Index */
+#define XAPM_METRIC_COUNTER_2	2 /**< Metric Counter 2 Register Index */
+#define XAPM_METRIC_COUNTER_3	3 /**< Metric Counter 3 Register Index */
+#define XAPM_METRIC_COUNTER_4	4 /**< Metric Counter 4 Register Index */
+#define XAPM_METRIC_COUNTER_5	5 /**< Metric Counter 5 Register Index */
+#define XAPM_METRIC_COUNTER_6	6 /**< Metric Counter 6 Register Index */
+#define XAPM_METRIC_COUNTER_7	7 /**< Metric Counter 7 Register Index */
+#define XAPM_METRIC_COUNTER_8	8 /**< Metric Counter 8 Register Index */
+#define XAPM_METRIC_COUNTER_9	9 /**< Metric Counter 9 Register Index */
+
+#define XAPM_INCREMENTER_0	0 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_1	1 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_2	2 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_3	3 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_4	4 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_5	5 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_6	6 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_7	7 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_8	8 /**< Metric Counter 0 Register Index */
+#define XAPM_INCREMENTER_9	9 /**< Metric Counter 0 Register Index */
+
+#define XAPM_METRIC_SET_0	0 /**< Write Transaction Count */
+#define XAPM_METRIC_SET_1	1 /**< Read Transaction Count */
+#define XAPM_METRIC_SET_2	2 /**< Write Byte Count */
+#define XAPM_METRIC_SET_3	3 /**< Read Byte Count */
+#define XAPM_METRIC_SET_4	4 /**< Write Beat Count */
+#define XAPM_METRIC_SET_5	5 /**< Total Read Latency */
+#define XAPM_METRIC_SET_6	6 /**< Total Write Latency */
+#define XAPM_METRIC_SET_7	7 /**< Slv_Wr_Idle_Cnt */
+#define XAPM_METRIC_SET_8	8 /**< Mst_Rd_Idle_Cnt */
+#define XAPM_METRIC_SET_9	9 /**< Num_BValids */
+#define XAPM_METRIC_SET_10	10 /**< Num_WLasts */
+#define XAPM_METRIC_SET_11	11 /**< Num_RLasts */
+#define XAPM_METRIC_SET_12	12 /**< Minimum Write Latency */
+#define XAPM_METRIC_SET_13	13 /**< Maximum Write Latency */
+#define XAPM_METRIC_SET_14	14 /**< Minimum Read Latency */
+#define XAPM_METRIC_SET_15	15 /**< Maximum Read Latency */
+#define XAPM_METRIC_SET_16	16 /**< Transfer Cycle Count */
+#define XAPM_METRIC_SET_17	17 /**< Packet Count */
+#define XAPM_METRIC_SET_18	18 /**< Data Byte Count */
+#define XAPM_METRIC_SET_19	19 /**< Position Byte Count */
+#define XAPM_METRIC_SET_20	20 /**< Null Byte Count */
+#define XAPM_METRIC_SET_21	21 /**< Slv_Idle_Cnt */
+#define XAPM_METRIC_SET_22	22 /**< Mst_Idle_Cnt */
+#define XAPM_METRIC_SET_30	30 /**< External event count */
+
+#define XAPM_MAX_AGENTS		8 /**< Maximum number of Agents */
+
+#define XAPM_FLAG_WRADDR	0x00000001 /**< Write Address flag */
+#define XAPM_FLAG_FIRSTWR	0x00000002 /**< First Write flag */
+#define XAPM_FLAG_LASTWR	0x00000004 /**< Last Write flag */
+#define XAPM_FLAG_RESPONSE	0x00000008 /**< Response flag */
+#define XAPM_FLAG_RDADDR	0x00000010 /**< Read Address flag */
+#define XAPM_FLAG_FIRSTRD	0x00000020 /**< First Read flag */
+#define XAPM_FLAG_LASTRD	0x00000040 /**< Last Read flag */
+#define XAPM_FLAG_SWDATA	0x00010000 /**< Software-written Data flag */
+#define XAPM_FLAG_EVENT		0x00020000 /**< Last Read flag */
+#define XAPM_FLAG_EVNTSTOP	0x00040000 /**< Last Read flag */
+#define XAPM_FLAG_EVNTSTART	0x00080000 /**< Last Read flag */
+#define XAPM_FLAG_GCCOVF	0x00100000 /**< Global Clock Counter Overflow
+					     *  flag */
+#define XAPM_FLAG_SCLAPSE	0x00200000 /**< Sample Counter Lapse flag */
+#define XAPM_FLAG_MC0		0x00400000 /**< Metric Counter 0 flag */
+#define XAPM_FLAG_MC1		0x00800000 /**< Metric Counter 1 flag */
+#define XAPM_FLAG_MC2		0x01000000 /**< Metric Counter 2 flag */
+#define XAPM_FLAG_MC3		0x02000000 /**< Metric Counter 3 flag */
+#define XAPM_FLAG_MC4		0x04000000 /**< Metric Counter 4 flag */
+#define XAPM_FLAG_MC5		0x08000000 /**< Metric Counter 5 flag */
+#define XAPM_FLAG_MC6		0x10000000 /**< Metric Counter 6 flag */
+#define XAPM_FLAG_MC7		0x20000000 /**< Metric Counter 7 flag */
+#define XAPM_FLAG_MC8		0x40000000 /**< Metric Counter 8 flag */
+#define XAPM_FLAG_MC9		0x80000000 /**< Metric Counter 9 flag */
+
+#define XAPM_LATENCY_ADDR_ISSUE		0 /**< Address Issue as start
+					point for Latency calculation*/
+#define XAPM_LATENCY_ADDR_ACCEPT	1 /**< Address Acceptance as start
+					point for Latency calculation*/
+#define XAPM_LATENCY_LASTRD		0 /**< Last Read as end point for
+					Latency calculation */
+#define XAPM_LATENCY_LASTWR		0 /**< Last Write as end point for
+					Latency calculation */
+#define XAPM_LATENCY_FIRSTRD		1 /**< First Read as end point for
+					Latency calculation */
+#define XAPM_LATENCY_FIRSTWR		1 /**< First Write as end point for
+					Latency calculation */
+
+#define XAPM_MODE_TRACE			2 /**< APM in Trace mode */
+
+#define XAPM_MODE_PROFILE		1 /**< APM in Profile mode */
+
+#define XAPM_MODE_ADVANCED		0 /**< APM in Advanced mode */
+
+typedef unsigned char u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+u32 baseaddr;
+
+struct xapm_param {
+	u32	mode;
+	u32	maxslots;
+	u32	eventcnt;
+	u32	eventlog;
+	u32	sampledcnt;
+	u32	numcounters;
+	u32	metricwidth;
+	u32	sampledwidth;
+	u32	globalcntwidth;
+	u32     scalefactor;
+	u32	isr;
+};
+
+static struct xapm_param *params;
+
+/*****************************************************************************/
+/**
+*
+* Read a register of the AXI Performance Monitor device. This macro provides
+* register access to all registers using the register offsets defined above.
+*
+* @param	baseaddr contains the base address of the device.
+* @param	regoffset is the offset of the register to read.
+*
+* @return	The contents of the register.
+*
+* @note		C-style Signature:
+*		u32 readreg(u32 baseaddr, u32 regoffset);
+*
+******************************************************************************/
+#define readreg(baseaddr, regoffset) \
+			(*(u32 *)(baseaddr + regoffset))
+
+/*****************************************************************************/
+/**
+*
+* Write a register of the AXI Performance Monitor device. This macro provides
+* register access to all registers using the register offsets defined above.
+*
+* @param	baseaddr contains the base address of the device.
+* @param	regoffset is the offset of the register to write.
+* @param	data is the value to write to the register.
+*
+* @return	None.
+*
+* @note		C-style Signature:
+*		void writereg(u32 baseaddr,
+*					u32 regoffset,u32 Data)
+*
+******************************************************************************/
+#define writereg(baseaddr, regoffset, data) \
+				(*(u32 *)(baseaddr + regoffset) = data)
+
+/****************************************************************************/
+/**
+*
+* This routine enables the Global Interrupt.
+*
+* @note		C-Style signature:
+*		void intrglobalenable()
+*
+*****************************************************************************/
+#define intrglobalenable()			\
+		writereg(baseaddr, XAPM_GIE_OFFSET, 1)
+
+
+/****************************************************************************/
+/**
+*
+* This routine disables the Global Interrupt.
+*
+* @note		C-Style signature:
+*		void intrglobaldisable(void)
+*
+*****************************************************************************/
+#define intrglobaldisable()				\
+		writereg(baseaddr, XAPM_GIE_OFFSET, 0)
+
+/****************************************************************************/
+/**
+*
+* This routine enables interrupt(s). Use the XAPM_IXR_* constants defined in
+* xaxipmon_hw.h to create the bit-mask to enable interrupts.
+*
+* @param	mask is the mask to enable. Bit positions of 1 will be enabled.
+*		Bit positions of 0 will keep the previous setting. This mask is
+*		formed by OR'ing XAPM_IXR__* bits defined in xaxipmon_hw.h.
+*
+* @return	None.
+*
+* @note		C-Style signature:
+*		void intrenable(u32 mask)
+*
+*****************************************************************************/
+#define intrenable(mask)				     \
+	writereg(baseaddr, XAPM_IE_OFFSET, readreg(baseaddr, \
+			XAPM_IE_OFFSET) | mask);
+
+
+/****************************************************************************/
+/**
+*
+* This routine disable interrupt(s). Use the XAPM_IXR_* constants defined in
+* xaxipmon_hw.h to create the bit-mask to disable interrupts.
+*
+* @param	mask is the mask to disable. Bit positions of 1 will be
+*		disabled. Bit positions of 0 will keep the previous setting.
+*		This mask is formed by OR'ing XAPM_IXR_* bits defined in
+*		xaxipmon_hw.h.
+*
+* @return	None.
+*
+* @note		C-Style signature:
+*		void intrdisable(u32 mask)
+*
+*****************************************************************************/
+#define intrdisable(mask)				     \
+	writereg(baseaddr, XAPM_IE_OFFSET, readreg(baseaddr, \
+						XAPM_IE_OFFSET) | mask);
+
+/****************************************************************************/
+/**
+*
+* This routine clears the specified interrupt(s).
+*
+* @param	mask is the mask to clear. Bit positions of 1 will be cleared.
+*		This mask is formed by OR'ing XAPM_IXR_* bits defined in
+*		xaxipmon_hw.h.
+*
+* @return	None.
+*
+* @note		C-Style signature:
+*		void intrclear(u32 mask)
+*
+*****************************************************************************/
+#define intrclear(mask)				     \
+	writereg(baseaddr, XAPM_IS_OFFSET, readreg(baseaddr, \
+				XAPM_IS_OFFSET) | mask);
+
+/****************************************************************************/
+/**
+*
+* This routine returns the Interrupt Status Register.
+*
+* @return	isr value updated by kernel driver
+*
+* @note		This macro returns isr value updated by kernel driver.
+*		C-Style signature:
+*		void intrgetstatus(void)
+*
+*****************************************************************************/
+#define intrgetstatus()		(params->isr)
+
+/****************************************************************************/
+/**
+*
+* This routine returns the Interrupt Status Register.
+*
+* @return       Interrupt Status Register contents
+*
+* @note         C-Style signature:
+*               void intrhwgetstatus(void)
+*
+*****************************************************************************/
+#define intrhwgetstatus()         (params->isr)
+
+/****************************************************************************/
+/**
+*
+* This function enables the Global Clock Counter.
+*
+* @note		C-Style signature:
+*		void enablegcc(void);
+*
+*****************************************************************************/
+#define enablegcc() \
+	writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr, \
+			XAPM_CTL_OFFSET) | XAPM_CR_GCC_ENABLE_MASK);
+
+/****************************************************************************/
+/**
+*
+* This function disbles the Global Clock Counter.
+*
+* @note		C-Style signature:
+*		void disablegcc(void);
+*
+*****************************************************************************/
+#define disablegcc() \
+	writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr, \
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_GCC_ENABLE_MASK));
+
+/****************************************************************************/
+/**
+*
+* This function enables the specified flag in flag Control Register.
+*
+* @param	flag is one of the XAPM_FLAG_* masks defined in xaxipmon.h
+*
+* @return	None
+*
+* @note		C-Style signature:
+*		void enableflag(void);
+*
+*****************************************************************************/
+#define enableflag(flag) \
+	writereg(baseaddr, XAPM_FEC_OFFSET, \
+			readreg(baseaddr, XAPM_FEC_OFFSET) | flag);
+
+/****************************************************************************/
+/**
+*
+* This function disables the specified flag in flag Control Register.
+*
+* @param	flag is one of the XAPM_FLAG_* masks defined in xaxipmon.h*
+* @return	None
+*
+* @note		C-Style signature:
+*		void disableflag(void);
+*
+*****************************************************************************/
+#define disableflag(flag) \
+	writereg(baseaddr, XAPM_FEC_OFFSET, \
+			readreg(baseaddr, XAPM_FEC_OFFSET) & ~(flag));
+
+/****************************************************************************/
+/**
+*
+* This function loads the sample interval register value into the sample
+* interval counter.
+*
+* @note		C-Style signature:
+*		void loadsic(void);
+*
+*****************************************************************************/
+#define loadsic() \
+		writereg(baseaddr, XAPM_SICR_OFFSET, XAPM_SICR_LOAD_MASK)
+
+
+/****************************************************************************/
+/**
+*
+* This enables the down count of the sample interval counter.
+*
+* @note		C-Style signature:
+*	   void enablesic(void);
+*
+*****************************************************************************/
+#define enablesic() \
+	writereg(baseaddr, XAPM_SICR_OFFSET, XAPM_SICR_ENABLE_MASK)
+
+/****************************************************************************/
+/**
+*
+* This disables the down count of the sample interval counter.
+*
+* @note		C-Style signature:
+*	    void disablesic(void);
+*
+*****************************************************************************/
+#define disablesic() \
+	writereg(baseaddr, XAPM_SICR_OFFSET, \
+	readreg(baseaddr, XAPM_SICR_OFFSET) & ~(XAPM_SICR_ENABLE_MASK));
+
+/****************************************************************************/
+/**
+*
+* This enables Reset of Metric Counters when Sample Interval Counter lapses.
+*
+* @note		C-Style signature:
+*		void enablemcreset(void);
+*
+*****************************************************************************/
+#define enablemcreset() \
+	writereg(baseaddr, XAPM_SICR_OFFSET, XAPM_SICR_MCNTR_RST_MASK);
+
+/****************************************************************************/
+/**
+*
+* This disables the down count of the sample interval counter.
+*
+* @note		C-Style signature:
+*		void disablemcreset(void);
+*
+*****************************************************************************/
+#define disablemcreset() \
+	writereg(baseaddr, XAPM_SICR_OFFSET, \
+	readreg(baseaddr, XAPM_SICR_OFFSET) & ~(XAPM_SICR_MCNTR_RST_MASK));
+
+/****************************************************************************/
+/**
+*
+* This function enables the ID Filter Masking.
+*
+* @note		C-Style signature:
+*		void enableidfilter(void);
+*
+*****************************************************************************/
+#define enableidfilter()			\
+	writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr, \
+			XAPM_CTL_OFFSET) | XAPM_CR_IDFILTER_ENABLE_MASK);
+
+/****************************************************************************/
+/**
+*
+* This function disbles the ID Filter masking.
+*
+* @note		C-Style signature:
+*		void disableidfilter(void);
+*
+*****************************************************************************/
+#define disableidfilter() \
+	writereg(baseaddr, XAPM_CTL_OFFSET, readreg(baseaddr, \
+			XAPM_CTL_OFFSET) & ~(XAPM_CR_IDFILTER_ENABLE_MASK));
+
+/****************************************************************************/
+/**
+*
+* This function samples Metric Counters to Sampled Metric Counters by
+* reading Sample Register and also returns interval. i.e. the number of
+* clocks in between previous read to the current read of sample register.
+*
+* @return	Interval. i.e. the number of clocks in between previous
+*		read to the current read of sample register.
+*
+* @note		C-Style signature:
+*		u32 samplemetrics(void);
+*
+*****************************************************************************/
+#define samplemetrics()		readreg(baseaddr, XAPM_SR_OFFSET);
+
+
+/************************** Function Prototypes *****************************/
+
+int resetmetriccounter(void);
+
+void resetglobalclkcounter(void);
+
+int resetfifo(void);
+
+void setincrementerrange(u8 incrementer, u16 rangehigh, u16 rangelow);
+
+void getincrementerrange(u8 incrementer, u16 *rangehigh, u16 *rangelow);
+
+void setsampleinterval(u32 sampleinterval);
+
+void getsampleinterval(u32 *sampleinterval);
+
+int setmetrics(u8 slot, u8 metrics, u8 counter);
+
+int getmetrics(u8 counter, u8 *metrics, u8 *slot);
+void getglobalclkcounter(u32 *cnthigh, u32 *cntlow);
+
+u32 getmetriccounter(u32 counter);
+
+u32 getsampledmetriccounter(u32 counter);
+
+u32 getincrementer(u32 incrementer);
+
+u32 getsampledincrementer(u32 incrementer);
+
+void setswdatareg(u32 swdata);
+
+u32 getswdatareg(void);
+
+int starteventlog(u32 flagenables);
+
+int stopeventlog(void);
+
+int startcounters(u32 sampleinterval);
+
+int stopcounters(void);
+
+void enablemetricscounter(void);
+
+void disablemetricscounter(void);
+
+void setlogenableranges(u32 counter, u16 rangehigh, u16 rangelow);
+
+void getlogenableranges(u32 counter, u16 *rangehigh, u16 *rangelow);
+
+void enableeventlog(void);
+
+void enablemctrigger(void);
+
+void disablemctrigger(void);
+
+void enableeventlogtrigger(void);
+
+void disableeventlogtrigger(void);
+
+const char *getmetricname(u8 metrics);
+
+void setwriteid(u16 writeid);
+
+void setreadid(u16 readid);
+
+u16 getwriteid(void);
+
+u16 getreadid(void);
+
+void setwrlatencystart(u8 param);
+
+void setwrlatencyend(u8 param);
+
+void setrdlatencystart(u8 param);
+
+void setrdlatencyend(u8 param);
+
+u8 getwrlatencystart(void);
+
+u8 getwrlatencyend(void);
+
+u8 getrdlatencystart(void);
+
+u8 getrdlatencyend(void);
+
+void setwriteidmask(u16 wrmask);
+
+void setreadidmask(u16 rdmask);
+
+u16 getwriteidmask(void);
+
+u16 getreadidmask(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* End of protection macro. */
Index: linux-3.12.24-rt38-xilinx/scripts/package/builddeb
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/scripts/package/builddeb	2014-07-20 22:05:50.325065152 +0200
+++ linux-3.12.24-rt38-xilinx/scripts/package/builddeb	2014-07-20 22:06:39.997245662 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:82 @
 kernel_headers_dir="$objtree/debian/hdrtmp"
 libc_headers_dir="$objtree/debian/headertmp"
 dbg_dir="$objtree/debian/dbgtmp"
-packagename=linux-image-$version
-fwpackagename=linux-firmware-image-$version
-kernel_headers_packagename=linux-headers-$version
+packagename=linux-image-zedboard-$version
+fwpackagename=linux-firmware-image-zedboard-$version
+kernel_headers_packagename=linux-headers-zedboard-$version
 libc_headers_packagename=linux-libc-dev
 dbg_packagename=$packagename-dbg
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:139 @
 fi
 # Not all arches include the boot path in KBUILD_IMAGE
 if [ -e $KBUILD_IMAGE ]; then
-	cp $KBUILD_IMAGE "$tmpdir/$installed_image_path"
+	cp $KBUILD_IMAGE "$tmpdir/boot/"
 else
-	cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/$installed_image_path"
+	cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/"
 fi
 
+cp arch/arm/boot/dts/zynq-zed.dtb "$tmpdir/boot/"
+
 if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then
 	INSTALL_MOD_PATH="$tmpdir" $MAKE KBUILD_SRC= modules_install
 	rm -f "$tmpdir/lib/modules/$version/build"
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:212 @
 fi
 maintainer="$name <$email>"
 
+mkdir -p debian/source
+# Generate a source format template
+cat <<EOF > debian/source/format
+3.0 (git)
+EOF
+
+# Generate the source option file
+cat <<EOF > debian/source/options
+git-ref=HEAD
+git-depth=3
+EOF
+
 # Generate a simple changelog template
 cat <<EOF > debian/changelog
-linux-upstream ($packageversion) unstable; urgency=low
+$packagename ($KDEB_PKGVERSION) unstable; urgency=low
 
   * Custom built Linux kernel.
 
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:255 @
 
 # Generate a control file
 cat <<EOF > debian/control
-Source: linux-upstream
+Source: $packagename
 Section: kernel
 Priority: optional
 Maintainer: $maintainer
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:325 @
 	cat <<EOF >> debian/control
 
 Package: $fwpackagename
-Architecture: all
+Architecture: any
 Description: Linux kernel firmware, version $version
  This package contains firmware from the Linux kernel, version $version.
 EOF
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:377 @
 	create_package "$dbg_packagename" "$dbg_dir"
 fi
 
+if [ -x source ] ; then
+	mkdir -p source/debian
+	cp debian/changelog source/debian/
+	cp debian/control source/debian/
+	cp debian/copyright source/debian/
+	cp -a debian/source source/debian/
+	cp .config source/config
+	cd source
+	git add -f debian/changelog
+	git add -f debian/control
+	git add -f debian/copyright
+	git add -f debian/source
+	git commit -sm "add debian directory"
+	git add -f config
+	git commit -sm "add kernel config"
+	dpkg-source -b .
+
+	git reset --hard HEAD~2
+else
+	cp .config config
+	git add -f debian/changelog
+	git add -f debian/control
+	git add -f debian/copyright
+	git add -f debian/source
+	git commit -sm "add debian directory"
+	git add -f config
+	git commit -sm "add kernel config"
+
+	dpkg-source -b .
+
+	git reset --hard HEAD~2
+fi
+
 exit 0
Index: linux-3.12.24-rt38-xilinx/scripts/sortextable.c
===================================================================
--- linux-3.12.24-rt38-xilinx.orig/scripts/sortextable.c	2014-07-20 22:05:50.324065169 +0200
+++ linux-3.12.24-rt38-xilinx/scripts/sortextable.c	2014-07-20 22:06:40.007245497 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:38 @
 #define EM_AARCH64	183
 #endif
 
+#ifndef EM_MICROBLAZE
+#define EM_MICROBLAZE	189
+#endif
+
 static int fd_map;	/* File descriptor for file being modified. */
 static int mmap_failed; /* Boolean flag. */
 static void *ehdr_curr; /* current ElfXX_Ehdr *  for resource cleanup */
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:253 @
 		break;
 	case EM_ARM:
 	case EM_AARCH64:
+	case EM_MICROBLAZE:
 	case EM_MIPS:
 		break;
 	}  /* end switch */
Index: linux-3.12.24-rt38-xilinx/tools/rpmsg_proto.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/tools/rpmsg_proto.c	2014-07-20 22:06:40.018245315 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../include/net/rpmsg.h"
+
+#define M3_CORE0	(0)
+
+int main(void)
+{
+	int sock, sock2, err;
+	struct sockaddr_rpmsg src_addr, dst_addr;
+	socklen_t len;
+	const char *msg = "Hello there!";
+	char buf[512];
+
+	/* create an RPMSG socket */
+	sock = socket(AF_RPMSG, SOCK_SEQPACKET, 0);
+	if (sock < 0) {
+		printf("socket failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	/* connect to remote service */
+	memset(&dst_addr, 0, sizeof(dst_addr));
+	dst_addr.family = AF_RPMSG;
+	dst_addr.vproc_id = M3_CORE0;
+	dst_addr.addr = 51;
+
+	printf("Connecting to address 0x%x on processor %d\n",
+					dst_addr.addr, dst_addr.vproc_id);
+
+	len = sizeof(struct sockaddr_rpmsg);
+	err = connect(sock, (struct sockaddr *)&dst_addr, len);
+	if (err < 0) {
+		printf("connect failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	/* let's see what local address did we get */
+	err = getsockname(sock, (struct sockaddr *)&src_addr, &len);
+	if (err < 0) {
+		printf("getpeername failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	printf("Our address: socket family: %d, proc id = %d, addr = %d\n",
+			src_addr.family, src_addr.vproc_id, src_addr.addr);
+
+	printf("Sending \"%s\"\n", msg);
+	err = send(sock, msg, strlen(msg) + 1, 0);
+	if (err < 0) {
+		printf("sendto failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	memset(&src_addr, 0, sizeof(src_addr));
+
+	len = sizeof(src_addr);
+
+	err = recvfrom(sock, buf, sizeof(buf), 0,
+					(struct sockaddr *)&src_addr, &len);
+	if (err < 0) {
+		printf("recvfrom failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+	if (len != sizeof(src_addr)) {
+		printf("recvfrom: got bad addr len (%d)\n", len);
+		return -1;
+	}
+
+	printf("Received a msg from address 0x%x on processor %d\n",
+					src_addr.addr, src_addr.vproc_id);
+	printf("Message content: \"%s\".\n", buf);
+
+
+	close(sock);
+
+	/* create another RPMSG socket */
+	sock2 = socket(AF_RPMSG, SOCK_SEQPACKET, 0);
+	if (sock2 < 0) {
+		printf("socket failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	/* bind a local addr */
+	memset(&src_addr, 0, sizeof(src_addr));
+	src_addr.family = AF_RPMSG;
+	src_addr.vproc_id = M3_CORE0;
+	src_addr.addr = 99;
+
+
+	printf("Exposing address %d to processor %d\n",
+					src_addr.addr, src_addr.vproc_id);
+
+	len = sizeof(struct sockaddr_rpmsg);
+	err = bind(sock2, (struct sockaddr *)&src_addr, len);
+	if (err < 0) {
+		printf("bind failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	/* let's see what local address did we bind */
+	err = getsockname(sock2, (struct sockaddr *)&src_addr, &len);
+	if (err < 0) {
+		printf("getpeername failed: %s (%d)\n", strerror(errno), errno);
+		return -1;
+	}
+
+	printf("Our address: socket family: %d, proc id = %d, addr = %d\n",
+			src_addr.family, src_addr.vproc_id, src_addr.addr);
+
+	return 0;
+}
Index: linux-3.12.24-rt38-xilinx/tools/test_rpmsg_omx.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-3.12.24-rt38-xilinx/tools/test_rpmsg_omx.c	2014-07-20 22:06:40.026245183 +0200
@ linux-3.12.24-rt38-xilinx/arch/arm/boot/bootp/Makefile:4 @
+/*
+ * test_rpmsg_omx
+ *
+ * user space testing tool for the rpmsg_omx driver
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ *
+ *   Neither the name of Texas Instruments Incorporated nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/eventfd.h>
+
+#include "../include/linux/rpmsg_omx.h"
+
+static pthread_t listener;
+static int omxfd;
+static int die_now_fd;
+
+static void *listener_cb(void *arg)
+{
+	fd_set rfds;
+	struct timeval tv;
+	int ret = 0, maxfd;
+	char buf[512];
+
+	do {
+		/* Wait for OMX messages or self die_now notification */
+		FD_ZERO(&rfds);
+		FD_SET(omxfd, &rfds);
+		FD_SET(die_now_fd, &rfds);
+
+		maxfd = (die_now_fd > omxfd ? die_now_fd : omxfd) + 1;
+		ret = select(maxfd, &rfds, NULL, NULL, NULL);
+		if (ret == -1) {
+			perror("select()");
+			break;
+		}
+
+		if (FD_ISSET(omxfd, &rfds)) {
+			ret = read(omxfd, buf, sizeof(buf));
+			if (ret < 0) {
+				perror("Can't connect to OMX instance");
+				break;
+			}
+
+			printf("RX: %s\n", buf);
+		}
+
+		if (FD_ISSET(die_now_fd, &rfds)) {
+			printf("Need to die!\n");
+			break;
+		}
+
+	} while (1);
+
+	return (void *)ret;
+}
+
+int send_messages(void)
+{
+	const char *msg = "Hello there!";
+	int ret, i;
+
+	/* blather */
+	for (i = 0; i < 10; i++) {
+		ret = write(omxfd, msg, strlen(msg) + 1);
+		if (ret < 0) {
+			perror("Can't connect to OMX instance");
+			return -1;
+		}
+
+		printf("TX: %s\n", msg);
+		sleep(5);
+	}
+
+	return i;
+}
+
+int main(void)
+{
+	int ret;
+	uint64_t die_event = 1;
+	ssize_t s;
+	struct omx_conn_req connreq = { .name = "OMX" };
+
+	/* open the first OMX device */
+	omxfd = open("/dev/rpmsg-omx0", O_RDWR);
+	if (omxfd < 0) {
+		perror("Can't open OMX device");
+		return 1;
+	}
+
+	printf("Connecting to %s\n", connreq.name);
+	/* connect to an h264_decode instance */
+	ret = ioctl(omxfd, OMX_IOCCONNECT, &connreq);
+	if (ret < 0) {
+		perror("Can't connect to OMX instance");
+		return 1;
+	}
+
+	printf("Connected!\n", connreq.name);
+
+	die_now_fd = eventfd(0, 0);
+	if (die_now_fd < 0) {
+		perror("eventfd failed");
+		return 1;
+	}
+
+	ret = pthread_create(&listener, NULL, listener_cb, NULL);
+	if (ret) {
+		printf("can't spawn thread: %s\n", strerror(ret));
+		return 1;
+	}
+
+	ret = send_messages();
+	if (ret < 0)
+		return 1;
+
+	/* terminate connection and destroy OMX instance */
+	ret = close(omxfd);
+	if (ret < 0) {
+		perror("Can't close OMX fd ??");
+		return 1;
+	}
+
+	s = write(die_now_fd, &die_event, sizeof(uint64_t));
+	if (s != sizeof(uint64_t)) {
+		printf("failed to write die_now event\n");
+		return 1;
+	}
+
+	ret = pthread_join(listener, NULL);
+	if (ret) {
+		printf("can't join thread: %s\n", strerror(ret));
+		return 1;
+	}
+
+	printf("Bye!\n");
+
+	return 0;
+}